Significant revamp of RigState to only send changes. Not done yet.
This commit is contained in:
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 *
|
||||
**********************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user