573 lines
12 KiB
Arduino
573 lines
12 KiB
Arduino
|
/** 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);
|
||
|
}
|
||
|
|