458 lines
12 KiB
C++
458 lines
12 KiB
C++
#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 *
|
|
**********************************************************************/
|
|
|