Merge pull request #3 from reedbn/menu-refactor

Menu refactor
This commit is contained in:
reedbn 2020-01-19 22:36:37 -08:00 committed by GitHub
commit 59347af9ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 534 additions and 439 deletions

View File

@ -145,6 +145,7 @@ public:
static void drawChar(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size); static void drawChar(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size);
static void drawCharGFX(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size); static void drawCharGFX(coord_t x, coord_t y, unsigned char c, color_t color, color_t bg, uint8_t size);
static inline void setCursor(coord_t x, coord_t y); static inline void setCursor(coord_t x, coord_t y);
static inline void setBound(coord_t x, coord_t y);
static inline void setTextColor(color_t c); static inline void setTextColor(color_t c);
static inline void setTextColor(color_t c, color_t bg); static inline void setTextColor(color_t c, color_t bg);
static inline void setTextSize(uint8_t s); static inline void setTextSize(uint8_t s);
@ -157,8 +158,8 @@ public:
static inline uint8_t getRotation() __attribute__ ((always_inline)) { return rotation; } static inline uint8_t getRotation() __attribute__ ((always_inline)) { return rotation; }
static inline coord_t getCursorX() __attribute__ ((always_inline)) { return cursor_x; } static inline coord_t getCursorX() __attribute__ ((always_inline)) { return cursor_x; }
static inline coord_t getCursorY() __attribute__ ((always_inline)) { return cursor_y; } static inline coord_t getCursorY() __attribute__ ((always_inline)) { return cursor_y; }
static inline void getTextBounds(char *string, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); static inline void getTextBounds(char *string, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi = _width);
static inline void getTextBounds(const __FlashStringHelper *s, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); static inline void getTextBounds(const __FlashStringHelper *s, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi = _width);
virtual size_t write(uint8_t); // used by Arduino "Print.h" (and the one required virtual function) virtual size_t write(uint8_t); // used by Arduino "Print.h" (and the one required virtual function)
@ -167,6 +168,7 @@ protected:
static coord_t WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes static coord_t WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes
static coord_t _width, _height; // Display w/h as modified by current rotation static coord_t _width, _height; // Display w/h as modified by current rotation
static coord_t cursor_x, cursor_y; static coord_t cursor_x, cursor_y;
static coord_t bound_x1, bound_x2;
static color_t textcolor, textbgcolor; static color_t textcolor, textbgcolor;
static uint8_t textsize; static uint8_t textsize;
static uint8_t rotation; static uint8_t rotation;
@ -216,6 +218,10 @@ int16_t PDQ_GFX<HW>::cursor_x;
template<class HW> template<class HW>
int16_t PDQ_GFX<HW>::cursor_y; int16_t PDQ_GFX<HW>::cursor_y;
template<class HW> template<class HW>
int16_t PDQ_GFX<HW>::bound_x1;
template<class HW>
int16_t PDQ_GFX<HW>::bound_x2;
template<class HW>
color_t PDQ_GFX<HW>::textcolor; color_t PDQ_GFX<HW>::textcolor;
template<class HW> template<class HW>
color_t PDQ_GFX<HW>::textbgcolor; color_t PDQ_GFX<HW>::textbgcolor;
@ -239,6 +245,8 @@ PDQ_GFX<HW>::PDQ_GFX(coord_t w, coord_t h)
_height = (int16_t)h; _height = (int16_t)h;
cursor_x = 0; cursor_x = 0;
cursor_y = 0; cursor_y = 0;
bound_x1 = 0;
bound_x2 = WIDTH;
rotation = 0; rotation = 0;
textsize = 1; textsize = 1;
textcolor = 0xffff; textcolor = 0xffff;
@ -740,7 +748,7 @@ size_t PDQ_GFX<HW>::write(uint8_t c)
{ {
if(c == '\n') if(c == '\n')
{ {
cursor_x = 0; cursor_x = bound_x1;
cursor_y += (coord_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance); cursor_y += (coord_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} }
else if (c != '\r') else if (c != '\r')
@ -756,10 +764,10 @@ size_t PDQ_GFX<HW>::write(uint8_t c)
if ((w > 0) && (h > 0)) if ((w > 0) && (h > 0))
{ {
coord_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic coord_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
if(wrap && ((cursor_x + textsize * (xo + w)) >= _width)) if(wrap && ((cursor_x + textsize * (xo + w)) >= bound_x2))
{ {
// Drawing character would go off right edge; wrap to new line // Drawing character would go off right edge; wrap to new line
cursor_x = 0; cursor_x = bound_x1;
cursor_y += (coord_t)textsize * cursor_y += (coord_t)textsize *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance); (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} }
@ -970,6 +978,13 @@ void PDQ_GFX<HW>::setCursor(coord_t x, coord_t y)
cursor_y = (int16_t)y; cursor_y = (int16_t)y;
} }
template<class HW>
void PDQ_GFX<HW>::setBound(coord_t x1, coord_t x2)
{
bound_x1 = (int16_t)x1;
bound_x2 = (int16_t)x2;
}
template<class HW> template<class HW>
void PDQ_GFX<HW>::setTextSize(uint8_t s) void PDQ_GFX<HW>::setTextSize(uint8_t s)
{ {
@ -1046,10 +1061,13 @@ void PDQ_GFX<HW>::setFont(const GFXfont *f)
// Pass string and a cursor position, returns UL corner and W,H. // Pass string and a cursor position, returns UL corner and W,H.
template<class HW> template<class HW>
void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi)
{ {
uint8_t c; // Current character uint8_t c; // Current character
coord_t xs = x;
coord_t xe = xs+wi;
*x1 = x; *x1 = x;
*y1 = y; *y1 = y;
*w = *h = 0; *w = *h = 0;
@ -1080,9 +1098,9 @@ void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, in
xa = pgm_read_byte(&glyph->xAdvance); xa = pgm_read_byte(&glyph->xAdvance);
xo = pgm_read_byte(&glyph->xOffset); xo = pgm_read_byte(&glyph->xOffset);
yo = pgm_read_byte(&glyph->yOffset); yo = pgm_read_byte(&glyph->yOffset);
if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= _width)) // Line wrap if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= xe)) // Line wrap
{ {
x = 0; // Reset x to 0 x = xs; // Reset x to 0
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
gx1 = x + xo * ts; gx1 = x + xo * ts;
@ -1103,7 +1121,7 @@ void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, in
} }
else // Newline else // Newline
{ {
x = 0; // Reset x x = xs; // Reset x
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
} }
@ -1158,10 +1176,12 @@ void PDQ_GFX<HW>::getTextBounds(char *str, coord_t x, coord_t y, int16_t *x1, in
// Same as above, but for PROGMEM strings // Same as above, but for PROGMEM strings
template<class HW> template<class HW>
void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h, coord_t wi)
{ {
uint8_t *s = (uint8_t *)str; uint8_t *s = (uint8_t *)str;
uint8_t c; uint8_t c;
coord_t xs = x;
coord_t xe = xs+wi;
*x1 = x; *x1 = x;
*y1 = y; *y1 = y;
@ -1194,9 +1214,9 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
xa = pgm_read_byte(&glyph->xAdvance); xa = pgm_read_byte(&glyph->xAdvance);
xo = pgm_read_byte(&glyph->xOffset); xo = pgm_read_byte(&glyph->xOffset);
yo = pgm_read_byte(&glyph->yOffset); yo = pgm_read_byte(&glyph->yOffset);
if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= _width)) // Line wrap if (wrap && ((x + (((int16_t)xo + gw) * ts)) >= xe)) // Line wrap
{ {
x = 0; // Reset x to 0 x = xs; // Reset x to 0
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
gx1 = x + xo * ts; gx1 = x + xo * ts;
@ -1217,7 +1237,7 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
} }
else // Newline else // Newline
{ {
x = 0; // Reset x x = xs; // Reset x
y += ya; // Advance y by 1 line y += ya; // Advance y by 1 line
} }
} }

View File

@ -56,12 +56,12 @@ static const PROGMEM struct Morse morse_table[] = {
{'?', 0x8c}, // 10001100 {'?', 0x8c}, // 10001100
}; };
static void morseLetter(char c){ static void morseLetter(char c, uint16_t dit_duration_ms){
unsigned char mask = 0x80; unsigned char mask = 0x80;
//handle space character as three dashes //handle space character as three dashes
if (c == ' '){ if (c == ' '){
active_delay(9 * globalSettings.cwDitDurationMs); active_delay(7 * dit_duration_ms);
//Serial.print(' '); //Serial.print(' ');
return; return;
} }
@ -81,36 +81,28 @@ static void morseLetter(char c){
while(mask){ while(mask){
tone(CW_TONE, globalSettings.cwSideToneFreq,10000); tone(CW_TONE, globalSettings.cwSideToneFreq,10000);
if (mask & code){ if (mask & code){
delay(3 * globalSettings.cwDitDurationMs); delay(3 * dit_duration_ms);
//Serial.print('-'); //Serial.print('-');
} }
else{ else{
delay(globalSettings.cwDitDurationMs); delay(dit_duration_ms);
//Serial.print('.'); //Serial.print('.');
} }
//Serial.print('#'); //Serial.print('#');
noTone(CW_TONE); noTone(CW_TONE);
delay(globalSettings.cwDitDurationMs); // space between dots and dashes delay(dit_duration_ms); // space between dots and dashes
mask = mask >> 1; mask = mask >> 1;
} }
//Serial.println('@'); //Serial.println('@');
delay(2*globalSettings.cwDitDurationMs); // space between letters is a dash (3 dots), one dot's space has already been sent delay(2*dit_duration_ms); // 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 break;//We've played the letter, so don't bother checking the rest of the list
} }
} }
} }
void morseText(char *text){ void morseText(char *text, uint16_t dit_duration_ms){
// while (1){
noTone(CW_TONE);
delay(1000);
tone(CW_TONE, 600);
delay(1000);
// }
//Serial.println(globalSettings.cwSideToneFreq);
while(*text){ while(*text){
morseLetter(*text++); morseLetter(*text++, dit_duration_ms);
} }
} }

