mirror of
https://codeberg.org/mclemens/ubitxv6.git
synced 2025-02-21 06:57:27 -05:00
commit
59347af9ed
@ -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 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 setBound(coord_t x, coord_t y);
|
||||
static inline void setTextColor(color_t c);
|
||||
static inline void setTextColor(color_t c, color_t bg);
|
||||
static inline void setTextSize(uint8_t s);
|
||||
@ -157,8 +158,8 @@ public:
|
||||
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 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(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(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, coord_t wi = _width);
|
||||
|
||||
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; // Display w/h as modified by current rotation
|
||||
static coord_t cursor_x, cursor_y;
|
||||
static coord_t bound_x1, bound_x2;
|
||||
static color_t textcolor, textbgcolor;
|
||||
static uint8_t textsize;
|
||||
static uint8_t rotation;
|
||||
@ -216,6 +218,10 @@ int16_t PDQ_GFX<HW>::cursor_x;
|
||||
template<class HW>
|
||||
int16_t PDQ_GFX<HW>::cursor_y;
|
||||
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;
|
||||
template<class HW>
|
||||
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;
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
bound_x1 = 0;
|
||||
bound_x2 = WIDTH;
|
||||
rotation = 0;
|
||||
textsize = 1;
|
||||
textcolor = 0xffff;
|
||||
@ -740,7 +748,7 @@ size_t PDQ_GFX<HW>::write(uint8_t c)
|
||||
{
|
||||
if(c == '\n')
|
||||
{
|
||||
cursor_x = 0;
|
||||
cursor_x = bound_x1;
|
||||
cursor_y += (coord_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
}
|
||||
else if (c != '\r')
|
||||
@ -756,10 +764,10 @@ size_t PDQ_GFX<HW>::write(uint8_t c)
|
||||
if ((w > 0) && (h > 0))
|
||||
{
|
||||
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
|
||||
cursor_x = 0;
|
||||
cursor_x = bound_x1;
|
||||
cursor_y += (coord_t)textsize *
|
||||
(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;
|
||||
}
|
||||
|
||||
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>
|
||||
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.
|
||||
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
|
||||
|
||||
coord_t xs = x;
|
||||
coord_t xe = xs+wi;
|
||||
|
||||
*x1 = x;
|
||||
*y1 = y;
|
||||
*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);
|
||||
xo = pgm_read_byte(&glyph->xOffset);
|
||||
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
|
||||
}
|
||||
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
|
||||
{
|
||||
x = 0; // Reset x
|
||||
x = xs; // Reset x
|
||||
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
|
||||
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 c;
|
||||
coord_t xs = x;
|
||||
coord_t xe = xs+wi;
|
||||
|
||||
*x1 = x;
|
||||
*y1 = y;
|
||||
@ -1194,9 +1214,9 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
|
||||
xa = pgm_read_byte(&glyph->xAdvance);
|
||||
xo = pgm_read_byte(&glyph->xOffset);
|
||||
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
|
||||
}
|
||||
gx1 = x + xo * ts;
|
||||
@ -1217,7 +1237,7 @@ void PDQ_GFX<HW>::getTextBounds(const __FlashStringHelper *str, coord_t x, coord
|
||||
}
|
||||
else // Newline
|
||||
{
|
||||
x = 0; // Reset x
|
||||
x = xs; // Reset x
|
||||
y += ya; // Advance y by 1 line
|
||||
}
|
||||
}
|
||||
|
24
morse.cpp
24
morse.cpp
@ -56,12 +56,12 @@ static const PROGMEM struct Morse morse_table[] = {
|
||||
{'?', 0x8c}, // 10001100
|
||||
};
|
||||
|
||||
static void morseLetter(char c){
|
||||
static void morseLetter(char c, uint16_t dit_duration_ms){
|
||||
unsigned char mask = 0x80;
|
||||
|
||||
//handle space character as three dashes
|
||||
if (c == ' '){
|
||||
active_delay(9 * globalSettings.cwDitDurationMs);
|
||||
active_delay(7 * dit_duration_ms);
|
||||
//Serial.print(' ');
|
||||
return;
|
||||
}
|
||||
@ -81,36 +81,28 @@ static void morseLetter(char c){
|
||||
while(mask){
|
||||
tone(CW_TONE, globalSettings.cwSideToneFreq,10000);
|
||||
if (mask & code){
|
||||
delay(3 * globalSettings.cwDitDurationMs);
|
||||
delay(3 * dit_duration_ms);
|
||||
//Serial.print('-');
|
||||
}
|
||||
else{
|
||||
delay(globalSettings.cwDitDurationMs);
|
||||
delay(dit_duration_ms);
|
||||
//Serial.print('.');
|
||||
}
|
||||
//Serial.print('#');
|
||||
noTone(CW_TONE);
|
||||
delay(globalSettings.cwDitDurationMs); // space between dots and dashes
|
||||
delay(dit_duration_ms); // space between dots and dashes
|
||||
mask = mask >> 1;
|
||||
}
|
||||
//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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void morseText(char *text){
|
||||
// while (1){
|
||||
noTone(CW_TONE);
|
||||
delay(1000);
|
||||
tone(CW_TONE, 600);
|
||||
delay(1000);
|
||||
// }
|
||||
|
||||
//Serial.println(globalSettings.cwSideToneFreq);
|
||||
void morseText(char *text, uint16_t dit_duration_ms){
|
||||
while(*text){
|
||||
morseLetter(*text++);
|
||||
morseLetter(*text++, dit_duration_ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
4
morse.h
4
morse.h
@ -1,3 +1,3 @@
|
||||
#include "settings.h"
|
||||
//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);
|
||||
void morseText(char *text, uint16_t dit_duration_ms = globalSettings.cwDitDurationMs);
|
||||
|
18
nano_gui.cpp
18
nano_gui.cpp
@ -178,7 +178,7 @@ void displayInit(void){
|
||||
|
||||
tft.begin();
|
||||
tft.setFont(ubitx_font);
|
||||
tft.setTextWrap(false);
|
||||
tft.setTextWrap(true);
|
||||
tft.setTextColor(DISPLAY_GREEN,DISPLAY_BLACK);
|
||||
tft.setTextSize(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){
|
||||
tft.setTextColor(color,background);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -228,10 +236,10 @@ void displayText(char *text, int x1, int y1, int w, int h, int color, int backgr
|
||||
int16_t y1_out;
|
||||
uint16_t width_out;
|
||||
uint16_t height_out;
|
||||
tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out);
|
||||
x1 += (w - ( width_out + (x1_out-x1)))/2;
|
||||
y1 += h - (h - height_out)/2;
|
||||
displayRawText(text,x1,y1,color,background);
|
||||
tft.getTextBounds(text,x1,y1,&x1_out,&y1_out,&width_out,&height_out,w);
|
||||
x1 += (w - ( (int32_t)width_out + (x1_out-x1)))/2;
|
||||
y1 += (ubitx_font->yAdvance + h - ( (int32_t)height_out + (y1_out-y1)))/2;
|
||||
displayRawText(text,x1,y1,w,color,background);
|
||||
}
|
||||
|
||||
void setupTouch(){
|
||||
|
@ -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
|
||||
|
687
setup.cpp
687
setup.cpp
@ -1,9 +1,9 @@
|
||||
#include <Arduino.h>
|
||||
#include <EEPROM.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.
|
||||
@ -18,13 +18,6 @@
|
||||
* - 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_BACKGROUND = DISPLAY_BLACK;
|
||||
static const unsigned int COLOR_TITLE_BACKGROUND = DISPLAY_NAVY;
|
||||
@ -58,276 +51,460 @@ 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_HEIGHT = LAYOUT_ITEM_HEIGHT;
|
||||
|
||||
static const unsigned int LAYOUT_INSTRUCTION_TEXT_X = 20;
|
||||
static const unsigned int LAYOUT_INSTRUCTION_TEXT_Y = LAYOUT_ITEM_Y + 5*LAYOUT_ITEM_PITCH_Y;
|
||||
static const unsigned int LAYOUT_INSTRUCTION_TEXT_WIDTH = LAYOUT_ITEM_WIDTH;
|
||||
static const unsigned int LAYOUT_INSTRUCTION_TEXT_HEIGHT = LAYOUT_ITEM_HEIGHT;
|
||||
static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_X = 20;
|
||||
static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_Y = LAYOUT_ITEM_Y;
|
||||
static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_WIDTH = LAYOUT_ITEM_WIDTH;
|
||||
static const unsigned int LAYOUT_INSTRUCTIONS_TEXT_HEIGHT = LAYOUT_SETTING_VALUE_Y - LAYOUT_ITEM_Y - 1;
|
||||
|
||||
void displayDialog(const __FlashStringHelper* title, const __FlashStringHelper* instructions){
|
||||
strcpy_P(b,(const char*)title);
|
||||
strcpy_P(c,(const char*)instructions);
|
||||
static const unsigned int LAYOUT_CONFIRM_TEXT_X = 20;
|
||||
static const unsigned int LAYOUT_CONFIRM_TEXT_Y = LAYOUT_ITEM_Y + 5*LAYOUT_ITEM_PITCH_Y;
|
||||
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);
|
||||
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);
|
||||
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(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));
|
||||
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);
|
||||
}
|
||||
SettingScreen_t screen = {0};
|
||||
memcpy_P(&screen,p_screen,sizeof(screen));
|
||||
displayDialog(screen.Title,
|
||||
screen.AdditionalText);
|
||||
|
||||
void setupFreq(){
|
||||
displayDialog(F("Set Frequency"),F("Push TUNE to Save"));
|
||||
|
||||
//round off the the nearest khz
|
||||
{
|
||||
uint32_t freq = GetActiveVfoFreq();
|
||||
freq = (freq/1000l)* 1000l;
|
||||
setFrequency(freq);
|
||||
//Wait for button to stop being pressed
|
||||
while(btnDown()){
|
||||
active_delay(10);
|
||||
}
|
||||
active_delay(10);
|
||||
|
||||
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);
|
||||
long int raw_value = 0;
|
||||
long int last_value = 0;
|
||||
|
||||
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);
|
||||
//keep clear of any previous button press
|
||||
while (btnDown())
|
||||
active_delay(100);
|
||||
active_delay(100);
|
||||
|
||||
raw_value = last_value * (int32_t)screen.KnobDivider;
|
||||
|
||||
while (!btnDown())
|
||||
{
|
||||
int knob = enc_read();
|
||||
if(knob != 0){
|
||||
globalSettings.oscillatorCal += knob * 875;
|
||||
raw_value += knob * screen.StepSize;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if(knob < 0 && tmp_mode > KeyerMode_e::KEYER_STRAIGHT){
|
||||
tmp_mode--;
|
||||
}
|
||||
if(knob > 0 && tmp_mode < KeyerMode_e::KEYER_IAMBIC_B){
|
||||
tmp_mode++;
|
||||
|
||||
const long int candidate_value = raw_value / (int32_t)screen.KnobDivider;
|
||||
long int value = 0;
|
||||
screen.Validate(candidate_value,&value);
|
||||
|
||||
//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){
|
||||
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);
|
||||
if(value == last_value){
|
||||
continue;
|
||||
}
|
||||
else if(KeyerMode_e::KEYER_IAMBIC_A == tmp_mode){
|
||||
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 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);
|
||||
else{
|
||||
screen.OnValueChange(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);
|
||||
last_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
setupExit();
|
||||
si5351_set_calibration(globalSettings.oscillatorCal);
|
||||
setFrequency(GetActiveVfoFreq());
|
||||
}
|
||||
|
||||
const char MI_SET_FREQ [] PROGMEM = "Set Freq...";
|
||||
const char MI_SET_BFO [] PROGMEM = "Set BFO...";
|
||||
const char MI_CW_DELAY [] PROGMEM = "CW Delay...";
|
||||
const char MI_CW_KEYER [] PROGMEM = "CW Keyer...";
|
||||
const char MI_TOUCH [] PROGMEM = "Touch Screen...";
|
||||
const char MI_EXIT [] PROGMEM = "Exit";
|
||||
|
||||
enum MenuIds {
|
||||
MENU_SET_FREQ,
|
||||
MENU_SET_BFO,
|
||||
MENU_CW_DELAY,
|
||||
MENU_CW_KEYER,
|
||||
MENU_TOUCH,
|
||||
MENU_EXIT,
|
||||
MENU_TOTAL
|
||||
const char SS_LOCAL_OSC_T [] PROGMEM = "Local Oscillator";
|
||||
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);}
|
||||
|
||||
const char* const menuItems [MENU_TOTAL] PROGMEM {
|
||||
MI_SET_FREQ,
|
||||
MI_SET_BFO,
|
||||
MI_CW_DELAY,
|
||||
MI_CW_KEYER,
|
||||
MI_TOUCH,
|
||||
MI_EXIT
|
||||
//BFO
|
||||
void ssBfoInitialize(long int* start_value_out){
|
||||
si5351bx_setfreq(0, globalSettings.usbCarrierFreq);
|
||||
*start_value_out = globalSettings.usbCarrierFreq;
|
||||
}
|
||||
void ssBfoValidate(const long int candidate_value_in, long int* validated_value_out)
|
||||
{
|
||||
*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(){
|
||||
displayClear(COLOR_BACKGROUND);
|
||||
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);
|
||||
for(unsigned int i = 0; i < MENU_TOTAL; ++i){
|
||||
strcpy_P(b,(const char*)pgm_read_word(&(menuItems[i])));
|
||||
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);
|
||||
//CW Speed
|
||||
void ssCwSpeedInitialize(long int* start_value_out)
|
||||
{
|
||||
*start_value_out = 1200L/globalSettings.cwDitDurationMs;
|
||||
}
|
||||
void ssCwSpeedValidate(const long int candidate_value_in, long int* validated_value_out)
|
||||
{
|
||||
*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){
|
||||
static int prevPuck = 1;//Start value at 1 so that on init, when we get called with 0, we'll update
|
||||
//Reset all settings
|
||||
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
|
||||
if(prevPuck == i){
|
||||
if(old_index == new_index){
|
||||
return;
|
||||
}
|
||||
|
||||
//Clear old
|
||||
displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (prevPuck*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_INACTIVE_BORDER);
|
||||
else if(((unsigned int)-1) != old_index){
|
||||
//Clear old
|
||||
displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (old_index*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_INACTIVE_BORDER);
|
||||
}
|
||||
//Draw new
|
||||
displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (i*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_ACTIVE_BORDER);
|
||||
prevPuck = i;
|
||||
|
||||
displayRect(LAYOUT_ITEM_X, LAYOUT_ITEM_Y + (new_index*LAYOUT_ITEM_PITCH_Y), LAYOUT_ITEM_WIDTH, LAYOUT_ITEM_HEIGHT, COLOR_ACTIVE_BORDER);
|
||||
}
|
||||
|
||||
void doSetup2(){
|
||||
void runMenu(const MenuItem_t* const menu_items, const uint16_t num_items)
|
||||
{
|
||||
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();
|
||||
movePuck(select);
|
||||
drawMenu(menu_items,num_items);
|
||||
movePuck(1,0);//Force draw of puck
|
||||
|
||||
//wait for the button to be raised up
|
||||
while(btnDown())
|
||||
while(btnDown()){
|
||||
active_delay(50);
|
||||
}
|
||||
active_delay(50); //debounce
|
||||
|
||||
menuOn = 2;
|
||||
|
||||
while (menuOn){
|
||||
i = enc_read();
|
||||
while (true){
|
||||
knob_sum += enc_read();
|
||||
if(knob_sum < 0){
|
||||
knob_sum = 0;
|
||||
}
|
||||
else if(MAX_KNOB_VALUE < knob_sum){
|
||||
knob_sum = MAX_KNOB_VALUE;
|
||||
}
|
||||
|
||||
if (i > 0){
|
||||
if (select + i < MENU_TOTAL*COUNTS_PER_ITEM)
|
||||
select += i;
|
||||
movePuck(select/COUNTS_PER_ITEM);
|
||||
}
|
||||
if (i < 0 && select + i >= 0){
|
||||
select += i; //caught ya, i is already -ve here, so you add it
|
||||
movePuck(select/COUNTS_PER_ITEM);
|
||||
}
|
||||
uint16_t index = knob_sum/COUNTS_PER_ITEM;
|
||||
movePuck(old_index,index);
|
||||
old_index = index;
|
||||
|
||||
if (!btnDown()){
|
||||
active_delay(50);
|
||||
@ -338,50 +515,28 @@ void doSetup2(){
|
||||
while(btnDown()){
|
||||
active_delay(50);
|
||||
}
|
||||
active_delay(300);
|
||||
active_delay(50);//debounce
|
||||
|
||||
switch(select/COUNTS_PER_ITEM){
|
||||
case MENU_SET_FREQ:
|
||||
{
|
||||
setupFreq();
|
||||
break;
|
||||
}
|
||||
case MENU_SET_BFO:
|
||||
{
|
||||
setupBFO();
|
||||
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();
|
||||
if(num_items-1 > index){
|
||||
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
|
||||
mi.OnSelect();
|
||||
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
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//debounce the button
|
||||
while(btnDown())
|
||||
while(btnDown()){
|
||||
active_delay(50);
|
||||
active_delay(50);
|
||||
}
|
||||
active_delay(50);//debounce
|
||||
}
|
||||
|
||||
checkCAT();
|
||||
void doSetup2(){
|
||||
RUN_MENU(mainMenu);
|
||||
guiUpdate();
|
||||
}
|
||||
|
6
setup.h
Normal file
6
setup.h
Normal 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
11
ubitx.h
@ -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 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.
|
||||
@ -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
|
||||
|
@ -123,13 +123,6 @@ void catReadEEPRom(void)
|
||||
//for remove warnings
|
||||
byte temp0 = cat[0];
|
||||
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[1] = 0;
|
||||
@ -385,10 +378,6 @@ void processCATCommand2(byte* cmd) {
|
||||
default:
|
||||
//somehow, get this to print the four bytes
|
||||
ultoa(*((unsigned long *)cmd), c, 16);
|
||||
/*itoa(cmd[4], b, 16);
|
||||
strcat(b, ">");
|
||||
strcat(b, c);
|
||||
printLine2(b);*/
|
||||
response[0] = 0x00;
|
||||
Serial.write(response[0]);
|
||||
}
|
||||
|
147
ubitx_ui.cpp
147
ubitx_ui.cpp
@ -1,7 +1,7 @@
|
||||
#include <Arduino.h>
|
||||
#include <EEPROM.h>
|
||||
#include "morse.h"
|
||||
#include "settings.h"
|
||||
#include "setup.h"
|
||||
#include "ubitx.h"
|
||||
#include "nano_gui.h"
|
||||
|
||||
@ -65,8 +65,8 @@ enum btn_set_e {
|
||||
BUTTON_17,
|
||||
BUTTON_15,
|
||||
BUTTON_10,
|
||||
BUTTON_WPM,
|
||||
BUTTON_TON,
|
||||
BUTTON_BLANK_1,
|
||||
BUTTON_MNU,
|
||||
BUTTON_FRQ,
|
||||
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 + 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 + 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 + 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 + 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 + 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 + 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_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'},
|
||||
};
|
||||
|
||||
@ -165,10 +165,10 @@ int getValueByKnob(int minimum, int maximum, int step_size, int initial, const
|
||||
active_delay(200);
|
||||
knob_value = initial;
|
||||
|
||||
strcpy_P(b,(const char*)prefix);
|
||||
strncpy_P(b,(const char*)prefix,sizeof(b));
|
||||
itoa(knob_value, c, 10);
|
||||
strcat(b, c);
|
||||
strcat_P(b, (const char*)postfix);
|
||||
strncat(b, c, sizeof(b) - strlen(b));
|
||||
strncat_P(b, (const char*)postfix, sizeof(b) - strlen(b));
|
||||
drawCommandbar(b);
|
||||
|
||||
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)
|
||||
knob_value += step_size;
|
||||
|
||||
strcpy_P(b,(const char*)prefix);
|
||||
strncpy_P(b,(const char*)prefix,sizeof(b));
|
||||
itoa(knob_value, c, 10);
|
||||
strcat(b, c);
|
||||
strcat_P(b,(const char*)postfix);
|
||||
strncat(b, c, sizeof(b) - strlen(b));
|
||||
strncat_P(b,(const char*)postfix, sizeof(b) - strlen(b));
|
||||
drawCommandbar(b);
|
||||
}
|
||||
checkCAT();
|
||||
@ -334,8 +334,8 @@ void displayRIT(){
|
||||
c[0] = 0;
|
||||
displayFillrect(LAYOUT_MODE_TEXT_X,LAYOUT_MODE_TEXT_Y,LAYOUT_MODE_TEXT_WIDTH,LAYOUT_MODE_TEXT_HEIGHT, COLOR_BACKGROUND);
|
||||
if(globalSettings.ritOn){
|
||||
strcpy_P(c,(const char*)F("TX:"));
|
||||
formatFreq(globalSettings.ritFrequency, c+3, sizeof(c)-3);
|
||||
strncpy_P(c,(const char*)F("TX:"),sizeof(c));
|
||||
formatFreq(globalSettings.ritFrequency, c+3, sizeof(c)-strlen(c));
|
||||
if (VFO_A == globalSettings.activeVfo)
|
||||
displayText(c, LAYOUT_VFO_LABEL_X + 0*LAYOUT_VFO_LABEL_PITCH_X, LAYOUT_MODE_TEXT_Y, LAYOUT_VFO_LABEL_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
|
||||
else
|
||||
@ -349,9 +349,9 @@ void fastTune(){
|
||||
active_delay(50);
|
||||
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);
|
||||
while(1){
|
||||
while(true){
|
||||
checkCAT();
|
||||
|
||||
//exit after debouncing the btnDown
|
||||
@ -471,8 +471,8 @@ void enterFreq(){
|
||||
}//switch
|
||||
}//if button hit test
|
||||
}// end of the button scanning loop
|
||||
strcpy(b, c);
|
||||
strcat_P(b,(const char*)F(" KHz"));
|
||||
strncpy(b, c, sizeof(b));
|
||||
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);
|
||||
active_delay(300);
|
||||
while(readTouch())
|
||||
@ -481,21 +481,21 @@ void enterFreq(){
|
||||
}
|
||||
|
||||
void drawCWStatus(){
|
||||
strcpy_P(b,(const char*)F(" cw: "));
|
||||
strncpy_P(b,(const char*)F(" cw: "),sizeof(b));
|
||||
int wpm = 1200/globalSettings.cwDitDurationMs;
|
||||
itoa(wpm,c, 10);
|
||||
strcat(b, c);
|
||||
strcat_P(b,(const char*)F("wpm, "));
|
||||
strncat(b, c, sizeof(b) - strlen(b));
|
||||
strncat_P(b,(const char*)F("wpm, "), sizeof(b) - strlen(b));
|
||||
itoa(globalSettings.cwSideToneFreq, c, 10);
|
||||
strcat(b, c);
|
||||
strcat_P(b,(const char*)F("hz"));
|
||||
strncat(b, c, sizeof(b) - strlen(b));
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void drawTx(){
|
||||
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);
|
||||
}
|
||||
else{
|
||||
@ -808,65 +808,6 @@ void switchBand(uint32_t bandfreq){
|
||||
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){
|
||||
//Serial.print(F("Doing command: "));
|
||||
//Serial.print(button->text);
|
||||
@ -957,14 +898,9 @@ void doCommand(Button* button){
|
||||
enterFreq();
|
||||
break;
|
||||
}
|
||||
case BUTTON_WPM:
|
||||
case BUTTON_MNU:
|
||||
{
|
||||
setCwSpeed();
|
||||
break;
|
||||
}
|
||||
case BUTTON_TON:
|
||||
{
|
||||
setCwTone();
|
||||
doSetup2();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1017,20 +953,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));
|
||||
|
||||
@ -1050,27 +983,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();
|
||||
|
||||
|
@ -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[128];
|
||||
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();
|
||||
@ -473,13 +474,14 @@ void setup()
|
||||
|
||||
//Run initial calibration routine if button is pressed during power up
|
||||
if(btnDown()){
|
||||
LoadDefaultSettings();
|
||||
setupTouch();
|
||||
SetActiveVfoMode(VfoMode_e::VFO_MODE_USB);
|
||||
setFrequency(10000000l);
|
||||
setupFreq();
|
||||
setFrequency(10000000L);
|
||||
runLocalOscSetting();
|
||||
SetActiveVfoMode(VfoMode_e::VFO_MODE_LSB);
|
||||
setFrequency(7100000l);
|
||||
setupBFO();
|
||||
setFrequency(7100000L);
|
||||
runBfoSetting();
|
||||
}
|
||||
|
||||
guiUpdate();
|
||||
|
Loading…
x
Reference in New Issue
Block a user