Refactor local oscillator cal

This commit is contained in:
Reed Nightingale 2020-01-19 18:40:11 -08:00
parent ec409d8805
commit d0900aa392
5 changed files with 102 additions and 125 deletions

View File

@ -23,7 +23,6 @@ void formatFreq(uint32_t freq, char* buff, uint16_t buff_size);
/* touch functions */
boolean readTouch();
void setupTouch();
void scaleTouch(struct Point *p);
// Color definitions

171
setup.cpp
View File

@ -1,9 +1,10 @@
#include <Arduino.h>
#include <EEPROM.h>
#include "freeRam.h"
#include "morse.h"
#include "nano_gui.h"
#include "setup.h"
#include "settings.h"
#include "ubitx.h"
#include "nano_gui.h"
/** Menus
* The Radio menus are accessed by tapping on the function button.
@ -85,43 +86,6 @@ struct SettingScreen_t {
void (*Finalize)(const long int final_value);
};
#define LIMIT(val,min,max) ((val) < (min)) ? (min) : (((max) < (val)) ? (max) : (val))
ssCwToneInitialize(long int* start_value_out)
{
*start_value_out = globalSettings.cwSideToneFreq;
}
ssCwToneValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = LIMIT(candidate_value_in,100,2000);
}
ssCwToneChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
globalSettings.cwSideToneFreq = new_value;
tone(CW_TONE, globalSettings.cwSideToneFreq);
ltoa(globalSettings.cwSideToneFreq,buff_out,10);
}
ssCwToneFinalize(const long int final_value)
{
noTone(CW_TONE);
globalSettings.cwSideToneFreq = final_value;
SaveSettingsToEeprom();
}
const char SS_EMPTY [] PROGMEM = "";
const char SS_CW_TONE [] PROGMEM = "Set CW Tone (Hz)";
const char SS_LONG_TEXT [] PROGMEM = "This is a long string of text that should be wrapped at least once, possibly more.";
const SettingScreen_t settingScreens [] PROGMEM = {
SS_CW_TONE,
SS_LONG_TEXT,
1,
10,
ssCwToneInitialize,
ssCwToneValidate,
ssCwToneChange,
ssCwToneFinalize
};
void runSetting(const SettingScreen_t* const screen);
void runToneSetting(){runSetting(&settingScreens[0]);}
void runSetting(const SettingScreen_t* const p_screen)
{
SettingScreen_t screen = {0};
@ -142,7 +106,7 @@ void runSetting(const SettingScreen_t* const p_screen)
screen.OnValueChange(last_value,b,sizeof(b));
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);
raw_value = last_value * screen.KnobDivider;
raw_value = last_value * (int32_t)screen.KnobDivider;
while (!btnDown())
{
@ -176,73 +140,96 @@ void runSetting(const SettingScreen_t* const p_screen)
screen.Finalize(last_value);
}
void printCarrierFreq(unsigned long freq)
#define LIMIT(val,min,max) ((val) < (min)) ? (min) : (((max) < (val)) ? (max) : (val))
ssCwToneInitialize(long int* start_value_out)
{
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);
*start_value_out = globalSettings.cwSideToneFreq;
}
ssCwToneValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = LIMIT(candidate_value_in,100,2000);
}
ssCwToneChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
globalSettings.cwSideToneFreq = new_value;
tone(CW_TONE, globalSettings.cwSideToneFreq);
ltoa(globalSettings.cwSideToneFreq,buff_out,10);
strcat_P(buff_out,(const char*)F("Hz"));
}
ssCwToneFinalize(const long int final_value)
{
noTone(CW_TONE);
globalSettings.cwSideToneFreq = final_value;
SaveSettingsToEeprom();
}
const char SS_CW_TONE_T [] PROGMEM = "Set CW Tone";
const char SS_CW_TONE_A [] PROGMEM = "Select a frequency that\nCW mode to tune for";
const SettingScreen_t ssTone PROGMEM = {
SS_CW_TONE_T,
SS_CW_TONE_A,
1,
10,
ssCwToneInitialize,
ssCwToneValidate,
ssCwToneChange,
ssCwToneFinalize
};
void runToneSetting(){runSetting(&ssTone);}
void setupFreq(){
//displayDialog(F("Set Frequency"),F("Push TUNE to Save"));
//round off the the nearest khz
void ssLocalOscInitialize(long int* start_value_out){
//round off the current frequency the nearest kHz
{
uint32_t freq = GetActiveVfoFreq();
freq = (freq/1000l)* 1000l;
freq = (freq/1000L) * 1000L;
setFrequency(freq);
si5351bx_setfreq(0, globalSettings.usbCarrierFreq); //set back the carrier oscillator, cw tx switches it off
}
strcpy_P(c,(const char*)F("You should have a"));
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);
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"));
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(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())
active_delay(100);
active_delay(100);
while (!btnDown())
{
int knob = enc_read();
if(knob != 0){
globalSettings.oscillatorCal += knob * 875;
}
else{
continue; //don't update the frequency or the display
}
si5351bx_setfreq(0, globalSettings.usbCarrierFreq); //set back the carrier oscillator anyway, cw tx switches it off
si5351_set_calibration(globalSettings.oscillatorCal);
setFrequency(GetActiveVfoFreq());
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);
*start_value_out = globalSettings.oscillatorCal;
Serial.println(freeRam());
}
void ssLocalOscValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = candidate_value_in;//No check - allow anything
}
void ssLocalOscChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
si5351_set_calibration(new_value);
setFrequency(GetActiveVfoFreq());
const long int u = abs(new_value);
if(new_value != u){
strcpy_P(buff_out,(const char*)F("-"));
++buff_out;
}
formatFreq(u,buff_out,buff_out_size);
strcat_P(buff_out,(const char*)F("Hz"));
}
void ssLocalOscFinalize(const long int final_value)
{
globalSettings.oscillatorCal = final_value;
SaveSettingsToEeprom();
initOscillators();
si5351_set_calibration(globalSettings.oscillatorCal);
setFrequency(GetActiveVfoFreq());
//debounce and delay
while(btnDown())
active_delay(50);
active_delay(100);
}
const char SS_LOCAL_OSC_T [] PROGMEM = "Set Local Osc Calibration";
const char SS_LOCAL_OSC_A [] PROGMEM = "Exit menu, tune so that the\ndial displays the desired freq,\nthen tune here until the\nsignal is zerobeat";
const SettingScreen_t ssLocalOsc PROGMEM = {
SS_LOCAL_OSC_T,
SS_LOCAL_OSC_A,
1,
875,
ssLocalOscInitialize,
ssLocalOscValidate,
ssLocalOscChange,
ssLocalOscFinalize
};
void runLocalOscSetting(){runSetting(&ssLocalOsc);}
void setupBFO(){
//displayDialog(F("Set BFO"),F("Press TUNE to Save"));
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
printCarrierFreq(globalSettings.usbCarrierFreq);
//printCarrierFreq(globalSettings.usbCarrierFreq);
while (!btnDown()){
int knob = enc_read();
@ -255,7 +242,7 @@ void setupBFO(){
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
setFrequency(GetActiveVfoFreq());
printCarrierFreq(globalSettings.usbCarrierFreq);
//printCarrierFreq(globalSettings.usbCarrierFreq);
active_delay(100);
}
@ -450,7 +437,7 @@ const char MI_SET_BFO [] PROGMEM = "Beat Frequency Osc (BFO)";
const char MI_TOUCH [] PROGMEM = "Touch Screen";
const MenuItem_t calibrationMenu [] PROGMEM {
{MT_CAL,nullptr},//Title
{MI_SET_FREQ,setupFreq},
{MI_SET_FREQ,runLocalOscSetting},
{MI_SET_BFO,setupBFO},
{MI_TOUCH,setupTouch},
};

View File

@ -92,10 +92,6 @@ extern char c[30], b[30];
#define HIGHEST_FREQ (30000000l)
static const uint32_t THRESHOLD_USB_LSB = 10000000L;
extern unsigned long firstIF;
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();
@ -122,11 +118,6 @@ void drawTx();
//are useful to concatanate the values with text like "Set Freq to " x " KHz"
int getValueByKnob(int minimum, int maximum, int step_size, int initial, char* prefix, char *postfix);
//functions of the setup menu. implemented in seteup.cpp
void doSetup2(); //main setup function, displays the setup menu, calls various dialog boxes
void setupBFO();
void setupFreq();
//main functions to check if any button is pressed and other user interface events
void doCommands(); //does the commands with encoder to jump from button to button
void checkTouch(); //does the commands with a touch on the buttons

View File

@ -1,7 +1,8 @@
#include <Arduino.h>
#include <EEPROM.h>
#include "freeRam.h"
#include "morse.h"
#include "settings.h"
#include "setup.h"
#include "ubitx.h"
#include "nano_gui.h"
@ -900,6 +901,7 @@ void doCommand(Button* button){
}
case BUTTON_MNU:
{
Serial.println(freeRam());
doSetup2();
break;
}
@ -953,20 +955,17 @@ void drawFocus(int ibtn, int color){
}
void doCommands(){
int select=0, i, prevButton, btnState;
int select = 0;
int prev_button = 0;
//wait for the button to be raised up
while(btnDown())
active_delay(50);
active_delay(50); //debounce
menuOn = 2;
while (menuOn){
while (true){
//check if the knob's button was pressed
btnState = btnDown();
if (btnState){
if (btnDown()){
Button button;
memcpy_P(&button, &(btn_set[select/10]), sizeof(Button));
@ -986,27 +985,27 @@ void doCommands(){
return;
}
i = enc_read();
int knob = enc_read();
if (i == 0){
if (knob == 0){
active_delay(50);
continue;
}
if (i > 0){
if (select + i < BUTTON_TOTAL * 10)
select += i;
if (knob > 0){
if (select + knob < BUTTON_TOTAL * 10)
select += knob;
}
if (i < 0 && select + i >= 0)
select += i; //caught ya, i is already -ve here, so you add it
if (knob < 0 && select + knob >= 0)
select += knob; //caught ya, i is already -ve here, so you add it
if (prevButton == select / 10)
if (prev_button == select / 10)
continue;
//we are on a new button
drawFocus(prevButton, COLOR_INACTIVE_BORDER);
drawFocus(prev_button, COLOR_INACTIVE_BORDER);
drawFocus(select/10, COLOR_ACTIVE_BORDER);
prevButton = select/10;
prev_button = select/10;
}
// guiUpdate();

View File

@ -31,6 +31,7 @@
*/
#include <Wire.h>
#include "settings.h"
#include "setup.h"
#include "ubitx.h"
#include "nano_gui.h"
@ -40,16 +41,16 @@
* created in a memory region called the stack. The stack has just a few bytes of space on the Arduino
* if you declare large strings inside functions, they can easily exceed the capacity of the stack
* and mess up your programs.
* We circumvent this by declaring a few global buffers as kitchen counters where we can
* We circumvent this by declaring a few global buffers as kitchen counters where we can
* slice and dice our strings. These strings are mostly used to control the display or handle
* the input and output from the USB port. We must keep a count of the bytes used while reading
* the serial port as we can easily run out of buffer space. This is done in the serial_in_count variable.
*/
char c[30], b[30];
char b[30];
char c[30];
//during CAT commands, we will freeeze the display until CAT is disengaged
unsigned char doingCAT = 0;
byte menuOn = 0; //set to 1 when the menu is being displayed, if a menu item sets it to zero, the menu is exited
/**
@ -463,7 +464,7 @@ void initPorts(){
void setup()
{
Serial.begin(38400);
Serial.flush();
Serial.flush();
initSettings();
displayInit();
@ -477,7 +478,7 @@ void setup()
setupTouch();
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
setFrequency(10000000L);
setupFreq();
runLocalOscSetting();
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
setFrequency(7100000L);
setupBFO();