View File

@ -1,3 +1,3 @@
#include "settings.h"
//sends out morse code at the speed set by cwSpeed //sends out morse code at the speed set by cwSpeed
extern int cwSpeed; //this is actuall the dot period in milliseconds void morseText(char *text, uint16_t dit_duration_ms = globalSettings.cwDitDurationMs);
void morseText(char *text);

View File

@ -178,7 +178,7 @@ void displayInit(void){
tft.begin(); tft.begin();
tft.setFont(ubitx_font); tft.setFont(ubitx_font);
tft.setTextWrap(false); tft.setTextWrap(true);
tft.setTextColor(DISPLAY_GREEN,DISPLAY_BLACK); tft.setTextColor(DISPLAY_GREEN,DISPLAY_BLACK);
tft.setTextSize(1); tft.setTextSize(1);
tft.setRotation(1); tft.setRotation(1);
@ -217,6 +217,14 @@ 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 displayRawText(char *text, int x1, int y1, int color, int background){
tft.setTextColor(color,background); tft.setTextColor(color,background);
tft.setCursor(x1,y1); tft.setCursor(x1,y1);
tft.setBound(0,320);
tft.print(text);
}
void displayRawText(char *text, int x1, int y1, int w, int color, int background){
tft.setTextColor(color,background);
tft.setCursor(x1,y1);
tft.setBound(x1,x1+w);
tft.print(text); tft.print(text);
} }
@ -228,10 +236,10 @@ void displayText(char *text, int x1, int y1, int w, int h, int color, int backgr
int16_t y1_out; int16_t y1_out;
uint16_t width_out; uint16_t width_out;
uint16_t height_out; uint16_t height_out;
tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out); tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out,w);
x1 += (w - ( width_out + (x1_out-x1)))/2; x1 += (w - ( (int32_t)width_out + (x1_out-x1)))/2;
y1 += h - (h - height_out)/2; y1 += (ubitx_font->yAdvance + h - ( (int32_t)height_out + (y1_out-y1)))/2;
displayRawText(text,x1,y1,color,background); displayRawText(text,x1,y1,w,color,background);
} }
void setupTouch(){ void setupTouch(){

View File

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

683
setup.cpp
View File

@ -1,9 +1,9 @@
#include <Arduino.h> #include <Arduino.h>
#include <EEPROM.h>
#include "morse.h" #include "morse.h"
#include "nano_gui.h"
#include "setup.h"
#include "settings.h" #include "settings.h"
#include "ubitx.h" #include "ubitx.h"
#include "nano_gui.h"
/** Menus /** Menus
* The Radio menus are accessed by tapping on the function button. * The Radio menus are accessed by tapping on the function button.
@ -18,13 +18,6 @@
* - If the menu item is NOT clicked on, then the menu's prompt is to be displayed * - If the menu item is NOT clicked on, then the menu's prompt is to be displayed
*/ */
void setupExit(){
menuOn = 0;
}
//this is used by the si5351 routines in the ubitx_5351 file
extern uint32_t si5351bx_vcoa;
static const unsigned int COLOR_TEXT = DISPLAY_WHITE; static const unsigned int COLOR_TEXT = DISPLAY_WHITE;
static const unsigned int COLOR_BACKGROUND = DISPLAY_BLACK; static const unsigned int COLOR_BACKGROUND = DISPLAY_BLACK;
static const unsigned int COLOR_TITLE_BACKGROUND = DISPLAY_NAVY; static const unsigned int COLOR_TITLE_BACKGROUND = DISPLAY_NAVY;
@ -58,277 +51,461 @@ static const unsigned int LAYOUT_SETTING_VALUE_Y = LAYOUT_ITEM_Y + 3*LAYOUT_ITEM
static const unsigned int LAYOUT_SETTING_VALUE_WIDTH = LAYOUT_ITEM_WIDTH; static const unsigned int LAYOUT_SETTING_VALUE_WIDTH = LAYOUT_ITEM_WIDTH;
static const unsigned int LAYOUT_SETTING_VALUE_HEIGHT = LAYOUT_ITEM_HEIGHT; static const unsigned int LAYOUT_SETTING_VALUE_HEIGHT = LAYOUT_ITEM_HEIGHT;
static const unsigned int LAYOUT_INSTRUCTION_TEXT_X = 20; static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_X = 20;
static const unsigned int LAYOUT_INSTRUCTION_TEXT_Y = LAYOUT_ITEM_Y + 5*LAYOUT_ITEM_PITCH_Y; static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_Y = LAYOUT_ITEM_Y;
static const unsigned int LAYOUT_INSTRUCTION_TEXT_WIDTH = LAYOUT_ITEM_WIDTH; static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_WIDTH = LAYOUT_ITEM_WIDTH;
static const unsigned int LAYOUT_INSTRUCTION_TEXT_HEIGHT = LAYOUT_ITEM_HEIGHT; static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_HEIGHT = LAYOUT_SETTING_VALUE_Y - LAYOUT_ITEM_Y - 1;
void displayDialog(const __FlashStringHelper* title, const __FlashStringHelper* instructions){ static const unsigned int LAYOUT_CONFIRM_TEXT_X = 20;
strcpy_P(b,(const char*)title); static const unsigned int LAYOUT_CONFIRM_TEXT_Y = LAYOUT_ITEM_Y + 5*LAYOUT_ITEM_PITCH_Y;
strcpy_P(c,(const char*)instructions); static const unsigned int LAYOUT_CONFIRM_TEXT_WIDTH = LAYOUT_ITEM_WIDTH;
static const unsigned int LAYOUT_CONFIRM_TEXT_HEIGHT = LAYOUT_ITEM_HEIGHT;
void displayDialog(const char* title,
const char* instructions){
displayClear(COLOR_BACKGROUND); displayClear(COLOR_BACKGROUND);
displayRect(LAYOUT_OUTER_BORDER_X,LAYOUT_OUTER_BORDER_Y,LAYOUT_OUTER_BORDER_WIDTH,LAYOUT_OUTER_BORDER_HEIGHT, COLOR_ACTIVE_BORDER); displayRect(LAYOUT_OUTER_BORDER_X,LAYOUT_OUTER_BORDER_Y,LAYOUT_OUTER_BORDER_WIDTH,LAYOUT_OUTER_BORDER_HEIGHT, COLOR_ACTIVE_BORDER);
displayRect(LAYOUT_INNER_BORDER_X,LAYOUT_INNER_BORDER_Y,LAYOUT_INNER_BORDER_WIDTH,LAYOUT_INNER_BORDER_HEIGHT, COLOR_ACTIVE_BORDER); displayRect(LAYOUT_INNER_BORDER_X,LAYOUT_INNER_BORDER_Y,LAYOUT_INNER_BORDER_WIDTH,LAYOUT_INNER_BORDER_HEIGHT, COLOR_ACTIVE_BORDER);
strncpy_P(b,title,sizeof(b));
displayText(b, LAYOUT_TITLE_X, LAYOUT_TITLE_Y, LAYOUT_TITLE_WIDTH, LAYOUT_TITLE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_ACTIVE_BORDER); displayText(b, LAYOUT_TITLE_X, LAYOUT_TITLE_Y, LAYOUT_TITLE_WIDTH, LAYOUT_TITLE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_ACTIVE_BORDER);
displayText(c, LAYOUT_INSTRUCTION_TEXT_X, LAYOUT_INSTRUCTION_TEXT_Y, LAYOUT_INSTRUCTION_TEXT_WIDTH, LAYOUT_INSTRUCTION_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); strncpy_P(b,instructions,sizeof(b));
displayText(b, LAYOUT_INSTRUCTIONS_TEXT_X, LAYOUT_INSTRUCTIONS_TEXT_Y, LAYOUT_INSTRUCTIONS_TEXT_WIDTH, LAYOUT_INSTRUCTIONS_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
strncpy_P(b,(const char*)F("Push Tune to Save"),sizeof(b));
displayText(b, LAYOUT_CONFIRM_TEXT_X, LAYOUT_CONFIRM_TEXT_Y, LAYOUT_CONFIRM_TEXT_WIDTH, LAYOUT_CONFIRM_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
} }
void printCarrierFreq(unsigned long freq) struct SettingScreen_t {
const char* const Title;
const char* const AdditionalText;
const uint16_t KnobDivider;
const int16_t StepSize;//int so that it can be negative
void (*Initialize)(long int* start_value_out);
void (*Validate)(const long int candidate_value_in, long int* validated_value_out);
void (*OnValueChange)(const long int new_value, char* buff_out, const size_t buff_out_size);
void (*Finalize)(const long int final_value);
};
void runSetting(const SettingScreen_t* const p_screen)
{ {
formatFreq(freq,c,sizeof(c)); SettingScreen_t screen = {0};
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); memcpy_P(&screen,p_screen,sizeof(screen));
} displayDialog(screen.Title,
screen.AdditionalText);
void setupFreq(){ //Wait for button to stop being pressed
displayDialog(F("Set Frequency"),F("Push TUNE to Save")); while(btnDown()){
active_delay(10);
//round off the the nearest khz
{
uint32_t freq = GetActiveVfoFreq();
freq = (freq/1000l)* 1000l;
setFrequency(freq);
} }
active_delay(10);
strcpy_P(c,(const char*)F("You should have a")); long int raw_value = 0;
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_ITEM_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); long int last_value = 0;
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); screen.Initialize(&last_value);
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); 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()) raw_value = last_value * (int32_t)screen.KnobDivider;
active_delay(100);
active_delay(100);
while (!btnDown()) while (!btnDown())
{ {
int knob = enc_read(); int knob = enc_read();
if(knob != 0){ if(knob != 0){
globalSettings.oscillatorCal += knob * 875; raw_value += knob * screen.StepSize;
} }
else{ 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);
}
SaveSettingsToEeprom();
initOscillators();
si5351_set_calibration(globalSettings.oscillatorCal);
setFrequency(GetActiveVfoFreq());
//debounce and delay
while(btnDown())
active_delay(50);
active_delay(100);
}
void setupBFO(){
displayDialog(F("Set BFO"),F("Press TUNE to Save"));
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
printCarrierFreq(globalSettings.usbCarrierFreq);
while (!btnDown()){
int knob = enc_read();
if(knob != 0){
globalSettings.usbCarrierFreq -= 50 * knob;
}
else{
continue; //don't update the frequency or the display
}
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
setFrequency(GetActiveVfoFreq());
printCarrierFreq(globalSettings.usbCarrierFreq);
active_delay(100);
}
SaveSettingsToEeprom();
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
setFrequency(GetActiveVfoFreq());
}
void setupCwDelay(){
int knob = 0;
int prev_cw_delay;
displayDialog(F("Set CW T/R Delay"),F("Press tune to Save"));
active_delay(500);
prev_cw_delay = globalSettings.cwActiveTimeoutMs;
ltoa(globalSettings.cwActiveTimeoutMs, b, 10);
strcat_P(b,(const char*)F(" msec"));
displayText(b, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
while (!btnDown()){
knob = enc_read();
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
ltoa(globalSettings.cwActiveTimeoutMs, b, 10);
strcat_P(b,(const char*)F(" msec"));
displayText(b, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
}
SaveSettingsToEeprom();
active_delay(500);
setupExit();
}
void setupKeyer(){
displayDialog(F("Set CW Keyer"),F("Press tune to Save"));
if(KeyerMode_e::KEYER_STRAIGHT == globalSettings.keyerMode){
strcpy_P(c,(const char*)F("< Hand Key >"));
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
}
else if(KeyerMode_e::KEYER_IAMBIC_A == globalSettings.keyerMode){
strcpy_P(c,(const char*)F("< Iambic A >"));
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
}
else{
strcpy_P(c,(const char*)F("< Iambic B >"));
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
}
int knob = 0;
uint32_t tmp_mode = globalSettings.keyerMode;
while (!btnDown())
{
knob = enc_read();
if(knob == 0){
active_delay(50);
continue; continue;
} }
if(knob < 0 && tmp_mode > KeyerMode_e::KEYER_STRAIGHT){
tmp_mode--; const long int candidate_value = raw_value / (int32_t)screen.KnobDivider;
} long int value = 0;
if(knob > 0 && tmp_mode < KeyerMode_e::KEYER_IAMBIC_B){ screen.Validate(candidate_value,&value);
tmp_mode++;
//If we're going out of bounds, prevent the raw value from going too far out
if(candidate_value != value){
raw_value = value * (int32_t)screen.KnobDivider;
} }
if (KeyerMode_e::KEYER_STRAIGHT == tmp_mode){ if(value == last_value){
strcpy_P(c,(const char*)F("< Hand Key >")); continue;
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
} }
else if(KeyerMode_e::KEYER_IAMBIC_A == tmp_mode){ else{
strcpy_P(c,(const char*)F("< Iambic A >")); screen.OnValueChange(value,b,sizeof(b));
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND); 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);
} last_value = value;
else if (KeyerMode_e::KEYER_IAMBIC_B == tmp_mode){
strcpy_P(c,(const char*)F("< Iambic B >"));
displayText(c, LAYOUT_SETTING_VALUE_X, LAYOUT_SETTING_VALUE_Y, LAYOUT_SETTING_VALUE_WIDTH, LAYOUT_SETTING_VALUE_HEIGHT, COLOR_TEXT, COLOR_SETTING_BACKGROUND, COLOR_BACKGROUND);
} }
} }
active_delay(500); screen.Finalize(last_value);
}
globalSettings.keyerMode = tmp_mode; #define LIMIT(val,min,max) ((val) < (min)) ? (min) : (((max) < (val)) ? (max) : (val))
//Local Oscillator
void ssLocalOscInitialize(long int* start_value_out){
{
uint32_t freq = GetActiveVfoFreq();
freq = (freq/1000L) * 1000L;//round off the current frequency the nearest kHz
setFrequency(freq);
si5351bx_setfreq(0, globalSettings.usbCarrierFreq); //set back the carrier oscillator, cw tx switches it off
}
*start_value_out = globalSettings.oscillatorCal;
}
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){
strncpy_P(buff_out,(const char*)F("-"),buff_out_size);
++buff_out;
}
formatFreq(u,buff_out,buff_out_size - strlen(buff_out));
strncat_P(buff_out,(const char*)F("Hz"),buff_out_size - strlen(buff_out));
}
void ssLocalOscFinalize(const long int final_value)
{
globalSettings.oscillatorCal = final_value;
SaveSettingsToEeprom(); SaveSettingsToEeprom();
si5351_set_calibration(globalSettings.oscillatorCal);
setupExit(); setFrequency(GetActiveVfoFreq());
} }
const char SS_LOCAL_OSC_T [] PROGMEM = "Local Oscillator";
const char MI_SET_FREQ [] PROGMEM = "Set Freq..."; 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 char MI_SET_BFO [] PROGMEM = "Set BFO..."; const SettingScreen_t ssLocalOsc PROGMEM = {
const char MI_CW_DELAY [] PROGMEM = "CW Delay..."; SS_LOCAL_OSC_T,
const char MI_CW_KEYER [] PROGMEM = "CW Keyer..."; SS_LOCAL_OSC_A,
const char MI_TOUCH [] PROGMEM = "Touch Screen..."; 1,
const char MI_EXIT [] PROGMEM = "Exit"; 875,
ssLocalOscInitialize,
enum MenuIds { ssLocalOscValidate,
MENU_SET_FREQ, ssLocalOscChange,
MENU_SET_BFO, ssLocalOscFinalize
MENU_CW_DELAY,
MENU_CW_KEYER,
MENU_TOUCH,
MENU_EXIT,
MENU_TOTAL
}; };
void runLocalOscSetting(){runSetting(&ssLocalOsc);}
const char* const menuItems [MENU_TOTAL] PROGMEM { //BFO
MI_SET_FREQ, void ssBfoInitialize(long int* start_value_out){
MI_SET_BFO, si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
MI_CW_DELAY, *start_value_out = globalSettings.usbCarrierFreq;
MI_CW_KEYER, }
MI_TOUCH, void ssBfoValidate(const long int candidate_value_in, long int* validated_value_out)
MI_EXIT {
*validated_value_out = LIMIT(candidate_value_in,11048000L,11060000L);
}
void ssBfoChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
globalSettings.usbCarrierFreq = new_value;
setFrequency(GetActiveVfoFreq());
si5351bx_setfreq(0, new_value);
formatFreq(new_value,buff_out,buff_out_size);
strncat_P(buff_out,(const char*)F("Hz"),buff_out_size - strlen(buff_out));
}
void ssBfoFinalize(const long int final_value)
{
globalSettings.usbCarrierFreq = final_value;
SaveSettingsToEeprom();
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
setFrequency(GetActiveVfoFreq());
}
const char SS_BFO_T [] PROGMEM = "Beat Frequency Osc (BFO)";
const char SS_BFO_A [] PROGMEM = "Exit menu, tune to an unused\nfrequency, then tune here\nuntil the audio is between\n300-3000Hz";
const SettingScreen_t ssBfo PROGMEM = {
SS_BFO_T,
SS_BFO_A,
1,
-50,//Negative to make dial more intuitive: turning clockwise increases the perceived audio frequency
ssBfoInitialize,
ssBfoValidate,
ssBfoChange,
ssBfoFinalize
}; };
void runBfoSetting(){runSetting(&ssBfo);}
void drawSetupMenu(){ //CW Speed
displayClear(COLOR_BACKGROUND); void ssCwSpeedInitialize(long int* start_value_out)
strcpy_P(b,(const char*)F("Setup")); {
displayText(b, LAYOUT_TITLE_X, LAYOUT_TITLE_Y, LAYOUT_TITLE_WIDTH, LAYOUT_TITLE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_ACTIVE_BORDER); *start_value_out = 1200L/globalSettings.cwDitDurationMs;
for(unsigned int i = 0; i < MENU_TOTAL; ++i){ }
strcpy_P(b,(const char*)pgm_read_word(&(menuItems[i]))); void ssCwSpeedValidate(const long int candidate_value_in, long int* validated_value_out)
displayText(b, LAYOUT_ITEM_X, LAYOUT_ITEM_Y + i*LAYOUT_ITEM_PITCH_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_INACTIVE_BORDER); {
*validated_value_out = LIMIT(candidate_value_in,1,100);
}
void ssCwSpeedChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
ltoa(new_value, buff_out, 10);
}
void ssCwSpeedFinalize(const long int final_value)
{
globalSettings.cwDitDurationMs = 1200L/final_value;
SaveSettingsToEeprom();
}
const char SS_CW_SPEED_T [] PROGMEM = "CW Play Speed";
const char SS_CW_SPEED_A [] PROGMEM = "Select speed to play CW\ncharacters";
const SettingScreen_t ssCwSpeed PROGMEM = {
SS_CW_SPEED_T,
SS_CW_SPEED_A,
5,
1,
ssCwSpeedInitialize,
ssCwSpeedValidate,
ssCwSpeedChange,
ssCwSpeedFinalize
};
void runCwSpeedSetting(){runSetting(&ssCwSpeed);}
//CW Tone
void ssCwToneInitialize(long int* start_value_out)
{
*start_value_out = globalSettings.cwSideToneFreq;
}
void ssCwToneValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = LIMIT(candidate_value_in,100,2000);
}
void 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);
strncat_P(buff_out,(const char*)F("Hz"),buff_out_size - strlen(buff_out));
}
void ssCwToneFinalize(const long int final_value)
{
noTone(CW_TONE);
globalSettings.cwSideToneFreq = final_value;
SaveSettingsToEeprom();
}
const char SS_CW_TONE_T [] PROGMEM = "CW Tone Frequency";
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);}
//CW Switch Delay
void ssCwSwitchDelayInitialize(long int* start_value_out)
{
*start_value_out = globalSettings.cwActiveTimeoutMs;
}
void ssCwSwitchDelayValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = LIMIT(candidate_value_in,100,1000);
}
void ssCwSwitchDelayChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
ltoa(new_value,buff_out,10);
strncat_P(buff_out,(const char*)F("ms"),buff_out_size - strlen(buff_out));
}
void ssCwSwitchDelayFinalize(const long int final_value)
{
globalSettings.cwActiveTimeoutMs = final_value;
SaveSettingsToEeprom();
}
const char SS_CW_SWITCH_T [] PROGMEM = "CW Tx -> Rx Switch Delay";
const char SS_CW_SWITCH_A [] PROGMEM = "Select how long the radio\nshould wait before switching\nbetween TX and RX when in\nCW mode";
const SettingScreen_t ssCwSwitchDelay PROGMEM = {
SS_CW_SWITCH_T,
SS_CW_SWITCH_A,
1,
100,
ssCwSwitchDelayInitialize,
ssCwSwitchDelayValidate,
ssCwSwitchDelayChange,
ssCwSwitchDelayFinalize
};
void runCwSwitchDelaySetting(){runSetting(&ssCwSwitchDelay);}
//CW Keyer
void ssKeyerInitialize(long int* start_value_out)
{
*start_value_out = globalSettings.keyerMode;
}
void ssKeyerValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = LIMIT(candidate_value_in,KeyerMode_e::KEYER_STRAIGHT,KeyerMode_e::KEYER_IAMBIC_B);
}
void ssKeyerChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
if(KeyerMode_e::KEYER_STRAIGHT == new_value){
strncpy_P(buff_out,(const char*)F("< Hand Key >"),buff_out_size);
}
else if(KeyerMode_e::KEYER_IAMBIC_A == new_value){
strncpy_P(buff_out,(const char*)F("< Iambic A >"),buff_out_size);
}
else{
strncpy_P(buff_out,(const char*)F("< Iambic B >"),buff_out_size);
} }
} }
void ssKeyerFinalize(const long int final_value)
{
globalSettings.keyerMode = final_value;
SaveSettingsToEeprom();
}
const char SS_KEYER_T [] PROGMEM = "CW Keyer/Paddle Type";
const char SS_KEYER_A [] PROGMEM = "Select which type of\nkeyer/paddle is being used";
const SettingScreen_t ssKeyer PROGMEM = {
SS_KEYER_T,
SS_KEYER_A,
10,
1,
ssKeyerInitialize,
ssKeyerValidate,
ssKeyerChange,
ssKeyerFinalize
};
void runKeyerSetting(){runSetting(&ssKeyer);}
void movePuck(int i){ //Reset all settings
static int prevPuck = 1;//Start value at 1 so that on init, when we get called with 0, we'll update void ssResetAllInitialize(long int* start_value_out)
{
*start_value_out = 0;//Default to NOT resetting
}
void ssResetAllValidate(const long int candidate_value_in, long int* validated_value_out)
{
*validated_value_out = LIMIT(candidate_value_in,0,1);
}
void ssResetAllChange(const long int new_value, char* buff_out, const size_t buff_out_size)
{
if(new_value){
strncpy_P(buff_out,(const char*)F("Yes"),buff_out_size);
}
else{
strncpy_P(buff_out,(const char*)F("No"),buff_out_size);
}
}
void ssResetAllFinalize(const long int final_value)
{
if(final_value){
LoadDefaultSettings();
SaveSettingsToEeprom();
setup();
}
}
const char SS_RESET_ALL_T [] PROGMEM = "Reset All Cals/Settings";
const char SS_RESET_ALL_A [] PROGMEM = "WARNING: Selecting \"Yes\"\nwill reset all calibrations and\nsettings to their default\nvalues";
const SettingScreen_t ssResetAll PROGMEM = {
SS_RESET_ALL_T,
SS_RESET_ALL_A,
20,
1,
ssResetAllInitialize,
ssResetAllValidate,
ssResetAllChange,
ssResetAllFinalize
};
void runResetAllSetting(){runSetting(&ssResetAll);}
struct MenuItem_t {
const char* const ItemName;
const void (*OnSelect)();
};
void runMenu(const MenuItem_t* const menu_items, const uint16_t num_items);
#define RUN_MENU(menu) runMenu(menu,sizeof(menu)/sizeof(menu[0]))
const char MT_CAL [] PROGMEM = "Calibrations";
const char MI_TOUCH [] PROGMEM = "Touch Screen";
const MenuItem_t calibrationMenu [] PROGMEM {
{MT_CAL,nullptr},//Title
{SS_LOCAL_OSC_T,runLocalOscSetting},
{SS_BFO_T,runBfoSetting},
{MI_TOUCH,setupTouch},
};
void runCalibrationMenu(){RUN_MENU(calibrationMenu);}
const char MT_CW [] PROGMEM = "CW/Morse Setup";
const MenuItem_t cwMenu [] PROGMEM {
{MT_CW,nullptr},//Title
{SS_CW_SPEED_T,runCwSpeedSetting},
{SS_CW_TONE_T,runToneSetting},
{SS_CW_SWITCH_T,runCwSwitchDelaySetting},
{SS_KEYER_T,runKeyerSetting},
};
void runCwMenu(){RUN_MENU(cwMenu);}
const char MT_SETTINGS [] PROGMEM = "Settings";
const MenuItem_t mainMenu [] PROGMEM {
{MT_SETTINGS,nullptr},//Title
{MT_CAL,runCalibrationMenu},
{MT_CW,runCwMenu},
{SS_RESET_ALL_T,runResetAllSetting},
};
const char MI_EXIT [] PROGMEM = "Exit";
const MenuItem_t exitMenu PROGMEM = {MI_EXIT,nullptr};
void drawMenu(const MenuItem_t* const items, const uint16_t num_items)
{
displayClear(COLOR_BACKGROUND);
MenuItem_t mi = {"",nullptr};
memcpy_P(&mi,&items[0],sizeof(mi));
strncpy_P(b,mi.ItemName,sizeof(b));
displayText(b, LAYOUT_TITLE_X, LAYOUT_TITLE_Y, LAYOUT_TITLE_WIDTH, LAYOUT_TITLE_HEIGHT, COLOR_TEXT, COLOR_TITLE_BACKGROUND, COLOR_ACTIVE_BORDER);
for(unsigned int i = 1; i < num_items; ++i){
memcpy_P(&mi,&items[i],sizeof(mi));
strncpy_P(b,mi.ItemName,sizeof(b));
displayText(b, LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (i-1)*LAYOUT_ITEM_PITCH_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_INACTIVE_BORDER);
}
memcpy_P(&mi,&exitMenu,sizeof(mi));
strncpy_P(b,mi.ItemName,sizeof(b));
displayText(b, LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (num_items-1)*LAYOUT_ITEM_PITCH_Y, LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_INACTIVE_BORDER);
}
void movePuck(unsigned int old_index, unsigned int new_index)
{
//Don't update if we're already on the right selection //Don't update if we're already on the right selection
if(prevPuck == i){ if(old_index == new_index){
return; return;
} }
else if(((unsigned int)-1) != old_index){
//Clear old //Clear old
displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (prevPuck*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_INACTIVE_BORDER); displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (old_index*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_INACTIVE_BORDER);
}
//Draw new //Draw new
displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (i*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_ACTIVE_BORDER); displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (new_index*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_ACTIVE_BORDER);
prevPuck = i;
} }
void doSetup2(){ void runMenu(const MenuItem_t* const menu_items, const uint16_t num_items)
{
static const unsigned int COUNTS_PER_ITEM = 10; static const unsigned int COUNTS_PER_ITEM = 10;
int select=0, i, btnState; const unsigned int MAX_KNOB_VALUE = num_items*COUNTS_PER_ITEM - 1;
int knob_sum = 0;
unsigned int old_index = 0;
drawSetupMenu(); drawMenu(menu_items,num_items);
movePuck(select); movePuck(1,0);//Force draw of puck
//wait for the button to be raised up //wait for the button to be raised up
while(btnDown()) while(btnDown()){
active_delay(50); active_delay(50);
}
active_delay(50); //debounce active_delay(50); //debounce
menuOn = 2; while (true){
knob_sum += enc_read();
while (menuOn){ if(knob_sum < 0){
i = enc_read(); knob_sum = 0;
if (i > 0){
if (select + i < MENU_TOTAL*COUNTS_PER_ITEM)
select += i;
movePuck(select/COUNTS_PER_ITEM);
} }
if (i < 0 && select + i >= 0){ else if(MAX_KNOB_VALUE < knob_sum){
select += i; //caught ya, i is already -ve here, so you add it knob_sum = MAX_KNOB_VALUE;
movePuck(select/COUNTS_PER_ITEM);
} }
uint16_t index = knob_sum/COUNTS_PER_ITEM;
movePuck(old_index,index);
old_index = index;
if (!btnDown()){ if (!btnDown()){
active_delay(50); active_delay(50);
continue; continue;
@ -338,50 +515,28 @@ void doSetup2(){
while(btnDown()){ while(btnDown()){
active_delay(50); active_delay(50);
} }
active_delay(300); active_delay(50);//debounce
switch(select/COUNTS_PER_ITEM){ if(num_items-1 > index){
case MENU_SET_FREQ: MenuItem_t mi = {"",nullptr};
{ memcpy_P(&mi,&menu_items[index+1],sizeof(mi));//The 0th element in the array is the title, so offset by 1
setupFreq(); mi.OnSelect();
break; drawMenu(menu_items,num_items);//Need to re-render, since whatever ran just now is assumed to have drawn something
} old_index = -1;//Force redraw
case MENU_SET_BFO: }
{ else{
setupBFO(); break;
break; }
}
case MENU_CW_DELAY:
{
setupCwDelay();
break;
}
case MENU_CW_KEYER:
{
setupKeyer();
break;
}
case MENU_TOUCH:
{
setupTouch();
break;
}
case MENU_EXIT:
default:
{
menuOn = 0;
break;
}
}//switch
//redraw
drawSetupMenu();
} }
//debounce the button //debounce the button
while(btnDown()) while(btnDown()){
active_delay(50); active_delay(50);
active_delay(50); }
active_delay(50);//debounce
}
checkCAT(); void doSetup2(){
RUN_MENU(mainMenu);
guiUpdate(); guiUpdate();
} }

6
setup.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
void doSetup2(); //main setup function, displays the setup menu, calls various dialog boxes
void setupTouch();
void runLocalOscSetting();
void runBfoSetting();

11
ubitx.h
View File

@ -56,7 +56,7 @@ it uses an ILI9341 display controller and an XPT2046 touch controller.
* the input and output from the USB port. We must keep a count of the bytes used while reading * 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. * 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 c[30], b[128];
/** /**
* 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. * 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.
@ -92,10 +92,6 @@ extern char c[30], b[30];
#define HIGHEST_FREQ (30000000l) #define HIGHEST_FREQ (30000000l)
static const uint32_t THRESHOLD_USB_LSB = 10000000L; 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 */ /* these are functions implemented in the main file named as ubitx_xxx.ino */
void active_delay(int delay_by); void active_delay(int delay_by);
void saveVFOs(); void saveVFOs();
@ -122,11 +118,6 @@ void drawTx();
//are useful to concatanate the values with text like "Set Freq to " x " KHz" //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); 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 //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 doCommands(); //does the commands with encoder to jump from button to button
void checkTouch(); //does the commands with a touch on the buttons void checkTouch(); //does the commands with a touch on the buttons

View File

@ -123,13 +123,6 @@ void catReadEEPRom(void)
//for remove warnings //for remove warnings
byte temp0 = cat[0]; byte temp0 = cat[0];
byte temp1 = cat[1]; byte temp1 = cat[1];
/*
itoa((int) cat[0], b, 16);
strcat(b, ":");
itoa((int) cat[1], c, 16);
strcat(b, c);
printLine2(b);
*/
cat[0] = 0; cat[0] = 0;
cat[1] = 0; cat[1] = 0;
@ -385,10 +378,6 @@ void processCATCommand2(byte* cmd) {
default: default:
//somehow, get this to print the four bytes //somehow, get this to print the four bytes
ultoa(*((unsigned long *)cmd), c, 16); ultoa(*((unsigned long *)cmd), c, 16);
/*itoa(cmd[4], b, 16);
strcat(b, ">");
strcat(b, c);
printLine2(b);*/
response[0] = 0x00; response[0] = 0x00;
Serial.write(response[0]); Serial.write(response[0]);
} }

View File

@ -1,7 +1,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <EEPROM.h>
#include "morse.h" #include "morse.h"
#include "settings.h" #include "settings.h"
#include "setup.h"
#include "ubitx.h" #include "ubitx.h"
#include "nano_gui.h" #include "nano_gui.h"
@ -65,8 +65,8 @@ enum btn_set_e {
BUTTON_17, BUTTON_17,
BUTTON_15, BUTTON_15,
BUTTON_10, BUTTON_10,
BUTTON_WPM, BUTTON_BLANK_1,
BUTTON_TON, BUTTON_MNU,
BUTTON_FRQ, BUTTON_FRQ,
BUTTON_TOTAL BUTTON_TOTAL
}; };
@ -85,7 +85,7 @@ constexpr Button btn_set[BUTTON_TOTAL] PROGMEM = {
{LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_RIT, "RIT", 'R'}, {LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_RIT, "RIT", 'R'},
{LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_USB, "USB", 'U'}, {LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_USB, "USB", 'U'},
{LAYOUT_BUTTON_X + 2*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_LSB, "LSB", 'L'}, {LAYOUT_BUTTON_X + 2*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_LSB, "LSB", 'L'},
{LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_CW , "CW", 'M'}, {LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_CW , "CW", 'C'},
{LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_SPL, "SPL", 'S'}, {LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_SPL, "SPL", 'S'},
{LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_80, "80", '8'}, {LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_80, "80", '8'},
@ -96,8 +96,8 @@ constexpr Button btn_set[BUTTON_TOTAL] PROGMEM = {
{LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_15 , "15", '5'}, {LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_15 , "15", '5'},
{LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_10 , "10", '1'}, {LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_10 , "10", '1'},
{LAYOUT_BUTTON_X + 2*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_WPM, "WPM", 'W'}, {LAYOUT_BUTTON_X + 2*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_BLANK_1, "", '\0'},
{LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_TON, "TON", 'T'}, {LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_MNU, "MNU", 'M'},
{LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_FRQ, "FRQ", 'F'}, {LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, LAYOUT_BUTTON_WIDTH, LAYOUT_BUTTON_HEIGHT, BUTTON_FRQ, "FRQ", 'F'},
}; };
@ -165,10 +165,10 @@ int getValueByKnob(int minimum, int maximum, int step_size, int initial, const
active_delay(200); active_delay(200);
knob_value = initial; knob_value = initial;
strcpy_P(b,(const char*)prefix); strncpy_P(b,(const char*)prefix,sizeof(b));
itoa(knob_value, c, 10); itoa(knob_value, c, 10);
strcat(b, c); strncat(b, c, sizeof(b) - strlen(b));
strcat_P(b, (const char*)postfix); strncat_P(b, (const char*)postfix, sizeof(b) - strlen(b));
drawCommandbar(b); drawCommandbar(b);
while(!btnDown() && digitalRead(PTT) == HIGH){ while(!btnDown() && digitalRead(PTT) == HIGH){
@ -179,10 +179,10 @@ int getValueByKnob(int minimum, int maximum, int step_size, int initial, const
if (knob_value < maximum && knob > 0) if (knob_value < maximum && knob > 0)
knob_value += step_size; knob_value += step_size;
strcpy_P(b,(const char*)prefix); strncpy_P(b,(const char*)prefix,sizeof(b));
itoa(knob_value, c, 10); itoa(knob_value, c, 10);
strcat(b, c); strncat(b, c, sizeof(b) - strlen(b));
strcat_P(b,(const char*)postfix); strncat_P(b,(const char*)postfix, sizeof(b) - strlen(b));
drawCommandbar(b); drawCommandbar(b);
} }
checkCAT(); checkCAT();
@ -334,8 +334,8 @@ void displayRIT(){
c[0] = 0; c[0] = 0;
displayFillrect(LAYOUT_MODE_TEXT_X,LAYOUT_MODE_TEXT_Y,LAYOUT_MODE_TEXT_WIDTH,LAYOUT_MODE_TEXT_HEIGHT, COLOR_BACKGROUND); displayFillrect(LAYOUT_MODE_TEXT_X,LAYOUT_MODE_TEXT_Y,LAYOUT_MODE_TEXT_WIDTH,LAYOUT_MODE_TEXT_HEIGHT, COLOR_BACKGROUND);
if(globalSettings.ritOn){ if(globalSettings.ritOn){
strcpy_P(c,(const char*)F("TX:")); strncpy_P(c,(const char*)F("TX:"),sizeof(c));
formatFreq(globalSettings.ritFrequency, c+3, sizeof(c)-3); formatFreq(globalSettings.ritFrequency, c+3, sizeof(c)-strlen(c));
if (VFO_A == globalSettings.activeVfo) 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); 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 else
@ -349,9 +349,9 @@ void fastTune(){
active_delay(50); active_delay(50);
active_delay(300); active_delay(300);
strcpy_P(c,(const char*)F("Fast tune")); strncpy_P(c,(const char*)F("Fast tune"),sizeof(c));
displayText(c, LAYOUT_MODE_TEXT_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); 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){ while(true){
checkCAT(); checkCAT();
//exit after debouncing the btnDown //exit after debouncing the btnDown
@ -471,8 +471,8 @@ void enterFreq(){
}//switch }//switch
}//if button hit test }//if button hit test
}// end of the button scanning loop }// end of the button scanning loop
strcpy(b, c); strncpy(b, c, sizeof(b));
strcat_P(b,(const char*)F(" KHz")); strncat_P(b,(const char*)F(" KHz"),sizeof(b) - strlen(b));
displayText(b, LAYOUT_MODE_TEXT_X, LAYOUT_MODE_TEXT_Y, LAYOUT_MODE_TEXT_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); 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); active_delay(300);
while(readTouch()) while(readTouch())
@ -481,21 +481,21 @@ void enterFreq(){
} }
void drawCWStatus(){ void drawCWStatus(){
strcpy_P(b,(const char*)F(" cw: ")); strncpy_P(b,(const char*)F(" cw: "),sizeof(b));
int wpm = 1200/globalSettings.cwDitDurationMs; int wpm = 1200/globalSettings.cwDitDurationMs;
itoa(wpm,c, 10); itoa(wpm,c, 10);
strcat(b, c); strncat(b, c, sizeof(b) - strlen(b));
strcat_P(b,(const char*)F("wpm, ")); strncat_P(b,(const char*)F("wpm, "), sizeof(b) - strlen(b));
itoa(globalSettings.cwSideToneFreq, c, 10); itoa(globalSettings.cwSideToneFreq, c, 10);
strcat(b, c); strncat(b, c, sizeof(b) - strlen(b));
strcat_P(b,(const char*)F("hz")); strncat_P(b,(const char*)F("hz"), sizeof(b) - strlen(b));
displayText(b, LAYOUT_CW_TEXT_X, LAYOUT_CW_TEXT_Y, LAYOUT_CW_TEXT_WIDTH, LAYOUT_CW_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND); 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(){ void drawTx(){
if (globalSettings.txActive){ if (globalSettings.txActive){
strcpy_P(b,(const char*)F("TX")); strncpy_P(b,(const char*)F("TX"), sizeof(b));
displayText(b, LAYOUT_TX_X, LAYOUT_TX_Y, LAYOUT_TX_WIDTH, LAYOUT_TX_HEIGHT, COLOR_ACTIVE_TEXT, COLOR_ACTIVE_BACKGROUND, COLOR_BACKGROUND); displayText(b, LAYOUT_TX_X, LAYOUT_TX_Y, LAYOUT_TX_WIDTH, LAYOUT_TX_HEIGHT, COLOR_ACTIVE_TEXT, COLOR_ACTIVE_BACKGROUND, COLOR_BACKGROUND);
} }
else{ else{
@ -808,65 +808,6 @@ void switchBand(uint32_t bandfreq){
saveVFOs(); saveVFOs();
} }
void setCwSpeed()
{
int wpm = 1200/globalSettings.cwDitDurationMs;
wpm = getValueByKnob(1, 100, 1, wpm,F("CW: "),F(" WPM"));
globalSettings.cwDitDurationMs = 1200/wpm;
SaveSettingsToEeprom();
active_delay(500);
drawStatusbar();
//printLine2("");
//updateDisplay();
}
void setCwTone(){
int knob = 0;
int prev_sideTone;
tone(CW_TONE, globalSettings.cwSideToneFreq);
itoa(globalSettings.cwSideToneFreq, c, 10);
strcpy_P(b,(const char*)F("CW Tone: "));
strcat(b, c);
strcat_P(b,(const char*)F(" Hz"));
drawCommandbar(b);
//disable all clock 1 and clock 2
while (digitalRead(PTT) == HIGH && !btnDown())
{
knob = enc_read();
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, globalSettings.cwSideToneFreq);
itoa(globalSettings.cwSideToneFreq, c, 10);
strcpy_P(b,(const char*)F("CW Tone: "));
strcat(b, c);
strcat_P(b,(const char*)F(" Hz"));
drawCommandbar(b);
//printLine2(b);
checkCAT();
active_delay(20);
}
noTone(CW_TONE);
SaveSettingsToEeprom();
b[0] = 0;
drawCommandbar(b);
drawStatusbar();
//printLine2("");
//updateDisplay();
}
void doCommand(Button* button){ void doCommand(Button* button){
//Serial.print(F("Doing command: ")); //Serial.print(F("Doing command: "));
//Serial.print(button->text); //Serial.print(button->text);
@ -957,14 +898,9 @@ void doCommand(Button* button){
enterFreq(); enterFreq();
break; break;
} }
case BUTTON_WPM: case BUTTON_MNU:
{ {
setCwSpeed(); doSetup2();
break;
}
case BUTTON_TON:
{
setCwTone();
break; break;
} }
default: default:
@ -1017,20 +953,17 @@ void drawFocus(int ibtn, int color){
} }
void doCommands(){ void doCommands(){
int select=0, i, prevButton, btnState; int select = 0;
int prev_button = 0;
//wait for the button to be raised up //wait for the button to be raised up
while(btnDown()) while(btnDown())
active_delay(50); active_delay(50);
active_delay(50); //debounce active_delay(50); //debounce
menuOn = 2; while (true){
while (menuOn){
//check if the knob's button was pressed //check if the knob's button was pressed
btnState = btnDown(); if (btnDown()){
if (btnState){
Button button; Button button;
memcpy_P(&button, &(btn_set[select/10]), sizeof(Button)); memcpy_P(&button, &(btn_set[select/10]), sizeof(Button));
@ -1050,27 +983,27 @@ void doCommands(){
return; return;
} }
i = enc_read(); int knob = enc_read();
if (i == 0){ if (knob == 0){
active_delay(50); active_delay(50);
continue; continue;
} }
if (i > 0){ if (knob > 0){
if (select + i < BUTTON_TOTAL * 10) if (select + knob < BUTTON_TOTAL * 10)
select += i; select += knob;
} }
if (i < 0 && select + i >= 0) if (knob < 0 && select + knob >= 0)
select += i; //caught ya, i is already -ve here, so you add it select += knob; //caught ya, i is already -ve here, so you add it
if (prevButton == select / 10) if (prev_button == select / 10)
continue; continue;
//we are on a new button //we are on a new button
drawFocus(prevButton, COLOR_INACTIVE_BORDER); drawFocus(prev_button, COLOR_INACTIVE_BORDER);
drawFocus(select/10, COLOR_ACTIVE_BORDER); drawFocus(select/10, COLOR_ACTIVE_BORDER);
prevButton = select/10; prev_button = select/10;
} }
// guiUpdate(); // guiUpdate();

View File

@ -31,6 +31,7 @@
*/ */
#include <Wire.h> #include <Wire.h>
#include "settings.h" #include "settings.h"
#include "setup.h"
#include "ubitx.h" #include "ubitx.h"
#include "nano_gui.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 * 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 * if you declare large strings inside functions, they can easily exceed the capacity of the stack
* and mess up your programs. * 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 * 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 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. * 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[128];
char c[30];
//during CAT commands, we will freeeze the display until CAT is disengaged //during CAT commands, we will freeeze the display until CAT is disengaged
unsigned char doingCAT = 0; 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
/** /**
@ -473,13 +474,14 @@ void setup()
//Run initial calibration routine if button is pressed during power up //Run initial calibration routine if button is pressed during power up
if(btnDown()){ if(btnDown()){
LoadDefaultSettings();
setupTouch(); setupTouch();
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB); SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
setFrequency(10000000l); setFrequency(10000000L);
setupFreq(); runLocalOscSetting();
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB); SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
setFrequency(7100000l); setFrequency(7100000L);
setupBFO(); runBfoSetting();
} }
guiUpdate(); guiUpdate();