diff --git a/STM32F072xB.ld b/STM32F072xB.ld index 577e87f..b1f2ea2 100644 --- a/STM32F072xB.ld +++ b/STM32F072xB.ld @@ -19,14 +19,14 @@ */ MEMORY { - flash0 : org = 0x08000000, len = 96k + flash0 : org = 0x08000000, len = 104k flash1 : org = 0x00000000, len = 0 flash2 : org = 0x00000000, len = 0 flash3 : org = 0x00000000, len = 0 flash4 : org = 0x00000000, len = 0 flash5 : org = 0x00000000, len = 0 flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x08018000, len = 32k + flash7 : org = 0x0801C000, len = 16k ram0 : org = 0x20000000, len = 16k ram1 : org = 0x00000000, len = 0 ram2 : org = 0x00000000, len = 0 diff --git a/ili9341.c b/ili9341.c index 0cd5ad2..f423b19 100644 --- a/ili9341.c +++ b/ili9341.c @@ -524,7 +524,7 @@ void ili9341_clear_screen(void) { ili9341_fill(0, 0, ILI9341_WIDTH, ILI9341_HEIGHT, background_color); } - +#if 0 void ili9341_set_foreground(uint16_t fg) { foreground_color = fg; @@ -534,7 +534,7 @@ void ili9341_set_background(uint16_t bg) { background_color = bg; } - +#endif void ili9341_set_rotation(uint8_t r) { // static const uint8_t rotation_const[]={DISPLAY_ROTATION_0, DISPLAY_ROTATION_90, diff --git a/main.c b/main.c index 424b80c..51a7e6e 100644 --- a/main.c +++ b/main.c @@ -117,7 +117,7 @@ const char *info_about[]={ 0 // sentinel }; -static THD_WORKING_AREA(waThread1, 750); +static THD_WORKING_AREA(waThread1, 730); static THD_FUNCTION(Thread1, arg) { (void)arg; @@ -813,10 +813,10 @@ static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, reserved, }; static const marker_t def_markers[MARKERS_MAX] = { - { 1, M_REFERENCE, 30, 0 }, - { 0, M_NORMAL, 40, 0 }, - { 0, M_NORMAL, 60, 0 }, - { 0, M_NORMAL, 80, 0 } + { M_TRACKING_ENABLED, M_REFERENCE, 30, 0 }, + { M_DISABLED, M_NORMAL, 40, 0 }, + { M_DISABLED, M_NORMAL, 60, 0 }, + { M_DISABLED, M_NORMAL, 80, 0 } }; // Load propeties default settings @@ -2140,7 +2140,7 @@ VNA_SHELL_FUNCTION(cmd_threads) thread_t *tp; (void)argc; (void)argv; - shell_printf("stklimit| stack|stk free| addr|refs|prio| state| name"VNA_SHELL_NEWLINE_STR); + shell_printf("stklimit| |stk free| addr|refs|prio| state| name"VNA_SHELL_NEWLINE_STR); tp = chRegFirstThread(); do { uint32_t max_stack_use = 0U; diff --git a/nanovna.h b/nanovna.h index 276df10..82d5efa 100644 --- a/nanovna.h +++ b/nanovna.h @@ -199,8 +199,8 @@ extern int _height; #define CELLWIDTH (32) #define CELLHEIGHT (32) -//#define NGRIDY 10 -#define NGRIDY 9 +#define NGRIDY 10 +//#define NGRIDY 9 #define FREQUENCIES_XPOS1 OFFSETX #define FREQUENCIES_XPOS2 200 @@ -316,7 +316,11 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]); #endif // marker enum { - M_REFERENCE, M_NORMAL, M_DELTA + M_REFERENCE, M_NORMAL, M_DELTA, M_TRACKING +}; + +enum { + M_DISABLED, M_ENABLED, M_TRACKING_ENABLED }; typedef struct { @@ -404,8 +408,13 @@ void ili9341_init(void); void ili9341_test(int mode); void ili9341_bulk(int x, int y, int w, int h); void ili9341_fill(int x, int y, int w, int h, int color); +#if 0 void ili9341_set_foreground(uint16_t fg); void ili9341_set_background(uint16_t fg); +#else +#define ili9341_set_foreground(fg) { foreground_color = fg; } +#define ili9341_set_background(bg) { background_color = bg;} +#endif void ili9341_clear_screen(void); void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap); void ili9341_drawchar(uint8_t ch, int x, int y); @@ -427,15 +436,15 @@ void show_logo(void); #if 1 #define SAVEAREA_MAX 5 // Begin addr 0x08018000 -#define SAVE_CONFIG_AREA_SIZE 0x00008000 +#define SAVE_CONFIG_AREA_SIZE 0x00000800 // config save area -#define SAVE_CONFIG_ADDR 0x08018000 +#define SAVE_CONFIG_ADDR 0x0801C000 // properties_t save area -#define SAVE_PROP_CONFIG_0_ADDR 0x08018800 -#define SAVE_PROP_CONFIG_1_ADDR 0x0801a000 -#define SAVE_PROP_CONFIG_2_ADDR 0x0801b800 -#define SAVE_PROP_CONFIG_3_ADDR 0x0801d000 -#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 +#define SAVE_PROP_CONFIG_0_ADDR 0x0801C800 +#define SAVE_PROP_CONFIG_1_ADDR 0x0801D000 +#define SAVE_PROP_CONFIG_2_ADDR 0x0801D800 +#define SAVE_PROP_CONFIG_3_ADDR 0x0801E000 +#define SAVE_PROP_CONFIG_4_ADDR 0x0801E800 #else #define SAVEAREA_MAX 4 // Begin addr 0x0801C000 diff --git a/plot.c b/plot.c index 56748a3..a6e4bad 100644 --- a/plot.c +++ b/plot.c @@ -1465,10 +1465,10 @@ draw_all_cells(bool flush_markmap) if (waterfall) { for (m = 226; m >= HEIGHT+3; m -= 1) { // Scroll down uint16_t *buf = &spi_buffer[0]; - ili9341_read_memory(5*5, m, area_width, 1, area_width, buf); - ili9341_bulk(5*5,m+1, area_width,1); + ili9341_read_memory(5*5, m, 290, 1, 290, buf); + ili9341_bulk(5*5,m+1, 290,1); } - for (int i=0; i actual_t[i]) { // Follow down + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + } else if (temppeakLevel + MAX_NOISE < actual_t[i]) { // Local minimum found + temppeakIndex = i; // This is now the latest maximum + temppeakLevel = actual_t[i]; + downslope = false; + } + } else { + if (temppeakLevel < actual_t[i]) { // Follow up + temppeakIndex = i; + temppeakLevel = actual_t[i]; + } else if (temppeakLevel - MAX_NOISE > actual_t[i]) { // Local max found + + int j = 0; // Insertion index + while (j= temppeakLevel) // Find where to insert + j++; + if (j < MAX_MAX) { // Larger then one of the previous found + int k = MAX_MAX-1; + while (k > j) { // Shift to make room for max + max_index[k] = max_index[k-1]; +// maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging + k--; + } + max_index[j] = temppeakIndex; +// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging + if (cur_max < MAX_MAX) { + cur_max++; + } +//STOP_PROFILE + } + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + + downslope = true; + } + } +#else if (frequencies[i] > 1000000) { if (temppeakLevel < actual_t[i]) { temppeakIndex = i; @@ -626,7 +679,7 @@ static bool sweep(bool break_on_operation) } if (temp_min_level > actual_t[i]) temp_min_level = actual_t[i]; -//STOP_PROFILE +#endif } // if (setting_spur == 1) { // setting_spur = -1; @@ -638,9 +691,37 @@ static bool sweep(bool break_on_operation) scandirty = false; draw_cal_status(); } - peakIndex = temppeakIndex; +#if 1 + int i = 0; + int m = 0; + while (i < cur_max) { // For all maxima found + while (m < MARKERS_MAX) { + if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found + markers[m].index = max_index[i]; + markers[m].frequency = frequencies[markers[m].index]; + m++; + break; // Next maximum + } + m++; // Try next marker + } + i++; + } + while (m < MARKERS_MAX) { + if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found + markers[m].index = 0; // Enabled but no max + markers[m].frequency = frequencies[markers[m].index]; + } + m++; // Try next marker + } + peakIndex = max_index[0]; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; +#else + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; +#endif min_level = temp_min_level; #if 0 // Auto ref level setting int scale = get_trace_scale(2); @@ -655,80 +736,12 @@ static bool sweep(bool break_on_operation) } #endif - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; // redraw_marker(peak_marker, FALSE); palSetPad(GPIOC, GPIOC_LED); return true; } -#if 0 -void PeakSearch() -{ -#define PEAKSTACK 4 -#define PEAKDISTANCE 10 - int level = 0; - int searchLeft[PEAKSTACK]; - int peakIndex[PEAKSTACK]; - int peak_marker = 0; - searchLeft[level] = true; - peakIndex[level] = markers[peak_marker].index; - level++; - searchLeft[level] = true; - int peakFrom; - int peakTo; - while (peak_marker < 4){ - if (searchLeft[level]) - { - int fromLevel = level; - while (fromLevel > 0 && searchLeft[fromLevel]) - fromLevel-- - if(fromLevel == 0) { - peakFrom = PEAKDISTANCE; - } else { - peakFrom = peakIndex[fromLevel] + PEAKDISTANCE; - } - peakTo = peakIndex[level] - PEAKDISTANCE; - } else { - int toLevel = level; - while (toLevel > 0 && !searchLeft[toLevel]) - toLevel-- - if(toLevel == 0) { - peakTo = POINTS_COUNT - 1 - PEAKDISTANCE; - } else { - peakTo = peakIndex[fromLevel] - PEAKDISTANCE; - } - peakFrom = peakIndex[level] + PEAKDISTANCE; - } - float peakMax = actual_t[peakFrom]; - int peakIndex = peakFrom; - for (int i = peakFrom; i < peakTo; i++) { - if (peakMax < actual_t[i]) { - peakMax = actual_t[i]; - peakIndex = i; - } - } - - - peakIndex = temppeakIndex; - peakLevel = actual_t[peakIndex]; - peakFreq = frequencies[peakIndex]; - setting_spur = -setting_spur; - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; -// redraw_marker(peak_marker, FALSE); - - -} - -} -#endif - const char *averageText[] = { "OFF", "MIN", "MAX", "2", "4", "8"}; const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; diff --git a/ui.c b/ui.c index 544d47b..6fc675c 100644 --- a/ui.c +++ b/ui.c @@ -434,10 +434,13 @@ enum { MT_CALLBACK, MT_CANCEL, MT_TITLE, - MT_CLOSE + MT_CLOSE, + MT_KEYPAD }; -#define MT_FORM 0x80 // Or with menu type to get large button with current value -#define MT_MASK(x) (0x7F & (x)) +#define MT_FORM 0x80 // Or with menu type to get large button with current value +#define MT_BACK 0x40 +#define MT_LEAVE 0x20 +#define MT_MASK(x) (0xF & (x)) typedef void (*menuaction_cb_t)(int item, uint8_t data); @@ -767,15 +770,15 @@ menu_marker_op_cb(int item, uint8_t data) static void menu_marker_search_cb(int item, uint8_t data) { - (void)data; + (void)item; int i = -1; if (active_marker == -1) return; - switch (item) { + switch (data) { case 0: /* maximum */ case 1: /* minimum */ - set_marker_search(item); + set_marker_search(data); i = marker_search(); break; case 2: /* search Left */ @@ -830,18 +833,18 @@ menu_marker_sel_cb(int item, uint8_t data) if (markers[item].enabled) { if (item == active_marker) { // disable if active trace is selected - markers[item].enabled = FALSE; + markers[item].enabled = M_DISABLED; active_marker_select(-1); } else { active_marker_select(item); } } else { - markers[item].enabled = TRUE; + markers[item].enabled = M_TRACKING_ENABLED; // default tracking enabled active_marker_select(item); } } else if (item == 4) { /* all off */ for (t = 0; t < MARKERS_MAX; t++) - markers[t].enabled = FALSE; + markers[t].enabled = M_DISABLED; previous_marker = -1; active_marker = -1; } else if (item == 5) { /* marker delta */ @@ -1088,7 +1091,7 @@ ensure_selection(void) { const menuitem_t *menu = menu_stack[menu_current_level]; int i; - for (i = 0; MT_MASK(menu[i].type) != MT_NONE; i++) + for (i = 0; MT_MASK(menu[i].type) != MT_NONE && MT_MASK(menu[i].type) != MT_TITLE ; i++) ; if (selection >= i) selection = i-1; @@ -1145,10 +1148,11 @@ menu_move_top(void) static void menu_invoke(int item) { + int status; const menuitem_t *menu = menu_stack[menu_current_level]; menu = &menu[item]; - switch (menu->type & 0x0f) { + switch (MT_MASK(menu->type)) { case MT_NONE: case MT_BLANK: case MT_CLOSE: @@ -1164,12 +1168,30 @@ menu_invoke(int item) if (cb == NULL) return; (*cb)(item, menu->data); + if (!(menu->type & MT_FORM)) + draw_cal_status(); break; } case MT_SUBMENU: menu_push_submenu((const menuitem_t*)menu->reference); break; + + case MT_KEYPAD: + status = btn_wait_release(); + if (status & EVT_BUTTON_DOWN_LONG) { + ui_mode_numeric(menu->data); + // ui_process_numeric(); + } else { + if (menu->type & MT_FORM) { + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; + redraw_frame(); // Remove form numbers + } + ui_mode_keypad(menu->data); + ui_process_keypad(); + } + draw_cal_status(); + break; } } @@ -1306,14 +1328,22 @@ draw_keypad(void) i++; } } +static int +menu_is_multiline(const char *label, const char **l1, const char **l2); static void draw_numeric_area_frame(void) { + const char *l1; + const char *l2; ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, config.menu_normal_color); ili9341_set_foreground(DEFAULT_MENU_TEXT_COLOR); ili9341_set_background(config.menu_normal_color); - ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); + if (menu_is_multiline(keypad_mode_label[keypad_mode], &l1, &l2)) { + ili9341_drawstring_7x13(l1, 10, 240-NUM_INPUT_HEIGHT+1); + ili9341_drawstring_7x13(l2, 10, 240-NUM_INPUT_HEIGHT/2 + 1); + } else + ili9341_drawstring_7x13(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); //ili9341_drawfont(KP_KEYPAD, 300, 216); } @@ -1482,7 +1512,7 @@ draw_menu_buttons(const menuitem_t *menu) if (menu[i].type & MT_FORM) { active_button_start = 320 - MENU_FORM_WIDTH; active_button_width = MENU_FORM_WIDTH - 30; // Shorten at the right - if (MT_MASK(menu[i].type) == MT_CALLBACK) { // Only callback can have value + if (MT_MASK(menu[i].type) == MT_KEYPAD) { // Only keypad retrieves value keypad_mode = menu[i].data; fetch_numeric_target(); } @@ -1737,7 +1767,7 @@ ui_mode_numeric(int _keypad_mode) static void ui_mode_keypad(int _keypad_mode) { - if (ui_mode == UI_KEYPAD) + if (ui_mode == UI_KEYPAD && keypad_mode == _keypad_mode ) return; // keypads array @@ -2307,6 +2337,7 @@ void ui_process_touch(void) // switch menu mode after release touch_wait_release(); selection = -1; // hide keyboard mode selection + ensure_selection(); ui_mode_menu(); break; case UI_MENU: @@ -2329,6 +2360,7 @@ ui_process(void) int button_state = READ_PORT() & BUTTON_MASK; if (ui_mode == UI_NORMAL && current_menu_is_form()) { // Force into menu mode selection = -1; // hide keyboard mode selection + ensure_selection(); ui_mode_menu(); } if (operation_requested&OP_LEVER || previous_button_state != button_state) { diff --git a/ui_sa.c b/ui_sa.c index d997f30..58875ca 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -167,7 +167,7 @@ static const char * const keypad_mode_label[] = { #endif #ifdef __SA__ static const char * const keypad_mode_label[] = { - "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "ATTENUATION", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL" + "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL" }; #endif @@ -216,9 +216,9 @@ void menu_autosettings_cb(int item, uint8_t data) active_marker = 0; for (int i = 1; i= 0 && markers[active_marker].enabled) { + if (item == 3 && markers[active_marker].enabled == M_TRACKING_ENABLED) + mark = true; + else if (item == markers[active_marker].mtype) + mark = true; + } else if (menu == menu_marker_sel) { + if (item < MARKERS_MAX && markers[item].enabled) + mark = true; + } + if (mark) { + *bg = DEFAULT_MENU_TEXT_COLOR; + *fg = config.menu_normal_color; } if (ui_mode == UI_MENU && menu_is_form(menu)) { // if (item == 0) // redraw_frame(); if (item <= 1) { - area_width = 0; -#if 0 - // area_height = HEIGHT - 32; - int y = MENU_BUTTON_HEIGHT*item; - uint16_t bg = config.menu_normal_color; - uint16_t fg = DEFAULT_MENU_TEXT_COLOR; - // ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); - ili9341_set_foreground(fg); - ili9341_set_background(bg); - char buf[15]; - ili9341_fill(50+25, y, 170, MENU_BUTTON_HEIGHT-2, bg); - if (menu == menu_lowoutputmode) { - switch (item) { - case 0: - set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode - plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); - break; - case 1: - plot_printf(buf, sizeof buf, "%ddB", -10 - setting_attenuate); - break; - } - } - if (menu == menu_highoutputmode) { - switch (item) { - case 0: - set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode - plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); - break; - case 1: - plot_printf(buf, sizeof buf, "%ddB", -10 - setting_drive); - break; - } - } - ili9341_drawstring_size(buf, 130, y+6, 2); -#endif } }else{ area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH;