Forgot to add the Keyer on the previous commit.

This commit is contained in:
Rob French 2021-02-11 23:56:08 -06:00
parent d2213e34ff
commit 47840e09dd
2 changed files with 264 additions and 0 deletions

185
TeensyDSP/Keyer.cpp Normal file
View 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
View 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
//======================================================================