From 9dee71f5bd0495a0d83e535558478e35a75ce229 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Fri, 3 Jan 2020 01:07:32 -0800 Subject: [PATCH 01/22] Offload settings to it's own set of files --- settings.cpp | 111 ++++++++++++++++++++++++++++++++++++++ settings.h | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 258 insertions(+) create mode 100644 settings.cpp create mode 100644 settings.h diff --git a/settings.cpp b/settings.cpp new file mode 100644 index 0000000..31b97be --- /dev/null +++ b/settings.cpp @@ -0,0 +1,111 @@ +/** + * These are the "magic" indices where these user changable settinngs are stored in the EEPROM + */ +static const uint8_t EEPROM_ADDR_MASTER_CAL = 0;//int32_t +//4 is currently unused, but may have been LSB_CAL on other versions +static const uint8_t EEPROM_ADDR_USB_CAL = 8;//uint32_t +//12 is currently unused, but may have been CW_SIDETONE on other versions? +static const uint8_t EEPROM_ADDR_VFO_A_FREQ = 16;//uint32_t +static const uint8_t EEPROM_ADDR_VFO_B_FREQ = 20;//uint32_t +static const uint8_t EEPROM_ADDR_CW_SIDETONE = 24;//uint32_t +static const uint8_t EEPROM_ADDR_CW_DIT_TIME = 28;//uint32_t +static const uint8_t EEPROM_ADDR_TOUCH_SLOPE_X = 32;//int16_t +static const uint8_t EEPROM_ADDR_TOUCH_SLOPE_Y = 36;//int16_t +static const uint8_t EEPROM_ADDR_TOUCH_OFFSET_X = 40;//int16_t +static const uint8_t EEPROM_ADDR_TOUCH_OFFSET_Y = 44;//int16_t +static const uint8_t EEPROM_ADDR_CW_DELAYTIME = 48; +static const uint8_t EEPROM_ADDR_VFO_A_MODE = 256; +static const uint8_t EEPROM_ADDR_VFO_B_MODE = 257; +static const uint8_t EEPROM_ADDR_CW_KEY_TYPE = 358; + +template +bool LoadSane(T& dest,uint16_t addr, T min, T max) +{ + T read_value; + EEPROM.get(addr,read_value); + if((min <= read_value) && (read_value <= max)){ + dest = read_value; + return true; + } + return false; +} + +#include +#include "settings.h" + +//This is the non-extern version that actually gets built +SettingsRam globalSettings; + +void LoadDefaultSettings() +{ + memset(&globalSettings,0x00,sizeof(globalSettings)); + + globalSettings.oscillatorCal = 0; + globalSettings.usbCarrierFreq = 11052000L; + + globalSettings.activeVfo = Vfo_e::VFO_A; + globalSettings.vfoA.frequency = 7150000L; + globalSettings.vfoA.mode = VFO_MODE_LSB; + globalSettings.vfoB.frequency = 14150000L; + globalSettings.vfoB.mode = VFO_MODE_USB; + + globalSettings.keyerMode = KEYER_STRAIGHT; + globalSettings.cwSideToneFreq = 800; + globalSettings.cwDitDurationMs = 100; + globalSettings.cwActiveTimeoutMs = 50; + + globalSettings.touchSlopeX = 104; + globalSettings.touchSlopeY = 137; + globalSettings.touchOffsetX = 28; + globalSettings.touchOffsetY = 29; + + globalSettings.ritOn = false; + globalSettings.ritFrequency = globalSettings.vfoA.frequency; + + globalSettings.tuningMode = TuningMode_e::TUNE_VOICE; + + globalSettings.splitOn = false; + + globalSettings.txActive = false; + globalSettings.txCatActive = false; +} + +void LoadSettingsFromEeprom() +{ + LoadSane(globalSettings.usbCarrierFreq,EEPROM_ADDR_USB_CAL,11048000L,11060000L); + LoadSane(globalSettings.vfoA.frequency,EEPROM_ADDR_VFO_A_FREQ,3500000L,30000000L); + LoadSane(globalSettings.vfoB.frequency,EEPROM_ADDR_VFO_B_FREQ,3500000L,30000000L); + LoadSane(globalSettings.cwSideToneFreq,EEPROM_ADDR_CW_SIDETONE,100,2000); + LoadSane(globalSettings.cwDitDurationMs,EEPROM_ADDR_CW_DIT_TIME,10,1000); + if(LoadSane(globalSettings.cwActiveTimeoutMs,EEPROM_ADDR_CW_DELAYTIME,10,100)){ + globalSettings.cwActiveTimeoutMs *= 10;//scale by 10 for legacy reasons + } + LoadSane(globalSettings.vfoA.mode,EEPROM_ADDR_VFO_A_MODE,VFO_MODE_LSB,VFO_MODE_USB); + LoadSane(globalSettings.vfoB.mode,EEPROM_ADDR_VFO_B_MODE,VFO_MODE_LSB,VFO_MODE_USB); + LoadSane(globalSettings.keyerMode,EEPROM_ADDR_CW_KEY_TYPE,KEYER_STRAIGHT,KEYER_IAMBIC_B); + + //No sanity check on these - cal your heart out + EEPROM.get(EEPROM_ADDR_MASTER_CAL,globalSettings.masterCalibration); + EEPROM.get(EEPROM_ADDR_TOUCH_SLOPE_X,globalSettings.touchSlopeX); + EEPROM.get(EEPROM_ADDR_TOUCH_SLOPE_Y,globalSettings.touchSlopeY); + EEPROM.get(EEPROM_ADDR_TOUCH_OFFSET_X,globalSettings.touchOffsetX); + EEPROM.get(EEPROM_ADDR_TOUCH_OFFSET_Y,globalSettings.touchOffsetY); +} + +void SaveSettingsToEeprom() +{ + EEPROM.put(EEPROM_ADDR_MASTER_CAL,globalSettings.masterCalibration); + EEPROM.put(EEPROM_ADDR_USB_CAL,globalSettings.usbCarrierFreq); + EEPROM.put(EEPROM_ADDR_VFO_A_FREQ,globalSettings.vfoA.frequency); + EEPROM.put(EEPROM_ADDR_VFO_B_FREQ,globalSettings.vfoB.frequency); + EEPROM.put(EEPROM_ADDR_CW_SIDETONE,globalSettings.cwSideToneFreq); + EEPROM.put(EEPROM_ADDR_CW_DIT_TIME,globalSettings.cwDitDurationMs); + EEPROM.put(EEPROM_ADDR_TOUCH_SLOPE_X,globalSettings.touchSlopeX); + EEPROM.put(EEPROM_ADDR_TOUCH_SLOPE_Y,globalSettings.touchSlopeY); + EEPROM.put(EEPROM_ADDR_TOUCH_OFFSET_X,globalSettings.touchOffsetX); + EEPROM.put(EEPROM_ADDR_TOUCH_OFFSET_Y,globalSettings.touchOffsetY); + EEPROM.put(EEPROM_ADDR_CW_DELAYTIME,globalSettings.cwActiveTimeoutMs/10);//scale by 10 for legacy reasons + EEPROM.put(EEPROM_ADDR_VFO_A_MODE,globalSettings.vfoA.mode); + EEPROM.put(EEPROM_ADDR_VFO_B_MODE,globalSettings.vfoB.mode); + EEPROM.put(EEPROM_ADDR_CW_KEY_TYPE,globalSettings.keyerMode); +} diff --git a/settings.h b/settings.h new file mode 100644 index 0000000..17a0e14 --- /dev/null +++ b/settings.h @@ -0,0 +1,147 @@ +/* + * This class deals with all of the radio settings, + * so that other areas of the code doesn't have to + * + * Example usage: + * LoadSettingsFromEeprom(); + * Serial.println(globalSettings.vfoAFreq); + * globalSettings.vfoAFreq = 12345678; + * SaveSettingsToEeprom(); + * Serial.println(globalSettings.vfoAFreq); + */ + +#pragma once + +/* + * Loads default values for all settings + */ +void LoadDefaultSettings(); + +/* + * Loads all persistent settings from the EEPROM + */ +void LoadSettingsFromEeprom(); + +/* + * Saves all persistent settings to the EEPROM + * + * It's a little CPU-cycle-wasteful to save EVERYTHING + * each time, but keeps things simple + */ +void SaveSettingsToEeprom(); + +/* + * These are all of the settings + * Note that not all settings are saved to the EEPROM + */ +enum Vfo_e : uint8_t +{ + VFO_A, + VFO_B +}; + +enum VfoMode_e : uint16_t +{ + VFO_MODE_LSB = 2, + VFO_MODE_USB = 3 +}; + +struct VfoSettings_t +{ + uint32_t frequency; + VfoMode_e mode; +}; + +enum TuningMode_e : uint8_t +{ + TUNE_SSB, + TUNE_CW +}; + +enum KeyerMode_e : uint8_t +{ + KEYER_STRAIGHT, + KEYER_IAMBIC_A, + KEYER_IAMBIC_B +}; + +/* + * This is the definition of the settings/state variables + */ +struct SettingsRam +{ + uint32_t oscillatorCal; + uint32_t usbCarrierFreq; + + Vfo_e activeVfo; + VfoSettings_t vfoA; + VfoSettings_t vfoB; + + KeyerMode_e keyerMode; + uint32_t cwSideToneFreq; + uint32_t cwDitDurationMs; + uint16_t cwActiveTimeoutMs; + + int16_t touchSlopeX; + int16_t touchSlopeY; + int16_t touchOffsetX; + int16_t touchOffsetY; + + bool ritOn; + uint32_t ritFrequency; + + TuningMode_e tuningMode; + + bool splitOn; + + bool txActive; + bool txCatActive; + + uint32_t cwExpirationTimeMs; +}; + +//This is the shared declaration +extern SettingsRam globalSettings; + +//Some convenience functions +uint32_t GetActiveVfoFreq() +{ + if(VFO_A == globalSettings.activeVfo){ + return globalSettings.vfoA.frequency; + } + else{ + return globalSettings.vfoB.frequency; + } +} + +void SetActiveVfoFreq(uint32_t frequency) +{ + if(VFO_A == globalSettings.activeVfo) + { + globalSettings.vfoA.frequency = frequency; + } + else{ + globalSettings.vfoB.frequency = frequency; + } +} + +VfoMode_e GetActiveVfoMode() +{ + if(VFO_A == globalSettings.activeVfo){ + return globalSettings.vfoA.mode; + } + else{ + return globalSettings.vfoB.mode; + } +} + +void SetActiveVfoMode(VfoMode_e mode) +{ + if(VFO_A == globalSettings.activeVfo) + { + globalSettings.vfoA.mode = mode; + } + else{ + globalSettings.vfoB.mode = mode; + } +} \ No newline at end of file From 0bf8424ab994dcbe636f4501b113e4cf2ed76f96 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Fri, 3 Jan 2020 23:11:08 -0800 Subject: [PATCH 02/22] Get settings files compiling --- settings.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++--------- settings.h | 46 +++-------------------------------- 2 files changed, 61 insertions(+), 54 deletions(-) diff --git a/settings.cpp b/settings.cpp index 31b97be..5f5aa0b 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1,3 +1,8 @@ +#include //memset +#include +#include +#include "settings.h" + /** * These are the "magic" indices where these user changable settinngs are stored in the EEPROM */ @@ -30,9 +35,6 @@ bool LoadSane(T& dest,uint16_t addr, T min, T max) return false; } -#include -#include "settings.h" - //This is the non-extern version that actually gets built SettingsRam globalSettings; @@ -62,22 +64,23 @@ void LoadDefaultSettings() globalSettings.ritOn = false; globalSettings.ritFrequency = globalSettings.vfoA.frequency; - globalSettings.tuningMode = TuningMode_e::TUNE_VOICE; + globalSettings.tuningMode = TuningMode_e::TUNE_SSB; globalSettings.splitOn = false; globalSettings.txActive = false; globalSettings.txCatActive = false; + globalSettings.cwExpirationTimeMs = 0; } void LoadSettingsFromEeprom() { - LoadSane(globalSettings.usbCarrierFreq,EEPROM_ADDR_USB_CAL,11048000L,11060000L); - LoadSane(globalSettings.vfoA.frequency,EEPROM_ADDR_VFO_A_FREQ,3500000L,30000000L); - LoadSane(globalSettings.vfoB.frequency,EEPROM_ADDR_VFO_B_FREQ,3500000L,30000000L); - LoadSane(globalSettings.cwSideToneFreq,EEPROM_ADDR_CW_SIDETONE,100,2000); - LoadSane(globalSettings.cwDitDurationMs,EEPROM_ADDR_CW_DIT_TIME,10,1000); - if(LoadSane(globalSettings.cwActiveTimeoutMs,EEPROM_ADDR_CW_DELAYTIME,10,100)){ + LoadSane(globalSettings.usbCarrierFreq,EEPROM_ADDR_USB_CAL,11048000UL,11060000UL); + LoadSane(globalSettings.vfoA.frequency,EEPROM_ADDR_VFO_A_FREQ,3500000UL,30000000UL); + LoadSane(globalSettings.vfoB.frequency,EEPROM_ADDR_VFO_B_FREQ,3500000UL,30000000UL); + LoadSane(globalSettings.cwSideToneFreq,EEPROM_ADDR_CW_SIDETONE,100UL,2000UL); + LoadSane(globalSettings.cwDitDurationMs,EEPROM_ADDR_CW_DIT_TIME,10UL,1000UL); + if(LoadSane(globalSettings.cwActiveTimeoutMs,EEPROM_ADDR_CW_DELAYTIME,10U,100U)){ globalSettings.cwActiveTimeoutMs *= 10;//scale by 10 for legacy reasons } LoadSane(globalSettings.vfoA.mode,EEPROM_ADDR_VFO_A_MODE,VFO_MODE_LSB,VFO_MODE_USB); @@ -85,7 +88,7 @@ void LoadSettingsFromEeprom() LoadSane(globalSettings.keyerMode,EEPROM_ADDR_CW_KEY_TYPE,KEYER_STRAIGHT,KEYER_IAMBIC_B); //No sanity check on these - cal your heart out - EEPROM.get(EEPROM_ADDR_MASTER_CAL,globalSettings.masterCalibration); + EEPROM.get(EEPROM_ADDR_MASTER_CAL,globalSettings.oscillatorCal); EEPROM.get(EEPROM_ADDR_TOUCH_SLOPE_X,globalSettings.touchSlopeX); EEPROM.get(EEPROM_ADDR_TOUCH_SLOPE_Y,globalSettings.touchSlopeY); EEPROM.get(EEPROM_ADDR_TOUCH_OFFSET_X,globalSettings.touchOffsetX); @@ -94,7 +97,7 @@ void LoadSettingsFromEeprom() void SaveSettingsToEeprom() { - EEPROM.put(EEPROM_ADDR_MASTER_CAL,globalSettings.masterCalibration); + EEPROM.put(EEPROM_ADDR_MASTER_CAL,globalSettings.oscillatorCal); EEPROM.put(EEPROM_ADDR_USB_CAL,globalSettings.usbCarrierFreq); EEPROM.put(EEPROM_ADDR_VFO_A_FREQ,globalSettings.vfoA.frequency); EEPROM.put(EEPROM_ADDR_VFO_B_FREQ,globalSettings.vfoB.frequency); @@ -109,3 +112,45 @@ void SaveSettingsToEeprom() EEPROM.put(EEPROM_ADDR_VFO_B_MODE,globalSettings.vfoB.mode); EEPROM.put(EEPROM_ADDR_CW_KEY_TYPE,globalSettings.keyerMode); } + +uint32_t GetActiveVfoFreq() +{ + if(VFO_A == globalSettings.activeVfo){ + return globalSettings.vfoA.frequency; + } + else{ + return globalSettings.vfoB.frequency; + } +} + +void SetActiveVfoFreq(uint32_t frequency) +{ + if(VFO_A == globalSettings.activeVfo) + { + globalSettings.vfoA.frequency = frequency; + } + else{ + globalSettings.vfoB.frequency = frequency; + } +} + +VfoMode_e GetActiveVfoMode() +{ + if(VFO_A == globalSettings.activeVfo){ + return globalSettings.vfoA.mode; + } + else{ + return globalSettings.vfoB.mode; + } +} + +void SetActiveVfoMode(VfoMode_e mode) +{ + if(VFO_A == globalSettings.activeVfo) + { + globalSettings.vfoA.mode = mode; + } + else{ + globalSettings.vfoB.mode = mode; + } +} diff --git a/settings.h b/settings.h index 17a0e14..4d2bd39 100644 --- a/settings.h +++ b/settings.h @@ -96,7 +96,6 @@ struct SettingsRam bool txActive; bool txCatActive; - uint32_t cwExpirationTimeMs; }; @@ -104,44 +103,7 @@ struct SettingsRam extern SettingsRam globalSettings; //Some convenience functions -uint32_t GetActiveVfoFreq() -{ - if(VFO_A == globalSettings.activeVfo){ - return globalSettings.vfoA.frequency; - } - else{ - return globalSettings.vfoB.frequency; - } -} - -void SetActiveVfoFreq(uint32_t frequency) -{ - if(VFO_A == globalSettings.activeVfo) - { - globalSettings.vfoA.frequency = frequency; - } - else{ - globalSettings.vfoB.frequency = frequency; - } -} - -VfoMode_e GetActiveVfoMode() -{ - if(VFO_A == globalSettings.activeVfo){ - return globalSettings.vfoA.mode; - } - else{ - return globalSettings.vfoB.mode; - } -} - -void SetActiveVfoMode(VfoMode_e mode) -{ - if(VFO_A == globalSettings.activeVfo) - { - globalSettings.vfoA.mode = mode; - } - else{ - globalSettings.vfoB.mode = mode; - } -} \ No newline at end of file +uint32_t GetActiveVfoFreq(); +void SetActiveVfoFreq(uint32_t frequency); +VfoMode_e GetActiveVfoMode(); +void SetActiveVfoMode(VfoMode_e mode); From 39168d663e4558ab766c201b1542ea3155444401 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Fri, 3 Jan 2020 23:11:55 -0800 Subject: [PATCH 03/22] Use settings in all files. Compiles, but untested --- keyer.cpp | 164 +++++--------- morse.cpp | 20 +- nano_gui.cpp | 54 ++--- setup.cpp | 149 ++++++------ ubitx.h | 84 +------ ubitx_cat.cpp | 49 ++-- ubitx_si5351.cpp | 5 +- ubitx_ui.cpp | 200 ++++++++-------- ubitx_v6.3.1_code.ino | 513 +++++++++++------------------------------- 9 files changed, 417 insertions(+), 821 deletions(-) diff --git a/keyer.cpp b/keyer.cpp index aa4fdc2..dbbf4e7 100644 --- a/keyer.cpp +++ b/keyer.cpp @@ -1,4 +1,5 @@ #include +#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 } diff --git a/morse.cpp b/morse.cpp index d1b6dd5..d052138 100644 --- a/morse.cpp +++ b/morse.cpp @@ -1,5 +1,6 @@ #include #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++); } diff --git a/nano_gui.cpp b/nano_gui.cpp index a801d58..0c532d0 100644 --- a/nano_gui.cpp +++ b/nano_gui.cpp @@ -1,5 +1,5 @@ #include -#include +#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); diff --git a/setup.cpp b/setup.cpp index c37f433..798ae46 100644 --- a/setup.cpp +++ b/setup.cpp @@ -1,6 +1,7 @@ #include #include #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; diff --git a/ubitx.h b/ubitx.h index 10fdc63..196e759 100644 --- a/ubitx.h +++ b/ubitx.h @@ -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(); diff --git a/ubitx_cat.cpp b/ubitx_cat.cpp index c15bc26..d216b78 100644 --- a/ubitx_cat.cpp +++ b/ubitx_cat.cpp @@ -1,4 +1,5 @@ #include +#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 diff --git a/ubitx_si5351.cpp b/ubitx_si5351.cpp index 544648a..3d378ab 100644 --- a/ubitx_si5351.cpp +++ b/ubitx_si5351.cpp @@ -1,5 +1,6 @@ #include #include +#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); } diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index 07e4b4d..7e48a1a 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -1,6 +1,7 @@ #include #include #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); diff --git a/ubitx_v6.3.1_code.ino b/ubitx_v6.3.1_code.ino index d2518d1..4e73bf4 100644 --- a/ubitx_v6.3.1_code.ino +++ b/ubitx_v6.3.1_code.ino @@ -30,21 +30,10 @@ * Si5351 object to control the clocks. */ #include -#include +#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(); } From e9702bd955627f2a9871b2b42aa5d176cd865a5f Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Fri, 3 Jan 2020 23:43:06 -0800 Subject: [PATCH 04/22] Fix settings - some variables weren't being read quite right --- settings.cpp | 46 +++++++++++++++++++++++++++------------------- settings.h | 4 ++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/settings.cpp b/settings.cpp index 5f5aa0b..ffd4c0e 100644 --- a/settings.cpp +++ b/settings.cpp @@ -2,26 +2,27 @@ #include #include #include "settings.h" +#include /** * These are the "magic" indices where these user changable settinngs are stored in the EEPROM */ -static const uint8_t EEPROM_ADDR_MASTER_CAL = 0;//int32_t +static const uint16_t EEPROM_ADDR_MASTER_CAL = 0;//int32_t //4 is currently unused, but may have been LSB_CAL on other versions -static const uint8_t EEPROM_ADDR_USB_CAL = 8;//uint32_t +static const uint16_t EEPROM_ADDR_USB_CAL = 8;//uint32_t //12 is currently unused, but may have been CW_SIDETONE on other versions? -static const uint8_t EEPROM_ADDR_VFO_A_FREQ = 16;//uint32_t -static const uint8_t EEPROM_ADDR_VFO_B_FREQ = 20;//uint32_t -static const uint8_t EEPROM_ADDR_CW_SIDETONE = 24;//uint32_t -static const uint8_t EEPROM_ADDR_CW_DIT_TIME = 28;//uint32_t -static const uint8_t EEPROM_ADDR_TOUCH_SLOPE_X = 32;//int16_t -static const uint8_t EEPROM_ADDR_TOUCH_SLOPE_Y = 36;//int16_t -static const uint8_t EEPROM_ADDR_TOUCH_OFFSET_X = 40;//int16_t -static const uint8_t EEPROM_ADDR_TOUCH_OFFSET_Y = 44;//int16_t -static const uint8_t EEPROM_ADDR_CW_DELAYTIME = 48; -static const uint8_t EEPROM_ADDR_VFO_A_MODE = 256; -static const uint8_t EEPROM_ADDR_VFO_B_MODE = 257; -static const uint8_t EEPROM_ADDR_CW_KEY_TYPE = 358; +static const uint16_t EEPROM_ADDR_VFO_A_FREQ = 16;//uint32_t +static const uint16_t EEPROM_ADDR_VFO_B_FREQ = 20;//uint32_t +static const uint16_t EEPROM_ADDR_CW_SIDETONE = 24;//uint32_t +static const uint16_t EEPROM_ADDR_CW_DIT_TIME = 28;//uint32_t +static const uint16_t EEPROM_ADDR_TOUCH_SLOPE_X = 32;//int16_t +static const uint16_t EEPROM_ADDR_TOUCH_SLOPE_Y = 36;//int16_t +static const uint16_t EEPROM_ADDR_TOUCH_OFFSET_X = 40;//int16_t +static const uint16_t EEPROM_ADDR_TOUCH_OFFSET_Y = 44;//int16_t +static const uint16_t EEPROM_ADDR_CW_DELAYTIME = 48; +static const uint16_t EEPROM_ADDR_VFO_A_MODE = 256; +static const uint16_t EEPROM_ADDR_VFO_B_MODE = 257; +static const uint16_t EEPROM_ADDR_CW_KEY_TYPE = 358; template bool LoadSane(T& dest,uint16_t addr, T min, T max) @@ -30,8 +31,14 @@ bool LoadSane(T& dest,uint16_t addr, T min, T max) EEPROM.get(addr,read_value); if((min <= read_value) && (read_value <= max)){ dest = read_value; + //Serial.print(addr); + //Serial.print(F(":")); + //Serial.println(dest); return true; } + //Serial.print(addr); + //Serial.print(F(": Not valid: ")); + //Serial.println(read_value); return false; } @@ -42,13 +49,13 @@ void LoadDefaultSettings() { memset(&globalSettings,0x00,sizeof(globalSettings)); - globalSettings.oscillatorCal = 0; - globalSettings.usbCarrierFreq = 11052000L; + globalSettings.oscillatorCal = 0L; + globalSettings.usbCarrierFreq = 11052000UL; globalSettings.activeVfo = Vfo_e::VFO_A; - globalSettings.vfoA.frequency = 7150000L; + globalSettings.vfoA.frequency = 7150000UL; globalSettings.vfoA.mode = VFO_MODE_LSB; - globalSettings.vfoB.frequency = 14150000L; + globalSettings.vfoB.frequency = 14150000UL; globalSettings.vfoB.mode = VFO_MODE_USB; globalSettings.keyerMode = KEYER_STRAIGHT; @@ -79,7 +86,7 @@ void LoadSettingsFromEeprom() LoadSane(globalSettings.vfoA.frequency,EEPROM_ADDR_VFO_A_FREQ,3500000UL,30000000UL); LoadSane(globalSettings.vfoB.frequency,EEPROM_ADDR_VFO_B_FREQ,3500000UL,30000000UL); LoadSane(globalSettings.cwSideToneFreq,EEPROM_ADDR_CW_SIDETONE,100UL,2000UL); - LoadSane(globalSettings.cwDitDurationMs,EEPROM_ADDR_CW_DIT_TIME,10UL,1000UL); + LoadSane(globalSettings.cwDitDurationMs,EEPROM_ADDR_CW_DIT_TIME,10U,1000U); if(LoadSane(globalSettings.cwActiveTimeoutMs,EEPROM_ADDR_CW_DELAYTIME,10U,100U)){ globalSettings.cwActiveTimeoutMs *= 10;//scale by 10 for legacy reasons } @@ -97,6 +104,7 @@ void LoadSettingsFromEeprom() void SaveSettingsToEeprom() { + //Serial.println(F("Saving...")); EEPROM.put(EEPROM_ADDR_MASTER_CAL,globalSettings.oscillatorCal); EEPROM.put(EEPROM_ADDR_USB_CAL,globalSettings.usbCarrierFreq); EEPROM.put(EEPROM_ADDR_VFO_A_FREQ,globalSettings.vfoA.frequency); diff --git a/settings.h b/settings.h index 4d2bd39..efd90ba 100644 --- a/settings.h +++ b/settings.h @@ -40,7 +40,7 @@ enum Vfo_e : uint8_t VFO_B }; -enum VfoMode_e : uint16_t +enum VfoMode_e : uint8_t { VFO_MODE_LSB = 2, VFO_MODE_USB = 3 @@ -79,7 +79,7 @@ struct SettingsRam KeyerMode_e keyerMode; uint32_t cwSideToneFreq; - uint32_t cwDitDurationMs; + uint16_t cwDitDurationMs; uint16_t cwActiveTimeoutMs; int16_t touchSlopeX; From 4cefa08eaf7b489643b9b0f5101a73443c7af5b8 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Fri, 3 Jan 2020 23:43:33 -0800 Subject: [PATCH 05/22] Fix WPM calculations --- ubitx_cat.cpp | 2 +- ubitx_ui.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ubitx_cat.cpp b/ubitx_cat.cpp index d216b78..815c18b 100644 --- a/ubitx_cat.cpp +++ b/ubitx_cat.cpp @@ -211,7 +211,7 @@ void catReadEEPRom(void) //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] = 12000 / globalSettings.cwDitDurationMs - 4; + cat[0] = 1200 / globalSettings.cwDitDurationMs - 4; cat[1] = 0xB2; break; case 0x63 : // diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index 7e48a1a..aff1be5 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -532,7 +532,7 @@ void enterFreq(){ void drawCWStatus(){ strcpy(b, " cw: "); - int wpm = 12000/globalSettings.cwDitDurationMs; + int wpm = 1200/globalSettings.cwDitDurationMs; itoa(wpm,c, 10); strcat(b, c); strcat(b, "wpm, "); @@ -770,11 +770,11 @@ void switchBand(uint32_t bandfreq){ void setCwSpeed() { - int wpm = 12000/globalSettings.cwDitDurationMs; + int wpm = 1200/globalSettings.cwDitDurationMs; wpm = getValueByKnob(1, 100, 1, wpm, "CW: ", " WPM"); - globalSettings.cwDitDurationMs = 12000/wpm; + globalSettings.cwDitDurationMs = 1200/wpm; SaveSettingsToEeprom(); active_delay(500); drawStatusbar(); From fbfb7c89d6920a7e21ea45f51305282f6c2eb4f5 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 01:50:17 -0800 Subject: [PATCH 06/22] Fix merge issue --- setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cpp b/setup.cpp index 7e9b3d2..fa4915c 100644 --- a/setup.cpp +++ b/setup.cpp @@ -111,7 +111,7 @@ void setupFreq(){ strcpy_P(c,(const char*)F("Rotate to zerobeat")); displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_ITEM_Y + 4*LAYOUT_ITEM_PITCH_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); - ltoa(calibration, b, 10); + ltoa(globalSettings.oscillatorCal, b, 10); displayText(b, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_BACKGROUND); //keep clear of any previous button press while (btnDown()) From 8d34a3461b7ed7deb282d218a315f79361f1f732 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 01:56:05 -0800 Subject: [PATCH 07/22] Fix ritToggle logic --- ubitx_ui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index f27abdf..9aa6e75 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -628,7 +628,7 @@ int enc_read(void) { } void ritToggle(struct Button *button){ - if (globalSettings.ritOn){ + if(!globalSettings.ritOn){ ritEnable(GetActiveVfoFreq()); } else{ From a2109de63f4b5253523f43705ddbe86eb1d8cd98 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 02:14:21 -0800 Subject: [PATCH 08/22] Fix issue with RIT restore during VFO change --- ubitx_v6.3.1_code.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ubitx_v6.3.1_code.ino b/ubitx_v6.3.1_code.ino index 4e73bf4..a25964d 100644 --- a/ubitx_v6.3.1_code.ino +++ b/ubitx_v6.3.1_code.ino @@ -336,6 +336,8 @@ void checkButton(){ } void switchVFO(Vfo_e new_vfo){ + ritDisable();//If we are in RIT mode, we need to disable it before setting the active VFO so that the correct VFO gets it's frequency restored + globalSettings.activeVfo = new_vfo; setFrequency(GetActiveVfoFreq()); redrawVFOs(); From 4674230f513ee60c76c5d02c73d1585ba24d2f9a Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 02:41:06 -0800 Subject: [PATCH 09/22] Make more strings progmem. Probably should consolidate strings at some point so that we don't have lots of duplicate '.' and 'Hz' floating around --- ubitx_ui.cpp | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index 8ea3067..0e6fc11 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -165,12 +165,12 @@ void formatFreq(long f, char *buff) { if (f < 10000000l){ buff[0] = ' '; strncat(buff, b, 4); - strcat(buff, "."); + strcat_P(buff,(const char*)F(".")); strncat(buff, &b[4], 2); } else { strncat(buff, b, 5); - strcat(buff, "."); + strcat_P(buff,(const char*)F(".")); strncat(buff, &b[5], 2); } } @@ -181,7 +181,7 @@ inline void drawCommandbar(char* text){ /** A generic control to read variable values */ -int getValueByKnob(int minimum, int maximum, int step_size, int initial, char* prefix, char *postfix) +int getValueByKnob(int minimum, int maximum, int step_size, int initial, const __FlashStringHelper* prefix, const __FlashStringHelper* postfix) { int knob = 0; int knob_value; @@ -192,10 +192,10 @@ int getValueByKnob(int minimum, int maximum, int step_size, int initial, char* active_delay(200); knob_value = initial; - strcpy(b, prefix); + strcpy_P(b,(const char*)prefix); itoa(knob_value, c, 10); strcat(b, c); - strcat(b, postfix); + strcat_P(b, (const char*)postfix); drawCommandbar(b); while(!btnDown() && digitalRead(PTT) == HIGH){ @@ -206,10 +206,10 @@ int getValueByKnob(int minimum, int maximum, int step_size, int initial, char* if (knob_value < maximum && knob > 0) knob_value += step_size; - strcpy(b, prefix); + strcpy_P(b,(const char*)prefix); itoa(knob_value, c, 10); strcat(b, c); - strcat(b, postfix); + strcat_P(b,(const char*)postfix); drawCommandbar(b); } checkCAT(); @@ -376,7 +376,8 @@ void fastTune(){ active_delay(50); active_delay(300); - displayText("Fast tune", LAYOUT_MODE_TEXT_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); + strcpy_P(c,(const char*)F("Fast tune")); + displayText(c, LAYOUT_MODE_TEXT_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); while(1){ checkCAT(); @@ -498,7 +499,7 @@ void enterFreq(){ }//if button hit test }// end of the button scanning loop strcpy(b, c); - strcat(b, " KHz"); + strcat_P(b,(const char*)F(" 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); active_delay(300); while(readTouch()) @@ -507,23 +508,26 @@ void enterFreq(){ } void drawCWStatus(){ - strcpy(b, " cw: "); + strcpy_P(b,(const char*)F(" cw: ")); int wpm = 1200/globalSettings.cwDitDurationMs; itoa(wpm,c, 10); strcat(b, c); - strcat(b, "wpm, "); + strcat_P(b,(const char*)F("wpm, ")); itoa(globalSettings.cwSideToneFreq, c, 10); strcat(b, c); - strcat(b, "hz"); + strcat_P(b,(const char*)F("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); } void drawTx(){ - 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 + if (globalSettings.txActive){ + strcpy_P(b,(const char*)F("TX")); + displayText(b, 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); + } } void drawStatusbar(){ drawCWStatus(); @@ -748,7 +752,7 @@ void setCwSpeed() { int wpm = 1200/globalSettings.cwDitDurationMs; - wpm = getValueByKnob(1, 100, 1, wpm, "CW: ", " WPM"); + wpm = getValueByKnob(1, 100, 1, wpm,F("CW: "),F(" WPM")); globalSettings.cwDitDurationMs = 1200/wpm; SaveSettingsToEeprom(); @@ -764,9 +768,9 @@ void setCwTone(){ tone(CW_TONE, globalSettings.cwSideToneFreq); itoa(globalSettings.cwSideToneFreq, c, 10); - strcpy(b, "CW Tone: "); + strcpy_P(b,(const char*)F("CW Tone: ")); strcat(b, c); - strcat(b, " Hz"); + strcat_P(b,(const char*)F(" Hz")); drawCommandbar(b); //disable all clock 1 and clock 2 @@ -783,9 +787,9 @@ void setCwTone(){ tone(CW_TONE, globalSettings.cwSideToneFreq); itoa(globalSettings.cwSideToneFreq, c, 10); - strcpy(b, "CW Tone: "); + strcpy_P(b,(const char*)F("CW Tone: ")); strcat(b, c); - strcat(b, " Hz"); + strcat_P(b,(const char*)F(" Hz")); drawCommandbar(b); //printLine2(b); From a0abe466c0efd6c2fb1e20c3f9eb289a1acecf69 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 02:52:56 -0800 Subject: [PATCH 10/22] Redraw VFO after mode change so that UI will reflect active setting --- settings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/settings.cpp b/settings.cpp index ffd4c0e..eb95c18 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1,8 +1,9 @@ #include //memset #include #include +#include //only needed for debugging's Serial.print stuff #include "settings.h" -#include +#include "ubitx.h"//redrawVFOs() function /** * These are the "magic" indices where these user changable settinngs are stored in the EEPROM @@ -161,4 +162,5 @@ void SetActiveVfoMode(VfoMode_e mode) else{ globalSettings.vfoB.mode = mode; } + redrawVFOs(); } From b655704264d7160a1d1ee4c2d2b11386173ed324 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 02:53:33 -0800 Subject: [PATCH 11/22] Update side band when band buttons are used --- ubitx_ui.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index 0e6fc11..1f63bc1 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -744,7 +744,15 @@ void switchBand(uint32_t bandfreq){ //Serial.println(offset); setFrequency(bandfreq + offset); - updateDisplay(); + + if(bandfreq >= THRESHOLD_USB_LSB){ + SetActiveVfoMode(VfoMode_e::VFO_MODE_USB); + } + else{ + SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB); + } + + updateDisplay(); saveVFOs(); } From 9a68846b5814ca716f311801b05a3bffeb0987d2 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sat, 4 Jan 2020 22:51:29 -0800 Subject: [PATCH 12/22] Use correct version of strcat for flash strings --- setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cpp b/setup.cpp index fa4915c..f8f5feb 100644 --- a/setup.cpp +++ b/setup.cpp @@ -83,7 +83,7 @@ void printCarrierFreq(unsigned long freq){ strncat(c, b, 2); strcat_P(c,(const char*)F(".")); strncat(c, &b[2], 3); - strcat(c,(const char*)F(".")); + strcat_P(c,(const char*)F(".")); strncat(c, &b[5], 1); displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_BACKGROUND); } From 227cbe9b071caaf2564323ff262c1bf14a05a285 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Mon, 13 Jan 2020 23:38:12 -0800 Subject: [PATCH 13/22] Load EEPROM settings immediately, and load defaults prior to loading EEPROM values so that we fall back on defaults rather than 0's --- nano_gui.cpp | 1 - ubitx_v6.3.1_code.ino | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nano_gui.cpp b/nano_gui.cpp index a3932ac..938ccee 100644 --- a/nano_gui.cpp +++ b/nano_gui.cpp @@ -157,7 +157,6 @@ void displayInit(void){ tft.setRotation(1); xpt2046_Init(); - readTouchCalibration(); } void displayPixel(unsigned int x, unsigned int y, unsigned int c){ diff --git a/ubitx_v6.3.1_code.ino b/ubitx_v6.3.1_code.ino index a25964d..4af8c35 100644 --- a/ubitx_v6.3.1_code.ino +++ b/ubitx_v6.3.1_code.ino @@ -420,6 +420,7 @@ void doRIT(){ * variables. */ void initSettings(){ + LoadDefaultSettings(); LoadSettingsFromEeprom(); } @@ -461,8 +462,8 @@ void setup() Serial.begin(38400); Serial.flush(); - displayInit(); initSettings(); + displayInit(); initPorts(); initOscillators(); setFrequency(globalSettings.vfoA.frequency); From f6894e03f817eb65eeb5123e63bc6eda8b4a0138 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Mon, 13 Jan 2020 23:38:43 -0800 Subject: [PATCH 14/22] Add more debugging context (commented out) --- settings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/settings.cpp b/settings.cpp index eb95c18..dac384a 100644 --- a/settings.cpp +++ b/settings.cpp @@ -39,7 +39,9 @@ bool LoadSane(T& dest,uint16_t addr, T min, T max) } //Serial.print(addr); //Serial.print(F(": Not valid: ")); - //Serial.println(read_value); + //Serial.print(read_value); + //Serial.print(F(" Leaving value at ")); + //Serial.println(dest); return false; } From 6e797adc7021fbb1dc1661beab3371e3b275168d Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Tue, 14 Jan 2020 22:07:24 -0800 Subject: [PATCH 15/22] Expand range of allowed sane frequencies to anything the tuner driver will actually tune --- settings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.cpp b/settings.cpp index dac384a..2c395a1 100644 --- a/settings.cpp +++ b/settings.cpp @@ -86,8 +86,8 @@ void LoadDefaultSettings() void LoadSettingsFromEeprom() { LoadSane(globalSettings.usbCarrierFreq,EEPROM_ADDR_USB_CAL,11048000UL,11060000UL); - LoadSane(globalSettings.vfoA.frequency,EEPROM_ADDR_VFO_A_FREQ,3500000UL,30000000UL); - LoadSane(globalSettings.vfoB.frequency,EEPROM_ADDR_VFO_B_FREQ,3500000UL,30000000UL); + LoadSane(globalSettings.vfoA.frequency,EEPROM_ADDR_VFO_A_FREQ,500000UL+1,109000000UL-1);//Allow all freq supported by si5351 driver + LoadSane(globalSettings.vfoB.frequency,EEPROM_ADDR_VFO_B_FREQ,500000UL+1,109000000UL-1);//Allow all freq supported by si5351 driver LoadSane(globalSettings.cwSideToneFreq,EEPROM_ADDR_CW_SIDETONE,100UL,2000UL); LoadSane(globalSettings.cwDitDurationMs,EEPROM_ADDR_CW_DIT_TIME,10U,1000U); if(LoadSane(globalSettings.cwActiveTimeoutMs,EEPROM_ADDR_CW_DELAYTIME,10U,100U)){ From 9a205522d90722d75e253c1ea1150aa5a9ff5115 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Tue, 14 Jan 2020 22:22:26 -0800 Subject: [PATCH 16/22] Don't reset cals to fixed values when starting cal routine --- setup.cpp | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/setup.cpp b/setup.cpp index f8f5feb..7be7b14 100644 --- a/setup.cpp +++ b/setup.cpp @@ -89,9 +89,6 @@ void printCarrierFreq(unsigned long freq){ } void setupFreq(){ - int knob = 0; - int32_t prev_calibration; - displayDialog(F("Set Frequency"),F("Push TUNE to Save")); //round off the the nearest khz @@ -105,7 +102,7 @@ void setupFreq(){ displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_ITEM_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); strcpy_P(c,(const char*)F("signal exactly at")); displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_ITEM_Y + 1*LAYOUT_ITEM_PITCH_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); - ltoa(GetActiveVfoFreq()/1000l, c, 10); + ltoa(GetActiveVfoFreq()/1000L, c, 10); strcat_P(c,(const char*)F(" KHz")); displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_ITEM_Y + 2*LAYOUT_ITEM_PITCH_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); strcpy_P(c,(const char*)F("Rotate to zerobeat")); @@ -117,21 +114,18 @@ void setupFreq(){ while (btnDown()) active_delay(100); active_delay(100); - - prev_calibration = globalSettings.oscillatorCal; - globalSettings.oscillatorCal = 0; while (!btnDown()) { - knob = enc_read(); - if (knob != 0) + int knob = enc_read(); + if(knob != 0){ globalSettings.oscillatorCal += knob * 875; - /* else if (knob < 0) - calibration -= 875; */ - else + } + else{ continue; //don't update the frequency or the display - - si5351bx_setfreq(0, globalSettings.usbCarrierFreq); //set back the cardrier oscillator anyway, cw tx switches it off + } + + si5351bx_setfreq(0, globalSettings.usbCarrierFreq); //set back the carrier oscillator anyway, cw tx switches it off si5351_set_calibration(globalSettings.oscillatorCal); setFrequency(GetActiveVfoFreq()); @@ -151,24 +145,19 @@ void setupFreq(){ } void setupBFO(){ - int knob = 0; - unsigned long prevCarrier; - - prevCarrier = globalSettings.usbCarrierFreq; - displayDialog(F("Set BFO"),F("Press TUNE to Save")); - - globalSettings.usbCarrierFreq = 11053000l; + si5351bx_setfreq(0, globalSettings.usbCarrierFreq); printCarrierFreq(globalSettings.usbCarrierFreq); while (!btnDown()){ - knob = enc_read(); - - if (knob != 0) + int knob = enc_read(); + if(knob != 0){ globalSettings.usbCarrierFreq -= 50 * knob; - else + } + else{ continue; //don't update the frequency or the display + } si5351bx_setfreq(0, globalSettings.usbCarrierFreq); setFrequency(GetActiveVfoFreq()); @@ -180,8 +169,6 @@ void setupBFO(){ SaveSettingsToEeprom(); si5351bx_setfreq(0, globalSettings.usbCarrierFreq); setFrequency(GetActiveVfoFreq()); - updateDisplay(); - setupExit(); } void setupCwDelay(){ From 9a2a25abe9cdfdec885c02031ea5dc12a69c90d2 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Tue, 14 Jan 2020 22:47:53 -0800 Subject: [PATCH 17/22] Fix rendering of BFO --- setup.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/setup.cpp b/setup.cpp index 7be7b14..13cc06e 100644 --- a/setup.cpp +++ b/setup.cpp @@ -80,11 +80,27 @@ void printCarrierFreq(unsigned long freq){ ultoa(freq, b, DEC); - strncat(c, b, 2); - strcat_P(c,(const char*)F(".")); - strncat(c, &b[2], 3); - strcat_P(c,(const char*)F(".")); - strncat(c, &b[5], 1); + unsigned int characters_remaining = strlen(b); + char* destination = c; + char* source = b; + while(characters_remaining > 0){ + if(characters_remaining > 3){ + unsigned int characters_to_read = characters_remaining % 3; + if(0 == characters_to_read){ + characters_to_read = 3; + } + memcpy(destination,source,characters_to_read); + source += characters_to_read; + destination += characters_to_read; + characters_remaining -= characters_to_read; + memcpy_P(destination,(const char*)F("."),1); + destination += 1; + } + else{ + memcpy(destination,source,characters_remaining); + characters_remaining -= characters_remaining; + } + } displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_BACKGROUND); } From d62ff59c90295d387ca79cdec4d1d03fd48899d7 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Tue, 14 Jan 2020 23:27:42 -0800 Subject: [PATCH 18/22] Fix frequency display for VFOs --- ubitx_ui.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index 0481a56..f339fba 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -152,26 +152,27 @@ boolean getButton(btn_set_e index, Button* button){ /* * This formats the frequency given in f */ -void formatFreq(long f, char *buff) { - // tks Jack Purdum W8TEE - // replaced fsprint commmands by str commands for code size reduction +void formatFreq(uint32_t freq, char* buff, uint16_t buff_size) { + memset(buff, 0, buff_size); - memset(buff, 0, 10); - memset(b, 0, sizeof(b)); + ultoa(freq, buff, DEC); + uint8_t num_digits = strlen(buff); + const uint8_t num_spacers = (num_digits-1) / 3; + const uint8_t num_leading_digits_raw = num_digits % 3; + const uint8_t num_leading_digits = (0 == num_leading_digits_raw) ? 3 : num_leading_digits_raw; - ultoa(f, b, DEC); - - //one mhz digit if less than 10 M, two digits if more - if (f < 10000000l){ - buff[0] = ' '; - strncat(buff, b, 4); - strcat_P(buff,(const char*)F(".")); - strncat(buff, &b[4], 2); + if(0 == num_spacers){ + return; } - else { - strncat(buff, b, 5); - strcat_P(buff,(const char*)F(".")); - strncat(buff, &b[5], 2); + + buff += num_leading_digits; + num_digits -= num_leading_digits; + for(int i = num_digits-1; i >= 0; --i){ + buff[i + (i/3 + 1)] = buff[i]; + } + for(unsigned int i = 0; i < num_spacers; ++i){ + memcpy_P(buff,F("."),1); + buff += 4; } } @@ -248,7 +249,7 @@ void displayVFO(Vfo_e vfo){ if (VFO_A == vfo){ getButton(BUTTON_VFOA, &button); - formatFreq(globalSettings.vfoA.frequency, c+2); + formatFreq(globalSettings.vfoA.frequency, c+2, sizeof(c)-2); if (VFO_A == globalSettings.activeVfo){ displayColor = COLOR_ACTIVE_VFO_TEXT; @@ -263,7 +264,7 @@ void displayVFO(Vfo_e vfo){ if (VFO_B == vfo){ getButton(BUTTON_VFOB, &button); - formatFreq(globalSettings.vfoB.frequency, c+2); + formatFreq(globalSettings.vfoB.frequency, c+2, sizeof(c)-2); if (VFO_B == globalSettings.activeVfo){ displayColor = COLOR_ACTIVE_VFO_TEXT; @@ -362,7 +363,7 @@ void displayRIT(){ displayFillrect(LAYOUT_MODE_TEXT_X,LAYOUT_MODE_TEXT_Y,LAYOUT_MODE_TEXT_WIDTH,LAYOUT_MODE_TEXT_HEIGHT, COLOR_BACKGROUND); if(globalSettings.ritOn){ strcpy_P(c,(const char*)F("TX:")); - formatFreq(globalSettings.ritFrequency, c+3); + formatFreq(globalSettings.ritFrequency, c+3, sizeof(c)-3); if (VFO_A == globalSettings.activeVfo) displayText(c, LAYOUT_VFO_LABEL_X + 0*LAYOUT_VFO_LABEL_PITCH_X, LAYOUT_MODE_TEXT_Y, LAYOUT_VFO_LABEL_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); else From afeb056667eb32de232cd8ee3a79fa72d8facc05 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Tue, 14 Jan 2020 23:33:11 -0800 Subject: [PATCH 19/22] Move formatFreq to nano_gui so that both ubitx_ui and setup can use the single function --- nano_gui.cpp | 27 +++++++++++++++++++++++++++ nano_gui.h | 2 ++ setup.cpp | 31 +++---------------------------- ubitx_ui.cpp | 28 ---------------------------- 4 files changed, 32 insertions(+), 56 deletions(-) diff --git a/nano_gui.cpp b/nano_gui.cpp index 938ccee..6ca1ddb 100644 --- a/nano_gui.cpp +++ b/nano_gui.cpp @@ -8,6 +8,33 @@ struct Point ts_point; +/* + * This formats the frequency given in f + */ +void formatFreq(uint32_t freq, char* buff, uint16_t buff_size) { + memset(buff, 0, buff_size); + + ultoa(freq, buff, DEC); + uint8_t num_digits = strlen(buff); + const uint8_t num_spacers = (num_digits-1) / 3; + const uint8_t num_leading_digits_raw = num_digits % 3; + const uint8_t num_leading_digits = (0 == num_leading_digits_raw) ? 3 : num_leading_digits_raw; + + if(0 == num_spacers){ + return; + } + + buff += num_leading_digits; + num_digits -= num_leading_digits; + for(int i = num_digits-1; i >= 0; --i){ + buff[i + (i/3 + 1)] = buff[i]; + } + for(unsigned int i = 0; i < num_spacers; ++i){ + memcpy_P(buff,F("."),1); + buff += 4; + } +} + void readTouchCalibration(){ LoadSettingsFromEeprom(); /* for debugging diff --git a/nano_gui.h b/nano_gui.h index efb163b..f58cf02 100644 --- a/nano_gui.h +++ b/nano_gui.h @@ -18,6 +18,8 @@ void displayChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t void displayRawText(char *text, int x1, int y1, int color, int background); void displayText(char *text, int x1, int y1, int w, int h, int color, int background, int border); +void formatFreq(uint32_t freq, char* buff, uint16_t buff_size); + /* touch functions */ boolean readTouch(); diff --git a/setup.cpp b/setup.cpp index 13cc06e..10bace7 100644 --- a/setup.cpp +++ b/setup.cpp @@ -73,34 +73,9 @@ void displayDialog(const __FlashStringHelper* title, const __FlashStringHelper* displayText(c, LAYOUT_INSTRUCTION_TEXT_X, LAYOUT_INSTRUCTION_TEXT_Y, LAYOUT_INSTRUCTION_TEXT_WIDTH, LAYOUT_INSTRUCTION_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); } -void printCarrierFreq(unsigned long freq){ - - memset(c, 0, sizeof(c)); - memset(b, 0, sizeof(b)); - - ultoa(freq, b, DEC); - - unsigned int characters_remaining = strlen(b); - char* destination = c; - char* source = b; - while(characters_remaining > 0){ - if(characters_remaining > 3){ - unsigned int characters_to_read = characters_remaining % 3; - if(0 == characters_to_read){ - characters_to_read = 3; - } - memcpy(destination,source,characters_to_read); - source += characters_to_read; - destination += characters_to_read; - characters_remaining -= characters_to_read; - memcpy_P(destination,(const char*)F("."),1); - destination += 1; - } - else{ - memcpy(destination,source,characters_remaining); - characters_remaining -= characters_remaining; - } - } +void printCarrierFreq(unsigned long freq) +{ + formatFreq(freq,c,sizeof(c)); displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_BACKGROUND); } diff --git a/ubitx_ui.cpp b/ubitx_ui.cpp index f339fba..5e4e52b 100644 --- a/ubitx_ui.cpp +++ b/ubitx_ui.cpp @@ -148,34 +148,6 @@ boolean getButton(btn_set_e index, Button* button){ return true; } - -/* - * This formats the frequency given in f - */ -void formatFreq(uint32_t freq, char* buff, uint16_t buff_size) { - memset(buff, 0, buff_size); - - ultoa(freq, buff, DEC); - uint8_t num_digits = strlen(buff); - const uint8_t num_spacers = (num_digits-1) / 3; - const uint8_t num_leading_digits_raw = num_digits % 3; - const uint8_t num_leading_digits = (0 == num_leading_digits_raw) ? 3 : num_leading_digits_raw; - - if(0 == num_spacers){ - return; - } - - buff += num_leading_digits; - num_digits -= num_leading_digits; - for(int i = num_digits-1; i >= 0; --i){ - buff[i + (i/3 + 1)] = buff[i]; - } - for(unsigned int i = 0; i < num_spacers; ++i){ - memcpy_P(buff,F("."),1); - buff += 4; - } -} - inline void drawCommandbar(char* text){ displayText(text, LAYOUT_MODE_TEXT_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); } From 79fd056af0c5fbbd883f138641e3988bab2963da Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Tue, 14 Jan 2020 23:49:44 -0800 Subject: [PATCH 20/22] Rename oscillator variables so it's clear which is which not just from the math --- ubitx_v6.3.1_code.ino | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ubitx_v6.3.1_code.ino b/ubitx_v6.3.1_code.ino index 2fb6ead..8871f4f 100644 --- a/ubitx_v6.3.1_code.ino +++ b/ubitx_v6.3.1_code.ino @@ -159,24 +159,24 @@ void setFrequency(unsigned long freq){ setTXFilters(freq); - uint32_t primary_osc_freq; - if(VfoMode_e::VFO_MODE_USB == GetActiveVfoMode()){ - primary_osc_freq = firstIF + globalSettings.usbCarrierFreq; - } - else{ - primary_osc_freq = firstIF - globalSettings.usbCarrierFreq; - } - - uint32_t secondary_osc_freq; + uint32_t local_osc_freq; if(TuningMode_e::TUNE_CW == globalSettings.tuningMode){ - secondary_osc_freq = firstIF + freq + globalSettings.cwSideToneFreq; + local_osc_freq = firstIF + freq + globalSettings.cwSideToneFreq; } else{ - secondary_osc_freq = firstIF + freq; + local_osc_freq = firstIF + freq; } - si5351bx_setfreq(2, secondary_osc_freq); - si5351bx_setfreq(1, primary_osc_freq); + uint32_t ssb_osc_freq; + if(VfoMode_e::VFO_MODE_USB == GetActiveVfoMode()){ + ssb_osc_freq = firstIF + globalSettings.usbCarrierFreq; + } + else{ + ssb_osc_freq = firstIF - globalSettings.usbCarrierFreq; + } + + si5351bx_setfreq(2, local_osc_freq); + si5351bx_setfreq(1, ssb_osc_freq); SetActiveVfoFreq(freq); } From c17136279e581209693107c01070dab090476414 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Thu, 16 Jan 2020 23:36:58 -0800 Subject: [PATCH 21/22] Fix .,? morse encodings, and use correct letter spacing based on settings, not hard coded --- morse.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/morse.cpp b/morse.cpp index 4d7b8d4..2afaeaa 100644 --- a/morse.cpp +++ b/morse.cpp @@ -2,18 +2,18 @@ #include "ubitx.h" #include "settings.h" #include "morse.h" -/* - * Each byte of the morse table stores one letter. - * The 0 is a dot, a 1 is a dash - * From the Most significant byte onwards, the letter is padded with 1s. - * The first zero after the 1s indicates the start of the letter, it MUST be discarded - */ struct Morse { char letter; unsigned char code; }; +/* + * Each byte of the morse table stores one letter. + * The 0 is a dot, a 1 is a dash + * From the Most significant byte onwards, the letter is padded with 1s. + * The first zero after the 1s indicates the start of the letter, it MUST be discarded + */ static const PROGMEM struct Morse morse_table[] = { {'a', 0xf9}, // 11111001 {'b', 0xe8}, // 11101000 @@ -51,9 +51,9 @@ static const PROGMEM struct Morse morse_table[] = { {'8', 0xdc}, // 11011100 {'9', 0xde}, // 11011110 {'0', 0xdf}, // 11011111 -{'.', 0xd5}, // 11010101 -{',', 0xd3}, // 11010011 //AD7U 20191217 -{'?', 0xcc}, // 11001100 //AD7U 20191217 - Added +{'.', 0x95}, // 10010101 +{',', 0xb3}, // 10110011 +{'?', 0x8c}, // 10001100 }; static void morseLetter(char c){ @@ -62,7 +62,7 @@ static void morseLetter(char c){ //handle space character as three dashes if (c == ' '){ active_delay(9 * globalSettings.cwDitDurationMs); - Serial.print(' '); + //Serial.print(' '); return; } @@ -94,7 +94,8 @@ static void morseLetter(char c){ mask = mask >> 1; } //Serial.println('@'); - delay(200); // space between letters is a dash (3 dots), one dot's space has already been sent + delay(2*globalSettings.cwDitDurationMs); // space between letters is a dash (3 dots), one dot's space has already been sent + break;//We've played the letter, so don't bother checking the rest of the list } } } @@ -107,7 +108,7 @@ void morseText(char *text){ delay(1000); // } - Serial.println(globalSettings.cwSideToneFreq); + //Serial.println(globalSettings.cwSideToneFreq); while(*text){ morseLetter(*text++); } From 692c862b6eb8c6eab746f7616389d43038745ba1 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Fri, 17 Jan 2020 00:16:31 -0800 Subject: [PATCH 22/22] Load actual setting, not just the defaulted 0 --- ubitx_si5351.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ubitx_si5351.cpp b/ubitx_si5351.cpp index 3d378ab..8e900e0 100644 --- a/ubitx_si5351.cpp +++ b/ubitx_si5351.cpp @@ -49,7 +49,6 @@ uint32_t si5351bx_vcoa = (SI5351BX_XTAL*SI5351BX_MSA); // 25mhzXtal calibrate uint8_t si5351bx_rdiv = 0; // 0-7, CLK pin sees fout/(2**rdiv) uint8_t si5351bx_drive[3] = {3, 3, 3}; // 0=2ma 1=4ma 2=6ma 3=8ma for CLK 0,1,2 uint8_t si5351bx_clken = 0xFF; // Private, all CLK output drivers off -int32_t calibration = 0; void i2cWrite(uint8_t reg, uint8_t val) { // write reg via i2c Wire.beginTransmission(SI5351BX_ADDR); @@ -122,8 +121,7 @@ void si5351_set_calibration(int32_t cal){ void initOscillators(){ //initialize the SI5351 si5351bx_init(); - si5351bx_vcoa = (SI5351BX_XTAL * SI5351BX_MSA) + calibration; // apply the calibration correction factor - si5351bx_setfreq(0, globalSettings.usbCarrierFreq); + si5351_set_calibration(globalSettings.oscillatorCal); }