Significant revamp of RigState to only send changes. Not done yet.
This commit is contained in:
parent
5b395cd922
commit
e5de516633
@ -1474,15 +1474,7 @@ void checkAutoSaveFreqMode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rigState.vfo[0] = vfoA;
|
rigState.begin();
|
||||||
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(){
|
void loop(){
|
||||||
|
@ -340,10 +340,4 @@ extern void DisplayVersionInfo(const char* fwVersionInfo);
|
|||||||
//I2C Signal Meter, Version 1.097
|
//I2C Signal Meter, Version 1.097
|
||||||
extern int GetI2CSmeterValue(int valueType); //ubitx_ui.ino
|
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;
|
|
||||||
|
|
||||||
#endif //end of if header define
|
#endif //end of if header define
|
||||||
|
@ -990,16 +990,14 @@ void SWS_Process(void)
|
|||||||
char checkCount = 0;
|
char checkCount = 0;
|
||||||
char checkCountSMeter = 0;
|
char checkCountSMeter = 0;
|
||||||
|
|
||||||
UBitxRigState rigState;
|
|
||||||
UBitxRigState catState;
|
|
||||||
|
|
||||||
//execute interval : 0.25sec
|
//execute interval : 0.25sec
|
||||||
void idle_process()
|
void idle_process()
|
||||||
{
|
{
|
||||||
// KC4UPR 2021-02-05 added update process for Raduino-TeensyDSP coordination
|
// KC4UPR 2021-02-05 added update process for Raduino-TeensyDSP coordination
|
||||||
updateStateFromRaduino(rigState);
|
rigState.update();
|
||||||
doRaduinoToTeensy(&rigState);
|
//updateStateFromRaduino(rigState);
|
||||||
updateRaduinoFromState(rigState);
|
//doRaduinoToTeensy(&rigState);
|
||||||
|
//updateRaduinoFromState(rigState);
|
||||||
|
|
||||||
//S-Meter Display
|
//S-Meter Display
|
||||||
if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency))
|
if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency))
|
||||||
|
@ -299,94 +299,3 @@ int GetI2CSmeterValue(int valueType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
void doRaduinoToTeensy(UBitxRigState* r) {
|
|
||||||
uint8_t* ptr = (uint8_t*)r;
|
|
||||||
|
|
||||||
Wire.beginTransmission(I2CMETER_ADDR);
|
|
||||||
Wire.write(I2CMETER_RIGINF);
|
|
||||||
//for (size_t i = 0; i < sizeof(UBitxRigState); i++) {
|
|
||||||
// Wire.write(ptr[i]);
|
|
||||||
//}
|
|
||||||
//Note, I can switch this back...
|
|
||||||
Wire.write(ptr, sizeof(UBitxRigState));
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
Serial.println("BEFORE:");
|
|
||||||
Serial.print("VFO A: ");
|
|
||||||
Serial.print(r->vfo[0]);
|
|
||||||
Serial.print(", VFO B: ");
|
|
||||||
Serial.print(r->vfo[1]);
|
|
||||||
Serial.print(", Data Size: ");
|
|
||||||
Serial.print(sizeof(UBitxRigState));
|
|
||||||
Serial.println();
|
|
||||||
|
|
||||||
// First we need to see if there's any updated state.
|
|
||||||
Wire.requestFrom(I2CMETER_ADDR, sizeof(uint8_t));
|
|
||||||
int len = 0;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
if (rigState.vfo[1] != frequency) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
457
TeensyDSP/RigState.cpp
Normal file
457
TeensyDSP/RigState.cpp
Normal file
@ -0,0 +1,457 @@
|
|||||||
|
#include "RigState.h"
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
// Handle the case of the TeensyDSP.
|
||||||
|
|
||||||
|
#ifdef TEENSYDUINO
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
bool readVFOA(uint32_t* d) {
|
||||||
|
unsigned freq = (vfoActive == VFO_A) ? frequency : vfoA;
|
||||||
|
if (*d == freq) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
*d = freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeVFOA(uint32_t d) {
|
||||||
|
if (vfoActive == VFO_A) {
|
||||||
|
setFrequency(d);
|
||||||
|
} else {
|
||||||
|
vfoA = frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readVFOB(uint32_t* d) {
|
||||||
|
unsigned freq = (vfoActive == VFO_B) ? frequency : vfoB;
|
||||||
|
if (*d == freq) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
*d = freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeVFOB(uint32_t d) {
|
||||||
|
if (vfoActive == VFO_B) {
|
||||||
|
setFrequency(d);
|
||||||
|
} else {
|
||||||
|
vfoB = frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readRIT(uint32_t* d) {
|
||||||
|
int freq = ritRxFrequency - frequency;
|
||||||
|
if (*d == (uint32_t)freq) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
*d = (uint32_t)freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeRIT(uint32_t d) {
|
||||||
|
ritRxFrequency = (int)d + ritTxFrequency;
|
||||||
|
if ((ritOn == 1) && (inTx == 0)) {
|
||||||
|
setFrequency(ritRxFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readXIT(uint32_t* d) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeXIT(uint32_t d) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readFlags(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFlags(uint32_t d) {
|
||||||
|
char prev = vfoActive;
|
||||||
|
vfoActive = (d & UBITX_VFOB_FLAG ? VFO_B : VFO_A);
|
||||||
|
if (vfoActive != prev) {
|
||||||
|
if (vfoActive == VFO_A) {
|
||||||
|
if (vfoA != frequency) {
|
||||||
|
setFrequency(vfoA);
|
||||||
|
}
|
||||||
|
} else if (vfoActive == VFO_B) {
|
||||||
|
if (vfoB != frequency) {
|
||||||
|
setFrequency(vfoB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
splitOn = rigState.flags & UBITX_SPLIT_FLAG ? 1 : 0;
|
||||||
|
|
||||||
|
prev = ritOn;
|
||||||
|
ritOn = rigState.flags & UBITX_RIT_FLAG ? 1 : 0;
|
||||||
|
if (ritOn != prev) {
|
||||||
|
if ((ritOn == 1) && (inTx == 0)) {
|
||||||
|
setFrequency(ritRxFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char prev = (cwMode << 1) | isUSB;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if ((cwMode << 1) | isUSB != prev) {
|
||||||
|
setFrequency(frequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
RigState inState;
|
||||||
|
RigState outState;
|
||||||
|
|
||||||
|
void RigState::begin() {
|
||||||
|
field[WIREBUS_VFO_A].data = vfoA;
|
||||||
|
field[WIREBUS_VFO_B].data = vfoB;
|
||||||
|
field[WIREBUS_RIT_OFS].data = (uint32_t)(ritRxFrequency - frequency);
|
||||||
|
field[WIREBUS_XIT_OFS].data = 0;
|
||||||
|
field[WIREBUS_FLAGS].data = 0;
|
||||||
|
field[WIREBUS_FLAGS].data |= (vfoActive == VFO_B ? UBITX_VFOB_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (cwMode != 0 ? UBITX_CW_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (isUSB != 0 ? UBITX_USB_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (splitOn != 0 ? UBITX_SPLIT_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (ritOn != 0 ? UBITX_RIT_FLAG : 0);
|
||||||
|
//field[WIREBUS_FLAGS].data |= (xitOn != 0 ? UBITX_XIT_FLAG : 0);
|
||||||
|
|
||||||
|
for (byte i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
field[i].dirty = true; // Set true to force an initial send to the TeensyDSP.
|
||||||
|
}
|
||||||
|
|
||||||
|
readFunc[WIREBUS_VFO_A] = &readVFOA;
|
||||||
|
readFunc[WIREBUS_VFO_B] = &readVFOB;
|
||||||
|
readFunc[WIREBUS_RIT_OFS] = &readRIT;
|
||||||
|
readFunc[WIREBUS_XIT_OFS] = &readXIT;
|
||||||
|
readFunc[WIREBUS_FLAGS] = &readFlags;
|
||||||
|
writeFunc[WIREBUS_VFO_A] = &writeVFOA;
|
||||||
|
writeFunc[WIREBUS_VFO_B] = &writeVFOB;
|
||||||
|
writeFunc[WIREBUS_RIT_OFS] = &writeRIT;
|
||||||
|
writeFunc[WIREBUS_XIT_OFS] = &writeXIT;
|
||||||
|
writeFunc[WIREBUS_FLAGS] = &writeFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RigState::update() {
|
||||||
|
// First we need to determine which fields have changed (and are
|
||||||
|
// thus dirty and need to be sent to the TeensyDSP).
|
||||||
|
for (byte i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
if (read(i)) {
|
||||||
|
field[i].dirty = true;
|
||||||
|
numDirty++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next we need to send the current (changed) Raduino information
|
||||||
|
// to the TeensyDSP. The expected response is the number of fields
|
||||||
|
// (in bytes) that the TeensyDSP needs to send in response.
|
||||||
|
Wire.beginTransmission(I2CMETER_ADDR);
|
||||||
|
Wire.write(I2CMETER_RIGINF);
|
||||||
|
Wire.write(numDirty * sizeof(Field), 1); // Write the number of dirty fields (in bytes).
|
||||||
|
for (int i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
if (field[i].dirty) { // Write each field that is dirty to the bus.
|
||||||
|
Wire.write((byte*)(&(field[i].data)), sizeof(Field));
|
||||||
|
field[i].dirty = false;
|
||||||
|
numDirty--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
// Now we're going to read the response from the TeensyDSP. All
|
||||||
|
// fields should be marked as clean at this point (unless there's
|
||||||
|
// something that has been updated via interrupt???).
|
||||||
|
Wire.requestFrom(I2CMETER_ADDR, 1);
|
||||||
|
byte numBytes;
|
||||||
|
while (Wire.available()) {
|
||||||
|
numBytes = Wire.read(); // Should only get executed for one byte... but just in case.
|
||||||
|
}
|
||||||
|
if (numBytes == 0) return;
|
||||||
|
|
||||||
|
// Let the TeensyDSP know that we want it to send its deltas now.
|
||||||
|
Wire.beginTransmission(I2CMETER_ADDR);
|
||||||
|
Wire.write(I2CMETER_RIGREQ);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
// Retrieve all of the deltas. Mark any received field as dirty.
|
||||||
|
Wire.requestFrom(I2CMETER_ADDR, numBytes);
|
||||||
|
int index = -1;
|
||||||
|
byte* ptr;
|
||||||
|
while (Wire.available()) {
|
||||||
|
byte b = Wire.read();
|
||||||
|
if (index = -1) {
|
||||||
|
ptr = (byte*)(&(field[b].data));
|
||||||
|
field[b].dirty = true;
|
||||||
|
numDirty++;
|
||||||
|
index = 0;
|
||||||
|
} else {
|
||||||
|
ptr[index++] = b;
|
||||||
|
if (index == 4) {
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the corresponding update for each dirty field.
|
||||||
|
for (byte i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
if (field[i].dirty) {
|
||||||
|
write(i);
|
||||||
|
field[i].dirty = false;
|
||||||
|
numDirty--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
// Handle the case of the Raduino
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
bool readVFOA(uint32_t* d) {
|
||||||
|
unsigned freq = (vfoActive == VFO_A) ? frequency : vfoA;
|
||||||
|
if (*d == freq) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
*d = freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeVFOA(uint32_t d) {
|
||||||
|
if (vfoActive == VFO_A) {
|
||||||
|
setFrequency(d);
|
||||||
|
} else {
|
||||||
|
vfoA = frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readVFOB(uint32_t* d) {
|
||||||
|
unsigned freq = (vfoActive == VFO_B) ? frequency : vfoB;
|
||||||
|
if (*d == freq) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
*d = freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeVFOB(uint32_t d) {
|
||||||
|
if (vfoActive == VFO_B) {
|
||||||
|
setFrequency(d);
|
||||||
|
} else {
|
||||||
|
vfoB = frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readRIT(uint32_t* d) {
|
||||||
|
int freq = ritRxFrequency - frequency;
|
||||||
|
if (*d == (uint32_t)freq) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
*d = (uint32_t)freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeRIT(uint32_t d) {
|
||||||
|
ritRxFrequency = (int)d + ritTxFrequency;
|
||||||
|
if ((ritOn == 1) && (inTx == 0)) {
|
||||||
|
setFrequency(ritRxFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readXIT(uint32_t* d) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeXIT(uint32_t d) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readFlags(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFlags(uint32_t d) {
|
||||||
|
char prev = vfoActive;
|
||||||
|
vfoActive = (d & UBITX_VFOB_FLAG ? VFO_B : VFO_A);
|
||||||
|
if (vfoActive != prev) {
|
||||||
|
if (vfoActive == VFO_A) {
|
||||||
|
if (vfoA != frequency) {
|
||||||
|
setFrequency(vfoA);
|
||||||
|
}
|
||||||
|
} else if (vfoActive == VFO_B) {
|
||||||
|
if (vfoB != frequency) {
|
||||||
|
setFrequency(vfoB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
splitOn = rigState.flags & UBITX_SPLIT_FLAG ? 1 : 0;
|
||||||
|
|
||||||
|
prev = ritOn;
|
||||||
|
ritOn = rigState.flags & UBITX_RIT_FLAG ? 1 : 0;
|
||||||
|
if (ritOn != prev) {
|
||||||
|
if ((ritOn == 1) && (inTx == 0)) {
|
||||||
|
setFrequency(ritRxFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char prev = (cwMode << 1) | isUSB;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if ((cwMode << 1) | isUSB != prev) {
|
||||||
|
setFrequency(frequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
RigState rigState;
|
||||||
|
|
||||||
|
void RigState::begin() {
|
||||||
|
field[WIREBUS_VFO_A].data = vfoA;
|
||||||
|
field[WIREBUS_VFO_B].data = vfoB;
|
||||||
|
field[WIREBUS_RIT_OFS].data = (uint32_t)(ritRxFrequency - frequency);
|
||||||
|
field[WIREBUS_XIT_OFS].data = 0;
|
||||||
|
field[WIREBUS_FLAGS].data = 0;
|
||||||
|
field[WIREBUS_FLAGS].data |= (vfoActive == VFO_B ? UBITX_VFOB_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (cwMode != 0 ? UBITX_CW_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (isUSB != 0 ? UBITX_USB_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (splitOn != 0 ? UBITX_SPLIT_FLAG : 0);
|
||||||
|
field[WIREBUS_FLAGS].data |= (ritOn != 0 ? UBITX_RIT_FLAG : 0);
|
||||||
|
//field[WIREBUS_FLAGS].data |= (xitOn != 0 ? UBITX_XIT_FLAG : 0);
|
||||||
|
|
||||||
|
for (byte i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
field[i].dirty = true; // Set true to force an initial send to the TeensyDSP.
|
||||||
|
}
|
||||||
|
|
||||||
|
readFunc[WIREBUS_VFO_A] = &readVFOA;
|
||||||
|
readFunc[WIREBUS_VFO_B] = &readVFOB;
|
||||||
|
readFunc[WIREBUS_RIT_OFS] = &readRIT;
|
||||||
|
readFunc[WIREBUS_XIT_OFS] = &readXIT;
|
||||||
|
readFunc[WIREBUS_FLAGS] = &readFlags;
|
||||||
|
writeFunc[WIREBUS_VFO_A] = &writeVFOA;
|
||||||
|
writeFunc[WIREBUS_VFO_B] = &writeVFOB;
|
||||||
|
writeFunc[WIREBUS_RIT_OFS] = &writeRIT;
|
||||||
|
writeFunc[WIREBUS_XIT_OFS] = &writeXIT;
|
||||||
|
writeFunc[WIREBUS_FLAGS] = &writeFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RigState::update() {
|
||||||
|
// First we need to determine which fields have changed (and are
|
||||||
|
// thus dirty and need to be sent to the TeensyDSP).
|
||||||
|
for (byte i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
if (read(i)) {
|
||||||
|
field[i].dirty = true;
|
||||||
|
numDirty++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next we need to send the current (changed) Raduino information
|
||||||
|
// to the TeensyDSP. The expected response is the number of fields
|
||||||
|
// (in bytes) that the TeensyDSP needs to send in response.
|
||||||
|
Wire.beginTransmission(I2CMETER_ADDR);
|
||||||
|
Wire.write(I2CMETER_RIGINF);
|
||||||
|
Wire.write(numDirty * sizeof(Field), 1); // Write the number of dirty fields (in bytes).
|
||||||
|
for (int i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
if (field[i].dirty) { // Write each field that is dirty to the bus.
|
||||||
|
Wire.write((byte*)(&(field[i].data)), sizeof(Field));
|
||||||
|
field[i].dirty = false;
|
||||||
|
numDirty--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
// Now we're going to read the response from the TeensyDSP. All
|
||||||
|
// fields should be marked as clean at this point (unless there's
|
||||||
|
// something that has been updated via interrupt???).
|
||||||
|
Wire.requestFrom(I2CMETER_ADDR, 1);
|
||||||
|
byte numBytes;
|
||||||
|
while (Wire.available()) {
|
||||||
|
numBytes = Wire.read(); // Should only get executed for one byte... but just in case.
|
||||||
|
}
|
||||||
|
if (numBytes == 0) return;
|
||||||
|
|
||||||
|
// Let the TeensyDSP know that we want it to send its deltas now.
|
||||||
|
Wire.beginTransmission(I2CMETER_ADDR);
|
||||||
|
Wire.write(I2CMETER_RIGREQ);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
// Retrieve all of the deltas. Mark any received field as dirty.
|
||||||
|
Wire.requestFrom(I2CMETER_ADDR, numBytes);
|
||||||
|
int index = -1;
|
||||||
|
byte* ptr;
|
||||||
|
while (Wire.available()) {
|
||||||
|
byte b = Wire.read();
|
||||||
|
if (index = -1) {
|
||||||
|
ptr = (byte*)(&(field[b].data));
|
||||||
|
field[b].dirty = true;
|
||||||
|
numDirty++;
|
||||||
|
index = 0;
|
||||||
|
} else {
|
||||||
|
ptr[index++] = b;
|
||||||
|
if (index == 4) {
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the corresponding update for each dirty field.
|
||||||
|
for (byte i = 0; i < WIREBUS_NUM_FIELDS; i++) {
|
||||||
|
if (field[i].dirty) {
|
||||||
|
write(i);
|
||||||
|
field[i].dirty = false;
|
||||||
|
numDirty--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* EOF *
|
||||||
|
**********************************************************************/
|
||||||
|
|
@ -26,15 +26,13 @@ struct UBitxRigState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
// NEW IMPLEMENTATION
|
||||||
|
|
||||||
template<typename T, int ID>
|
|
||||||
struct Field {
|
struct Field {
|
||||||
byte id = ID;
|
|
||||||
bool dirty;
|
bool dirty;
|
||||||
T data;
|
uint32_t data;
|
||||||
|
|
||||||
inline size_t sizeOfWrite() { return dirty ? sizeof(byte) + sizeof(T) : 0; }
|
/*
|
||||||
|
|
||||||
template<typename STREAM> void writeChanges() {
|
template<typename STREAM> void writeChanges() {
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
STREAM().write(id);
|
STREAM().write(id);
|
||||||
@ -50,8 +48,9 @@ struct Field {
|
|||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
inline void merge(Field<T,ID>& f) {
|
inline void merge(Field& f) {
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
f.data = data;
|
f.data = data;
|
||||||
f.dirty = true;
|
f.dirty = true;
|
||||||
@ -64,13 +63,56 @@ struct Field {
|
|||||||
inline void markClean() { dirty = false; }
|
inline void markClean() { dirty = false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RigState {
|
#define WIREBUS_NONE 0
|
||||||
Field<uint32_t, 0> vfoA;
|
#define WIREBUS_VFO_A 1
|
||||||
Field<uint32_t, 1> vfoB;
|
#define WIREBUS_VFO_B 2
|
||||||
Field<int32_t, 2> rit;
|
#define WIREBUS_RIT_OFS 3
|
||||||
Field<int32_t, 3> xit;
|
#define WIREBUS_XIT_OFS 4
|
||||||
Field<uint32_t, 4> flags;
|
#define WIREBUS_FLAGS 5
|
||||||
|
#define WIREBUS_NUM_FIELDS 6
|
||||||
|
|
||||||
|
typedef bool (*readfunc)(uint32_t*);
|
||||||
|
typedef void (*writefunc)(uint32_t);
|
||||||
|
|
||||||
|
struct RigState {
|
||||||
|
Field field[WIREBUS_NUM_FIELDS];
|
||||||
|
readfunc readFunc[WIREBUS_NUM_FIELDS];
|
||||||
|
writefunc writeFunc[WIREBUS_NUM_FIELDS;
|
||||||
|
int numDirty;
|
||||||
|
|
||||||
|
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 readFunc[i](&field[i].data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Use the specified (vy index) rig state field to update the
|
||||||
|
* external value.
|
||||||
|
*/
|
||||||
|
inline void write(byte i) {
|
||||||
|
writeFunc[i](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; }
|
||||||
|
|
||||||
|
/*
|
||||||
inline size_t sizeOfWrite() {
|
inline size_t sizeOfWrite() {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size += vfoA.sizeOfWrite();
|
size += vfoA.sizeOfWrite();
|
||||||
@ -134,8 +176,20 @@ struct RigState {
|
|||||||
xit.markClean();
|
xit.markClean();
|
||||||
flags.markClean();
|
flags.markClean();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef TEENSYDUINO
|
||||||
|
|
||||||
|
extern RigState inState; // the state as received from the Raduino
|
||||||
|
extern RigState outState; // the state as commanded via CAT
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern RigState rigState;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Protocol discussion:
|
Protocol discussion:
|
||||||
- I2C master: Raduino
|
- I2C master: Raduino
|
||||||
|
@ -363,8 +363,6 @@ void setup()
|
|||||||
//Serial1.println("Start...");
|
//Serial1.println("Start...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sentRigInfFlag = false;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Receive a command via I2C. The most recent command will be received, which will
|
@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.
|
indicate which data the DSP should be preparing to return.
|
||||||
@ -375,20 +373,13 @@ void i2cReceiveEvent(size_t numBytes)
|
|||||||
{
|
{
|
||||||
int readCommand = 0;
|
int readCommand = 0;
|
||||||
bool exitLoop = false;
|
bool exitLoop = false;
|
||||||
UBitxRigState tmpState;
|
|
||||||
|
|
||||||
while (Wire1.available() > 0 && !exitLoop) {
|
while (Wire1.available() > 0 && !exitLoop) {
|
||||||
readCommand = Wire1.read();
|
readCommand = Wire1.read();
|
||||||
if (readCommand == I2CMETER_RIGINF) {
|
if (readCommand == I2CMETER_RIGINF) {
|
||||||
size_t len = 0;
|
// NEEDS TO GET UPDATED
|
||||||
uint8_t* const ptr = (uint8_t* const)&tmpState;
|
//rigState.getSizeOfChanges();
|
||||||
while ((Wire1.available() > 0) && (len < sizeof(UBitxRigState))) {
|
//rigState.update(I2CMETER_RIGINF);
|
||||||
ptr[len++] = Wire1.read();
|
|
||||||
}
|
|
||||||
if (!Rig.updatedByCAT()) {
|
|
||||||
Rig.updateState(tmpState);
|
|
||||||
}
|
|
||||||
sentRigInfFlag = false; // so we know that we need to send the flag first
|
|
||||||
exitLoop = true;
|
exitLoop = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,11 +447,13 @@ void i2cRequestEvent(void)
|
|||||||
case I2CMETER_RIGINF:
|
case I2CMETER_RIGINF:
|
||||||
// Receive current rig state; transmit any CAT updates, if required.
|
// Receive current rig state; transmit any CAT updates, if required.
|
||||||
//Wire1.write(catState.header); // temporary - just writing a single, null byte
|
//Wire1.write(catState.header); // temporary - just writing a single, null byte
|
||||||
//break;
|
// NEEDS TO GET UPDATED
|
||||||
|
break;
|
||||||
|
|
||||||
case I2CMETER_REQCAT:
|
case I2CMETER_REQCAT:
|
||||||
// Provide latest CAT updates, if any.
|
// Provide latest CAT updates, if any.
|
||||||
//Wire1.write(catState.header); // temporary - just writing a single, null byte
|
//Wire1.write(catState.header); // temporary - just writing a single, null byte
|
||||||
|
// NEEDS TO GET UPDATED
|
||||||
if (Rig.updatedByCAT()) {
|
if (Rig.updatedByCAT()) {
|
||||||
if (sentRigInfFlag) {
|
if (sentRigInfFlag) {
|
||||||
DBGPRINTLN("I2CMETER_REQCAT -- updated by CAT");
|
DBGPRINTLN("I2CMETER_REQCAT -- updated by CAT");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user