ubitx-upr/ubitx_20/ubitx_menu.ino

573 lines
12 KiB
C++

/** Menus
* The Radio menus are accessed by tapping on the function button.
* - The main loop() constantly looks for a button press and calls doMenu() when it detects
* a function button press.
* - As the encoder is rotated, at every 10th pulse, the next or the previous menu
* item is displayed. Each menu item is controlled by it's own function.
* - Eache menu function may be called to display itself
* - Each of these menu routines is called with a button parameter.
* - The btn flag denotes if the menu itme was clicked on or not.
* - If the menu item is clicked on, then it is selected,
* - If the menu item is NOT clicked on, then the menu's prompt is to be displayed
*/
int menuBand(int btn){
int knob = 0;
int band;
unsigned long offset;
// band = frequency/1000000l;
// offset = frequency % 1000000l;
if (!btn){
printLine2("Band Select?");
return;
}
printLine2("Press to confirm");
//wait for the button menu select button to be lifted)
while (btnDown())
delay(50);
delay(50);
ritDisable();
while(!btnDown()){
knob = enc_read();
if (knob != 0){
/*
if (band > 3 && knob < 0)
band--;
if (band < 30 && knob > 0)
band++;
if (band > 10)
isUSB = true;
else
isUSB = false;
setFrequency(((unsigned long)band * 1000000l) + offset); */
if (knob < 0 && frequency > 3000000l)
setFrequency(frequency - 200000l);
if (knob > 0 && frequency < 30000000l)
setFrequency(frequency + 200000l);
if (frequency > 10000000l)
isUSB = true;
else
isUSB = false;
updateDisplay();
}
delay(20);
}
while(btnDown())
delay(50);
delay(50);
printLine2("");
updateDisplay();
menuOn = 0;
}
void menuVfoToggle(int btn){
if (!btn){
if (vfoActive == VFO_A)
printLine2("Select VFO B? ");
else
printLine2("Select VFO A? ");
}
else {
if (vfoActive == VFO_B){
vfoB = frequency;
EEPROM.put(VFO_B, frequency);
vfoActive = VFO_A;
printLine2("Selected VFO A ");
frequency = vfoA;
}
else {
vfoA = frequency;
EEPROM.put(VFO_A, frequency);
vfoActive = VFO_B;
printLine2("Selected VFO B ");
frequency = vfoB;
}
ritDisable();
setFrequency(frequency);
if (frequency >= 10000000l)
isUSB = true;
else
isUSB = false;
updateDisplay();
printLine2("");
delay(1000);
//exit the menu
menuOn = 0;
}
}
void menuRitToggle(int btn){
if (!btn){
if (ritOn == 1)
printLine2("RIT:On, Off? ");
else
printLine2("RIT:Off, On? ");
}
else {
if (ritOn == 0){
printLine2("RIT is ON");
//enable RIT so the current frequency is used at transmit
ritEnable(frequency);
}
else{
printLine2("RIT is OFF");
ritDisable();
}
menuOn = 0;
delay(500);
printLine2("");
updateDisplay();
}
}
void menuSidebandToggle(int btn){
if (!btn){
if (isUSB == true)
printLine2("Select LSB?");
else
printLine2("Select USB?");
}
else {
if (isUSB == true){
isUSB = false;
printLine2("LSB Selected");
delay(500);
printLine2("");
}
else {
isUSB = true;
printLine2("USB Selected");
delay(500);
printLine2("");
}
updateDisplay();
menuOn = 0;
}
}
/**
* The calibration routines are not normally shown in the menu as they are rarely used
* They can be enabled by choosing this menu option
*/
void menuSetup(int btn){
if (!btn){
if (!modeCalibrate)
printLine2("Setup On?");
else
printLine2("Setup Off?");
}else {
if (!modeCalibrate){
modeCalibrate = true;
printLine2("Setup:On ");
}
else {
modeCalibrate = false;
printLine2("Setup:Off ");
}
delay(2000);
printLine2("");
menuOn = 0;
}
}
void menuExit(int btn){
if (!btn){
printLine2("Exit Menu? ");
}
else{
printLine2("Exiting menu");
delay(300);
printLine2("");
updateDisplay();
menuOn = 0;
}
}
int menuCWSpeed(int btn){
int knob = 0;
int wpm;
wpm = 1200/cwSpeed;
if (!btn){
strcpy(b, "CW:");
itoa(wpm,c, 10);
strcat(b, c);
strcat(b, "WPM Change?");
printLine2(b);
return;
}
printLine1("Press PTT to set");
strcpy(b, "WPM:");
itoa(wpm,c, 10);
strcat(b, c);
printLine2(b);
delay(300);
while(!btnDown() && digitalRead(PTT) == HIGH){
knob = enc_read();
if (knob != 0){
if (wpm > 3 && knob < 0)
wpm--;
if (wpm < 50 && knob > 0)
wpm++;
strcpy(b, "WPM:");
itoa(wpm,c, 10);
strcat(b, c);
printLine2(b);
}
//abort if this button is down
if (btnDown())
//re-enable the clock1 and clock 2
break;
}
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("CW Speed set!");
cwSpeed = 1200/wpm;
EEPROM.put(CW_SPEED, cwSpeed);
delay(2000);
}
printLine2("");
menuOn = 0;
}
/**
* Take a deep breath, math(ematics) ahead
* The 25 mhz oscillator is multiplied by 35 to run the vco at 875 mhz
* This is divided by a number to generate different frequencies.
* If we divide it by 875, we will get 1 mhz signal
* So, if the vco is shifted up by 875 hz, the generated frequency of 1 mhz is shifted by 1 hz (875/875)
* At 12 Mhz, the carrier will needed to be shifted down by 12 hz for every 875 hz of shift up of the vco
*
*/
//this is used by the si5351 routines in the ubitx_5351 file
extern int32_t calibration;
extern uint32_t si5351bx_vcoa;
int factoryCalibration(int btn){
int knob = 0;
int32_t prev_calibration;
//keep clear of any previous button press
while (btnDown())
delay(100);
delay(100);
if (!btn){
printLine2("Set Calibration?");
return 0;
}
prev_calibration = calibration;
calibration = 0;
isUSB = true;
//turn off the second local oscillator and the bfo
si5351_set_calibration(calibration);
startTx(TX_CW);
si5351bx_setfreq(2, 10000000l);
strcpy(b, "#1 10 MHz cal:");
ltoa(calibration/8750, c, 10);
strcat(b, c);
printLine2(b);
while (!btnDown())
{
if (digitalRead(PTT) == LOW && !keyDown)
cwKeydown();
if (digitalRead(PTT) == HIGH && keyDown)
cwKeyUp();
knob = enc_read();
if (knob > 0)
calibration += 875;
else if (knob < 0)
calibration -= 875;
else
continue; //don't update the frequency or the display
si5351_set_calibration(calibration);
si5351bx_setfreq(2, 10000000l);
strcpy(b, "#1 10 MHz cal:");
ltoa(calibration/8750, c, 10);
strcat(b, c);
printLine2(b);
}
cwTimeout = 0;
keyDown = 0;
stopTx();
printLine2("Calibration set!");
EEPROM.put(MASTER_CAL, calibration);
initOscillators();
setFrequency(frequency);
updateDisplay();
while(btnDown())
delay(50);
delay(100);
}
int menuSetupCalibration(int btn){
int knob = 0;
int32_t prev_calibration;
if (!btn){
printLine2("Set Calibration?");
return 0;
}
printLine1("Set to Zero-beat,");
printLine2("press PTT to save");
delay(1000);
prev_calibration = calibration;
calibration = 0;
si5351_set_calibration(calibration);
setFrequency(frequency);
strcpy(b, "cal:");
ltoa(calibration/8750, c, 10);
strcat(b, c);
printLine2(b);
while (digitalRead(PTT) == HIGH && !btnDown())
{
knob = enc_read();
if (knob > 0){
calibration += 8750;
usbCarrier += 120;
}
else if (knob < 0){
calibration -= 8750;
usbCarrier -= 120;
}
else
continue; //don't update the frequency or the display
si5351_set_calibration(calibration);
si5351bx_setfreq(0, usbCarrier);
setFrequency(frequency);
strcpy(b, "cal:");
ltoa(calibration/8750, c, 10);
strcat(b, c);
printLine2(b);
}
//save the setting
if (digitalRead(PTT) == LOW){
printLine1("Calibration set!");
printLine2("Set Carrier now");
EEPROM.put(MASTER_CAL, calibration);
delay(2000);
}
else
calibration = prev_calibration;
printLine2("");
initOscillators();
//si5351_set_calibration(calibration);
setFrequency(frequency);
updateDisplay();
menuOn = 0;
}
void printCarrierFreq(unsigned long freq){
memset(c, 0, sizeof(c));
memset(b, 0, sizeof(b));
ultoa(freq, b, DEC);
strncat(c, b, 2);
strcat(c, ".");
strncat(c, &b[2], 3);
strcat(c, ".");
strncat(c, &b[5], 1);
printLine2(c);
}
void menuSetupCarrier(int btn){
int knob = 0;
unsigned long prevCarrier;
if (!btn){
printLine2("Set the BFO");
return;
}
prevCarrier = usbCarrier;
printLine1("Tune to best Signal");
printLine2("PTT to confirm. ");
delay(1000);
usbCarrier = 11995000l;
si5351bx_setfreq(0, usbCarrier);
printCarrierFreq(usbCarrier);
//disable all clock 1 and clock 2
while (digitalRead(PTT) == HIGH && !btnDown())
{
knob = enc_read();
if (knob > 0)
usbCarrier -= 50;
else if (knob < 0)
usbCarrier += 50;
else
continue; //don't update the frequency or the display
si5351bx_setfreq(0, usbCarrier);
printCarrierFreq(usbCarrier);
delay(100);
}
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("Carrier set! ");
EEPROM.put(USB_CAL, usbCarrier);
delay(1000);
}
else
usbCarrier = prevCarrier;
si5351bx_setfreq(0, usbCarrier);
setFrequency(frequency);
updateDisplay();
printLine2("");
menuOn = 0;
}
void menuSetupCwTone(int btn){
int knob = 0;
int prev_sideTone;
if (!btn){
printLine2("Change CW Tone");
return;
}
prev_sideTone = sideTone;
printLine1("Tune CW tone");
printLine2("PTT to confirm. ");
delay(1000);
tone(CW_TONE, sideTone);
//disable all clock 1 and clock 2
while (digitalRead(PTT) == LOW || !btnDown())
{
knob = enc_read();
if (knob > 0 && sideTone < 2000)
sideTone += 10;
else if (knob < 0 && sideTone > 100 )
sideTone -= 10;
else
continue; //don't update the frequency or the display
tone(CW_TONE, sideTone);
itoa(sideTone, b, 10);
printLine2(b);
delay(100);
}
noTone(CW_TONE);
//save the setting
if (digitalRead(PTT) == LOW){
printLine2("Sidetone set! ");
EEPROM.put(CW_SIDETONE, usbCarrier);
delay(2000);
}
else
sideTone = prev_sideTone;
printLine2("");
updateDisplay();
menuOn = 0;
}
void doMenu(){
int select=0, i,btnState;
//wait for the button to be raised up
while(btnDown())
delay(50);
delay(50); //debounce
menuOn = 2;
while (menuOn){
i = enc_read();
btnState = btnDown();
if (i > 0){
if (modeCalibrate && select + i < 110)
select += i;
if (!modeCalibrate && select + i < 70)
select += i;
}
if (i < 0 && select - i >= 0)
select += i; //caught ya, i is already -ve here, so you add it
if (select < 10)
menuBand(btnState);
else if (select < 20)
menuRitToggle(btnState);
else if (select < 30)
menuVfoToggle(btnState);
else if (select < 40)
menuSidebandToggle(btnState);
else if (select < 50)
menuCWSpeed(btnState);
else if (select < 60)
menuSetup(btnState);
else if (select < 70 && !modeCalibrate)
menuExit(btnState);
else if (select < 80 && modeCalibrate)
menuSetupCalibration(btnState); //crystal
else if (select < 90 && modeCalibrate)
menuSetupCarrier(btnState); //lsb
else if (select < 100 && modeCalibrate)
menuSetupCwTone(btnState);
else if (select < 110 && modeCalibrate)
menuExit(btnState);
}
//debounce the button
while(btnDown())
delay(50);
delay(50);
}