About to make a bunch of changes (really not all keyer related), so
committing for safety...
This commit is contained in:
parent
a039740466
commit
e9d021835a
123
ubitx_iop/cat.h
123
ubitx_iop/cat.h
@ -5,11 +5,134 @@
|
||||
#ifndef __iop_cat_h__
|
||||
#define __iop_cat_h__
|
||||
|
||||
#define ACK 0
|
||||
#define CAT_PREFIX 0xC0
|
||||
#define IOP_PREFIX 0xD0
|
||||
#define EEPROM_READ_PREFIX 0xE0
|
||||
#define EEPROM_WRITE_PREFIX 0xF0
|
||||
|
||||
#define IOP_MODE_COMMAND 0x00
|
||||
#define IOP_START_TX_COMMAND 0x01
|
||||
#define IOP_STOP_TX_COMMAND 0x02
|
||||
#define IOP_CW_CONFIG_MSG 0x03
|
||||
|
||||
#define IOP_MODE_REQUEST 0x00
|
||||
#define IOP_CW_STATUS_MSG 0x03
|
||||
|
||||
#define IOP_MODE_SSB 0x00
|
||||
#define IOP_MODE_DIGI 0x01
|
||||
#define IOP_MODE_CW 0x02
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define USBSERIAL Serial
|
||||
#define HWSERIAL Serial1
|
||||
|
||||
/*struct IOPTMsg {
|
||||
};
|
||||
*/
|
||||
|
||||
enum KeyMode {
|
||||
STRAIGHT = 0,
|
||||
IAMBIC_A,
|
||||
IAMBIC_B,
|
||||
//ULTIMATIC,
|
||||
//BUG,
|
||||
};
|
||||
|
||||
const byte MODE_LETTER[3] = {'S', 'A', 'B'};
|
||||
|
||||
const byte NO_FLAGS = 0;
|
||||
const byte REVERSED = 1;
|
||||
|
||||
#define R_MESSAGE_MAX_LEN 32
|
||||
#define T_MESSAGE_MAX_LEN 32
|
||||
|
||||
struct RMessage {
|
||||
uint8_t id;
|
||||
uint8_t len;
|
||||
byte data[R_MESSAGE_MAX_LEN];
|
||||
};
|
||||
|
||||
struct TMessage {
|
||||
uint8_t id;
|
||||
uint8_t len;
|
||||
byte data[T_MESSAGE_MAX_LEN];
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// CW CONFIGURATION MESSAGE
|
||||
//======================================================================
|
||||
|
||||
struct CWConfig {
|
||||
// mode
|
||||
KeyMode mode = IAMBIC_A;
|
||||
// flags
|
||||
bool reversed = false;
|
||||
// parameters
|
||||
uint8_t wpm = 15;
|
||||
float weight = 3.0;
|
||||
uint16_t sidetone = 700;
|
||||
};
|
||||
|
||||
void packR_CWConfig(RMessage &m, CWConfig const &c)
|
||||
{
|
||||
m.id = IOP_CW_CONFIG_MSG;
|
||||
m.len = 6;
|
||||
// mode
|
||||
m.data[0] = byte(c.mode);
|
||||
// flags
|
||||
m.data[1] = NO_FLAGS;
|
||||
m.data[1] |= (c.reversed ? REVERSED : 0);
|
||||
// parameters
|
||||
m.data[2] = byte(c.wpm);
|
||||
m.data[3] = byte(c.weight * 10.0);
|
||||
m.data[4] = byte(c.sidetone >> 8);
|
||||
m.data[5] = byte(c.sidetone | 0x0F);
|
||||
}
|
||||
|
||||
void unpackR_CWConfig(CWConfig &c, RMessage const &m)
|
||||
{
|
||||
//if (m.id != IOP_CW_CONFIG_MSG || m.len != 6) {
|
||||
// // do some error thing...
|
||||
//}
|
||||
//mode
|
||||
c.mode = KeyMode(m.data[0]);
|
||||
// flags
|
||||
c.reversed = bool(m.data[1] & REVERSED);
|
||||
// parameters
|
||||
c.wpm = uint8_t(m.data[2]);
|
||||
c.weight = float(m.data[3]) / 10.0;
|
||||
c.sidetone = (m.data[4] << 8) | m.data[5];
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// MODE REQUEST MESSAGE
|
||||
//======================================================================
|
||||
|
||||
void packT_ModeRequest(TMessage &m)
|
||||
{
|
||||
m.id = IOP_MODE_REQUEST;
|
||||
m.len = 0;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// CW STATUS MESSAGE
|
||||
//======================================================================
|
||||
|
||||
//void packT_DisplayText(TMessage &m, CWConfig const &c)
|
||||
//{
|
||||
// m.id = IOP_CW_STATUS_MSG;
|
||||
// m.len = 3;
|
||||
// m.data[0] = ' '; // growth
|
||||
// m.data[1] = MODE_LETTER[c.mode];
|
||||
// m.data[2] = ' '; // TODO: RX filter width
|
||||
//}
|
||||
|
||||
// No unpack required: this is a string to put on the display.
|
||||
|
||||
//======================================================================
|
||||
|
||||
void initCAT(long, int);
|
||||
void serviceCAT();
|
||||
|
||||
|
@ -4,18 +4,18 @@
|
||||
|
||||
#include "cat.h"
|
||||
|
||||
#define ACK 0
|
||||
#define CAT_PREFIX 0xC0
|
||||
#define IOP_PREFIX 0xD0
|
||||
#define EEPROM_READ_PREFIX 0xE0
|
||||
#define EEPROM_WRITE_PREFIX 0xF0
|
||||
|
||||
#define IOP_MODE_COMMAND 0x00
|
||||
#define IOP_START_TX_COMMAND 0x01
|
||||
#define IOP_STOP_TX_COMMAND 0x02
|
||||
#define IOP_MODE_SSB 0x00
|
||||
#define IOP_MODE_DIGI 0x01
|
||||
#define IOP_MODE_CW 0x02
|
||||
//#define ACK 0
|
||||
//#define CAT_PREFIX 0xC0
|
||||
//#define IOP_PREFIX 0xD0
|
||||
//#define EEPROM_READ_PREFIX 0xE0
|
||||
//#define EEPROM_WRITE_PREFIX 0xF0
|
||||
//
|
||||
//#define IOP_MODE_COMMAND 0x00
|
||||
//#define IOP_START_TX_COMMAND 0x01
|
||||
//#define IOP_STOP_TX_COMMAND 0x02
|
||||
//#define IOP_MODE_SSB 0x00
|
||||
//#define IOP_MODE_DIGI 0x01
|
||||
//#define IOP_MODE_CW 0x02
|
||||
|
||||
//======================================================================
|
||||
// CAT from PC-to-IOP
|
||||
|
@ -5,6 +5,9 @@
|
||||
#ifndef __iop_config_h__
|
||||
#define __iop_config_h__
|
||||
|
||||
#define KEYER_LEFT_PADDLE_PIN 16
|
||||
#define KEYER_RIGHT_PADDLE_PIN 17
|
||||
|
||||
// Uncomment to use the "factory" calibration mode. This is intended to
|
||||
// allow calibration of IOP settings, separately from the uBITX/Raduino.
|
||||
// There will be no pass-thru of any CAT.
|
||||
|
81
ubitx_iop/keyer.h
Normal file
81
ubitx_iop/keyer.h
Normal file
@ -0,0 +1,81 @@
|
||||
//**********************************************************************
|
||||
//
|
||||
// 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 __iop_keyer_h__
|
||||
#define __iop_keyer_h__
|
||||
|
||||
//#include "Arduino.h"
|
||||
|
||||
//#include "config.h"
|
||||
|
||||
#define IAMBICA 0
|
||||
#define IAMBICB 1
|
||||
#define STRAIGHT 2
|
||||
|
||||
class Keyer
|
||||
{
|
||||
private:
|
||||
//int cw_pin_;
|
||||
//int ptt_pin_;
|
||||
bool key_down;
|
||||
|
||||
long ktimer;
|
||||
|
||||
int _speed;
|
||||
int _dashlen; // Length of dash
|
||||
int _dotlen; // Length of dot
|
||||
int _space_len; // Length of space
|
||||
float _weight;
|
||||
|
||||
char keyerControl;
|
||||
char keyerState;
|
||||
int key_mode;
|
||||
|
||||
void calc_ratio();
|
||||
void update_PaddleLatch();
|
||||
|
||||
public:
|
||||
Keyer(int wpm, float _weight);
|
||||
//void cw_pin(int pin);
|
||||
//void ptt_pin(int pin);
|
||||
void wpm(int spd);
|
||||
void set_mode(int md);
|
||||
int get_mode() { return key_mode; }
|
||||
bool is_down() { return key_down; }
|
||||
// void set__weight();
|
||||
|
||||
bool do_paddles();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
214
ubitx_iop/keyer.ino
Normal file
214
ubitx_iop/keyer.ino
Normal file
@ -0,0 +1,214 @@
|
||||
//======================================================================
|
||||
//
|
||||
// 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 };
|
||||
|
||||
Keyer::Keyer(int wpm, float weight)
|
||||
{
|
||||
//ptt_pin_ = PTT_PIN;
|
||||
//cw_pin_ = CW_PIN;
|
||||
// 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
|
||||
|
||||
// pinMode(ST_Pin, OUTPUT); // Sets the Sidetone digital pin as output
|
||||
|
||||
// digitalWrite(LP_in, HIGH); // Enable pullup resistor on Left Paddle Input Pin
|
||||
// digitalWrite(RP_in, HIGH); // Enable pullup resistor on Right Paddle Input Pin
|
||||
|
||||
keyerState = IDLE;
|
||||
keyerControl = 0;
|
||||
key_mode = IAMBICA;
|
||||
key_down = false;
|
||||
_weight = weight;
|
||||
|
||||
_speed = wpm;
|
||||
calc_ratio();
|
||||
}
|
||||
|
||||
// Calculate the length of dot, dash and silence
|
||||
void Keyer::calc_ratio()
|
||||
{
|
||||
float w = (1 + _weight) / (_weight -1);
|
||||
_space_len = (1200 / _speed);
|
||||
_dotlen = _space_len * (w - 1);
|
||||
_dashlen = (1 + w) * _space_len;
|
||||
}
|
||||
|
||||
//void Keyer::cw_pin(int pin)
|
||||
//{
|
||||
// ptt_pin_ = pin;
|
||||
//}
|
||||
|
||||
//void Keyer::ptt_pin(int pin)
|
||||
//{
|
||||
// cw_pin_ = pin;
|
||||
//}
|
||||
|
||||
void Keyer::set_mode(int md)
|
||||
{
|
||||
key_mode = md;
|
||||
}
|
||||
|
||||
void Keyer::wpm(int wpm)
|
||||
{
|
||||
_speed = wpm;
|
||||
calc_ratio();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Latch paddle press
|
||||
//======================================================================
|
||||
|
||||
void Keyer::update_PaddleLatch()
|
||||
{
|
||||
if (digitalRead(LP_in) == LOW) {
|
||||
keyerControl |= DIT_L;
|
||||
}
|
||||
if (digitalRead(RP_in) == LOW) {
|
||||
keyerControl |= DAH_L;
|
||||
}
|
||||
}
|
||||
|
||||
bool Keyer::do_paddles()
|
||||
{
|
||||
if (key_mode == STRAIGHT) { // Straight Key
|
||||
if ((digitalRead(LP_in) == LOW) || (digitalRead(RP_in) == LOW)) {
|
||||
// Key from either paddle
|
||||
// digitalWrite(ptt_pin_, HIGH);
|
||||
// digitalWrite(cw_pin_, HIGH);
|
||||
// tone(ST_Pin, 600);
|
||||
key_down = true;
|
||||
return true;
|
||||
} else {
|
||||
// digitalWrite(ptt_pin_, LOW);
|
||||
// digitalWrite(cw_pin_, LOW);
|
||||
// noTone(ST_Pin);
|
||||
key_down = 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)) {
|
||||
update_PaddleLatch();
|
||||
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
|
||||
// digitalWrite(ptt_pin_, HIGH); // Enable PTT
|
||||
// tone(ST_Pin, ST_Freq); // Turn the Sidetone on
|
||||
// digitalWrite(cw_pin_, HIGH); // Key the CW line
|
||||
key_down = 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 ?
|
||||
// digitalWrite(ptt_pin_, LOW); // Disable PTT
|
||||
// noTone(ST_Pin); // Turn the Sidetone off
|
||||
// digitalWrite(cw_pin_, LOW); // Unkey the CW line
|
||||
key_down = false;
|
||||
ktimer = millis() + _space_len; // inter-element time
|
||||
keyerState = INTER_ELEMENT; // next state
|
||||
// letting this fall through // return true;
|
||||
} else if (key_mode == IAMBICB) { // Iambic B Mode ?
|
||||
update_PaddleLatch(); // yes, early paddle latch in Iambic B mode
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
// break;
|
||||
|
||||
case INTER_ELEMENT: // Insert time between dits/dahs
|
||||
update_PaddleLatch(); // 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?
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
52
ubitx_iop/menu.h
Normal file
52
ubitx_iop/menu.h
Normal file
@ -0,0 +1,52 @@
|
||||
//======================================================================
|
||||
// menu.h
|
||||
//======================================================================
|
||||
|
||||
#ifndef __menu_h__
|
||||
#define __menu_h__
|
||||
|
||||
// 16 characters on display
|
||||
#define MAX_TEXT_LEN 16
|
||||
#define MENU_SELECTED_CHAR '>'
|
||||
/*
|
||||
public class MenuItem {
|
||||
public:
|
||||
MenuItem(bool active = true, int timeout = 0): _active(active), _timeout(timeout), _elapsed(0) {}
|
||||
void update() {
|
||||
if ((_timeout > 0) && (_elapsed > _timeout)) {
|
||||
_active = false;
|
||||
}
|
||||
}
|
||||
inline void activate() { _active = true; _elapsed = 0; }
|
||||
inline void deactivate() { _active = false; }
|
||||
virtual MenuItem* accept();
|
||||
virtual MenuItem* reject();
|
||||
virtual MenuItem* next();
|
||||
virtual MenuItem* prev();
|
||||
|
||||
private:
|
||||
bool _active;
|
||||
int _timeout;
|
||||
elapsedMillis _elapsed;
|
||||
};
|
||||
|
||||
public class SSBMenu {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
|
||||
public class DigiMenu {
|
||||
public:
|
||||
private:
|
||||
}
|
||||
|
||||
public class CWMenu {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
*/
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
139
ubitx_iop/menu.ino
Normal file
139
ubitx_iop/menu.ino
Normal file
@ -0,0 +1,139 @@
|
||||
//======================================================================
|
||||
// menu.ino
|
||||
//======================================================================
|
||||
|
||||
#include "menu.h"
|
||||
|
||||
/*
|
||||
CW mode:
|
||||
WPM (although we can get this from Raduino)
|
||||
WPM: # (L/R, select/abort)
|
||||
FILT
|
||||
WIDE NORM NARR
|
||||
|
||||
SSB mode:
|
||||
TX LVL
|
||||
COMP
|
||||
FILT
|
||||
WIDE NORM NARR
|
||||
|
||||
Digi mode:
|
||||
TX LVL
|
||||
*/
|
||||
|
||||
class MenuItem {
|
||||
public:
|
||||
MenuItem() {}
|
||||
virtual MenuItem* next() = 0;
|
||||
virtual MenuItem* prev() = 0;
|
||||
char text[MAX_TEXT_LEN + 1];
|
||||
};
|
||||
|
||||
class TextMenu : public MenuItem {
|
||||
public:
|
||||
TextMenu(int num_entries, int entry_len): MenuItem(), _num_entries(num_entries), _entry_len(entry_len), _selected(0), _leftmost(0) {
|
||||
text[0] = '\0';
|
||||
_entries = new MenuItem*[_num_entries];
|
||||
_labels = new char*[_num_entries];
|
||||
for (int i = 0; i < _num_entries; i++) {
|
||||
_labels[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
~TextMenu() {
|
||||
for (int i = 0; i < _num_entries; i++) {
|
||||
if (_labels[i] != NULL) {
|
||||
delete _labels[i];
|
||||
}
|
||||
}
|
||||
delete _labels;
|
||||
delete _entries;
|
||||
}
|
||||
|
||||
virtual MenuItem* next() {
|
||||
bool dirty = false;
|
||||
|
||||
if (++_selected == _num_entries) {
|
||||
_selected = 0;
|
||||
}
|
||||
|
||||
if (_selected < _leftmost) {
|
||||
_leftmost = _selected;
|
||||
dirty = true;
|
||||
} else {
|
||||
while ((_selected - _leftmost) * _entry_len >= MAX_TEXT_LEN) {
|
||||
_leftmost++;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
for (int i = _leftmost; i < _num_entries; i++) {
|
||||
strncpy(&text[i - _leftmost], _labels[i], _entry_len);
|
||||
}
|
||||
}
|
||||
text[_selected - _leftmost] = MENU_SELECTED_CHAR;
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual MenuItem* prev() {
|
||||
bool dirty = false;
|
||||
|
||||
if (_selected-- == 0) {
|
||||
_selected += _num_entries;
|
||||
}
|
||||
|
||||
if (_selected < _leftmost) {
|
||||
_leftmost = _selected;
|
||||
dirty = true;
|
||||
} else {
|
||||
while ((_selected - _leftmost) * _entry_len >= MAX_TEXT_LEN) {
|
||||
_leftmost++;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
updateText();
|
||||
} else {
|
||||
updateCursor();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void addEntry(int i, const char* label, MenuItem* entry) {
|
||||
if (i < _num_entries) {
|
||||
_labels[i] = new char[strlen(label) + 1]; // I need to learn to do strings the C++ way.
|
||||
strcpy(_labels[i], label); // Ditto.
|
||||
_entries[i] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
void updateText() {
|
||||
for (int i = _leftmost; i < _num_entries; i++) {
|
||||
strncpy(&text[i - _leftmost], _labels[i], _entry_len);
|
||||
}
|
||||
text[_selected - _leftmost] = MENU_SELECTED_CHAR;
|
||||
}
|
||||
|
||||
void updateCursor() {
|
||||
text[_selected - _leftmost] = MENU_SELECTED_CHAR;
|
||||
}
|
||||
|
||||
/*MenuItem* operator[](int i) {
|
||||
return this->entries[i];
|
||||
}*/
|
||||
|
||||
private:
|
||||
int _num_entries;
|
||||
int _entry_len;
|
||||
int _selected;
|
||||
int _leftmost;
|
||||
char** _labels;
|
||||
MenuItem** _entries;
|
||||
};
|
||||
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
@ -9,6 +9,7 @@
|
||||
#include "audio.h"
|
||||
#include "cat.h"
|
||||
#include "eeprom.h"
|
||||
#include "keyer.h"
|
||||
|
||||
// comment this out to disable debugging code
|
||||
//#define DEBUG
|
||||
@ -29,6 +30,8 @@ enum TxState {
|
||||
|
||||
extern RigMode rigMode;
|
||||
|
||||
extern bool keyerKeyDown;
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
|
@ -19,6 +19,13 @@ Bounce linePTT = Bounce();
|
||||
|
||||
TxState txState = TX_OFF;
|
||||
|
||||
Keyer keyer(15, 3.0); // need to make configurable
|
||||
|
||||
//SSBMenu ssbMenu();
|
||||
//DigiMenu digiMenu();
|
||||
//CWMenu cwMenu();
|
||||
//MenuItem* dspMenu = &ssbMenu;
|
||||
|
||||
//======================================================================
|
||||
// catPTTOn()
|
||||
//
|
||||
@ -195,6 +202,7 @@ void setRigMode(RigMode m)
|
||||
// automatically overridden by mic-in, if the mic PTT is pressed.
|
||||
audioSelectTxInput(TX_LINE_IN);
|
||||
audioSSBFilter();
|
||||
// dspMenu = &ssbMenu;
|
||||
break;
|
||||
|
||||
case MODE_DIGI:
|
||||
@ -207,12 +215,14 @@ void setRigMode(RigMode m)
|
||||
// than using CAT for PTT control.
|
||||
audioSelectTxInput(TX_USB_IN);
|
||||
audioDigiFilter();
|
||||
// dspMenu = &digiMenu;
|
||||
break;
|
||||
|
||||
case MODE_CW:
|
||||
// CW just gets the radio off of Mic-In; but it won't use Line-In.
|
||||
audioSelectTxInput(TX_LINE_IN);
|
||||
audioCWFilter();
|
||||
audioCWFilter();
|
||||
// dspMenu = &cwMenu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -239,12 +249,32 @@ void setup() {
|
||||
|
||||
//======================================================================
|
||||
|
||||
void loop() {
|
||||
elapsedMillis frame_timer = 0;
|
||||
void loop() {
|
||||
elapsedMillis elapsed = 0;
|
||||
|
||||
switch(rigMode) {
|
||||
case MODE_CW:
|
||||
if (keyer.do_paddles()) {
|
||||
if (keyer.is_down()) {
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
} else {
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
}
|
||||
// No break... if the paddle is not active, I want this to fall
|
||||
// through to checkMicPTT etc... but return early if the paddle is
|
||||
// active, to maximize responsiveness. Probably could just use
|
||||
// 'if' statements here instead of the 'switch'.
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
checkMicPTT();
|
||||
checkLinePTT();
|
||||
serviceCAT();
|
||||
}
|
||||
|
||||
//dspMenu->update();
|
||||
|
||||
checkMicPTT();
|
||||
checkLinePTT();
|
||||
serviceCAT();
|
||||
/*
|
||||
#if defined(DEBUG)
|
||||
int frame_skews = 0; // for debugging; see how often we skew frames
|
||||
|
Loading…
Reference in New Issue
Block a user