In theory, the code has now been modified to allow CW transmission when

used with the IOP.  However, at the moment, there is no way to put the
IOP into CW mode.

Intended behavior:
PTT/Key in SSB = transmit (PTT)
PTT/Key in CW = key down
This commit is contained in:
Rob French 2020-05-03 23:04:02 -05:00
parent 44c6c86838
commit 1aa9ce1bd6
2 changed files with 178 additions and 110 deletions

View File

@ -316,6 +316,17 @@ unsigned long delayBeforeTime = 0;
byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle
delayBeforeTime = millis(); delayBeforeTime = millis();
/*
* KC4UPR - IOP review, 2020-05-03
*
* I don't see anything in here that is either important to, or will adversely affect, IOP
* operation. I'm not planning on using the uBITX autokeyer (since all keying will be in the
* IOP), so neither getPaddle() nor autoSendPTTCheck() will be issues. I do need to look into
* overall CAT operation, in general.
*
* UPDATE: Fixed getPaddle() to be compatible.
*/
while (millis() - delayBeforeTime <= delayTime) { while (millis() - delayBeforeTime <= delayTime) {
if (fromType == 4) if (fromType == 4)
@ -678,6 +689,10 @@ void ritDisable(){
*/ */
void checkPTT(){ void checkPTT(){
/*
* KC4UPR - note that some of this is superfluous now that checkPTT() is only executed
* in SSB mode, and cwKeyer is only executed in CW mode...
*/
//we don't check for ptt when transmitting cw //we don't check for ptt when transmitting cw
if (cwTimeout > 0) if (cwTimeout > 0)
return; return;
@ -1459,15 +1474,34 @@ void checkAutoSaveFreqMode()
} }
void loop(){ void loop(){
if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process /*
if (!txCAT) * KC4UPR - IOP update, 2020-05-03
*
* Getting rid of the autokeyer code... not planning on using, since any autokeying
* would actually be done by the IOP. We'll check the PTT, but only in SSB mode
* (same line as CW, so it would be caught by cwKeyer() in CW mode).
*
* Only check the CW keyer if we are in one of the CW modes. Why? Because we
* are using the same input for PTT and CW.
*/
// if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process
// if (!txCAT)
// checkPTT();
// checkButton();
// }
// else
// 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)
checkPTT(); checkPTT();
checkButton(); else
cwKeyer();
checkButton();
} }
else
controlAutoCW(); //cwKeyer();
cwKeyer();
//tune only when not tranmsitting //tune only when not tranmsitting
if (!inTx){ if (!inTx){

View File

@ -39,6 +39,22 @@ char lastPaddle = 0;
//reads the analog keyer pin and reports the paddle //reads the analog keyer pin and reports the paddle
byte getPaddle(){ byte getPaddle(){
/*
* KC4UPR - IOP update, 2020-05-03
*
* Modifying this for the uBITX IOP. Big picture:
*
* (1) It uses the PTT input line.
*
* (2) It's always "straight key" mode (the IOP provides the keyer).
*/
if (digitalRead(PTT) == 1) // key/PTT is up
return 0;
else
return PADDLE_STRAIGHT;
/*
int paddle = analogRead(ANALOG_KEYER); int paddle = analogRead(ANALOG_KEYER);
if (paddle > 800) // above 4v is up if (paddle > 800) // above 4v is up
@ -52,6 +68,7 @@ byte getPaddle(){
return PADDLE_BOTH; //both are between 1 and 2v return PADDLE_BOTH; //both are between 1 and 2v
else else
return PADDLE_STRAIGHT; //less than 1v is the straight key return PADDLE_STRAIGHT; //less than 1v is the straight key
*/
} }
/** /**
@ -96,11 +113,20 @@ unsigned char keyerState = IDLE;
//Below is a test to reduce the keying error. do not delete lines //Below is a test to reduce the keying error. do not delete lines
//create by KD8CEC for compatible with new CW Logic //create by KD8CEC for compatible with new CW Logic
char update_PaddleLatch(byte isUpdateKeyState) { char update_PaddleLatch(byte isUpdateKeyState) {
/*
* KC4UPR - IOP update, 2020-05-03
*
* Modifying this for the uBITX IOP. Big picture:
*
* No iambic keyer. It's always "straight key" based on the IOP.
*
* It uses the PTT line.
*/
return (digitalRead(PTT) ? 0 : DIT_L);
/*
unsigned char tmpKeyerControl = 0; unsigned char tmpKeyerControl = 0;
int paddle = analogRead(ANALOG_KEYER); int paddle = analogRead(ANALOG_KEYER);
return 0; // KC4UPR: temporarily disabling keyer while doing ubitx_iop development.
if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo) if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo)
tmpKeyerControl |= DAH_L; tmpKeyerControl |= DAH_L;
else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo) else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo)
@ -121,6 +147,7 @@ char update_PaddleLatch(byte isUpdateKeyState) {
keyerControl |= tmpKeyerControl; keyerControl |= tmpKeyerControl;
return tmpKeyerControl; return tmpKeyerControl;
*/
} }
/***************************************************************************** /*****************************************************************************
@ -128,106 +155,113 @@ char update_PaddleLatch(byte isUpdateKeyState) {
// modified by KD8CEC // modified by KD8CEC
******************************************************************************/ ******************************************************************************/
void cwKeyer(void){ void cwKeyer(void){
lastPaddle = 0; /*
bool continue_loop = true; * KC4UPR - IOP update, 2020-05-03
unsigned tmpKeyControl = 0; *
* Modifying this for the uBITX IOP. Big picture:
if( Iambic_Key ) { *
while(continue_loop) { * No iambic keyer. It's always "straight key" based on the IOP.
switch (keyerState) { */
case IDLE: // lastPaddle = 0;
tmpKeyControl = update_PaddleLatch(0); // bool continue_loop = true;
if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L || // unsigned tmpKeyControl = 0;
tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) { //
update_PaddleLatch(1); // if( Iambic_Key ) {
keyerState = CHK_DIT; // while(continue_loop) {
}else{ // switch (keyerState) {
if (0 < cwTimeout && cwTimeout < millis()){ // case IDLE:
cwTimeout = 0; // tmpKeyControl = update_PaddleLatch(0);
stopTx(); // if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L ||
} // tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) {
continue_loop = false; // update_PaddleLatch(1);
} // keyerState = CHK_DIT;
break; // }else{
// if (0 < cwTimeout && cwTimeout < millis()){
case CHK_DIT: // cwTimeout = 0;
if (keyerControl & DIT_L) { // stopTx();
keyerControl |= DIT_PROC; // }
ktimer = cwSpeed; // continue_loop = false;
keyerState = KEYED_PREP; // }
}else{ // break;
keyerState = CHK_DAH; //
} // case CHK_DIT:
break; // if (keyerControl & DIT_L) {
// keyerControl |= DIT_PROC;
case CHK_DAH: // ktimer = cwSpeed;
if (keyerControl & DAH_L) { // keyerState = KEYED_PREP;
ktimer = cwSpeed*3; // }else{
keyerState = KEYED_PREP; // keyerState = CHK_DAH;
}else{ // }
keyerState = IDLE; // break;
} //
break; // case CHK_DAH:
// if (keyerControl & DAH_L) {
case KEYED_PREP: // ktimer = cwSpeed*3;
//modified KD8CEC // keyerState = KEYED_PREP;
/* // }else{
ktimer += millis(); // set ktimer to interval end time // keyerState = IDLE;
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits // }
keyerState = KEYED; // next state // break;
if (!inTx){ //
//DelayTime Option // case KEYED_PREP:
delay_background(delayBeforeCWStartTime * 2, 2); // //modified KD8CEC
// /*
keyDown = 0; // ktimer += millis(); // set ktimer to interval end time
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; // keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
startTx(TX_CW, 1); // keyerState = KEYED; // next state
} // if (!inTx){
*/ // //DelayTime Option
if (!inTx){ // delay_background(delayBeforeCWStartTime * 2, 2);
//DelayTime Option //
delay_background(delayBeforeCWStartTime * 2, 2); // keyDown = 0;
// cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
keyDown = 0; // startTx(TX_CW, 1);
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; // }
startTx(TX_CW, 1); // */
} // if (!inTx){
ktimer += millis(); // set ktimer to interval end time // //DelayTime Option
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits // delay_background(delayBeforeCWStartTime * 2, 2);
keyerState = KEYED; // next state //
// keyDown = 0;
cwKeydown(); // cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
break; // startTx(TX_CW, 1);
// }
case KEYED: // ktimer += millis(); // set ktimer to interval end time
if (millis() > ktimer) { // are we at end of key down ? // keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
cwKeyUp(); // keyerState = KEYED; // next state
ktimer = millis() + cwSpeed; // inter-element time //
keyerState = INTER_ELEMENT; // next state // cwKeydown();
}else if (keyerControl & IAMBICB) { // break;
update_PaddleLatch(1); // early paddle latch in Iambic B mode //
} // case KEYED:
break; // if (millis() > ktimer) { // are we at end of key down ?
// cwKeyUp();
case INTER_ELEMENT: // ktimer = millis() + cwSpeed; // inter-element time
// Insert time between dits/dahs // keyerState = INTER_ELEMENT; // next state
update_PaddleLatch(1); // latch paddle state // }else if (keyerControl & IAMBICB) {
if (millis() > ktimer) { // are we at end of inter-space ? // update_PaddleLatch(1); // early paddle latch in Iambic B mode
if (keyerControl & DIT_PROC) { // was it a dit or dah ? // }
keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits // break;
keyerState = CHK_DAH; // dit done, check for dah //
}else{ // case INTER_ELEMENT:
keyerControl &= ~(DAH_L); // clear dah latch // // Insert time between dits/dahs
keyerState = IDLE; // go idle // update_PaddleLatch(1); // latch paddle state
} // if (millis() > ktimer) { // are we at end of inter-space ?
} // if (keyerControl & DIT_PROC) { // was it a dit or dah ?
break; // keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits
} // keyerState = CHK_DAH; // dit done, check for dah
// }else{
Check_Cat(2); // keyerControl &= ~(DAH_L); // clear dah latch
} //end of while // keyerState = IDLE; // go idle
} // }
else{ // }
// break;
// }
//
// Check_Cat(2);
// } //end of while
// }
// else{
while(1){ while(1){
if (update_PaddleLatch(0) == DIT_L) { if (update_PaddleLatch(0) == DIT_L) {
// if we are here, it is only because the key is pressed // if we are here, it is only because the key is pressed
@ -264,7 +298,7 @@ void cwKeyer(void){
Check_Cat(2); Check_Cat(2);
} //end of while } //end of while
} //end of elese // } //end of elese
} }