Use settings in all files. Compiles, but untested

This commit is contained in:
Reed Nightingale 2020-01-03 23:11:55 -08:00
parent 0bf8424ab9
commit 39168d663e
9 changed files with 417 additions and 821 deletions

164
keyer.cpp
View File

@ -1,4 +1,5 @@
#include <Arduino.h>
#include "settings.h"
#include "ubitx.h"
/**
@ -28,72 +29,27 @@
*/
//CW ADC Range
int cwAdcSTFrom = 0;
int cwAdcSTTo = 50;
int cwAdcBothFrom = 51;
int cwAdcBothTo = 300;
int cwAdcDotFrom = 301;
int cwAdcDotTo = 600;
int cwAdcDashFrom = 601;
int cwAdcDashTo = 800;
//byte cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb
static const unsigned int cwAdcSTFrom = 0;
static const unsigned int cwAdcSTTo = 50;
static const unsigned int cwAdcBothFrom = cwAdcSTTo + 1;
static const unsigned int cwAdcBothTo = 300;
static const unsigned int cwAdcDotFrom = cwAdcBothTo + 1;
static const unsigned int cwAdcDotTo = 600;
static const unsigned int cwAdcDashFrom = cwAdcDotTo + 1;
static const unsigned int cwAdcDashTo = 800;
byte delayBeforeCWStartTime = 50;
static const unsigned int delayBeforeCWStartTime = 50;
// in milliseconds, this is the parameter that determines how long the tx will hold between cw key downs
//#define CW_TIMEOUT (600l) //Change to CW Delaytime for value save to eeprom
#define PADDLE_DOT 1
#define PADDLE_DASH 2
#define PADDLE_BOTH 3
#define PADDLE_STRAIGHT 4
//we store the last padde's character
//to alternatively send dots and dashes
//when both are simultaneously pressed
char lastPaddle = 0;
/*
//reads the analog keyer pin and reports the paddle
byte getPaddle(){
int paddle = analogRead(ANALOG_KEYER);
//handle the ptt as the straight key
if (digitalRead(PTT) == 0)
return PADDLE_STRAIGHT;
if (paddle > 800) // above 4v is up
return 0;
if (!Iambic_Key)
return PADDLE_STRAIGHT;
if (paddle > 600) // 4-3v is dot
return PADDLE_DASH;
else if (paddle > 300) //1-2v is dash
return PADDLE_DOT;
else if (paddle > 50)
return PADDLE_BOTH; //both are between 1 and 2v
else
return PADDLE_STRAIGHT; //less than 1v is the straight key
}
*/
/**
* Starts transmitting the carrier with the sidetone
* It assumes that we have called cwTxStart and not called cwTxStop
* each time it is called, the cwTimeOut is pushed further into the future
*/
void cwKeydown(){
tone(CW_TONE, globalSettings.cwSideToneFreq);
digitalWrite(CW_KEY, 1);
keyDown = 1; //tracks the CW_KEY
tone(CW_TONE, (int)sideTone);
digitalWrite(CW_KEY, 1);
//Modified by KD8CEC, for CW Delay Time save to eeprom
//cwTimeout = millis() + CW_TIMEOUT;
cwTimeout = millis() + cwDelayTime * 10;
globalSettings.cwExpirationTimeMs = millis() + globalSettings.cwActiveTimeoutMs;
}
/**
@ -101,13 +57,10 @@ void cwKeydown(){
* Pushes the cwTimeout further into the future
*/
void cwKeyUp(){
keyDown = 0; //tracks the CW_KEY
noTone(CW_TONE);
digitalWrite(CW_KEY, 0);
digitalWrite(CW_KEY, 0);
//Modified by KD8CEC, for CW Delay Time save to eeprom
//cwTimeout = millis() + CW_TIMEOUT;
cwTimeout = millis() + cwDelayTime * 10;
globalSettings.cwExpirationTimeMs = millis() + globalSettings.cwActiveTimeoutMs;
}
//Variables for Ron's new logic
@ -119,16 +72,14 @@ void cwKeyUp(){
enum KSTYPE {IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT };
static unsigned long ktimer;
unsigned char keyerState = IDLE;
uint8_t keyerControl = 0;
//Below is a test to reduce the keying error. do not delete lines
//create by KD8CEC for compatible with new CW Logic
char update_PaddleLatch(byte isUpdateKeyState) {
char update_PaddleLatch(bool isUpdateKeyState) {
unsigned char tmpKeyerControl = 0;
int paddle = analogRead(ANALOG_KEYER);
//diagnostic, VU2ESE
//itoa(paddle, b, 10);
//printLine2(b);
//use the PTT as the key for tune up, quick QSOs
if (digitalRead(PTT) == 0)
@ -138,18 +89,17 @@ char update_PaddleLatch(byte isUpdateKeyState) {
else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo)
tmpKeyerControl |= DIT_L;
else if (paddle >= cwAdcBothFrom && paddle <= cwAdcBothTo)
tmpKeyerControl |= (DAH_L | DIT_L) ;
else
{
if (Iambic_Key)
tmpKeyerControl |= (DAH_L | DIT_L) ;
else{
if (KeyerMode_e::KEYER_STRAIGHT != globalSettings.keyerMode)
tmpKeyerControl = 0 ;
else if (paddle >= cwAdcSTFrom && paddle <= cwAdcSTTo)
tmpKeyerControl = DIT_L ;
else
tmpKeyerControl = 0 ;
tmpKeyerControl = 0 ;
}
if (isUpdateKeyState == 1)
if (isUpdateKeyState)
keyerControl |= tmpKeyerControl;
return tmpKeyerControl;
@ -160,22 +110,24 @@ char update_PaddleLatch(byte isUpdateKeyState) {
// modified by KD8CEC
******************************************************************************/
void cwKeyer(void){
lastPaddle = 0;
bool continue_loop = true;
unsigned tmpKeyControl = 0;
if( Iambic_Key ) {
while(continue_loop) {
switch (keyerState) {
if(KeyerMode_e::KEYER_STRAIGHT != globalSettings.keyerMode){
while(continue_loop){
switch(keyerState){
case IDLE:
tmpKeyControl = update_PaddleLatch(0);
if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L ||
tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) {
update_PaddleLatch(1);
if((tmpKeyControl == DAH_L)//Currently dah
||(tmpKeyControl == DIT_L)//Currently dit
||(tmpKeyControl == (DAH_L | DIT_L))//Currently both
||( keyerControl & (DAH_L | DIT_L))){//Resolving either
update_PaddleLatch(true);
keyerState = CHK_DIT;
}else{
if (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
}
else{
if (0 < globalSettings.cwExpirationTimeMs && globalSettings.cwExpirationTimeMs < millis()){
globalSettings.cwExpirationTimeMs = 0;
stopTx();
}
continue_loop = false;
@ -185,7 +137,7 @@ void cwKeyer(void){
case CHK_DIT:
if (keyerControl & DIT_L) {
keyerControl |= DIT_PROC;
ktimer = cwSpeed;
ktimer = globalSettings.cwDitDurationMs;
keyerState = KEYED_PREP;
}else{
keyerState = CHK_DAH;
@ -194,7 +146,7 @@ void cwKeyer(void){
case CHK_DAH:
if (keyerControl & DAH_L) {
ktimer = cwSpeed*3;
ktimer = 3*globalSettings.cwDitDurationMs;
keyerState = KEYED_PREP;
}else{
keyerState = IDLE;
@ -203,13 +155,11 @@ void cwKeyer(void){
case KEYED_PREP:
//modified KD8CEC
if (!inTx){
if (!globalSettings.txActive){
//DelayTime Option
active_delay(delayBeforeCWStartTime * 2);
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
startTx(TX_CW);
globalSettings.cwExpirationTimeMs = millis() + globalSettings.cwActiveTimeoutMs;
startTx(TuningMode_e::TUNE_CW);
}
ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
@ -220,10 +170,11 @@ void cwKeyer(void){
case KEYED:
if (millis() > ktimer) { // are we at end of key down ?
cwKeyUp();
ktimer = millis() + cwSpeed; // inter-element time
cwKeyUp();
ktimer = millis() + (globalSettings.cwDitDurationMs / 10); // inter-element time
keyerState = INTER_ELEMENT; // next state
}else if (keyerControl & IAMBICB) {
}
else if(KeyerMode_e::KEYER_IAMBIC_B == globalSettings.keyerMode){
update_PaddleLatch(1); // early paddle latch in Iambic B mode
}
break;
@ -246,20 +197,19 @@ void cwKeyer(void){
checkCAT();
} //end of while
}
else{
else{//KEYER_STRAIGHT
while(1){
char state = update_PaddleLatch(0);
// Serial.println((int)state);
// Serial.println((int)state);
if (state == DIT_L) {
// if we are here, it is only because the key is pressed
if (!inTx){
startTx(TX_CW);
if (!globalSettings.txActive){
startTx(TuningMode_e::TUNE_CW);
//DelayTime Option
active_delay(delayBeforeCWStartTime * 2);
keyDown = 0;
cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT;
globalSettings.cwExpirationTimeMs = millis() + globalSettings.cwDitDurationMs;
}
cwKeydown();
@ -269,24 +219,16 @@ void cwKeyer(void){
cwKeyUp();
}
else{
if (0 < cwTimeout && cwTimeout < millis()){
cwTimeout = 0;
keyDown = 0;
if (0 < globalSettings.cwExpirationTimeMs && globalSettings.cwExpirationTimeMs < millis()){
globalSettings.cwExpirationTimeMs = 0;
stopTx();
}
//if (!cwTimeout) //removed by KD8CEC
// return;
// got back to the beginning of the loop, if no further activity happens on straight key
// we will time out, and return out of this routine
//delay(5);
//delay_background(5, 3); //removed by KD8CEC
//continue; //removed by KD8CEC
return; //Tx stop control by Main Loop
return;//Tx stop control by Main Loop
}
checkCAT();
} //end of while
} //end of elese
}//end of else KEYER_STRAIGHT
}

View File

@ -1,5 +1,6 @@
#include <Arduino.h>
#include "ubitx.h"
#include "settings.h"
#include "morse.h"
/*
* Each byte of the morse table stores one letter.
@ -8,10 +9,9 @@
* The first zero after the 1s indicates the start of the letter, it MUST be discarded
*/
extern int cwSpeed;
struct Morse {
char letter;
unsigned char code;
unsigned char code;
};
static const PROGMEM struct Morse morse_table[] = {
@ -51,8 +51,8 @@ static const PROGMEM struct Morse morse_table[] = {
{'8', 0xdc}, // 11011100
{'9', 0xde}, // 11011110
{'0', 0xdf}, // 11011111
{'.', 0xd5}, // 110010101
{',', 0xd3}, // 110110011 //AD7U 20191217
{'.', 0xd5}, // 11010101
{',', 0xd3}, // 11010011 //AD7U 20191217
{'?', 0xcc}, // 11001100 //AD7U 20191217 - Added
};
@ -61,7 +61,7 @@ static void morseLetter(char c){
//handle space character as three dashes
if (c == ' '){
active_delay(cwSpeed * 9);
active_delay(9 * globalSettings.cwDitDurationMs);
Serial.print(' ');
return;
}
@ -79,18 +79,18 @@ static void morseLetter(char c){
//now we are at the first zero, skip and carry on
mask = mask >> 1;
while(mask){
tone(CW_TONE, sideTone,10000);
tone(CW_TONE, globalSettings.cwSideToneFreq,10000);
if (mask & code){
delay(3 * (int)cwSpeed);
delay(3 * globalSettings.cwDitDurationMs);
//Serial.print('-');
}
else{
delay((int)cwSpeed);
delay(globalSettings.cwDitDurationMs);
//Serial.print('.');
}
//Serial.print('#');
noTone(CW_TONE);
delay((int)cwSpeed); // space between dots and dashes
delay(globalSettings.cwDitDurationMs); // space between dots and dashes
mask = mask >> 1;
}
//Serial.println('@');
@ -107,7 +107,7 @@ void morseText(char *text){
delay(1000);
// }
Serial.println(sideTone);
Serial.println(globalSettings.cwSideToneFreq);
while(*text){
morseLetter(*text++);
}

View File

@ -1,5 +1,5 @@
#include <Arduino.h>
#include <EEPROM.h>
#include "settings.h"
#include "ubitx.h"
#include "nano_gui.h"
@ -8,30 +8,18 @@
struct Point ts_point;
//filled from a test run of calibration routine
int slope_x=104, slope_y=137, offset_x=28, offset_y=29;
void readTouchCalibration(){
EEPROM.get(SLOPE_X, slope_x);
EEPROM.get(SLOPE_Y, slope_y);
EEPROM.get(OFFSET_X, offset_x);
EEPROM.get(OFFSET_Y, offset_y);
/*
//for debugging
Serial.print(slope_x); Serial.print(' ');
Serial.print(slope_y); Serial.print(' ');
Serial.print(offset_x); Serial.print(' ');
Serial.println(offset_y); Serial.println(' ');
*/
LoadSettingsFromEeprom();
/* for debugging
Serial.print(globalSettings.touchSlopeX); Serial.print(' ');
Serial.print(globalSettings.touchSlopeY); Serial.print(' ');
Serial.print(globalSettings.touchOffsetX); Serial.print(' ');
Serial.println(globalSettings.touchOffsetY); Serial.println(' ');
//*/
}
void writeTouchCalibration(){
EEPROM.put(SLOPE_X, slope_x);
EEPROM.put(SLOPE_Y, slope_y);
EEPROM.put(OFFSET_X, offset_x);
EEPROM.put(OFFSET_Y, offset_y);
SaveSettingsToEeprom();
}
#define Z_THRESHOLD 400
@ -118,7 +106,7 @@ static void touch_update(){
}
boolean readTouch(){
bool readTouch(){
touch_update();
if (zraw >= Z_THRESHOLD) {
ts_point.x = xraw;
@ -130,8 +118,8 @@ boolean readTouch(){
}
void scaleTouch(struct Point *p){
p->x = ((long)(p->x - offset_x) * 10l)/ (long)slope_x;
p->y = ((long)(p->y - offset_y) * 10l)/ (long)slope_y;
p->x = ((long)(p->x - globalSettings.touchOffsetX) * 10L)/ (long)globalSettings.touchSlopeX;
p->y = ((long)(p->y - globalSettings.touchOffsetY) * 10L)/ (long)globalSettings.touchSlopeY;
//Serial.print(p->x); Serial.print(",");Serial.println(p->y);
}
@ -176,7 +164,7 @@ void displayVline(unsigned int x, unsigned int y, unsigned int l, unsigned int c
tft.drawFastVLine(x,y,l,c);
}
void displayClear(unsigned int color){
void displayClear(unsigned int color){
tft.fillRect(0,0,320,240,color);
}
@ -283,14 +271,14 @@ void setupTouch(){
// we average two readings and divide them by half and store them as scaled integers 10 times their actual, fractional value
//the x points are located at 20 and 300 on x axis, hence, the delta x is 280, we take 28 instead, to preserve fractional value,
//there are two readings (x1,x2) and (x3, x4). Hence, we have to divide by 28 * 2 = 56
slope_x = ((x4 - x3) + (x2 - x1))/56;
globalSettings.touchSlopeX = ((x4 - x3) + (x2 - x1))/56;
//the y points are located at 20 and 220 on the y axis, hence, the delta is 200. we take it as 20 instead, to preserve the fraction value
//there are two readings (y1, y2) and (y3, y4). Hence we have to divide by 20 * 2 = 40
slope_y = ((y3 - y1) + (y4 - y2))/40;
globalSettings.touchSlopeY = ((y3 - y1) + (y4 - y2))/40;
//x1, y1 is at 20 pixels
offset_x = x1 + -((20 * slope_x)/10);
offset_y = y1 + -((20 * slope_y)/10);
globalSettings.touchOffsetX = x1 + -((20 * globalSettings.touchSlopeX)/10);
globalSettings.touchOffsetY = y1 + -((20 * globalSettings.touchSlopeY)/10);
/*
Serial.print(x1);Serial.print(':');Serial.println(y1);
@ -299,10 +287,10 @@ void setupTouch(){
Serial.print(x4);Serial.print(':');Serial.println(y4);
//for debugging
Serial.print(slope_x); Serial.print(' ');
Serial.print(slope_y); Serial.print(' ');
Serial.print(offset_x); Serial.print(' ');
Serial.println(offset_y); Serial.println(' ');
Serial.print(globalSettings.touchSlopeX); Serial.print(' ');
Serial.print(globalSettings.touchSlopeY); Serial.print(' ');
Serial.print(globalSettings.touchOffsetX); Serial.print(' ');
Serial.println(globalSettings.touchOffsetY); Serial.println(' ');
*/
writeTouchCalibration();
displayClear(DISPLAY_BLACK);

149
setup.cpp
View File

@ -1,6 +1,7 @@
#include <Arduino.h>
#include <EEPROM.h>
#include "morse.h"
#include "settings.h"
#include "ubitx.h"
#include "nano_gui.h"
@ -22,7 +23,6 @@ void setupExit(){
}
//this is used by the si5351 routines in the ubitx_5351 file
extern int32_t calibration;
extern uint32_t si5351bx_vcoa;
void setupFreq(){
@ -32,12 +32,15 @@ void setupFreq(){
displayDialog("Set Frequency", "Push TUNE to Save");
//round off the the nearest khz
frequency = (frequency/1000l)* 1000l;
setFrequency(frequency);
{
uint32_t freq = GetActiveVfoFreq();
freq = (freq/1000l)* 1000l;
setFrequency(freq);
}
displayRawText("You should have a", 20, 50, DISPLAY_CYAN, DISPLAY_NAVY);
displayRawText("signal exactly at ", 20, 75, DISPLAY_CYAN, DISPLAY_NAVY);
ltoa(frequency/1000l, c, 10);
ltoa(GetActiveVfoFreq()/1000l, c, 10);
strcat(c, " KHz");
displayRawText(c, 20, 100, DISPLAY_CYAN, DISPLAY_NAVY);
@ -47,38 +50,38 @@ void setupFreq(){
active_delay(100);
active_delay(100);
prev_calibration = calibration;
calibration = 0;
prev_calibration = globalSettings.oscillatorCal;
globalSettings.oscillatorCal = 0;
// ltoa(calibration/8750, c, 10);
// strcpy(b, c);
// strcat(b, "Hz");
// printLine2(b);
// printLine2(b);
while (!btnDown())
{
knob = enc_read();
if (knob != 0)
calibration += knob * 875;
globalSettings.oscillatorCal += knob * 875;
/* else if (knob < 0)
calibration -= 875; */
else
continue; //don't update the frequency or the display
si5351bx_setfreq(0, usbCarrier); //set back the cardrier oscillator anyway, cw tx switches it off
si5351_set_calibration(calibration);
setFrequency(frequency);
si5351bx_setfreq(0, globalSettings.usbCarrierFreq); //set back the cardrier oscillator anyway, cw tx switches it off
si5351_set_calibration(globalSettings.oscillatorCal);
setFrequency(GetActiveVfoFreq());
//displayRawText("Rotate to zerobeat", 20, 120, DISPLAY_CYAN, DISPLAY_NAVY);
ltoa(calibration, b, 10);
ltoa(globalSettings.oscillatorCal, b, 10);
displayText(b, 100, 140, 100, 26, DISPLAY_CYAN, DISPLAY_NAVY, DISPLAY_WHITE);
}
EEPROM.put(MASTER_CAL, calibration);
SaveSettingsToEeprom();
initOscillators();
si5351_set_calibration(calibration);
setFrequency(frequency);
si5351_set_calibration(globalSettings.oscillatorCal);
setFrequency(GetActiveVfoFreq());
//debounce and delay
while(btnDown())
@ -90,34 +93,34 @@ void setupBFO(){
int knob = 0;
unsigned long prevCarrier;
prevCarrier = usbCarrier;
prevCarrier = globalSettings.usbCarrierFreq;
displayDialog("Set BFO", "Press TUNE to Save");
usbCarrier = 11053000l;
si5351bx_setfreq(0, usbCarrier);
printCarrierFreq(usbCarrier);
globalSettings.usbCarrierFreq = 11053000l;
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
printCarrierFreq(globalSettings.usbCarrierFreq);
while (!btnDown()){
knob = enc_read();
if (knob != 0)
usbCarrier -= 50 * knob;
globalSettings.usbCarrierFreq -= 50 * knob;
else
continue; //don't update the frequency or the display
si5351bx_setfreq(0, usbCarrier);
setFrequency(frequency);
printCarrierFreq(usbCarrier);
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
setFrequency(GetActiveVfoFreq());
printCarrierFreq(globalSettings.usbCarrierFreq);
active_delay(100);
}
EEPROM.put(USB_CAL, usbCarrier);
si5351bx_setfreq(0, usbCarrier);
setFrequency(frequency);
SaveSettingsToEeprom();
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
setFrequency(GetActiveVfoFreq());
updateDisplay();
menuOn = 0;
setupExit();
}
void setupCwDelay(){
@ -127,93 +130,79 @@ void setupCwDelay(){
displayDialog("Set CW T/R Delay", "Press tune to Save");
active_delay(500);
prev_cw_delay = cwDelayTime;
prev_cw_delay = globalSettings.cwActiveTimeoutMs;
itoa(10 * (int)cwDelayTime, b, 10);
ltoa(globalSettings.cwActiveTimeoutMs, b, 10);
strcat(b, " msec");
displayText(b, 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
while (!btnDown()){
knob = enc_read();
if (knob < 0 && cwDelayTime > 10)
cwDelayTime -= 10;
else if (knob > 0 && cwDelayTime < 100)
cwDelayTime += 10;
if (knob < 0 && globalSettings.cwActiveTimeoutMs > 100)
globalSettings.cwActiveTimeoutMs -= 100;
else if (knob > 0 && globalSettings.cwActiveTimeoutMs < 1000)
globalSettings.cwActiveTimeoutMs += 100;
else
continue; //don't update the frequency or the display
itoa(10 * (int)cwDelayTime, b, 10);
ltoa(globalSettings.cwActiveTimeoutMs, b, 10);
strcat(b, " msec");
displayText(b, 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
}
EEPROM.put(CW_DELAYTIME, cwDelayTime);
// cwDelayTime = getValueByKnob(10, 1000, 50, cwDelayTime, "CW Delay>", " msec");
SaveSettingsToEeprom();
active_delay(500);
menuOn = 0;
setupExit();
}
void setupKeyer(){
int tmp_key, knob;
displayDialog("Set CW Keyer", "Press tune to Save");
if (!Iambic_Key)
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
else if (keyerControl & IAMBICB)
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
else
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
if (!Iambic_Key)
tmp_key = 0; //hand key
else if (keyerControl & IAMBICB)
tmp_key = 2; //Iambic B
else
tmp_key = 1;
if(KeyerMode_e::KEYER_STRAIGHT == globalSettings.keyerMode){
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
}
else if(KeyerMode_e::KEYER_IAMBIC_A == globalSettings.keyerMode){
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
}
else{
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
}
int knob = 0;
uint32_t tmp_mode = globalSettings.keyerMode;
while (!btnDown())
{
knob = enc_read();
if (knob == 0){
if(knob == 0){
active_delay(50);
continue;
}
if (knob < 0 && tmp_key > 0)
tmp_key--;
if (knob > 0)
tmp_key++;
if (tmp_key > 2)
tmp_key = 0;
if(knob < 0 && tmp_mode > KeyerMode_e::KEYER_STRAIGHT){
tmp_mode--;
}
if(knob > 0 && tmp_mode < KeyerMode_e::KEYER_IAMBIC_B){
tmp_mode++;
}
if (tmp_key == 0)
if (KeyerMode_e::KEYER_STRAIGHT == tmp_mode){
displayText("< Hand Key >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
else if (tmp_key == 1)
}
else if(KeyerMode_e::KEYER_IAMBIC_A == tmp_mode){
displayText("< Iambic A >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
else if (tmp_key == 2)
}
else if (KeyerMode_e::KEYER_IAMBIC_B == tmp_mode){
displayText("< Iambic B >", 100, 100, 120, 26, DISPLAY_CYAN, DISPLAY_BLACK, DISPLAY_BLACK);
}
}
active_delay(500);
if (tmp_key == 0)
Iambic_Key = false;
else if (tmp_key == 1){
Iambic_Key = true;
keyerControl &= ~IAMBICB;
}
else if (tmp_key == 2){
Iambic_Key = true;
keyerControl |= IAMBICB;
}
globalSettings.keyerMode = tmp_mode;
SaveSettingsToEeprom();
EEPROM.put(CW_KEY_TYPE, tmp_key);
menuOn = 0;
setupExit();
}
static const unsigned int COLOR_TEXT = DISPLAY_WHITE;

84
ubitx.h
View File

@ -1,3 +1,4 @@
#include "settings.h"
/* The ubitx is powered by an arduino nano. The pin assignment is as folows
*
@ -56,7 +57,6 @@ it uses an ILI9341 display controller and an XPT2046 touch controller.
* the serial port as we can easily run out of buffer space. This is done in the serial_in_count variable.
*/
extern char c[30], b[30];
extern char printBuff[2][20]; //mirrors what is showing on the two lines of the display
/**
* The second set of 16 pins on the Raduino's bottom connector are have the three clock outputs and the digital lines to control the rig.
@ -69,37 +69,6 @@ extern char printBuff[2][20]; //mirrors what is showing on the two lines of the
*/
/**
* These are the indices where these user changable settinngs are stored in the EEPROM
*/
#define MASTER_CAL 0
#define LSB_CAL 4
#define USB_CAL 8
#define SIDE_TONE 12
//these are ids of the vfos as well as their offset into the eeprom storage, don't change these 'magic' values
#define VFO_A 16
#define VFO_B 20
#define CW_SIDETONE 24
#define CW_SPEED 28
// the screen calibration parameters : int slope_x=104, slope_y=137, offset_x=28, offset_y=29;
#define SLOPE_X 32
#define SLOPE_Y 36
#define OFFSET_X 40
#define OFFSET_Y 44
#define CW_DELAYTIME 48
//These are defines for the new features back-ported from KD8CEC's software
//these start from beyond 256 as Ian, KD8CEC has kept the first 256 bytes free for the base version
#define VFO_A_MODE 256 // 2: LSB, 3: USB
#define VFO_B_MODE 257
//values that are stroed for the VFO modes
#define VFO_MODE_LSB 2
#define VFO_MODE_USB 3
// handkey, iambic a, iambic b : 0,1,2f
#define CW_KEY_TYPE 358
/**
* The uBITX is an upconnversion transceiver. The first IF is at 45 MHz.
* The first IF frequency is not exactly at 45 Mhz but about 5 khz lower,
@ -121,62 +90,23 @@ extern char printBuff[2][20]; //mirrors what is showing on the two lines of the
// limits the tuning and working range of the ubitx between 3 MHz and 30 MHz
#define LOWEST_FREQ (100000l)
#define HIGHEST_FREQ (30000000l)
static const uint32_t THRESHOLD_USB_LSB = 10000000L;
//we directly generate the CW by programmin the Si5351 to the cw tx frequency, hence, both are different modes
//these are the parameter passed to startTx
#define TX_SSB 0
#define TX_CW 1
extern char ritOn;
extern char vfoActive;
extern unsigned long vfoA, vfoB, sideTone, usbCarrier;
extern char isUsbVfoA, isUsbVfoB;
extern unsigned long frequency, ritRxFrequency, ritTxFrequency; //frequency is the current frequency on the dial
extern unsigned long firstIF;
// if cwMode is flipped on, the rx frequency is tuned down by sidetone hz instead of being zerobeat
extern int cwMode;
//these are variables that control the keyer behaviour
extern int cwSpeed; //this is actuall the dot period in milliseconds
extern int32_t calibration;
extern int cwDelayTime;
extern bool Iambic_Key;
#define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B
extern unsigned char keyerControl;
//during CAT commands, we will freeeze the display until CAT is disengaged
extern unsigned char doingCAT;
/**
* Raduino needs to keep track of current state of the transceiver. These are a few variables that do it
*/
extern boolean txCAT; //turned on if the transmitting due to a CAT command
extern char inTx; //it is set to 1 if in transmit mode (whatever the reason : cw, ptt or cat)
extern int splitOn; //working split, uses VFO B as the transmit frequency
extern char keyDown; //in cw mode, denotes the carrier is being transmitted
extern char isUSB; //upper sideband was selected, this is reset to the default for the
//frequency when it crosses the frequency border of 10 MHz
extern byte menuOn; //set to 1 when the menu is being displayed, if a menu item sets it to zero, the menu is exited
extern unsigned long cwTimeout; //milliseconds to go before the cw transmit line is released and the radio goes back to rx mode
extern unsigned long dbgCount; //not used now
extern unsigned char txFilter ; //which of the four transmit filters are in use
extern boolean modeCalibrate;//this mode of menus shows extended menus to calibrate the oscillators and choose the proper
//beat frequency
extern uint8_t menuOn;
/* these are functions implemented in the main file named as ubitx_xxx.ino */
void active_delay(int delay_by);
void saveVFOs();
void setFrequency(unsigned long f);
void startTx(byte txMode);
void startTx(TuningMode_e tx_mode);
void stopTx();
void ritEnable(unsigned long f);
void ritDisable();
void checkCAT();
void cwKeyer(void);
void switchVFO(int vfoSelect);
void switchVFO(Vfo_e vfoSelect);
int enc_read(void); // returns the number of ticks in a short interval, +ve in clockwise, -ve in anti-clockwise
int btnDown(); //returns true if the encoder button is pressed
@ -209,10 +139,6 @@ void checkTouch(); //does the commands with a touch on the buttons
/* these are functiosn implemented in ubitx_si5351.cpp */
void si5351bx_setfreq(uint8_t clknum, uint32_t fout);
void initOscillators();

View File

@ -1,4 +1,5 @@
#include <Arduino.h>
#include "settings.h"
#include "ubitx.h"
#include "nano_gui.h"
@ -159,7 +160,7 @@ void catReadEEPRom(void)
//5 : Memory/MTUNE select 0 = Memory, 1 = MTUNE
//6 :
//7 : MEM/VFO Select 0 = Memory, 1 = VFO (A or B - see bit 0)
cat[0] = 0x80 + (vfoActive == VFO_B ? 1 : 0);
cat[0] = 0x80 + ((VFO_B == globalSettings.activeVfo) ? 1 : 0);
cat[1] = 0x00;
break;
case 0x57 : //
@ -187,11 +188,11 @@ void catReadEEPRom(void)
//5-4 : Lock Mode (#32) 00 = Dial, 01 = Freq, 10 = Panel
//7-6 : Op Filter (#38) 00 = Off, 01 = SSB, 10 = CW
//CAT_BUFF[0] = 0x08;
cat[0] = (sideTone - 300)/50;
cat[0] = (globalSettings.cwSideToneFreq - 300)/50;
cat[1] = 0x25;
break;
case 0x61 : //Sidetone (Volume) (#44)
cat[0] = sideTone % 50;
case 0x61 : //globalSettings.cwSideToneFreq (Volume) (#44)
cat[0] = globalSettings.cwSideToneFreq % 50;
cat[1] = 0x08;
break;
case 0x5F : //
@ -203,14 +204,14 @@ void catReadEEPRom(void)
cat[1] = 0x08;
break;
case 0x60 : //CW Delay (10-2500 ms) (#17) From 1 to 250 (decimal) with each step representing 10 ms
cat[0] = cwDelayTime;
cat[0] = globalSettings.cwActiveTimeoutMs / 10;
cat[1] = 0x32;
break;
case 0x62 : //
//5-0 CW Speed (4-60 WPM) (#21) From 0 to 38 (HEX) with 0 = 4 WPM and 38 = 60 WPM (1 WPM steps)
//7-6 Batt-Chg (6/8/10 Hours (#11) 00 = 6 Hours, 01 = 8 Hours, 10 = 10 Hours
//CAT_BUFF[0] = 0x08;
cat[0] = 1200 / cwSpeed - 4;
cat[0] = 12000 / globalSettings.cwDitDurationMs - 4;
cat[1] = 0xB2;
break;
case 0x63 : //
@ -226,7 +227,7 @@ void catReadEEPRom(void)
cat[1] = 0xB2;
break; case 0x69 : //FM Mic (#29) Contains 0-100 (decimal) as displayed
case 0x78 :
if (isUSB)
if (VfoMode_e::VFO_MODE_USB == GetActiveVfoMode())
cat[0] = CAT_MODE_USB;
else
cat[0] = CAT_MODE_LSB;
@ -252,7 +253,7 @@ void catReadEEPRom(void)
//7A 6 ? ?
//7A 7 SPL On/Off 0 = Off, 1 = On
cat[0] = (splitOn ? 0xFF : 0x7F);
cat[0] = (globalSettings.splitOn ? 0xFF : 0x7F);
break;
case 0xB3 : //
cat[0] = 0x00;
@ -288,16 +289,16 @@ void processCATCommand2(byte* cmd) {
case 0x02:
//split on
splitOn = 1;
globalSettings.splitOn = 1;
break;
case 0x82:
//split off
splitOn = 0;
globalSettings.splitOn = 0;
break;
case 0x03:
writeFreq(frequency,response); // Put the frequency into the buffer
if (isUSB)
writeFreq(GetActiveVfoFreq(),response); // Put the frequency into the buffer
if (VfoMode_e::VFO_MODE_USB == GetActiveVfoMode())
response[4] = 0x01; //USB
else
response[4] = 0x00; //LSB
@ -307,21 +308,21 @@ void processCATCommand2(byte* cmd) {
case 0x07: // set mode
if (cmd[0] == 0x00 || cmd[0] == 0x03)
isUSB = 0;
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
else
isUSB = 1;
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
response[0] = 0x00;
Serial.write(response, 1);
setFrequency(frequency);
setFrequency(GetActiveVfoFreq());
//printLine2("cat: mode changed");
//updateDisplay();
break;
case 0x08: // PTT On
if (!inTx) {
if (!globalSettings.txActive) {
response[0] = 0;
txCAT = true;
startTx(TX_SSB);
globalSettings.txCatActive = true;
startTx(TuningMode_e::TUNE_SSB);
updateDisplay();
} else {
response[0] = 0xf0;
@ -331,9 +332,9 @@ void processCATCommand2(byte* cmd) {
break;
case 0x88 : //PTT OFF
if (inTx) {
if (globalSettings.txActive) {
stopTx();
txCAT = false;
globalSettings.txCatActive = false;
}
response[0] = 0;
Serial.write(response,1);
@ -343,7 +344,7 @@ void processCATCommand2(byte* cmd) {
case 0x81:
//toggle the VFOs
response[0] = 0;
if (vfoActive == VFO_A)
if (VFO_A == globalSettings.activeVfo)
switchVFO(VFO_B);
else
switchVFO(VFO_A);
@ -366,14 +367,14 @@ void processCATCommand2(byte* cmd) {
case 0xf7:
{
boolean isHighSWR = false;
boolean isSplitOn = false;
boolean issplitOn = false;
/*
Inverted -> *ptt = ((p->tx_status & 0x80) == 0); <-- souce code in ft817.c (hamlib)
*/
response[0] = ((inTx ? 0 : 1) << 7) +
response[0] = ((globalSettings.txActive ? 0 : 1) << 7) +
((isHighSWR ? 1 : 0) << 6) + //hi swr off / on
((isSplitOn ? 1 : 0) << 5) + //Split on / off
((issplitOn ? 1 : 0) << 5) + //Split on / off
(0 << 4) + //dummy data
0x08; //P0 meter data

View File

@ -1,5 +1,6 @@
#include <Arduino.h>
#include <Wire.h>
#include "settings.h"
#include "ubitx.h"
// ************* SI5315 routines - tks Jerry Gaffke, KE7ER ***********************
@ -115,14 +116,14 @@ void si5351bx_setfreq(uint8_t clknum, uint32_t fout) { // Set a CLK to fout Hz
void si5351_set_calibration(int32_t cal){
si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + cal; // apply the calibration correction factor
si5351bx_setfreq(0, usbCarrier);
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
}
void initOscillators(){
//initialize the SI5351
si5351bx_init();
si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor
si5351bx_setfreq(0, usbCarrier);
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
}

View File

@ -1,6 +1,7 @@
#include <Arduino.h>
#include <EEPROM.h>
#include "morse.h"
#include "settings.h"
#include "ubitx.h"
#include "nano_gui.h"
@ -242,13 +243,13 @@ void displayDialog(char *title, char *instructions){
displayRawText(instructions, 20, 200, COLOR_TEXT, COLOR_BACKGROUND);
}
void displayVFO(int vfo){
void displayVFO(Vfo_e vfo){
int x, y;
int displayColor, displayBackground, displayBorder;
Button button;
if (splitOn){
if (vfoActive == vfo){
if (globalSettings.splitOn){
if (vfo == globalSettings.activeVfo){
c[0] = 'R';
}
else{
@ -269,32 +270,30 @@ void displayVFO(int vfo){
c[1] = ':';
if (vfo == VFO_A){
if (VFO_A == vfo){
getButton(BUTTON_VFOA, &button);
formatFreq(globalSettings.vfoA.frequency, c+2);
if (vfoActive == VFO_A){
formatFreq(frequency, c+2);
if (VFO_A == globalSettings.activeVfo){
displayColor = COLOR_ACTIVE_VFO_TEXT;
displayBackground = COLOR_ACTIVE_VFO_BACKGROUND;
displayBorder = COLOR_ACTIVE_BORDER;
}else{
formatFreq(vfoA, c+2);
displayColor = COLOR_INACTIVE_VFO_TEXT;
displayBackground = COLOR_INACTIVE_VFO_BACKGROUND;
displayBorder = COLOR_INACTIVE_BORDER;
}
}
if (vfo == VFO_B){
if (VFO_B == vfo){
getButton(BUTTON_VFOB, &button);
formatFreq(globalSettings.vfoB.frequency, c+2);
if (vfoActive == VFO_B){
formatFreq(frequency, c+2);
if (VFO_B == globalSettings.activeVfo){
displayColor = COLOR_ACTIVE_VFO_TEXT;
displayBackground = COLOR_ACTIVE_VFO_BACKGROUND;
displayBorder = COLOR_ACTIVE_BORDER;
} else {
formatFreq(vfoB, c+2);
displayColor = COLOR_INACTIVE_VFO_TEXT;
displayBackground = COLOR_INACTIVE_VFO_BACKGROUND;
displayBorder = COLOR_INACTIVE_BORDER;
@ -325,7 +324,7 @@ void btnDraw(struct Button *button){
}
case BUTTON_RIT:
{
if(1 == ritOn){
if(globalSettings.ritOn){
btnDrawActive(button);
}
else{
@ -335,7 +334,7 @@ void btnDraw(struct Button *button){
}
case BUTTON_USB:
{
if(1 == isUSB){
if(VFO_MODE_USB == GetActiveVfoMode()){
btnDrawActive(button);
}
else{
@ -345,7 +344,7 @@ void btnDraw(struct Button *button){
}
case BUTTON_LSB:
{
if(0 == isUSB){
if(VFO_MODE_LSB == GetActiveVfoMode()){
btnDrawActive(button);
}
else{
@ -355,7 +354,7 @@ void btnDraw(struct Button *button){
}
case BUTTON_SPL:
{
if(1 == splitOn){
if(globalSettings.splitOn){
btnDrawActive(button);
}
else{
@ -365,7 +364,7 @@ void btnDraw(struct Button *button){
}
case BUTTON_CW:
{
if(1 == cwMode){
if(TuningMode_e::TUNE_CW == globalSettings.tuningMode){
btnDrawActive(button);
}
else{
@ -385,10 +384,10 @@ void btnDraw(struct Button *button){
void displayRIT(){
c[0] = 0;
displayFillrect(LAYOUT_MODE_TEXT_X,LAYOUT_MODE_TEXT_Y,LAYOUT_MODE_TEXT_WIDTH,LAYOUT_MODE_TEXT_HEIGHT, COLOR_BACKGROUND);
if (ritOn){
if(globalSettings.ritOn){
strcpy_P(c,(const char*)F("TX:"));
formatFreq(ritTxFrequency, c+3);
if (vfoActive == VFO_A)
formatFreq(globalSettings.ritFrequency, c+3);
if (VFO_A == globalSettings.activeVfo)
displayText(c, LAYOUT_MODE_TEXT_X + 0*LAYOUT_VFO_LABEL_PITCH_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
else
displayText(c, LAYOUT_MODE_TEXT_X + 1*LAYOUT_VFO_LABEL_PITCH_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
@ -396,8 +395,6 @@ void displayRIT(){
}
void fastTune(){
int encoder;
//if the btn is down, wait until it is up
while(btnDown())
active_delay(50);
@ -418,15 +415,17 @@ void fastTune(){
return;
}
encoder = enc_read();
int encoder = enc_read();
if (encoder != 0){
if (encoder > 0 && frequency < 30000000l)
frequency += 50000l;
else if (encoder < 0 && frequency > 600000l)
frequency -= 50000l;
setFrequency(frequency);
displayVFO(vfoActive);
uint32_t freq = GetActiveVfoFreq();
if (encoder > 0 && freq < 30000000l){
freq += 50000l;
}
else if (encoder < 0 && freq > 600000l){
freq -= 50000l;
}
setFrequency(freq);
displayVFO(globalSettings.activeVfo);
}
}// end of the event loop
}
@ -434,7 +433,6 @@ void fastTune(){
void enterFreq(){
//force the display to refresh everything
//display all the buttons
int f;
for (int i = 0; i < KEYS_TOTAL; i++){
Button button;
@ -444,7 +442,6 @@ void enterFreq(){
int cursor_pos = 0;
memset(c, 0, sizeof(c));
f = frequency / 1000l;
while(1){
@ -468,14 +465,16 @@ void enterFreq(){
switch(button.id){
case KEYS_OK:
{
long f = atol(c);
if(30000 >= f && f > 100){
frequency = f * 1000l;
setFrequency(frequency);
if (vfoActive == VFO_A)
vfoA = frequency;
else
vfoB = frequency;
long freq = atol(c);
if((LOWEST_FREQ/1000 <= freq) && (freq <= HIGHEST_FREQ/1000)){
freq *= 1000L;
setFrequency(freq);
if (VFO_A == globalSettings.activeVfo){
globalSettings.vfoA.frequency = freq;
}
else{
globalSettings.vfoB.frequency = freq;
}
saveVFOs();
}
guiUpdate();
@ -525,7 +524,7 @@ void enterFreq(){
strcpy(b, c);
strcat(b, " KHz");
displayText(b, LAYOUT_MODE_TEXT_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
delay(300);
active_delay(300);
while(readTouch())
checkCAT();
} // end of event loop : while(1)
@ -533,11 +532,11 @@ void enterFreq(){
void drawCWStatus(){
strcpy(b, " cw: ");
int wpm = 1200/cwSpeed;
int wpm = 12000/globalSettings.cwDitDurationMs;
itoa(wpm,c, 10);
strcat(b, c);
strcat(b, "wpm, ");
itoa(sideTone, c, 10);
itoa(globalSettings.cwSideToneFreq, c, 10);
strcat(b, c);
strcat(b, "hz");
displayText(b, LAYOUT_CW_TEXT_X, LAYOUT_CW_TEXT_Y, LAYOUT_CW_TEXT_WIDTH, LAYOUT_CW_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
@ -545,7 +544,7 @@ void drawCWStatus(){
void drawTx(){
if (inTx)
if (globalSettings.txActive)
displayText("TX", LAYOUT_TX_X, LAYOUT_TX_Y, LAYOUT_TX_WIDTH, LAYOUT_TX_HEIGHT, COLOR_ACTIVE_TEXT, COLOR_ACTIVE_BACKGROUND, COLOR_BACKGROUND);
else
displayFillrect(LAYOUT_TX_X, LAYOUT_TX_Y, LAYOUT_TX_WIDTH, LAYOUT_TX_HEIGHT, COLOR_BACKGROUND);
@ -586,7 +585,7 @@ void guiUpdate(){
// this builds up the top line of the display with frequency and mode
void updateDisplay() {
displayVFO(vfoActive);
displayVFO(globalSettings.activeVfo);
}
int enc_prev_state = 3;
@ -653,21 +652,19 @@ int enc_read(void) {
}
void ritToggle(struct Button *button){
if (ritOn == 0){
ritEnable(frequency);
if (globalSettings.ritOn){
ritEnable(GetActiveVfoFreq());
}
else
else{
ritDisable();
}
btnDraw(button);
displayRIT();
}
void splitToggle(Button *button){
if (splitOn)
splitOn = 0;
else
splitOn = 1;
globalSettings.splitOn = !globalSettings.splitOn;
btnDraw(button);
@ -685,17 +682,17 @@ void splitToggle(Button *button){
void vfoReset(){
Button button;
if (vfoActive = VFO_A)
vfoB = vfoA;
if (VFO_A == globalSettings.activeVfo)
globalSettings.vfoB.frequency = globalSettings.vfoA.frequency;
else
vfoA = vfoB;
globalSettings.vfoA.frequency = globalSettings.vfoB.frequency;
if (splitOn){
if(globalSettings.splitOn){
getButton(BUTTON_SPL, &button);
splitToggle(&button);
}
if (ritOn){
if(globalSettings.ritOn){
getButton(BUTTON_RIT, &button);
ritToggle(&button);
}
@ -707,21 +704,22 @@ void vfoReset(){
}
void cwToggle(struct Button *b){
if (cwMode == 0){
cwMode = 1;
if (TuningMode_e::TUNE_SSB == globalSettings.tuningMode){
globalSettings.tuningMode = TuningMode_e::TUNE_CW;
}
else{
globalSettings.tuningMode = TuningMode_e::TUNE_SSB;
}
else
cwMode = 0;
setFrequency(frequency);
setFrequency(GetActiveVfoFreq());
btnDraw(b);
}
void sidebandToggle(Button* button){
if(BUTTON_LSB == button->id)
isUSB = 0;
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
else
isUSB = 1;
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
struct Button button2;
getButton(BUTTON_USB, &button2);
@ -750,48 +748,46 @@ void redrawVFOs(){
}
void switchBand(long bandfreq){
long offset;
void switchBand(uint32_t bandfreq){
// Serial.println(frequency);
// Serial.println(bandfreq);
if (3500000l <= frequency && frequency <= 4000000l)
offset = frequency - 3500000l;
else if (24800000l <= frequency && frequency <= 25000000l)
offset = frequency - 24800000l;
//Serial.println(frequency);
//Serial.println(bandfreq);
uint32_t offset;
uint32_t freq = GetActiveVfoFreq();
if (3500000L <= freq && freq <= 4000000L)
offset = freq - 3500000l;
else if (24800000L <= freq && freq <= 25000000L)
offset = freq - 24800000L;
else
offset = frequency % 1000000l;
offset = freq % 1000000L;
// Serial.println(offset);
//Serial.println(offset);
setFrequency(bandfreq + offset);
updateDisplay();
saveVFOs();
}
int setCwSpeed(){
int knob = 0;
int wpm;
void setCwSpeed()
{
int wpm = 12000/globalSettings.cwDitDurationMs;
wpm = getValueByKnob(1, 100, 1, wpm, "CW: ", " WPM");
wpm = 1200/cwSpeed;
wpm = getValueByKnob(1, 100, 1, wpm, "CW: ", " WPM");
cwSpeed = 1200/wpm;
EEPROM.put(CW_SPEED, cwSpeed);
active_delay(500);
drawStatusbar();
// printLine2("");
// updateDisplay();
globalSettings.cwDitDurationMs = 12000/wpm;
SaveSettingsToEeprom();
active_delay(500);
drawStatusbar();
//printLine2("");
//updateDisplay();
}
void setCwTone(){
int knob = 0;
int prev_sideTone;
tone(CW_TONE, sideTone);
itoa(sideTone, c, 10);
tone(CW_TONE, globalSettings.cwSideToneFreq);
itoa(globalSettings.cwSideToneFreq, c, 10);
strcpy(b, "CW Tone: ");
strcat(b, c);
strcat(b, " Hz");
@ -802,15 +798,15 @@ void setCwTone(){
{
knob = enc_read();
if (knob > 0 && sideTone < 2000)
sideTone += 10;
else if (knob < 0 && sideTone > 100 )
sideTone -= 10;
if (knob > 0 && globalSettings.cwSideToneFreq < 2000)
globalSettings.cwSideToneFreq += 10;
else if (knob < 0 && globalSettings.cwSideToneFreq > 100 )
globalSettings.cwSideToneFreq -= 10;
else
continue; //don't update the frequency or the display
tone(CW_TONE, sideTone);
itoa(sideTone, c, 10);
tone(CW_TONE, globalSettings.cwSideToneFreq);
itoa(globalSettings.cwSideToneFreq, c, 10);
strcpy(b, "CW Tone: ");
strcat(b, c);
strcat(b, " Hz");
@ -821,14 +817,14 @@ void setCwTone(){
active_delay(20);
}
noTone(CW_TONE);
//save the setting
EEPROM.put(CW_SIDETONE, sideTone);
SaveSettingsToEeprom();
b[0] = 0;
drawCommandbar(b);
drawStatusbar();
// printLine2("");
// updateDisplay();
//printLine2("");
//updateDisplay();
}
void doCommand(Button* button){
@ -863,7 +859,7 @@ void doCommand(Button* button){
}
case BUTTON_VFOA:
{
if(VFO_A == vfoActive){
if(VFO_A == globalSettings.activeVfo){
fastTune();
}
else{
@ -873,7 +869,7 @@ void doCommand(Button* button){
}
case BUTTON_VFOB:
{
if(VFO_B == vfoActive){
if(VFO_B == globalSettings.activeVfo){
fastTune();
}
else{
@ -1002,7 +998,7 @@ void doCommands(){
//unfocus the buttons
drawFocus(select, COLOR_INACTIVE_BORDER);
if (vfoActive == VFO_A)
if (VFO_A == globalSettings.activeVfo)
drawFocus(BUTTON_VFOA, COLOR_ACTIVE_BORDER);
else
drawFocus(BUTTON_VFOB, COLOR_ACTIVE_BORDER);

View File

@ -30,21 +30,10 @@
* Si5351 object to control the clocks.
*/
#include <Wire.h>
#include <EEPROM.h>
#include "settings.h"
#include "ubitx.h"
#include "nano_gui.h"
/**
The main chip which generates upto three oscillators of various frequencies in the
Raduino is the Si5351a. To learn more about Si5351a you can download the datasheet
from www.silabs.com although, strictly speaking it is not a requirment to understand this code.
We no longer use the standard SI5351 library because of its huge overhead due to many unused
features consuming a lot of program space. Instead of depending on an external library we now use
Jerry Gaffke's, KE7ER, lightweight standalone mimimalist "si5351bx" routines (see further down the
code). Here are some defines and declarations used by Jerry's routines:
*/
/**
* The Arduino, unlike C/C++ on a regular computer with gigabytes of RAM, has very little memory.
* We have to be very careful with variables that are declared inside the functions as they are
@ -58,102 +47,10 @@
*/
char c[30], b[30];
/**
* These are the indices where these user changable settinngs are stored in the EEPROM
*/
#define MASTER_CAL 0
#define LSB_CAL 4
#define USB_CAL 8
#define SIDE_TONE 12
//these are ids of the vfos as well as their offset into the eeprom storage, don't change these 'magic' values
#define VFO_A 16
#define VFO_B 20
#define CW_SIDETONE 24
#define CW_SPEED 28
// the screen calibration parameters : int slope_x=104, slope_y=137, offset_x=28, offset_y=29;
#define SLOPE_X 32
#define SLOPE_Y 36
#define OFFSET_X 40
#define OFFSET_Y 44
#define CW_DELAYTIME 48
//These are defines for the new features back-ported from KD8CEC's software
//these start from beyond 256 as Ian, KD8CEC has kept the first 256 bytes free for the base version
#define VFO_A_MODE 256 // 2: LSB, 3: USB
#define VFO_B_MODE 257
//values that are stroed for the VFO modes
#define VFO_MODE_LSB 2
#define VFO_MODE_USB 3
// handkey, iambic a, iambic b : 0,1,2f
#define CW_KEY_TYPE 358
/**
* The uBITX is an upconnversion transceiver. The first IF is at 45 MHz.
* The first IF frequency is not exactly at 45 Mhz but about 5 khz lower,
* this shift is due to the loading on the 45 Mhz crystal filter by the matching
* L-network used on it's either sides.
* The first oscillator works between 48 Mhz and 75 MHz. The signal is subtracted
* from the first oscillator to arriive at 45 Mhz IF. Thus, it is inverted : LSB becomes USB
* and USB becomes LSB.
* The second IF of 12 Mhz has a ladder crystal filter. If a second oscillator is used at
* 57 Mhz, the signal is subtracted FROM the oscillator, inverting a second time, and arrives
* at the 12 Mhz ladder filter thus doouble inversion, keeps the sidebands as they originally were.
* If the second oscillator is at 33 Mhz, the oscilaltor is subtracated from the signal,
* thus keeping the signal's sidebands inverted. The USB will become LSB.
* We use this technique to switch sidebands. This is to avoid placing the lsbCarrier close to
* 12 MHz where its fifth harmonic beats with the arduino's 16 Mhz oscillator's fourth harmonic
*/
#define INIT_USB_FREQ (11059200l)
// limits the tuning and working range of the ubitx between 3 MHz and 30 MHz
#define LOWEST_FREQ (100000l)
#define HIGHEST_FREQ (30000000l)
//we directly generate the CW by programmin the Si5351 to the cw tx frequency, hence, both are different modes
//these are the parameter passed to startTx
#define TX_SSB 0
#define TX_CW 1
char ritOn = 0;
char vfoActive = VFO_A;
int8_t meter_reading = 0; // a -1 on meter makes it invisible
unsigned long vfoA=7150000L, vfoB=14200000L, sideTone=800, usbCarrier;
char isUsbVfoA=0, isUsbVfoB=1;
unsigned long frequency, ritRxFrequency, ritTxFrequency; //frequency is the current frequency on the dial
unsigned long firstIF = 45005000L;
// if cwMode is flipped on, the rx frequency is tuned down by sidetone hz instead of being zerobeat
int cwMode = 0;
//these are variables that control the keyer behaviour
int cwSpeed = 100; //this is actuall the dot period in milliseconds
extern int32_t calibration;
int cwDelayTime = 60;
bool Iambic_Key = true;
#define IAMBICB 0x10 // 0 for Iambic A, 1 for Iambic B
unsigned char keyerControl = IAMBICB;
//during CAT commands, we will freeeze the display until CAT is disengaged
unsigned char doingCAT = 0;
/**
* Raduino needs to keep track of current state of the transceiver. These are a few variables that do it
*/
boolean txCAT = false; //turned on if the transmitting due to a CAT command
char inTx = 0; //it is set to 1 if in transmit mode (whatever the reason : cw, ptt or cat)
int splitOn = 0; //working split, uses VFO B as the transmit frequency
char keyDown = 0; //in cw mode, denotes the carrier is being transmitted
char isUSB = 0; //upper sideband was selected, this is reset to the default for the
//frequency when it crosses the frequency border of 10 MHz
byte menuOn = 0; //set to 1 when the menu is being displayed, if a menu item sets it to zero, the menu is exited
unsigned long cwTimeout = 0; //milliseconds to go before the cw transmit line is released and the radio goes back to rx mode
unsigned long dbgCount = 0; //not used now
unsigned char txFilter = 0; //which of the four transmit filters are in use
boolean modeCalibrate = false;//this mode of menus shows extended menus to calibrate the oscillators and choose the proper
//beat frequency
/**
* Below are the basic functions that control the uBitx. Understanding the functions before
@ -168,32 +65,14 @@ void active_delay(int delay_by){
unsigned long timeStart = millis();
while (millis() - timeStart <= (unsigned long)delay_by) {
delay(10);
//Background Work
//Background Work
checkCAT();
}
}
void saveVFOs(){
if (vfoActive == VFO_A)
EEPROM.put(VFO_A, frequency);
else
EEPROM.put(VFO_A, vfoA);
if (isUsbVfoA)
EEPROM.put(VFO_A_MODE, VFO_MODE_USB);
else
EEPROM.put(VFO_A_MODE, VFO_MODE_LSB);
if (vfoActive == VFO_B)
EEPROM.put(VFO_B, frequency);
else
EEPROM.put(VFO_B, vfoB);
if (isUsbVfoB)
EEPROM.put(VFO_B_MODE, VFO_MODE_USB);
else
EEPROM.put(VFO_B_MODE, VFO_MODE_LSB);
void saveVFOs()
{
SaveSettingsToEeprom();
}
/**
@ -227,12 +106,12 @@ void setTXFilters(unsigned long freq){
else if (freq > 7000000L){
digitalWrite(TX_LPF_A, 0);
digitalWrite(TX_LPF_B, 1);
digitalWrite(TX_LPF_C, 0);
digitalWrite(TX_LPF_C, 0);
}
else {
digitalWrite(TX_LPF_A, 0);
digitalWrite(TX_LPF_B, 0);
digitalWrite(TX_LPF_C, 1);
digitalWrite(TX_LPF_C, 1);
}
}
@ -252,12 +131,12 @@ void setTXFilters_v5(unsigned long freq){
else if (freq > 7000000L){
digitalWrite(TX_LPF_A, 0);
digitalWrite(TX_LPF_B, 1);
digitalWrite(TX_LPF_C, 0);
digitalWrite(TX_LPF_C, 0);
}
else {
digitalWrite(TX_LPF_A, 0);
digitalWrite(TX_LPF_B, 0);
digitalWrite(TX_LPF_C, 1);
digitalWrite(TX_LPF_C, 1);
}
}
@ -275,38 +154,31 @@ void setTXFilters_v5(unsigned long freq){
* through mixing of the second local oscillator.
*/
void setFrequency(unsigned long f){
uint64_t osc_f, firstOscillator, secondOscillator;
void setFrequency(unsigned long freq){
static const unsigned long firstIF = 45005000L;
setTXFilters(f);
setTXFilters(freq);
/*
if (isUSB){
si5351bx_setfreq(2, firstIF + f);
si5351bx_setfreq(1, firstIF + usbCarrier);
uint32_t primary_osc_freq;
if(VfoMode_e::VFO_MODE_USB == GetActiveVfoMode()){
primary_osc_freq = firstIF + globalSettings.usbCarrierFreq;
}
else{
si5351bx_setfreq(2, firstIF + f);
si5351bx_setfreq(1, firstIF - usbCarrier);
primary_osc_freq = firstIF - globalSettings.usbCarrierFreq;
}
*/
//alternative to reduce the intermod spur
if (isUSB){
if (cwMode)
si5351bx_setfreq(2, firstIF + f + sideTone);
else
si5351bx_setfreq(2, firstIF + f);
si5351bx_setfreq(1, firstIF + usbCarrier);
uint32_t secondary_osc_freq;
if(TuningMode_e::TUNE_CW == globalSettings.tuningMode){
secondary_osc_freq = firstIF + freq + globalSettings.cwSideToneFreq;
}
else{
if (cwMode)
si5351bx_setfreq(2, firstIF + f + sideTone);
else
si5351bx_setfreq(2, firstIF + f);
si5351bx_setfreq(1, firstIF - usbCarrier);
secondary_osc_freq = firstIF + freq;
}
frequency = f;
si5351bx_setfreq(2, secondary_osc_freq);
si5351bx_setfreq(1, primary_osc_freq);
SetActiveVfoFreq(freq);
}
/**
@ -316,81 +188,72 @@ void setFrequency(unsigned long f){
* CW offest is calculated as lower than the operating frequency when in LSB mode, and vice versa in USB mode
*/
void startTx(byte txMode){
unsigned long tx_freq = 0;
digitalWrite(TX_RX, 1);
inTx = 1;
if (ritOn){
void startTx(TuningMode_e tx_mode){
globalSettings.tuningMode = tx_mode;
if (globalSettings.ritOn){
//save the current as the rx frequency
ritRxFrequency = frequency;
setFrequency(ritTxFrequency);
uint32_t rit_tx_freq = globalSettings.ritFrequency;
globalSettings.ritFrequency = GetActiveVfoFreq();
setFrequency(rit_tx_freq);
}
else
{
if (splitOn == 1) {
if (vfoActive == VFO_B) {
vfoActive = VFO_A;
isUSB = isUsbVfoA;
frequency = vfoA;
else{
if(globalSettings.splitOn){
if(Vfo_e::VFO_B == globalSettings.activeVfo){
globalSettings.activeVfo = Vfo_e::VFO_A;
}
else if (vfoActive == VFO_A){
vfoActive = VFO_B;
frequency = vfoB;
isUSB = isUsbVfoB;
else{
globalSettings.activeVfo = Vfo_e::VFO_B;
}
}
setFrequency(frequency);
setFrequency(GetActiveVfoFreq());
}
if (txMode == TX_CW){
digitalWrite(TX_RX, 0);
if(TuningMode_e::TUNE_CW == globalSettings.tuningMode){
//turn off the second local oscillator and the bfo
si5351bx_setfreq(0, 0);
si5351bx_setfreq(1, 0);
//shif the first oscillator to the tx frequency directly
//shift the first oscillator to the tx frequency directly
//the key up and key down will toggle the carrier unbalancing
//the exact cw frequency is the tuned frequency + sidetone
if (isUSB)
si5351bx_setfreq(2, frequency + sideTone);
else
si5351bx_setfreq(2, frequency - sideTone);
if(VfoMode_e::VFO_MODE_USB == GetActiveVfoMode()){
si5351bx_setfreq(2, GetActiveVfoFreq() + globalSettings.cwSideToneFreq);
}
else{
si5351bx_setfreq(2, GetActiveVfoFreq() - globalSettings.cwSideToneFreq);
}
delay(20);
digitalWrite(TX_RX, 1);
}
digitalWrite(TX_RX, 1);//turn on the tx
globalSettings.txActive = true;
drawTx();
//updateDisplay();
}
void stopTx(){
inTx = 0;
digitalWrite(TX_RX, 0);//turn off the tx
globalSettings.txActive = false;
digitalWrite(TX_RX, 0); //turn off the tx
si5351bx_setfreq(0, usbCarrier); //set back the cardrier oscillator anyway, cw tx switches it off
//set back the carrier oscillator - cw tx switches it off
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
if (ritOn)
setFrequency(ritRxFrequency);
if(globalSettings.ritOn){
uint32_t rit_rx_freq = globalSettings.ritFrequency;
globalSettings.ritFrequency = GetActiveVfoFreq();
setFrequency(rit_rx_freq);
}
else{
if (splitOn == 1) {
//vfo Change
if (vfoActive == VFO_B){
vfoActive = VFO_A;
frequency = vfoA;
isUSB = isUsbVfoA;
if(globalSettings.splitOn){
if(Vfo_e::VFO_B == globalSettings.activeVfo){
globalSettings.activeVfo = Vfo_e::VFO_A;
}
else if (vfoActive == VFO_A){
vfoActive = VFO_B;
frequency = vfoB;
isUSB = isUsbVfoB;
else{
globalSettings.activeVfo = Vfo_e::VFO_B;
}
}
setFrequency(frequency);
setFrequency(GetActiveVfoFreq());
}
//updateDisplay();
drawTx();
}
@ -398,18 +261,18 @@ void stopTx(){
* ritEnable is called with a frequency parameter that determines
* what the tx frequency will be
*/
void ritEnable(unsigned long f){
ritOn = 1;
void ritEnable(unsigned long freq){
globalSettings.ritOn = true;
//save the non-rit frequency back into the VFO memory
//as RIT is a temporary shift, this is not saved to EEPROM
ritTxFrequency = f;
globalSettings.ritFrequency = freq;
}
// this is called by the RIT menu routine
void ritDisable(){
if (ritOn){
ritOn = 0;
setFrequency(ritTxFrequency);
if(globalSettings.ritOn){
globalSettings.ritOn = false;
setFrequency(globalSettings.ritFrequency);
updateDisplay();
}
}
@ -424,17 +287,18 @@ void ritDisable(){
* flip the T/R line to T and update the display to denote transmission
*/
void checkPTT(){
void checkPTT(){
//we don't check for ptt when transmitting cw
if (cwTimeout > 0)
if (globalSettings.cwExpirationTimeMs > 0){
return;
}
if (digitalRead(PTT) == 0 && inTx == 0){
startTx(TX_SSB);
if(digitalRead(PTT) == 0 && !globalSettings.txActive){
startTx(TuningMode_e::TUNE_SSB);
active_delay(50); //debounce the PTT
}
if (digitalRead(PTT) == 1 && inTx == 1)
if (digitalRead(PTT) == 1 && globalSettings.txActive)
stopTx();
}
@ -471,41 +335,11 @@ void checkButton(){
active_delay(50);//debounce
}
void switchVFO(int vfoSelect){
if (vfoSelect == VFO_A){
if (vfoActive == VFO_B){
vfoB = frequency;
isUsbVfoB = isUSB;
EEPROM.put(VFO_B, frequency);
if (isUsbVfoB)
EEPROM.put(VFO_B_MODE, VFO_MODE_USB);
else
EEPROM.put(VFO_B_MODE, VFO_MODE_LSB);
}
vfoActive = VFO_A;
// printLine2("Selected VFO A ");
frequency = vfoA;
isUSB = isUsbVfoA;
}
else {
if (vfoActive == VFO_A){
vfoA = frequency;
isUsbVfoA = isUSB;
EEPROM.put(VFO_A, frequency);
if (isUsbVfoA)
EEPROM.put(VFO_A_MODE, VFO_MODE_USB);
else
EEPROM.put(VFO_A_MODE, VFO_MODE_LSB);
}
vfoActive = VFO_B;
// printLine2("Selected VFO B ");
frequency = vfoB;
isUSB = isUsbVfoB;
}
setFrequency(frequency);
redrawVFOs();
saveVFOs();
void switchVFO(Vfo_e new_vfo){
globalSettings.activeVfo = new_vfo;
setFrequency(GetActiveVfoFreq());
redrawVFOs();
saveVFOs();
}
/**
@ -516,46 +350,46 @@ void switchVFO(int vfoSelect){
*/
void doTuning(){
int s;
static unsigned long prev_freq;
static unsigned long nextFrequencyUpdate = 0;
unsigned long now = millis();
if (now >= nextFrequencyUpdate && prev_freq != frequency){
if (now >= nextFrequencyUpdate && prev_freq != GetActiveVfoFreq()){
updateDisplay();
nextFrequencyUpdate = now + 500;
prev_freq = frequency;
prev_freq = GetActiveVfoFreq();
}
s = enc_read();
int s = enc_read();
if (!s)
return;
doingCAT = 0; // go back to manual mode if you were doing CAT
prev_freq = frequency;
prev_freq = GetActiveVfoFreq();
uint32_t new_freq = prev_freq;
if (s > 10 || s < -10){
new_freq += 200L * s;
}
else if (s > 5 || s < -5){
new_freq += 100L * s;
}
else{
new_freq += 50L * s;
}
//Transition from below to above the traditional threshold for USB
if(prev_freq < THRESHOLD_USB_LSB && new_freq >= THRESHOLD_USB_LSB){
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
}
//Transition from aboveo to below the traditional threshold for USB
if(prev_freq >= THRESHOLD_USB_LSB && new_freq < THRESHOLD_USB_LSB){
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
}
if (s > 10)
frequency += 200l * s;
else if (s > 5)
frequency += 100l * s;
else if (s > 0)
frequency += 50l * s;
else if (s < -10)
frequency += 200l * s;
else if (s < -5)
frequency += 100l * s;
else if (s < 0)
frequency += 50l * s;
if (prev_freq < 10000000l && frequency > 10000000l)
isUSB = true;
if (prev_freq > 10000000l && frequency < 10000000l)
isUSB = false;
setFrequency(frequency);
setFrequency(new_freq);
}
@ -563,18 +397,17 @@ void doTuning(){
* RIT only steps back and forth by 100 hz at a time
*/
void doRIT(){
unsigned long newFreq;
int knob = enc_read();
unsigned long old_freq = frequency;
uint32_t old_freq = GetActiveVfoFreq();
uint32_t new_freq = old_freq;
if (knob < 0)
frequency -= 100l;
new_freq -= 100l;
else if (knob > 0)
frequency += 100;
new_freq += 100;
if (old_freq != frequency){
setFrequency(frequency);
if (old_freq != new_freq){
setFrequency(new_freq);
updateDisplay();
}
}
@ -585,87 +418,7 @@ void doRIT(){
* variables.
*/
void initSettings(){
byte x;
//read the settings from the eeprom and restore them
//if the readings are off, then set defaults
EEPROM.get(MASTER_CAL, calibration);
EEPROM.get(USB_CAL, usbCarrier);
EEPROM.get(VFO_A, vfoA);
EEPROM.get(VFO_B, vfoB);
EEPROM.get(CW_SIDETONE, sideTone);
EEPROM.get(CW_SPEED, cwSpeed);
EEPROM.get(CW_DELAYTIME, cwDelayTime);
// the screen calibration parameters : int slope_x=104, slope_y=137, offset_x=28, offset_y=29;
if (usbCarrier > 11060000l || usbCarrier < 11048000l)
usbCarrier = 11052000l;
if (vfoA > 35000000l || 3500000l > vfoA)
vfoA = 7150000l;
if (vfoB > 35000000l || 3500000l > vfoB)
vfoB = 14150000l;
if (sideTone < 100 || 2000 < sideTone)
sideTone = 800;
if (cwSpeed < 10 || 1000 < cwSpeed)
cwSpeed = 100;
if (cwDelayTime < 10 || cwDelayTime > 100)
cwDelayTime = 50;
/*
* The VFO modes are read in as either 2 (USB) or 3(LSB), 0, the default
* is taken as 'uninitialized
*/
EEPROM.get(VFO_A_MODE, x);
switch(x){
case VFO_MODE_USB:
isUsbVfoA = 1;
break;
case VFO_MODE_LSB:
isUsbVfoA = 0;
break;
default:
if (vfoA > 10000000l)
isUsbVfoA = 1;
else
isUsbVfoA = 0;
}
EEPROM.get(VFO_B_MODE, x);
switch(x){
case VFO_MODE_USB:
isUsbVfoB = 1;
break;
case VFO_MODE_LSB:
isUsbVfoB = 0;
break;
default:
if (vfoA > 10000000l)
isUsbVfoB = 1;
else
isUsbVfoB = 0;
}
//set the current mode
isUSB = isUsbVfoA;
/*
* The keyer type splits into two variables
*/
EEPROM.get(CW_KEY_TYPE, x);
if (x == 0)
Iambic_Key = false;
else if (x == 1){
Iambic_Key = true;
keyerControl &= ~IAMBICB;
}
else if (x == 2){
Iambic_Key = true;
keyerControl |= IAMBICB;
}
LoadSettingsFromEeprom();
}
void initPorts(){
@ -708,22 +461,22 @@ void setup()
displayInit();
initSettings();
initPorts();
initPorts();
initOscillators();
frequency = vfoA;
setFrequency(vfoA);
setFrequency(globalSettings.vfoA.frequency);
if (btnDown()){
//Run initial calibration routine if button is pressed during power up
if(btnDown()){
setupTouch();
isUSB = 1;
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
setFrequency(10000000l);
setupFreq();
isUSB = 0;
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
setFrequency(7100000l);
setupBFO();
}
guiUpdate();
guiUpdate();
}
@ -731,23 +484,23 @@ void setup()
* The loop checks for keydown, ptt, function button and tuning.
*/
byte flasher = 0;
boolean wastouched = false;
void loop(){
if (cwMode)
cwKeyer();
else if (!txCAT)
void loop(){
if(TuningMode_e::TUNE_CW == globalSettings.tuningMode){
cwKeyer();
}
else if(!globalSettings.txCatActive){
checkPTT();
}
checkButton();
//tune only when not tranmsitting
if (!inTx){
if (ritOn)
if(!globalSettings.txActive){
if(globalSettings.ritOn){
doRIT();
else
}
else{
doTuning();
}
checkTouch();
}