Compare commits
3 Commits
c3cc9a7cf7
...
47840e09dd
Author | SHA1 | Date | |
---|---|---|---|
|
47840e09dd | ||
|
d2213e34ff | ||
|
814fe6c733 |
@ -339,12 +339,12 @@ byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWK
|
||||
//Check PTT while auto Sending
|
||||
autoSendPTTCheck();
|
||||
|
||||
Check_Cat(3);
|
||||
//Check_Cat(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Background Work
|
||||
Check_Cat(fromType);
|
||||
//Check_Cat(fromType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -806,7 +806,7 @@ void checkButton(){
|
||||
//wait for the button to go up again
|
||||
while(keyStatus == getBtnStatus()) {
|
||||
delay(10);
|
||||
Check_Cat(0);
|
||||
//Check_Cat(0);
|
||||
}
|
||||
//delay(50);//debounce
|
||||
}
|
||||
@ -825,7 +825,7 @@ void checkButton(){
|
||||
//wait for the button to go up again
|
||||
while(btnDown()) {
|
||||
delay(10);
|
||||
Check_Cat(0);
|
||||
//Check_Cat(0);
|
||||
}
|
||||
//delay(50);//debounce
|
||||
}
|
||||
@ -1402,7 +1402,8 @@ void setup()
|
||||
//printLineF(1, FIRMWARE_VERSION_INFO);
|
||||
DisplayVersionInfo(FIRMWARE_VERSION_INFO);
|
||||
|
||||
Init_Cat(38400, SERIAL_8N1);
|
||||
//Init_Cat(38400, SERIAL_8N1);
|
||||
Serial.begin(38400);
|
||||
initSettings();
|
||||
initPorts();
|
||||
|
||||
@ -1475,6 +1476,13 @@ void checkAutoSaveFreqMode()
|
||||
|
||||
rigState.vfo[0] = vfoA;
|
||||
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(){
|
||||
@ -1497,13 +1505,14 @@ void loop(){
|
||||
// controlAutoCW();
|
||||
// KC4UPR: Note, implementation below leaves no manual way to abort TX due to CAT. May
|
||||
// want to add in a way to interrupt CAT transmission with a PTT/CW event.
|
||||
if (!txCAT) {
|
||||
if (cwMode == 0)
|
||||
//if (!txCAT) {
|
||||
if (cwMode == 0) {
|
||||
checkPTT();
|
||||
else
|
||||
} else {
|
||||
cwKeyer();
|
||||
}
|
||||
checkButton();
|
||||
}
|
||||
//}
|
||||
|
||||
//cwKeyer();
|
||||
|
||||
@ -1525,7 +1534,7 @@ void loop(){
|
||||
} //end of check TX Status
|
||||
|
||||
//we check CAT after the encoder as it might put the radio into TX
|
||||
Check_Cat(inTx? 1 : 0);
|
||||
//Check_Cat(inTx? 1 : 0);
|
||||
|
||||
//for SEND SW Serial
|
||||
#ifdef USE_SW_SERIAL
|
||||
|
@ -341,6 +341,8 @@ extern void DisplayVersionInfo(const char* fwVersionInfo);
|
||||
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;
|
||||
|
||||
|
@ -997,23 +997,10 @@ UBitxRigState catState;
|
||||
void idle_process()
|
||||
{
|
||||
// KC4UPR 2021-02-05 added update process for Raduino-TeensyDSP coordination
|
||||
// Note, need to not have to copy this every time...
|
||||
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;
|
||||
}
|
||||
updateStateFromRaduino(rigState);
|
||||
doRaduinoToTeensy(&rigState);
|
||||
if (vfoActive == VFO_A) {
|
||||
if (rigState.vfo[0] != frequency) {
|
||||
setFrequency(rigState.vfo[0]);
|
||||
} else if (vfoActive == VFO_B) {
|
||||
setFrequency(rigState.vfo[1]);
|
||||
}
|
||||
}
|
||||
|
||||
updateRaduinoFromState(rigState);
|
||||
|
||||
//S-Meter Display
|
||||
if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency))
|
||||
{
|
||||
|
@ -350,3 +350,43 @@ void doRaduinoToTeensy(UBitxRigState* r) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
185
TeensyDSP/Keyer.cpp
Normal file
185
TeensyDSP/Keyer.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
//======================================================================
|
||||
//
|
||||
// nanoIO paddle keyer (c) 2018, David Freese, W1HKJ
|
||||
//
|
||||
// based on code from Iambic Keyer Code Keyer Sketch
|
||||
// Copyright (c) 2009 Steven T. Elliott
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details:
|
||||
//
|
||||
// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
// Boston, MA 02111-1307 USA
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
#include <Arduino.h>
|
||||
//#include "TimerOne.h"
|
||||
//#include "config.h"
|
||||
#include "Keyer.h"
|
||||
|
||||
const uint8_t LP_in = KEYER_LEFT_PADDLE_PIN;
|
||||
const uint8_t RP_in = KEYER_RIGHT_PADDLE_PIN;
|
||||
|
||||
//#define ST_Freq 600 // Set the Sidetone Frequency to 600 Hz
|
||||
|
||||
//======================================================================
|
||||
// keyerControl bit definitions
|
||||
//
|
||||
#define DIT_L 0x01 // Dit latch
|
||||
#define DAH_L 0x02 // Dah latch
|
||||
#define DIT_PROC 0x04 // Dit is being processed
|
||||
#define PDLSWAP 0x08 // 0 for normal, 1 for swap
|
||||
//======================================================================
|
||||
//
|
||||
// State Machine Defines
|
||||
|
||||
enum KSTYPE { IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT };
|
||||
|
||||
UBitxKeyer::UBitxKeyer(int wpm, float weight):
|
||||
speed(wpm), symWeight(weight)
|
||||
{
|
||||
// Setup outputs
|
||||
pinMode(LP_in, INPUT_PULLUP); // sets Left Paddle digital pin as input
|
||||
pinMode(RP_in, INPUT_PULLUP); // sets Right Paddle digital pin as input
|
||||
|
||||
keyerState = IDLE;
|
||||
keyerControl = 0;
|
||||
keyMode = IAMBICA;
|
||||
keyDown = false;
|
||||
|
||||
calcRatio();
|
||||
}
|
||||
|
||||
// Calculate the length of dot, dash and silence
|
||||
void UBitxKeyer::calcRatio()
|
||||
{
|
||||
float w = (1 + symWeight) / (symWeight -1);
|
||||
spaceLen = (1200 / speed);
|
||||
dotLen = spaceLen * (w - 1);
|
||||
dashLen = (1 + w) * spaceLen;
|
||||
}
|
||||
|
||||
void UBitxKeyer::setWPM(int wpm)
|
||||
{
|
||||
speed = wpm;
|
||||
calcRatio();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Latch paddle press
|
||||
//======================================================================
|
||||
|
||||
void UBitxKeyer::updatePaddleLatch()
|
||||
{
|
||||
if (digitalRead(LP_in) == LOW) {
|
||||
keyerControl |= DIT_L;
|
||||
}
|
||||
if (digitalRead(RP_in) == LOW) {
|
||||
keyerControl |= DAH_L;
|
||||
}
|
||||
}
|
||||
|
||||
bool UBitxKeyer::doPaddles()
|
||||
{
|
||||
if (keyMode == STRAIGHT) { // Straight Key
|
||||
if ((digitalRead(LP_in) == LOW) || (digitalRead(RP_in) == LOW)) {
|
||||
keyDown = true;
|
||||
return true;
|
||||
} else {
|
||||
keyDown = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// keyerControl contains processing flags and keyer mode bits
|
||||
// Supports Iambic A and B
|
||||
// State machine based, uses calls to millis() for timing.
|
||||
switch (keyerState) {
|
||||
case IDLE: // Wait for direct or latched paddle press
|
||||
if ((digitalRead(LP_in) == LOW) || (digitalRead(RP_in) == LOW) || (keyerControl & 0x03)) {
|
||||
updatePaddleLatch();
|
||||
keyerState = CHK_DIT;
|
||||
// letting this fall through // return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// break;
|
||||
|
||||
case CHK_DIT: // See if the dit paddle was pressed
|
||||
if (keyerControl & DIT_L) {
|
||||
keyerControl |= DIT_PROC;
|
||||
ktimer = dotLen;
|
||||
keyerState = KEYED_PREP;
|
||||
return true;
|
||||
} else { // fall through
|
||||
keyerState = CHK_DAH;
|
||||
}
|
||||
|
||||
case CHK_DAH: // See if dah paddle was pressed
|
||||
if (keyerControl & DAH_L) {
|
||||
ktimer = dashLen;
|
||||
keyerState = KEYED_PREP;
|
||||
// letting this fall through // return true;
|
||||
} else {
|
||||
keyerState = IDLE;
|
||||
return false;
|
||||
}
|
||||
// break;
|
||||
|
||||
case KEYED_PREP: // Assert key down, start timing
|
||||
// state shared for dit or dah
|
||||
keyDown = true;
|
||||
ktimer += millis(); // set ktimer to interval end time
|
||||
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
|
||||
keyerState = KEYED; // next state
|
||||
// letting this fall through // return true;
|
||||
// break;
|
||||
|
||||
case KEYED: // Wait for timer to expire
|
||||
if (millis() > ktimer) { // are we at end of key down ?
|
||||
keyDown = false;
|
||||
ktimer = millis() + spaceLen; // inter-element time
|
||||
keyerState = INTER_ELEMENT; // next state
|
||||
// letting this fall through // return true;
|
||||
} else if (keyMode == IAMBICB) { // Iambic B Mode ?
|
||||
updatePaddleLatch(); // yes, early paddle latch in Iambic B mode
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
// break;
|
||||
|
||||
case INTER_ELEMENT: // Insert time between dits/dahs
|
||||
updatePaddleLatch(); // latch paddle state
|
||||
if (millis() > ktimer) { // are we at end of inter-space ?
|
||||
if (keyerControl & DIT_PROC) { // was it a dit or dah ?
|
||||
keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits
|
||||
keyerState = CHK_DAH; // dit done, check for dah
|
||||
return true;
|
||||
} else {
|
||||
keyerControl &= ~(DAH_L); // clear dah latch
|
||||
keyerState = IDLE; // go idle
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
// break;
|
||||
}
|
||||
|
||||
return false; // resolve compiler warning; do we ever get here?
|
||||
}
|
||||
|
||||
UBitxKeyer basicKeyer(15, 3.0);
|
||||
UBitxKeyer& Keyer = basicKeyer;
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
79
TeensyDSP/Keyer.h
Normal file
79
TeensyDSP/Keyer.h
Normal file
@ -0,0 +1,79 @@
|
||||
//**********************************************************************
|
||||
//
|
||||
// Keyer, a part of nanoIO
|
||||
//
|
||||
// nanoIO paddle keyer (c) 2018, David Freese, W1HKJ
|
||||
//
|
||||
// based on code from Iambic Keyer Code Keyer Sketch
|
||||
// Copyright (c) 2009 Steven T. Elliott
|
||||
//
|
||||
// nanoIO is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// nanoIO is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//Revisions:
|
||||
//
|
||||
//1.0.0: Initial release
|
||||
//
|
||||
//**********************************************************************
|
||||
|
||||
|
||||
#ifndef __Keyer_h__
|
||||
#define __Keyer_h__
|
||||
|
||||
#define IAMBICA 0
|
||||
#define IAMBICB 1
|
||||
#define STRAIGHT 2
|
||||
|
||||
#define KEYER_LEFT_PADDLE_PIN 17
|
||||
#define KEYER_RIGHT_PADDLE_PIN 16
|
||||
|
||||
class UBitxKeyer
|
||||
{
|
||||
public:
|
||||
UBitxKeyer(int wpm, float weight);
|
||||
//void cw_pin(int pin);
|
||||
//void ptt_pin(int pin);
|
||||
void setWPM(int wpm);
|
||||
inline void setMode(int mode) { keyMode = mode; }
|
||||
inline int getMode() { return keyMode; }
|
||||
inline bool isDown() { return keyDown; }
|
||||
// void setWeight();
|
||||
|
||||
bool doPaddles();
|
||||
|
||||
private:
|
||||
void calcRatio();
|
||||
void updatePaddleLatch();
|
||||
|
||||
bool keyDown;
|
||||
|
||||
long ktimer;
|
||||
|
||||
int speed;
|
||||
int dashLen; // Length of dash
|
||||
int dotLen; // Length of dot
|
||||
int spaceLen; // Length of space
|
||||
float symWeight;
|
||||
|
||||
char keyerControl;
|
||||
char keyerState;
|
||||
int keyMode;
|
||||
};
|
||||
|
||||
extern UBitxKeyer& Keyer;
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
@ -25,4 +25,150 @@ struct UBitxRigState {
|
||||
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
|
||||
|
@ -7,10 +7,20 @@
|
||||
|
||||
UBitxTR TR(DSP);
|
||||
|
||||
void UBitxTR::update(bool cw) {
|
||||
void UBitxTR::update(bool cw, bool extKey) {
|
||||
updateKey();
|
||||
|
||||
if (cw) {
|
||||
if ((keyEnable && keyDown) || extKey) {
|
||||
setTX();
|
||||
} else {
|
||||
setRX();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
updatePTT();
|
||||
updateVOX();
|
||||
updateKey();
|
||||
|
||||
if (isTX) {
|
||||
// If we are currently transmitting, then ANY T/R release (key
|
||||
|
@ -87,8 +87,12 @@ class UBitxTR {
|
||||
* @param cw
|
||||
* True if CW mode is currently active; false otherwise.
|
||||
* Different/faster logic is used in CW mode.
|
||||
*
|
||||
* @param extKey
|
||||
* True if an external keying signal (ie. CW keyer) is
|
||||
* currently active (ie. key down).
|
||||
*/
|
||||
void update(bool cw = false);
|
||||
void update(bool cw = false, bool extKey = false);
|
||||
|
||||
void end() {
|
||||
}
|
||||
|
@ -138,17 +138,17 @@ TS590Error TS590Command::theError = NoError;
|
||||
void TS590_FR::handleCommand(const char* cmd) {
|
||||
if (strlen(cmd) == 3) {
|
||||
switch (cmd[2]) {
|
||||
case 0:
|
||||
case '0':
|
||||
rig()->selectVFOA(true);
|
||||
rig()->splitOff(true);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case '1':
|
||||
rig()->selectVFOB(true);
|
||||
rig()->splitOff(true);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case '2':
|
||||
// TODO: Need to add something for channel mode.
|
||||
break;
|
||||
|
||||
@ -175,7 +175,7 @@ void TS590_FR::sendResponse(const char* cmd) {
|
||||
void TS590_FT::handleCommand(const char* cmd) {
|
||||
if (strlen(cmd) == 3) {
|
||||
switch (cmd[2]) {
|
||||
case 0:
|
||||
case '0':
|
||||
if (rig()->isVFOA()) {
|
||||
rig()->splitOff(true);
|
||||
} else if (rig()->isVFOB()) {
|
||||
@ -185,7 +185,7 @@ void TS590_FT::handleCommand(const char* cmd) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case '1':
|
||||
if (rig()->isVFOA()) {
|
||||
rig()->splitOn(true);
|
||||
} else if (rig()->isVFOB()) {
|
||||
@ -215,16 +215,76 @@ void TS590_FT::sendResponse(const char* cmd) {
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
void TS590_MD::handleCommand(const char* cmd) {
|
||||
if (strlen(cmd) == 3) {
|
||||
switch (cmd[2]) {
|
||||
case '0': // None (setting failure)
|
||||
case '4': // FM - not supported
|
||||
case '5': // AM - not supported
|
||||
case '6': // FSK - not supported
|
||||
case '8': // None (setting failure)
|
||||
case '9': // FSK-R - not supported
|
||||
setProcessError();
|
||||
break;
|
||||
|
||||
case '1': // LSB
|
||||
rig()->selectLSB(true);
|
||||
rig()->cwOff(true);
|
||||
break;
|
||||
|
||||
case '2': // USB
|
||||
rig()->selectUSB(true);
|
||||
rig()->cwOff(true);
|
||||
break;
|
||||
|
||||
case '3': // CW
|
||||
rig()->selectUSB(true);
|
||||
rig()->cwOn(true);
|
||||
break;
|
||||
|
||||
case '7': // CW-R
|
||||
rig()->selectLSB(true);
|
||||
rig()->cwOn(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
setSyntaxError();
|
||||
}
|
||||
} else {
|
||||
setSyntaxError();
|
||||
}
|
||||
}
|
||||
|
||||
void TS590_MD::sendResponse(const char* cmd) {
|
||||
if (rig()->isCW()) {
|
||||
if (rig()->isUSB()) {
|
||||
ts590SendCommand("MD3");
|
||||
} else {
|
||||
ts590SendCommand("MD7");
|
||||
}
|
||||
} else {
|
||||
if (rig()->isUSB()) {
|
||||
ts590SendCommand("MD2");
|
||||
} else {
|
||||
ts590SendCommand("MD1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
TS590_FA cmdFA;
|
||||
TS590_FB cmdFB;
|
||||
TS590_FR cmdFR;
|
||||
TS590_FT cmdFT;
|
||||
TS590_MD cmdMD;
|
||||
|
||||
TS590Command* catCommands[] = {
|
||||
&cmdFA,
|
||||
&cmdFB,
|
||||
&cmdFR,
|
||||
&cmdFT
|
||||
&cmdFT,
|
||||
&cmdMD
|
||||
};
|
||||
int numCatCommands = sizeof(catCommands) / sizeof(catCommands[0]);
|
||||
|
||||
|
@ -148,6 +148,18 @@ class TS590_FT : public TS590Command {
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief CAT command for setting the mode.
|
||||
*/
|
||||
class TS590_MD : public TS590Command {
|
||||
public:
|
||||
TS590_MD(): TS590Command("MD") {}
|
||||
virtual void handleCommand(const char* cmd);
|
||||
virtual void sendResponse(const char* cmd);
|
||||
};
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
class UBitxTS590 {
|
||||
public:
|
||||
UBitxTS590(TS590Command** cmds, int len): commands(cmds), numCommands(len) {}
|
||||
|
@ -10,6 +10,7 @@ KD8CEC, Ian Lee
|
||||
#include <Arduino.h>
|
||||
#include "Debug.h"
|
||||
#include "DSP.h"
|
||||
#include "Keyer.h"
|
||||
#include "Nextion.h"
|
||||
#include "Rig.h"
|
||||
#include "RigState.h"
|
||||
|
@ -540,6 +540,13 @@ void loop()
|
||||
return;
|
||||
}
|
||||
|
||||
// If CW mode, we need to update keying a lot...
|
||||
if (Rig.isCW()) {
|
||||
if (Rig.isCW()) Keyer.doPaddles();
|
||||
TR.update(Rig.isCW(), Keyer.isDown());
|
||||
//if (TR.transmitting()) return;
|
||||
}
|
||||
|
||||
// Start out by forwarding any data sitting in the RX buffer. We will
|
||||
// do this as often as possible.
|
||||
forwardData();
|
||||
@ -550,11 +557,13 @@ void loop()
|
||||
sinceFrameMillis = 0;
|
||||
|
||||
// Update each of the subsystems, beginning with CAT control.
|
||||
TS590.update();
|
||||
TR.update();
|
||||
TS590.update();
|
||||
TR.update(Rig.isCW(), Keyer.isDown());
|
||||
Rig.update();
|
||||
DSP.update();
|
||||
|
||||
//if (Rig.isCW()) return;
|
||||
|
||||
#ifdef DEBUG
|
||||
// For debugging, output some debug info every 1.0" (40 frames @ 40 Hz).
|
||||
frameCounter++;
|
||||
@ -676,6 +685,8 @@ void loop()
|
||||
forwardData();
|
||||
}
|
||||
|
||||
if (Rig.isCW()) return; // In CW, the ADC measurement messes with the timing. So need to use interrupts on the Keyer, and/or continuous ADC.
|
||||
|
||||
if (sinceADCMillis > adcIntervalMillis) {
|
||||
// Do stuff that we do once per ADC interval--ADC colllection.
|
||||
// TODO: debug output (frame skipping / utilization).
|
||||
@ -692,6 +703,8 @@ void loop()
|
||||
//forwardData();
|
||||
}
|
||||
|
||||
//if (Rig.isCW()) return;
|
||||
|
||||
// Check Response Command
|
||||
if (responseCommand > 0 && sinceForward > LAST_TIME_INTERVAL)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user