From 77b5d0bcc87ade5d4e76bf108880cfb82c10f841 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 8 Mar 2020 22:48:36 +0300 Subject: [PATCH 01/24] Select CH0 reflect channel before set freq (in some rare cases dsp started but CH not ready) Little code optimization Add commented 600kHz I2C bus timings (work, give x1.5 speed, but need change DSP ready timings not by wait_count, need use chVTGetSystemTimeX() its better) --- main.c | 43 +++++++++++++++---------------------------- plot.c | 32 +++++++++++--------------------- si5351.c | 2 +- 3 files changed, 27 insertions(+), 50 deletions(-) diff --git a/main.c b/main.c index c6c5a961..5bc5603b 100644 --- a/main.c +++ b/main.c @@ -787,8 +787,8 @@ bool sweep(bool break_on_operation) // Also touch made some DSP_START(1); DSP_WAIT_READY; for (i = 0; i < sweep_points; i++) { // 5300 - delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT + delay = set_frequency(frequencies[i]); // 700 DSP_START(delay); // 1900 //================================================ // Place some code thats need execute while delay @@ -1296,35 +1296,18 @@ void cal_collect(int type) { ensure_edit_config(); - + int dst, src; switch (type) { - case CAL_LOAD: - cal_status |= CALSTAT_LOAD; - memcpy(cal_data[CAL_LOAD], measured[0], sizeof measured[0]); - break; - - case CAL_OPEN: - cal_status |= CALSTAT_OPEN; - cal_status &= ~(CALSTAT_ES|CALSTAT_APPLY); - memcpy(cal_data[CAL_OPEN], measured[0], sizeof measured[0]); - break; - - case CAL_SHORT: - cal_status |= CALSTAT_SHORT; - cal_status &= ~(CALSTAT_ER|CALSTAT_APPLY); - memcpy(cal_data[CAL_SHORT], measured[0], sizeof measured[0]); - break; - - case CAL_THRU: - cal_status |= CALSTAT_THRU; - memcpy(cal_data[CAL_THRU], measured[1], sizeof measured[0]); - break; - - case CAL_ISOLN: - cal_status |= CALSTAT_ISOLN; - memcpy(cal_data[CAL_ISOLN], measured[1], sizeof measured[0]); - break; + case CAL_LOAD: cal_status|= CALSTAT_LOAD; dst = CAL_LOAD; src = 0; break; + case CAL_OPEN: cal_status|= CALSTAT_OPEN; dst = CAL_OPEN; src = 0; cal_status&= ~(CALSTAT_ES|CALSTAT_APPLY); break; + case CAL_SHORT: cal_status|= CALSTAT_SHORT; dst = CAL_SHORT; src = 0; cal_status&= ~(CALSTAT_ER|CALSTAT_APPLY); break; + case CAL_THRU: cal_status|= CALSTAT_THRU; dst = CAL_THRU; src = 1; break; + case CAL_ISOLN: cal_status|= CALSTAT_ISOLN; dst = CAL_ISOLN; src = 1; break; + default: + return; } + // Copy calibration data + memcpy(cal_data[dst], measured[src], sizeof measured[0]); redraw_request |= REDRAW_CAL_STATUS; } @@ -2209,6 +2192,10 @@ static const I2CConfig i2ccfg = { STM32_TIMINGR_PRESC(5U) | STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) | STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), + // 600kHz @ SYSCLK 48MHz, manually get values, x1.5 I2C speed, but need calc timings +// STM32_TIMINGR_PRESC(3U) | +// STM32_TIMINGR_SCLDEL(2U) | STM32_TIMINGR_SDADEL(2U) | +// STM32_TIMINGR_SCLH(4U) | STM32_TIMINGR_SCLL(4U), #else #error "Need Define STM32_I2C1SW and set correct TIMINGR settings" #endif diff --git a/plot.c b/plot.c index 5d712a61..498aa886 100644 --- a/plot.c +++ b/plot.c @@ -1636,27 +1636,17 @@ draw_cal_status(void) ili9341_drawstring(c, x, y); y += YSTEP; } - - if (cal_status & CALSTAT_ED) { - ili9341_drawstring("D", x, y); - y += YSTEP; - } - if (cal_status & CALSTAT_ER) { - ili9341_drawstring("R", x, y); - y += YSTEP; - } - if (cal_status & CALSTAT_ES) { - ili9341_drawstring("S", x, y); - y += YSTEP; - } - if (cal_status & CALSTAT_ET) { - ili9341_drawstring("T", x, y); - y += YSTEP; - } - if (cal_status & CALSTAT_EX) { - ili9341_drawstring("X", x, y); - y += YSTEP; - } + int i; + static const struct {char text, zero, mask;} calibration_text[]={ + {'D', 0, CALSTAT_ED}, + {'R', 0, CALSTAT_ER}, + {'S', 0, CALSTAT_ES}, + {'T', 0, CALSTAT_ET}, + {'X', 0, CALSTAT_EX} + }; + for (i = 0; i < 5; i++, y+= YSTEP) + if (cal_status & calibration_text[i].mask) + ili9341_drawstring(&calibration_text[i].text, x, y); } // Draw battery level diff --git a/si5351.c b/si5351.c index 92eeb8ae..9b3511b6 100644 --- a/si5351.c +++ b/si5351.c @@ -338,7 +338,7 @@ static inline uint8_t si5351_getBand(uint32_t freq){ // Minimum value is 2, freq change apply at next dsp measure, and need skip it #define DELAY_NORMAL 2 // Additional delay for band 1 (remove unstable generation at begin) -#define DELAY_BAND_1 1 +#define DELAY_BAND_1 1 // Band changes need additional delay after reset PLL #define DELAY_BANDCHANGE_1 2 #define DELAY_BANDCHANGE_2 2 From a2d90a5e9197ba4508f69a828b04dc7a403b1644 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 9 Mar 2020 01:25:46 +0300 Subject: [PATCH 02/24] Try not lost data on dsp (Less noise on small signals) Use int64_t acc for values Use double on calculation Not cache freq on si5351_set_frequency_with_offset (to fast change in rare cases on cw mode, and process wrong DSP block) as i write before need change DSP delay tactic --- dsp.c | 79 +++++++++++++++++++++++++++++++------------------------- si5351.c | 6 ++--- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/dsp.c b/dsp.c index 6e9f607c..2f5f97ed 100644 --- a/dsp.c +++ b/dsp.c @@ -41,48 +41,57 @@ const int16_t sincos_tbl[48][2] = { {-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 } }; -int32_t acc_samp_s; -int32_t acc_samp_c; -int32_t acc_ref_s; -int32_t acc_ref_c; +int64_t acc_samp_s; +int64_t acc_samp_c; +int64_t acc_ref_s; +int64_t acc_ref_c; void dsp_process(int16_t *capture, size_t length) { - uint32_t *p = (uint32_t*)capture; - uint32_t len = length / 2; uint32_t i; - int32_t samp_s = 0; - int32_t samp_c = 0; - int32_t ref_s = 0; - int32_t ref_c = 0; - - for (i = 0; i < len; i++) { - uint32_t sr = *p++; - int16_t ref = sr & 0xffff; - int16_t smp = (sr>>16) & 0xffff; +#if 1 + acc_samp_s = 0; + acc_samp_c = 0; + acc_ref_s = 0; + acc_ref_c = 0; + for (i = 0; i < length; i+=2) { + int32_t ref = capture[i+0]; + int32_t smp = capture[i+1]; #ifdef ENABLED_DUMP ref_buf[i] = ref; samp_buf[i] = smp; #endif - int32_t s = sincos_tbl[i][0]; - int32_t c = sincos_tbl[i][1]; - samp_s += smp * s / 16; - samp_c += smp * c / 16; - ref_s += ref * s / 16; - ref_c += ref * c / 16; -#if 0 - uint32_t sc = *(uint32_t)&sincos_tbl[i]; - samp_s = __SMLABB(sr, sc, samp_s); - samp_c = __SMLABT(sr, sc, samp_c); - ref_s = __SMLATB(sr, sc, ref_s); - ref_c = __SMLATT(sr, sc, ref_c); -#endif + int32_t s = ((int16_t *)sincos_tbl)[i+0]; + int32_t c = ((int16_t *)sincos_tbl)[i+1]; + acc_samp_s += (smp * s); + acc_samp_c += (smp * c); + acc_ref_s += (ref * s); + acc_ref_c += (ref * c); + } +#else + uint32_t len = length / 2; + int64_t samp_s = 0; + int64_t samp_c = 0; + int64_t ref_s = 0; + int64_t ref_c = 0; + // HI LO + int32_t *cos_sin = (int32_t *)sincos_tbl; + int32_t *ref_smp = (int32_t *)capture; + for (i = 0; i < len; i++) { + // + samp_s = __SMLALBB(*ref_smp, *cos_sin, samp_s); // samp_s+= smp * sin + samp_c = __SMLALBT(*ref_smp, *cos_sin, samp_c); // samp_c+= smp * cos + ref_s = __SMLALTB(*ref_smp, *cos_sin, ref_s); // ref_s += ref * sin + ref_c = __SMLALTT(*ref_smp, *cos_sin, ref_c); // ref_s += ref * cos + ref_smp++; + cos_sin++; } acc_samp_s = samp_s; acc_samp_c = samp_c; - acc_ref_s = ref_s; - acc_ref_c = ref_c; + acc_ref_s = ref_s; + acc_ref_c = ref_c; +#endif } void @@ -90,12 +99,12 @@ calculate_gamma(float gamma[2]) { #if 1 // calculate reflection coeff. by samp divide by ref - float rs = acc_ref_s; - float rc = acc_ref_c; - float rr = rs * rs + rc * rc; + double rs = acc_ref_s; + double rc = acc_ref_c; + double rr = rs * rs + rc * rc; //rr = sqrtf(rr) * 1e8; - float ss = acc_samp_s; - float sc = acc_samp_c; + double ss = acc_samp_s; + double sc = acc_samp_c; gamma[0] = (sc * rc + ss * rs) / rr; gamma[1] = (ss * rc - sc * rs) / rr; #elif 0 diff --git a/si5351.c b/si5351.c index 9b3511b6..a43a3133 100644 --- a/si5351.c +++ b/si5351.c @@ -354,13 +354,13 @@ int si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength){ uint8_t band; int delay = DELAY_NORMAL; - if (freq == current_freq) - return delay; +// if (freq == current_freq) +// return delay; uint32_t ofreq = freq + offset; uint32_t mul = 1, omul = 1; uint32_t rdiv = SI5351_R_DIV_1; uint32_t fdiv; - current_freq = freq; +// current_freq = freq; if (freq >= config.harmonic_freq_threshold * 7U) { mul = 9; omul = 11; From 5cf86ee1a6ef47ac63a01c19c88a6f70f58602b5 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 9 Mar 2020 10:28:33 +0300 Subject: [PATCH 03/24] Revert dsp changes, need more research --- dsp.c | 79 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/dsp.c b/dsp.c index 2f5f97ed..6e9f607c 100644 --- a/dsp.c +++ b/dsp.c @@ -41,57 +41,48 @@ const int16_t sincos_tbl[48][2] = { {-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 } }; -int64_t acc_samp_s; -int64_t acc_samp_c; -int64_t acc_ref_s; -int64_t acc_ref_c; +int32_t acc_samp_s; +int32_t acc_samp_c; +int32_t acc_ref_s; +int32_t acc_ref_c; void dsp_process(int16_t *capture, size_t length) { + uint32_t *p = (uint32_t*)capture; + uint32_t len = length / 2; uint32_t i; -#if 1 - acc_samp_s = 0; - acc_samp_c = 0; - acc_ref_s = 0; - acc_ref_c = 0; - for (i = 0; i < length; i+=2) { - int32_t ref = capture[i+0]; - int32_t smp = capture[i+1]; + int32_t samp_s = 0; + int32_t samp_c = 0; + int32_t ref_s = 0; + int32_t ref_c = 0; + + for (i = 0; i < len; i++) { + uint32_t sr = *p++; + int16_t ref = sr & 0xffff; + int16_t smp = (sr>>16) & 0xffff; #ifdef ENABLED_DUMP ref_buf[i] = ref; samp_buf[i] = smp; #endif - int32_t s = ((int16_t *)sincos_tbl)[i+0]; - int32_t c = ((int16_t *)sincos_tbl)[i+1]; - acc_samp_s += (smp * s); - acc_samp_c += (smp * c); - acc_ref_s += (ref * s); - acc_ref_c += (ref * c); - } -#else - uint32_t len = length / 2; - int64_t samp_s = 0; - int64_t samp_c = 0; - int64_t ref_s = 0; - int64_t ref_c = 0; - // HI LO - int32_t *cos_sin = (int32_t *)sincos_tbl; - int32_t *ref_smp = (int32_t *)capture; - for (i = 0; i < len; i++) { - // - samp_s = __SMLALBB(*ref_smp, *cos_sin, samp_s); // samp_s+= smp * sin - samp_c = __SMLALBT(*ref_smp, *cos_sin, samp_c); // samp_c+= smp * cos - ref_s = __SMLALTB(*ref_smp, *cos_sin, ref_s); // ref_s += ref * sin - ref_c = __SMLALTT(*ref_smp, *cos_sin, ref_c); // ref_s += ref * cos - ref_smp++; - cos_sin++; + int32_t s = sincos_tbl[i][0]; + int32_t c = sincos_tbl[i][1]; + samp_s += smp * s / 16; + samp_c += smp * c / 16; + ref_s += ref * s / 16; + ref_c += ref * c / 16; +#if 0 + uint32_t sc = *(uint32_t)&sincos_tbl[i]; + samp_s = __SMLABB(sr, sc, samp_s); + samp_c = __SMLABT(sr, sc, samp_c); + ref_s = __SMLATB(sr, sc, ref_s); + ref_c = __SMLATT(sr, sc, ref_c); +#endif } acc_samp_s = samp_s; acc_samp_c = samp_c; - acc_ref_s = ref_s; - acc_ref_c = ref_c; -#endif + acc_ref_s = ref_s; + acc_ref_c = ref_c; } void @@ -99,12 +90,12 @@ calculate_gamma(float gamma[2]) { #if 1 // calculate reflection coeff. by samp divide by ref - double rs = acc_ref_s; - double rc = acc_ref_c; - double rr = rs * rs + rc * rc; + float rs = acc_ref_s; + float rc = acc_ref_c; + float rr = rs * rs + rc * rc; //rr = sqrtf(rr) * 1e8; - double ss = acc_samp_s; - double sc = acc_samp_c; + float ss = acc_samp_s; + float sc = acc_samp_c; gamma[0] = (sc * rc + ss * rs) / rr; gamma[1] = (ss * rc - sc * rs) / rr; #elif 0 From 90407d5730edf9ffb9d8a34090ea85dae5006958 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 9 Mar 2020 13:12:01 +0300 Subject: [PATCH 04/24] Fix screen artifacts: In mark_cells_from_index(void) mark all rectangle (in most cases this not decrease render speed, and more fast in calculation, and no errors) --- plot.c | 50 +++++++++++++++----------------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/plot.c b/plot.c index 498aa886..9fa1c07f 100644 --- a/plot.c +++ b/plot.c @@ -787,48 +787,29 @@ invalidateRect(int x0, int y0, int x1, int y1){ mark_map(x, y); } +#define SWAP(x,y) {int t=x;x=y;y=t;} + static void mark_cells_from_index(void) { - int t; + int t, i; /* mark cells between each neighber points */ for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - int x0 = CELL_X(trace_index[t][0]); - int y0 = CELL_Y(trace_index[t][0]); - int m0 = x0 / CELLWIDTH; - int n0 = y0 / CELLHEIGHT; - int i; - mark_map(m0, n0); + int m0 = CELL_X(trace_index[t][0]) / CELLWIDTH; + int n0 = CELL_Y(trace_index[t][0]) / CELLHEIGHT; + markmap[current_mappage][n0] |= 1<x1) SWAP(x0, x1); m0=m1; + int y0 = n0; int y1 = n1; if (y0>y1) SWAP(y0, y1); n0=n1; + for (; y0<=y1; y0++) + for(int j=x0;j<=x1;j++) + markmap[current_mappage][y0]|= 1< Date: Mon, 9 Mar 2020 14:08:06 +0300 Subject: [PATCH 05/24] Reduce last patch fix size (use pointers) --- plot.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/plot.c b/plot.c index 9fa1c07f..9996d911 100644 --- a/plot.c +++ b/plot.c @@ -792,24 +792,26 @@ invalidateRect(int x0, int y0, int x1, int y1){ static void mark_cells_from_index(void) { - int t, i; + int t, i, j; /* mark cells between each neighber points */ + uint16_t *map = &markmap[current_mappage][0]; for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - int m0 = CELL_X(trace_index[t][0]) / CELLWIDTH; - int n0 = CELL_Y(trace_index[t][0]) / CELLHEIGHT; - markmap[current_mappage][n0] |= 1<x1) SWAP(x0, x1); m0=m1; int y0 = n0; int y1 = n1; if (y0>y1) SWAP(y0, y1); n0=n1; for (; y0<=y1; y0++) - for(int j=x0;j<=x1;j++) - markmap[current_mappage][y0]|= 1< Date: Mon, 9 Mar 2020 14:22:59 +0300 Subject: [PATCH 06/24] Fix typo --- plot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plot.c b/plot.c index 9996d911..2475a87b 100644 --- a/plot.c +++ b/plot.c @@ -811,7 +811,7 @@ mark_cells_from_index(void) int y0 = n0; int y1 = n1; if (y0>y1) SWAP(y0, y1); n0=n1; for (; y0<=y1; y0++) for(j=x0; j<=x1; j++) - map[y0]|= 1< Date: Mon, 9 Mar 2020 14:40:17 +0300 Subject: [PATCH 07/24] Auto determine mark_map mask size from MAX_MARKMAP_X on compilation (up to MAX_MARKMAP_X = 32) --- plot.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plot.c b/plot.c index 2475a87b..8aaef85f 100644 --- a/plot.c +++ b/plot.c @@ -25,8 +25,17 @@ int16_t area_height = AREA_HEIGHT_NORMAL; // indicate dirty cells (not redraw if cell data not changed) #define MAX_MARKMAP_X ((320+CELLWIDTH-1)/CELLWIDTH) #define MAX_MARKMAP_Y ((240+CELLHEIGHT-1)/CELLHEIGHT) -uint16_t markmap[2][MAX_MARKMAP_Y]; -uint16_t current_mappage = 0; +// Define markmap mask size +#if MAX_MARKMAP_X <= 8 +typedef uint8_t map_t; +#elif MAX_MARKMAP_X <= 16 +typedef uint16_t map_t; +#elif MAX_MARKMAP_X <= 32 +typedef uint32_t map_t; +#endif + +map_t markmap[2][MAX_MARKMAP_Y]; +uint8_t current_mappage = 0; // Trace data cache, for faster redraw cells // CELL_X[16:31] x position @@ -794,7 +803,7 @@ mark_cells_from_index(void) { int t, i, j; /* mark cells between each neighber points */ - uint16_t *map = &markmap[current_mappage][0]; + map_t *map = &markmap[current_mappage][0]; for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; @@ -1343,8 +1352,7 @@ draw_all_cells(bool flush_markmap){ // START_PROFILE for (m = 0; m < (area_width+CELLWIDTH-1) / CELLWIDTH; m++) for (n = 0; n < (area_height+CELLHEIGHT-1) / CELLHEIGHT; n++) { - uint16_t bit = 1< Date: Mon, 9 Mar 2020 16:18:29 +0300 Subject: [PATCH 08/24] Size fixes, use define exept const, typdef index_t for indexes --- plot.c | 55 +++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/plot.c b/plot.c index 8aaef85f..4e14ca7a 100644 --- a/plot.c +++ b/plot.c @@ -40,9 +40,10 @@ uint8_t current_mappage = 0; // Trace data cache, for faster redraw cells // CELL_X[16:31] x position // CELL_Y[ 0:15] y position -static uint32_t trace_index[TRACES_MAX][POINTS_COUNT]; +typedef uint32_t index_t; +static index_t trace_index[TRACES_MAX][POINTS_COUNT]; -#define INDEX(x, y) ((((uint32_t)x)<<16)|(((uint32_t)y))) +#define INDEX(x, y) ((((index_t)x)<<16)|(((index_t)y))) #define CELL_X(i) (int)(((i)>>16)) #define CELL_Y(i) (int)(((i)&0xFFFF)) //#define CELL_P(i, x, y) (((((x)&0x03e0UL)<<22) | (((y)&0x03e0UL)<<17)) == ((i)&0xffc00000UL)) @@ -516,7 +517,7 @@ gamma2reactance(const float v[2]) return 2*v[1] * d; } -static uint32_t +static index_t trace_into_index(int t, int i, float array[POINTS_COUNT][2]) { int y, x; @@ -766,7 +767,7 @@ mark_map(int x, int y) markmap[current_mappage][y] |= 1<= 0; i--) { - uint32_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(value, CELL_Y(index))) break; value = CELL_Y(index); } for (; i >= 0; i--) { - uint32_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(CELL_Y(index), value)) { break; } @@ -1115,14 +1116,14 @@ marker_search_right(int from) int value = CELL_Y(trace_index[uistat.current_trace][from]); for (i = from + 1; i < POINTS_COUNT; i++) { - uint32_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(value, CELL_Y(index))) break; value = CELL_Y(index); } for (; i < POINTS_COUNT; i++) { - uint32_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(CELL_Y(index), value)) { break; } @@ -1135,7 +1136,7 @@ marker_search_right(int from) int search_nearest_index(int x, int y, int t) { - uint32_t *index = trace_index[t]; + index_t *index = trace_index[t]; int min_i = -1; int min_d = 1000; int i; @@ -1164,8 +1165,9 @@ plot_into_index(float measured[2][POINTS_COUNT][2]) if (!trace[t].enabled) continue; int ch = trace[t].channel; + index_t *index = trace_index[t]; for (i = 0; i < sweep_points; i++) - trace_index[t][i] = trace_into_index(t, i, measured[ch]); + index[i] = trace_into_index(t, i, measured[ch]); } #if 0 for (t = 0; t < TRACES_MAX; t++) @@ -1281,7 +1283,7 @@ draw_cell(int m, int n) i1 = sweep_points-1; else // draw rectangular plot (search index range in cell, save 50-70 system ticks for all screen calls) search_index_range_x(x0, x0+w, trace_index[t], &i0, &i1); - uint32_t *index = trace_index[t]; + index_t *index = trace_index[t]; for (i=i0; i < i1; i++) { int x1 = CELL_X(index[i ]) - x0; int y1 = CELL_Y(index[i ]) - y0; @@ -1303,7 +1305,7 @@ draw_cell(int m, int n) for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - uint32_t index = trace_index[t][markers[i].index]; + index_t index = trace_index[t][markers[i].index]; int x = CELL_X(index) - x0 - X_MARKER_OFFSET; int y = CELL_Y(index) - y0 - Y_MARKER_OFFSET; // Check marker icon on cell @@ -1352,7 +1354,7 @@ draw_all_cells(bool flush_markmap){ // START_PROFILE for (m = 0; m < (area_width+CELLWIDTH-1) / CELLWIDTH; m++) for (n = 0; n < (area_height+CELLHEIGHT-1) / CELLHEIGHT; n++) { - if ((markmap[0][n]|markmap[1][n]) & (1< Date: Mon, 9 Mar 2020 18:24:31 +0300 Subject: [PATCH 09/24] Add flag in config for sweep mode #define FREQ_MODE_START_STOP 0x0 #define FREQ_MODE_CENTER_SPAN 0x1 Now sweep mode not defined from frequency0 > frequency1 or frequency0 < frequency1 frequency0 always < frequency1 All freq must get by use get_sweep_frequency(mode) Revert Select CH0 reflect channel before set freq, add additional delay on 0 sweep point --- main.c | 96 ++++++++++++++++--------------------------------------- nanovna.h | 15 ++++----- plot.c | 22 ++++++------- 3 files changed, 45 insertions(+), 88 deletions(-) diff --git a/main.c b/main.c index 5bc5603b..4ec00cc4 100644 --- a/main.c +++ b/main.c @@ -718,6 +718,7 @@ config_t config = { .trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR, DEFAULT_TRACE_4_COLOR }, // .touch_cal = { 693, 605, 124, 171 }, // 2.4 inch LCD panel .touch_cal = { 338, 522, 153, 192 }, // 2.8 inch LCD panel + .freq_mode = FREQ_MODE_START_STOP, .harmonic_freq_threshold = 300000000, .vbat_offset = 500 }; @@ -783,13 +784,11 @@ bool sweep(bool break_on_operation) int i, delay; // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); - // Power stabilization after LED off, also align timings - // Also touch made some - DSP_START(1); DSP_WAIT_READY; + // Power stabilization after LED off, also align timings on i == 0 for (i = 0; i < sweep_points; i++) { // 5300 - tlv320aic3204_select(0); // 60 CH0:REFLECT delay = set_frequency(frequencies[i]); // 700 - DSP_START(delay); // 1900 + tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure + DSP_START(delay+((i==0)?1:0)); // 1900 //================================================ // Place some code thats need execute while delay //================================================ @@ -797,7 +796,7 @@ bool sweep(bool break_on_operation) // calculate reflection coefficient (*sample_func)(measured[0][i]); // 60 - tlv320aic3204_select(1); // 60 CH1:TRANSMISSION + tlv320aic3204_select(1); // 60 CH1:TRANSMISSION, reset and begin measure DSP_START(DELAY_CHANNEL_CHANGE); // 1700 //================================================ // Place some code thats need execute while delay @@ -913,13 +912,8 @@ void update_frequencies(void) { uint32_t start, stop; - if (frequency0 < frequency1) { - start = frequency0; - stop = frequency1; - } else { - start = frequency1; - stop = frequency0; - } + start = get_sweep_frequency(ST_START); + stop = get_sweep_frequency(ST_STOP); set_frequencies(start, stop, sweep_points); // operation_requested|= OP_FREQCHANGE; @@ -930,28 +924,6 @@ update_frequencies(void) update_grid(); } -static void -freq_mode_startstop(void) -{ - if (frequency0 > frequency1) { - ensure_edit_config(); - uint32_t f = frequency1; - frequency1 = frequency0; - frequency0 = f; - } -} - -static void -freq_mode_centerspan(void) -{ - if (frequency0 <= frequency1) { - ensure_edit_config(); - uint32_t f = frequency1; - frequency1 = frequency0; - frequency0 = f; - } -} - void set_sweep_frequency(int type, uint32_t freq) { @@ -963,11 +935,11 @@ set_sweep_frequency(int type, uint32_t freq) if (freq > STOP_MAX) freq = STOP_MAX; + ensure_edit_config(); switch (type) { case ST_START: - freq_mode_startstop(); + config.freq_mode&=~FREQ_MODE_CENTER_SPAN; if (frequency0 != freq) { - ensure_edit_config(); frequency0 = freq; // if start > stop then make start = stop if (frequency1 < freq) @@ -975,9 +947,8 @@ set_sweep_frequency(int type, uint32_t freq) } break; case ST_STOP: - freq_mode_startstop(); + config.freq_mode&=~FREQ_MODE_CENTER_SPAN; if (frequency1 != freq) { - ensure_edit_config(); frequency1 = freq; // if start > stop then make start = stop if (frequency0 > freq) @@ -985,25 +956,23 @@ set_sweep_frequency(int type, uint32_t freq) } break; case ST_CENTER: - freq_mode_centerspan(); - uint32_t center = FREQ_CENTER(); + config.freq_mode|=FREQ_MODE_CENTER_SPAN; + uint32_t center = frequency0/2 + frequency1/2; if (center != freq) { - uint32_t span = FREQ_SPAN(); - ensure_edit_config(); + uint32_t span = frequency1 - frequency0; if (freq < START_MIN + span/2) { span = (freq - START_MIN) * 2; } if (freq > STOP_MAX - span/2) { span = (STOP_MAX - freq) * 2; } - frequency0 = freq + span/2; - frequency1 = freq - span/2; + frequency0 = freq - span/2; + frequency1 = freq + span/2; } break; case ST_SPAN: - freq_mode_centerspan(); - if (frequency0 - frequency1 != freq) { - ensure_edit_config(); + config.freq_mode|=FREQ_MODE_CENTER_SPAN; + if (frequency1 - frequency0 != freq) { uint32_t center = frequency0/2 + frequency1/2; if (center < START_MIN + freq/2) { center = START_MIN + freq/2; @@ -1011,14 +980,13 @@ set_sweep_frequency(int type, uint32_t freq) if (center > STOP_MAX - freq/2) { center = STOP_MAX - freq/2; } - frequency1 = center - freq/2; - frequency0 = center + freq/2; + frequency0 = center - freq/2; + frequency1 = center + freq/2; } break; case ST_CW: - freq_mode_centerspan(); + config.freq_mode|=FREQ_MODE_CENTER_SPAN; if (frequency0 != freq || frequency1 != freq) { - ensure_edit_config(); frequency0 = freq; frequency1 = freq; } @@ -1032,22 +1000,14 @@ set_sweep_frequency(int type, uint32_t freq) uint32_t get_sweep_frequency(int type) { - if (frequency0 <= frequency1) { - switch (type) { - case ST_START: return frequency0; - case ST_STOP: return frequency1; - case ST_CENTER: return frequency0/2 + frequency1/2; - case ST_SPAN: return frequency1 - frequency0; - case ST_CW: return frequency0/2 + frequency1/2; - } - } else { - switch (type) { - case ST_START: return frequency1; - case ST_STOP: return frequency0; + // Obsolete, ensure correct start/stop, start always must be < stop + if (frequency0>frequency1) {uint32_t t=frequency0; frequency0=frequency1; frequency1=t;} + switch (type) { + case ST_START: return frequency0; + case ST_STOP: return frequency1; case ST_CENTER: return frequency0/2 + frequency1/2; - case ST_SPAN: return frequency0 - frequency1; - case ST_CW: return frequency0/2 + frequency1/2; - } + case ST_SPAN: return frequency1 - frequency0; + case ST_CW: return frequency0; } return 0; } @@ -1055,7 +1015,7 @@ get_sweep_frequency(int type) VNA_SHELL_FUNCTION(cmd_sweep) { if (argc == 0) { - shell_printf("%d %d %d\r\n", frequency0, frequency1, sweep_points); + shell_printf("%d %d %d\r\n", get_sweep_frequency(ST_START), get_sweep_frequency(ST_STOP), sweep_points); return; } else if (argc > 3) { goto usage; diff --git a/nanovna.h b/nanovna.h index d5d14cc2..a618cb57 100644 --- a/nanovna.h +++ b/nanovna.h @@ -209,6 +209,9 @@ typedef struct trace { float refpos; } trace_t; +#define FREQ_MODE_START_STOP 0x0 +#define FREQ_MODE_CENTER_SPAN 0x1 + typedef struct config { int32_t magic; uint16_t dac_value; @@ -217,7 +220,7 @@ typedef struct config { uint16_t menu_active_color; uint16_t trace_color[TRACES_MAX]; int16_t touch_cal[4]; - int8_t reserved_1; + int8_t freq_mode; uint32_t harmonic_freq_threshold; uint16_t vbat_offset; uint8_t _reserved[22]; @@ -226,8 +229,6 @@ typedef struct config { extern config_t config; -//extern trace_t trace[TRACES_MAX]; - void set_trace_type(int t, int type); void set_trace_channel(int t, int channel); void set_trace_scale(int t, float scale); @@ -396,13 +397,9 @@ extern properties_t current_props; #define velocity_factor current_props._velocity_factor #define marker_smith_format current_props._marker_smith_format -#define FREQ_IS_STARTSTOP() (frequency0 < frequency1) -#define FREQ_IS_CENTERSPAN() (frequency0 > frequency1) +#define FREQ_IS_STARTSTOP() (!(config.freq_mode&FREQ_MODE_CENTER_SPAN)) +#define FREQ_IS_CENTERSPAN() (config.freq_mode&FREQ_MODE_CENTER_SPAN) #define FREQ_IS_CW() (frequency0 == frequency1) -#define FREQ_START() (frequency0) -#define FREQ_STOP() (frequency1) -#define FREQ_CENTER() (frequency0/2 + frequency1/2) -#define FREQ_SPAN() (frequency0 - frequency1) int caldata_save(int id); int caldata_recall(int id); diff --git a/plot.c b/plot.c index 4e14ca7a..0ee0c426 100644 --- a/plot.c +++ b/plot.c @@ -1585,18 +1585,18 @@ draw_frequencies(void) char buf1[32]; char buf2[32];buf2[0]=0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { - if (FREQ_IS_STARTSTOP()) { - plot_printf(buf1, sizeof(buf1), " START %qHz", frequency0); - plot_printf(buf2, sizeof(buf2), " STOP %qHz", frequency1); - } else if (FREQ_IS_CENTERSPAN()) { - plot_printf(buf1, sizeof(buf1), " CENTER %qHz", FREQ_CENTER()); - plot_printf(buf2, sizeof(buf2), " SPAN %qHz", FREQ_SPAN()); - } else { - plot_printf(buf1, sizeof(buf1), " CW %qHz", frequency0); - } + if (FREQ_IS_CW()){ + plot_printf(buf1, sizeof(buf1), " CW %qHz", get_sweep_frequency(ST_CW)); + } else if (FREQ_IS_STARTSTOP()) { + plot_printf(buf1, sizeof(buf1), " START %qHz", get_sweep_frequency(ST_START)); + plot_printf(buf2, sizeof(buf2), " STOP %qHz", get_sweep_frequency(ST_STOP)); + } else if (FREQ_IS_CENTERSPAN()) { + plot_printf(buf1, sizeof(buf1), " CENTER %qHz", get_sweep_frequency(ST_CENTER)); + plot_printf(buf2, sizeof(buf2), " SPAN %qHz", get_sweep_frequency(ST_SPAN)); + } } else { - plot_printf(buf1, sizeof(buf1), " START 0s"); - plot_printf(buf2, sizeof(buf2), "STOP %Fs (%Fm)", time_of_index(POINTS_COUNT-1), distance_of_index(POINTS_COUNT-1)); + plot_printf(buf1, sizeof(buf1), " START 0s"); + plot_printf(buf2, sizeof(buf2), "STOP %Fs (%Fm)", time_of_index(POINTS_COUNT-1), distance_of_index(POINTS_COUNT-1)); } setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); From eebb625b9dbcf9d2a22e0401a89f8b2bd6ad8404 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 9 Mar 2020 22:28:05 +0300 Subject: [PATCH 10/24] Always update marker info --- nanovna.h | 2 +- plot.c | 5 ++--- ui.c | 18 +++++++++--------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/nanovna.h b/nanovna.h index a618cb57..4a2063cf 100644 --- a/nanovna.h +++ b/nanovna.h @@ -261,7 +261,7 @@ void redraw_frame(void); //void redraw_all(void); void request_to_draw_cells_behind_menu(void); void request_to_draw_cells_behind_numeric_input(void); -void redraw_marker(int marker, int update_info); +void redraw_marker(int marker); void plot_into_index(float measured[2][POINTS_COUNT][2]); void force_set_markmap(void); void draw_frequencies(void); diff --git a/plot.c b/plot.c index 0ee0c426..39d0e9b2 100644 --- a/plot.c +++ b/plot.c @@ -1387,7 +1387,7 @@ draw_all(bool flush) } void -redraw_marker(int marker, int update_info) +redraw_marker(int marker) { if (marker < 0) return; @@ -1395,8 +1395,7 @@ redraw_marker(int marker, int update_info) markmap_marker(marker); // mark cells on marker info - if (update_info) - markmap_upperarea(); + markmap_upperarea(); draw_all_cells(TRUE); } diff --git a/ui.c b/ui.c index a2267da4..268ec511 100644 --- a/ui.c +++ b/ui.c @@ -767,7 +767,7 @@ menu_marker_search_cb(int item, uint8_t data) if (i != -1) markers[active_marker].index = i; draw_menu(); - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker); select_lever_mode(LM_SEARCH); } @@ -776,7 +776,7 @@ menu_marker_smith_cb(int item, uint8_t data) { (void)item; marker_smith_format = data; - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker); draw_menu(); } @@ -822,7 +822,7 @@ menu_marker_sel_cb(int item, uint8_t data) } else if (item == 5) { /* marker delta */ uistat.marker_delta = !uistat.marker_delta; } - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker); draw_menu(); } @@ -1639,18 +1639,18 @@ lever_move_marker(int status) if ((status & EVT_DOWN) && markers[active_marker].index > 0) { markers[active_marker].index--; markers[active_marker].frequency = frequencies[markers[active_marker].index]; - redraw_marker(active_marker, FALSE); + redraw_marker(active_marker); } if ((status & EVT_UP) && markers[active_marker].index < 100) { markers[active_marker].index++; markers[active_marker].frequency = frequencies[markers[active_marker].index]; - redraw_marker(active_marker, FALSE); + redraw_marker(active_marker); } } status = btn_wait_release(); } while (status != 0); if (active_marker >= 0) - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker); } static void @@ -1664,7 +1664,7 @@ lever_search_marker(int status) i = marker_search_right(markers[active_marker].index); if (i != -1) markers[active_marker].index = i; - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker); } } @@ -2067,7 +2067,7 @@ drag_marker(int t, int m) if (index >= 0) { markers[m].index = index; markers[m].frequency = frequencies[index]; - redraw_marker(m, TRUE); + redraw_marker(m); } } while(touch_check()!=EVT_TOUCH_RELEASED); } @@ -2097,7 +2097,7 @@ touch_pickup_marker(void) if (active_marker != m) { previous_marker = active_marker; active_marker = m; - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker); } // select trace uistat.current_trace = t; From 3714e053959be385e87ed55873a3adea544fe587 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 9 Mar 2020 22:47:35 +0300 Subject: [PATCH 11/24] Fix artifacts after marker move (For faster screen update on marker move, all old area update info invalidate after use draw_all_cells(TRUE) on page switch) Force redraw all cells after end marker move --- nanovna.h | 1 + plot.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/nanovna.h b/nanovna.h index 4a2063cf..826a0f29 100644 --- a/nanovna.h +++ b/nanovna.h @@ -284,6 +284,7 @@ int marker_search_right(int from); #define REDRAW_CAL_STATUS (1<<2) #define REDRAW_MARKER (1<<3) #define REDRAW_BATTERY (1<<4) +#define REDRAW_AREA (1<<5) extern volatile uint8_t redraw_request; /* diff --git a/plot.c b/plot.c index 39d0e9b2..8d3b1ca4 100644 --- a/plot.c +++ b/plot.c @@ -1383,6 +1383,8 @@ draw_all(bool flush) draw_cal_status(); if (redraw_request & REDRAW_BATTERY) draw_battery_status(); + if (redraw_request & REDRAW_AREA) + force_set_markmap(); redraw_request = 0; } @@ -1398,6 +1400,8 @@ redraw_marker(int marker) markmap_upperarea(); draw_all_cells(TRUE); + // Fores redraw all area after (disable artefacts after fast marker update area) + redraw_request|=REDRAW_AREA; } void From 10ae59e7869c91ed8e77afa13d66ce4e9bfda2fa Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 9 Mar 2020 23:57:03 +0300 Subject: [PATCH 12/24] Little cleanup --- plot.c | 11 +++++++---- ui.c | 1 - 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/plot.c b/plot.c index 8d3b1ca4..0975bb4e 100644 --- a/plot.c +++ b/plot.c @@ -1373,9 +1373,11 @@ draw_all_cells(bool flush_markmap){ void draw_all(bool flush) { + if (redraw_request & REDRAW_AREA) + force_set_markmap(); if (redraw_request & REDRAW_MARKER) markmap_upperarea(); - if (redraw_request & (REDRAW_CELLS | REDRAW_MARKER)) + if (redraw_request & (REDRAW_CELLS | REDRAW_MARKER | REDRAW_AREA)) draw_all_cells(flush); if (redraw_request & REDRAW_FREQUENCY) draw_frequencies(); @@ -1383,11 +1385,12 @@ draw_all(bool flush) draw_cal_status(); if (redraw_request & REDRAW_BATTERY) draw_battery_status(); - if (redraw_request & REDRAW_AREA) - force_set_markmap(); redraw_request = 0; } +// +// Call this function then need fast draw marker and marker info +// Used in ui.c for leveler move marker, drag marker and etc. void redraw_marker(int marker) { @@ -1400,7 +1403,7 @@ redraw_marker(int marker) markmap_upperarea(); draw_all_cells(TRUE); - // Fores redraw all area after (disable artefacts after fast marker update area) + // Force redraw all area after (disable artifacts after fast marker update area) redraw_request|=REDRAW_AREA; } diff --git a/ui.c b/ui.c index 268ec511..ab8ef6cf 100644 --- a/ui.c +++ b/ui.c @@ -2145,7 +2145,6 @@ void ui_process_touch(void) if (touch_pickup_marker()) break; if (touch_lever_mode_select()) { - draw_all(FALSE); touch_wait_release(); break; } From 51b5cce0167f2955363059bcc7557ba75132d275 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 11 Mar 2020 20:11:46 +0300 Subject: [PATCH 13/24] Fix Random jitters at band 1 and band change on some freq ranges Improve frequency stability on band change (100 MHz, 150MHz, 300 MHz, 450MHz) Restore freq cache in CW mode --- si5351.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/si5351.c b/si5351.c index a43a3133..96c82a2a 100644 --- a/si5351.c +++ b/si5351.c @@ -39,6 +39,17 @@ static uint8_t current_band = 0; static uint32_t current_freq = 0; +// Minimum value is 2, freq change apply at next dsp measure, and need skip it +#define DELAY_NORMAL 2 +// Delay for bands (depend set band 1 more fast (can change before next dsp bufer ready, need wait additional interval) +#define DELAY_BAND_1 3 +#define DELAY_BAND_2 2 +// Band changes need set delay after reset PLL +#define DELAY_BANDCHANGE_1 3 +#define DELAY_BANDCHANGE_2 3 +// Delay after set new PLL values, and send reset (on band 1 unstable if less then 900, on 4000-5000 no amplitude spike on change) +#define DELAY_RESET_PLL 5000 + static void si5351_bulk_write(const uint8_t *buf, int len) { @@ -118,7 +129,7 @@ static void si5351_reset_pll(uint8_t mask) { // Writing a 1<<5 will reset PLLA, 1<<7 reset PLLB, this is a self clearing bits. // !!! Need delay before reset PLL for apply PLL freq changes before - chThdSleepMicroseconds(400); + chThdSleepMicroseconds(DELAY_RESET_PLL); si5351_write(SI5351_REG_177_PLL_RESET, mask | 0x0C); } @@ -335,14 +346,6 @@ static inline uint8_t si5351_getBand(uint32_t freq){ return 3; } -// Minimum value is 2, freq change apply at next dsp measure, and need skip it -#define DELAY_NORMAL 2 -// Additional delay for band 1 (remove unstable generation at begin) -#define DELAY_BAND_1 1 -// Band changes need additional delay after reset PLL -#define DELAY_BANDCHANGE_1 2 -#define DELAY_BANDCHANGE_2 2 - /* * Maximum supported frequency = FREQ_HARMONICS * 9U * configure output as follows: @@ -354,13 +357,13 @@ int si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength){ uint8_t band; int delay = DELAY_NORMAL; -// if (freq == current_freq) -// return delay; + if (freq == current_freq) + return delay; uint32_t ofreq = freq + offset; uint32_t mul = 1, omul = 1; uint32_t rdiv = SI5351_R_DIV_1; uint32_t fdiv; -// current_freq = freq; + current_freq = freq; if (freq >= config.harmonic_freq_threshold * 7U) { mul = 9; omul = 11; @@ -391,12 +394,13 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng if (current_band != 1){ si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1); si5351_set_frequency_fixedpll(2, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA|SI5351_CLK_PLL_SELECT_A); - delay+=DELAY_BANDCHANGE_1; + delay=DELAY_BANDCHANGE_1; } + else + delay=DELAY_BAND_1; // Calculate and set CH0 and CH1 divider si5351_set_frequency_fixedpll(0, (uint64_t)omul * XTALFREQ * PLL_N, ofreq, rdiv, drive_strength|SI5351_CLK_PLL_SELECT_A); si5351_set_frequency_fixedpll(1, (uint64_t) mul * XTALFREQ * PLL_N, freq, rdiv, drive_strength|SI5351_CLK_PLL_SELECT_A); - delay+=DELAY_BAND_1; break; case 2:// fdiv = 6 case 3:// fdiv = 4; @@ -405,8 +409,10 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng if (current_band != band){ si5351_setupMultisynth(0, fdiv, 0, 1, SI5351_R_DIV_1, drive_strength|SI5351_CLK_PLL_SELECT_A); si5351_setupMultisynth(1, fdiv, 0, 1, SI5351_R_DIV_1, drive_strength|SI5351_CLK_PLL_SELECT_B); - delay+=DELAY_BANDCHANGE_2; + delay=DELAY_BANDCHANGE_2; } + else + delay=DELAY_BAND_2; // Calculate and set CH0 and CH1 PLL freq si5351_setupPLL_freq(SI5351_REG_PLL_A, ofreq, fdiv, omul);// set PLLA freq = (ofreq/omul)*fdiv si5351_setupPLL_freq(SI5351_REG_PLL_B, freq, fdiv, mul);// set PLLB freq = ( freq/ mul)*fdiv From 6f25d0d43f7b090671737a846916f4aa509011a5 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 12 Mar 2020 19:53:58 +0300 Subject: [PATCH 14/24] Remove Mutex use (CH_CFG_USE_MUTEXES = FALSE), now all Mutex depend functions run in sweep thread It allow: - reduce shell thread stack size - more compact code - fix some hardcoded scan command code, allow write better scan version - run calibrate (not depend from pause sweep flag) Rewrite uint32_t my_atoui(const char *p), now its allow read: hex 0xaAbBcC1122 dec 12345678 bin 0b00011100 oct 0o12345678 Add some comments --- chconf.h | 2 +- main.c | 153 +++++++++++++++++++++++++++++-------------------------- ui.c | 9 ++-- 3 files changed, 86 insertions(+), 78 deletions(-) diff --git a/chconf.h b/chconf.h index 5e5ce40f..fd54b74d 100644 --- a/chconf.h +++ b/chconf.h @@ -183,7 +183,7 @@ * * @note The default is @p TRUE. */ -#define CH_CFG_USE_MUTEXES TRUE +#define CH_CFG_USE_MUTEXES FALSE /** * @brief Enables recursive behavior on mutexes. diff --git a/main.c b/main.c index 4ec00cc4..f0cf527d 100644 --- a/main.c +++ b/main.c @@ -51,8 +51,11 @@ static BaseSequentialStream *shell_stream = (BaseSequentialStream *)&SDU1; typedef void (*vna_shellcmd_t)(int argc, char *argv[]); #define VNA_SHELL_FUNCTION(command_name) static void command_name(int argc, char *argv[]) -// Shell command line buffer +// Shell command line buffer, args, nargs, and function ptr static char shell_line[VNA_SHELL_MAX_LENGTH]; +static char *shell_args[VNA_SHELL_MAX_ARGUMENTS + 1]; +static uint16_t shell_nargs; +static volatile vna_shellcmd_t shell_function = 0; //#define ENABLED_DUMP //#define ENABLE_THREADS_COMMAND @@ -65,12 +68,9 @@ static void apply_edelay_at(int i); static void cal_interpolate(int s); void update_frequencies(void); void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); - static bool sweep(bool break_on_operation); static void transform_domain(void); -static MUTEX_DECL(mutex); - #define DRIVE_STRENGTH_AUTO (-1) #define FREQ_HARMONICS (config.harmonic_freq_threshold) #define IS_HARMONIC_MODE(f) ((f) > FREQ_HARMONICS) @@ -107,37 +107,36 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) { - chMtxLock(&mutex); completed = sweep(true); sweep_mode&=~SWEEP_ONCE; - chMtxUnlock(&mutex); } else { __WFI(); } - - chMtxLock(&mutex); + // Run Shell command in sweep thread + if (shell_function){ + shell_function(shell_nargs-1, &shell_args[1]); + shell_function = 0; + } + // Process UI inputs ui_process(); - - if (sweep_mode&SWEEP_ENABLE) { - // calculate trace coordinates and plot only if scan completed - if (completed) { - if ((domain_mode & DOMAIN_MODE) == DOMAIN_TIME) - transform_domain(); - plot_into_index(measured); - redraw_request |= REDRAW_CELLS|REDRAW_BATTERY; - - if (uistat.marker_tracking) { - int i = marker_search(); - if (i != -1 && active_marker != -1) { - markers[active_marker].index = i; - redraw_request |= REDRAW_MARKER; - } + // Process collected data, calculate trace coordinates and plot only if scan completed + if (sweep_mode&SWEEP_ENABLE && completed) { + if ((domain_mode & DOMAIN_MODE) == DOMAIN_TIME) + transform_domain(); + // Prepare draw graphics, cache all lines, mark screen cells for redraw + plot_into_index(measured); + redraw_request |= REDRAW_CELLS|REDRAW_BATTERY; + + if (uistat.marker_tracking) { + int i = marker_search(); + if (i != -1 && active_marker != -1) { + markers[active_marker].index = i; + redraw_request |= REDRAW_MARKER; } } } // plot trace and other indications as raster draw_all(completed); // flush markmap only if scan completed to prevent remaining traces - chMtxUnlock(&mutex); } } @@ -364,13 +363,30 @@ static int32_t my_atoi(const char *p){ } // Convert string to uint32 -uint32_t my_atoui(const char *p){ - uint32_t value = 0; - uint32_t c; +// 0x - for hex radix +// 0o - for oct radix +// 0b - for bin radix +// default dec radix +uint32_t my_atoui(const char *p) { + uint32_t value = 0, radix = 10, c; if (*p == '+') p++; - while ((c = *p++ - '0') < 10) - value = value * 10 + c; - return value; + if (*p == '0') { + switch (p[1]) { + case 'x': radix = 16; break; + case 'o': radix = 8; break; + case 'b': radix = 2; break; + default: goto calculate; + } + p+=2; + } +calculate: + while (1) { + c = *p++ - '0'; + // c = to_upper(*p) - 'A' + 10 + if (c >= 'A' - '0') c = (c&(~0x20)) - ('A' - '0') + 10; + if (c >= radix) return value; + value = value * radix + c; + } } double @@ -442,33 +458,33 @@ static int getStringIndex(char *v, const char *list){ VNA_SHELL_FUNCTION(cmd_offset) { - if (argc != 1) { - shell_printf("usage: offset {frequency offset(Hz)}\r\n"); - return; - } - frequency_offset = my_atoui(argv[0]); - set_frequency(frequency); + if (argc != 1) { + shell_printf("usage: offset {frequency offset(Hz)}\r\n"); + return; + } + frequency_offset = my_atoui(argv[0]); + set_frequency(frequency); } VNA_SHELL_FUNCTION(cmd_freq) { - if (argc != 1) { - goto usage; - } - uint32_t freq = my_atoui(argv[0]); + if (argc != 1) { + goto usage; + } + uint32_t freq = my_atoui(argv[0]); - pause_sweep(); - set_frequency(freq); - return; + pause_sweep(); + set_frequency(freq); + return; usage: - shell_printf("usage: freq {frequency(Hz)}\r\n"); + shell_printf("usage: freq {frequency(Hz)}\r\n"); } VNA_SHELL_FUNCTION(cmd_power) { if (argc != 1) { - shell_printf("usage: power {0-3|-1}\r\n"); - return; + shell_printf("usage: power {0-3|-1}\r\n"); + return; } drive_strength = my_atoi(argv[0]); set_frequency(frequency); @@ -788,7 +804,7 @@ bool sweep(bool break_on_operation) for (i = 0; i < sweep_points; i++) { // 5300 delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure - DSP_START(delay+((i==0)?1:0)); // 1900 + DSP_START(delay+((i==0)?2:0)); // 1900 //================================================ // Place some code thats need execute while delay //================================================ @@ -844,18 +860,11 @@ VNA_SHELL_FUNCTION(cmd_scan) } } - pause_sweep(); - chMtxLock(&mutex); set_frequencies(start, stop, points); if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) cal_interpolate(lastsaveid); - - sweep_mode|= SWEEP_ONCE; - chMtxUnlock(&mutex); - - // wait finishing sweep - while (sweep_mode&SWEEP_ONCE) - chThdSleepMilliseconds(10); + pause_sweep(); + sweep(false); } static void @@ -1266,6 +1275,8 @@ cal_collect(int type) default: return; } + // Run sweep for collect data + sweep(false); // Copy calibration data memcpy(cal_data[dst], measured[src], sizeof measured[0]); redraw_request |= REDRAW_CAL_STATUS; @@ -1960,7 +1971,7 @@ typedef struct { } VNAShellCommand; #pragma pack(pop) -// Some commands can executed only if process thread not in main cycle +// Some commands can executed only in sweep thread, not in main cycle #define CMD_WAIT_MUTEX 1 static const VNAShellCommand commands[] = { @@ -1985,7 +1996,7 @@ static const VNAShellCommand commands[] = {"power" , cmd_power , 0}, {"sample" , cmd_sample , 0}, // {"gamma" , cmd_gamma , 0}, - {"scan" , cmd_scan , 0}, // Wait mutex hardcoded in cmd, need wait one sweep manually + {"scan" , cmd_scan , CMD_WAIT_MUTEX}, {"sweep" , cmd_sweep , 0}, {"test" , cmd_test , 0}, {"touchcal" , cmd_touchcal , CMD_WAIT_MUTEX}, @@ -2079,44 +2090,44 @@ static int VNAShell_readLine(char *line, int max_size){ // static void VNAShell_executeLine(char *line){ // Parse and execute line - char *args[VNA_SHELL_MAX_ARGUMENTS + 1]; - int n = 0; char *lp = line, *ep; + shell_nargs = 0; while (*lp!=0){ // Skipping white space and tabs at string begin. while (*lp==' ' || *lp=='\t') lp++; // If an argument starts with a double quote then its delimiter is another quote, else delimiter is white space. ep = (*lp == '"') ? strpbrk(++lp, "\"") : strpbrk( lp, " \t"); // Store in args string - args[n++]=lp; + shell_args[shell_nargs++]=lp; // Stop, end of input string if ((lp = ep) == NULL) break; // Argument limits check - if (n > VNA_SHELL_MAX_ARGUMENTS) { + if (shell_nargs > VNA_SHELL_MAX_ARGUMENTS) { shell_printf("too many arguments, max "define_to_STR(VNA_SHELL_MAX_ARGUMENTS)""VNA_SHELL_NEWLINE_STR); return; } // Set zero at the end of string and continue check *lp++ = 0; } - if (n == 0) + if (shell_nargs == 0) return; // Execute line const VNAShellCommand *scp; for (scp = commands; scp->sc_name!=NULL;scp++) { - if (strcmp(scp->sc_name, args[0]) == 0) { - if (scp->flags&CMD_WAIT_MUTEX) { - chMtxLock(&mutex); - scp->sc_function(n-1, &args[1]); - chMtxUnlock(&mutex); + if (strcmp(scp->sc_name, shell_args[0]) == 0) { + if (scp->flags&CMD_WAIT_MUTEX){ + shell_function= scp->sc_function; + // Wait execute command in sweep thread + while(shell_function) + osalThreadSleepMilliseconds(100); } else - scp->sc_function(n-1, &args[1]); + scp->sc_function(shell_nargs-1, &shell_args[1]); return; } } - shell_printf("%s?"VNA_SHELL_NEWLINE_STR, args[0]); + shell_printf("%s?"VNA_SHELL_NEWLINE_STR, shell_args[0]); } #ifdef VNA_SHELL_THREAD @@ -2179,8 +2190,6 @@ int main(void) halInit(); chSysInit(); - chMtxObjectInit(&mutex); - //palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); //palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); i2cStart(&I2CD1, &i2ccfg); diff --git a/ui.c b/ui.c index ab8ef6cf..e3c85159 100644 --- a/ui.c +++ b/ui.c @@ -2142,20 +2142,19 @@ void ui_process_touch(void) if (status == EVT_TOUCH_PRESSED || status == EVT_TOUCH_DOWN) { switch (ui_mode) { case UI_NORMAL: + // Try drag marker if (touch_pickup_marker()) break; + // Try select lever mode (top and bottom screen) if (touch_lever_mode_select()) { touch_wait_release(); break; } - + // switch menu mode after release touch_wait_release(); - - // switch menu mode - selection = -1; + selection = -1; // hide keyboard mode selection ui_mode_menu(); break; - case UI_MENU: menu_apply_touch(); break; From 8bdb65021267b0d4ea63a75b20d4ac10d19af794 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 12 Mar 2020 21:43:35 +0300 Subject: [PATCH 15/24] Implement color command, allow change color settings in config (enabled bu default ENABLE_COLOR_COMMAND) Usage: usage: color {id} {rgb24} - Grid color: id = -3 - Menu bg color: id = -2 - Selected menu: id = -1 - Trace 1-4: id = 0..3 Color in hex RGB format (but possible any type input, dec, hex, bin. oct) --- main.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ui.c | 8 ++++---- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index f0cf527d..243f2ab0 100644 --- a/main.c +++ b/main.c @@ -58,10 +58,16 @@ static uint16_t shell_nargs; static volatile vna_shellcmd_t shell_function = 0; //#define ENABLED_DUMP +// Allow get threads debug info //#define ENABLE_THREADS_COMMAND +// RTC time not used //#define ENABLE_TIME_COMMAND +// Enable vbat_offset command, allow change battery voltage correction in config #define ENABLE_VBAT_OFFSET_COMMAND +// Info about NanoVNA, need fore soft #define ENABLE_INFO_COMMAND +// Enable color command, allow change config color for traces, grid, menu +#define ENABLE_COLOR_COMMAND static void apply_error_term_at(int i); static void apply_edelay_at(int i); @@ -1930,6 +1936,55 @@ VNA_SHELL_FUNCTION(cmd_info) } #endif +#ifdef ENABLE_COLOR_COMMAND +VNA_SHELL_FUNCTION(cmd_color) +{ + uint32_t color; + int i; + if (argc != 2) { + shell_printf("usage: color {id} {rgb24}\r\n"); + for (i=-3; i < TRACES_MAX; i++) { +#if 0 + switch(i){ + case -3: color = config.grid_color; break; + case -2: color = config.menu_normal_color; break; + case -1: color = config.menu_active_color; break; + default: color = config.trace_color[i];break; + } +#else + // WARNING!!! Dirty hack for size, depend from config struct + color = config.trace_color[i]; +#endif + color = ((color >> 3) & 0x001c00) | + ((color >> 5) & 0x0000f8) | + ((color << 16) & 0xf80000) | + ((color << 13) & 0x00e000); +// color = (color>>8)|(color<<8); +// color = ((color<<8)&0xF80000)|((color<<5)&0x00FC00)|((color<<3)&0x0000F8); + shell_printf(" %d: 0x%06x\r\n", i, color); + } + return; + } + i = my_atoi(argv[0]); + if (i < -3 && i >= TRACES_MAX) + return; + color = RGBHEX(my_atoui(argv[1])); +#if 0 + switch(i){ + case -3: config.grid_color = color; break; + case -2: config.menu_normal_color = color; break; + case -1: config.menu_active_color = color; break; + default: config.trace_color[i] = color;break; + } +#else + // WARNING!!! Dirty hack for size, depend from config struct + config.trace_color[i] = color; +#endif + // Redraw all + redraw_request|= REDRAW_AREA; +} +#endif + #ifdef ENABLE_THREADS_COMMAND #if CH_CFG_USE_REGISTRY == FALSE #error "Threads Requite enabled CH_CFG_USE_REGISTRY in chconf.h" @@ -2020,6 +2075,9 @@ static const VNAShellCommand commands[] = #ifdef ENABLE_INFO_COMMAND {"info" , cmd_info , 0}, #endif +#ifdef ENABLE_COLOR_COMMAND + {"color" , cmd_color , 0}, +#endif #ifdef ENABLE_THREADS_COMMAND {"threads" , cmd_threads , 0}, #endif diff --git a/ui.c b/ui.c index e3c85159..8d82c359 100644 --- a/ui.c +++ b/ui.c @@ -1250,9 +1250,9 @@ draw_keypad(void) static void draw_numeric_area_frame(void) { - ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, DEFAULT_MENU_COLOR); + ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, config.menu_normal_color); setForegroundColor(DEFAULT_MENU_TEXT_COLOR); - setBackgroundColor(DEFAULT_MENU_COLOR); + setBackgroundColor(config.menu_normal_color); ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); //ili9341_drawfont(KP_KEYPAD, 300, 216); } @@ -1267,7 +1267,7 @@ draw_numeric_input(const char *buf) for (i = 0, x = 64; i < 10 && buf[i]; i++, xsim<<=1) { uint16_t fg = DEFAULT_MENU_TEXT_COLOR; - uint16_t bg = DEFAULT_MENU_COLOR; + uint16_t bg = config.menu_normal_color; int c = buf[i]; if (c == '.') c = KP_PERIOD; @@ -1294,7 +1294,7 @@ draw_numeric_input(const char *buf) x += xsim&0x8000 ? NUM_FONT_GET_WIDTH+2+8 : NUM_FONT_GET_WIDTH+2; } // erase last - ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, DEFAULT_MENU_COLOR); + ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color); } static int From 88617a31fe8db14077c8b768603d4873061a653e Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 13 Mar 2020 22:42:28 +0300 Subject: [PATCH 16/24] In ili9341.c remove tabs, add palette mode blit function In plot.c prepare for 8bit/pixel mode (test, allow increase cell buffer size by use 4 or 8bit/pixel mode, but not need for now) main.c little change wait execute shell command in sweep thread --- ili9341.c | 877 ++++++++++++++++++++++++++++-------------------------- main.c | 7 +- nanovna.h | 2 + plot.c | 49 +-- si5351.c | 2 +- 5 files changed, 479 insertions(+), 458 deletions(-) diff --git a/ili9341.c b/ili9341.c index 3c7568b8..a66fc9ab 100644 --- a/ili9341.c +++ b/ili9341.c @@ -23,97 +23,97 @@ uint16_t spi_buffer[SPI_BUFFER_SIZE]; // Default foreground & background colors -uint16_t foreground_color=DEFAULT_FG_COLOR; -uint16_t background_color=DEFAULT_BG_COLOR; +uint16_t foreground_color=0; +uint16_t background_color=0; // Display width and height definition -#define ILI9341_WIDTH 320 -#define ILI9341_HEIGHT 240 +#define ILI9341_WIDTH 320 +#define ILI9341_HEIGHT 240 // Display commands list -#define ILI9341_NOP 0x00 -#define ILI9341_SOFTWARE_RESET 0x01 -#define ILI9341_READ_IDENTIFICATION 0x04 -#define ILI9341_READ_STATUS 0x09 -#define ILI9341_READ_POWER_MODE 0x0A -#define ILI9341_READ_MADCTL 0x0B -#define ILI9341_READ_PIXEL_FORMAT 0x0C -#define ILI9341_READ_IMAGE_FORMAT 0x0D -#define ILI9341_READ_SIGNAL_MODE 0x0E -#define ILI9341_READ_SELF_DIAGNOSTIC 0x0F -#define ILI9341_SLEEP_IN 0x10 -#define ILI9341_SLEEP_OUT 0x11 -#define ILI9341_PARTIAL_MODE_ON 0x12 -#define ILI9341_NORMAL_DISPLAY_MODE_ON 0x13 -#define ILI9341_INVERSION_OFF 0x20 -#define ILI9341_INVERSION_ON 0x21 -#define ILI9341_GAMMA_SET 0x26 -#define ILI9341_DISPLAY_OFF 0x28 -#define ILI9341_DISPLAY_ON 0x29 -#define ILI9341_COLUMN_ADDRESS_SET 0x2A -#define ILI9341_PAGE_ADDRESS_SET 0x2B -#define ILI9341_MEMORY_WRITE 0x2C -#define ILI9341_COLOR_SET 0x2D -#define ILI9341_MEMORY_READ 0x2E -#define ILI9341_PARTIAL_AREA 0x30 -#define ILI9341_VERTICAL_SCROLLING_DEF 0x33 -#define ILI9341_TEARING_LINE_OFF 0x34 -#define ILI9341_TEARING_LINE_ON 0x35 -#define ILI9341_MEMORY_ACCESS_CONTROL 0x36 -#define ILI9341_VERTICAL_SCROLLING 0x37 -#define ILI9341_IDLE_MODE_OFF 0x38 -#define ILI9341_IDLE_MODE_ON 0x39 -#define ILI9341_PIXEL_FORMAT_SET 0x3A -#define ILI9341_WRITE_MEMORY_CONTINUE 0x3C -#define ILI9341_READ_MEMORY_CONTINUE 0x3E -#define ILI9341_SET_TEAR_SCANLINE 0x44 -#define ILI9341_GET_SCANLINE 0x45 -#define ILI9341_WRITE_BRIGHTNESS 0x51 -#define ILI9341_READ_BRIGHTNESS 0x52 -#define ILI9341_WRITE_CTRL_DISPLAY 0x53 -#define ILI9341_READ_CTRL_DISPLAY 0x54 -#define ILI9341_WRITE_CA_BRIGHTNESS 0x55 -#define ILI9341_READ_CA_BRIGHTNESS 0x56 -#define ILI9341_WRITE_CA_MIN_BRIGHTNESS 0x5E -#define ILI9341_READ_CA_MIN_BRIGHTNESS 0x5F -#define ILI9341_READ_ID1 0xDA -#define ILI9341_READ_ID2 0xDB -#define ILI9341_READ_ID3 0xDC -#define ILI9341_RGB_INTERFACE_CONTROL 0xB0 -#define ILI9341_FRAME_RATE_CONTROL_1 0xB1 -#define ILI9341_FRAME_RATE_CONTROL_2 0xB2 -#define ILI9341_FRAME_RATE_CONTROL_3 0xB3 -#define ILI9341_DISPLAY_INVERSION_CONTROL 0xB4 -#define ILI9341_BLANKING_PORCH_CONTROL 0xB5 -#define ILI9341_DISPLAY_FUNCTION_CONTROL 0xB6 -#define ILI9341_ENTRY_MODE_SET 0xB7 -#define ILI9341_BACKLIGHT_CONTROL_1 0xB8 -#define ILI9341_BACKLIGHT_CONTROL_2 0xB9 -#define ILI9341_BACKLIGHT_CONTROL_3 0xBA -#define ILI9341_BACKLIGHT_CONTROL_4 0xBB -#define ILI9341_BACKLIGHT_CONTROL_5 0xBC -#define ILI9341_BACKLIGHT_CONTROL_7 0xBE -#define ILI9341_BACKLIGHT_CONTROL_8 0xBF -#define ILI9341_POWER_CONTROL_1 0xC0 -#define ILI9341_POWER_CONTROL_2 0xC1 -#define ILI9341_VCOM_CONTROL_1 0xC5 -#define ILI9341_VCOM_CONTROL_2 0xC7 -#define ILI9341_POWERA 0xCB -#define ILI9341_POWERB 0xCF -#define ILI9341_NV_MEMORY_WRITE 0xD0 -#define ILI9341_NV_PROTECTION_KEY 0xD1 -#define ILI9341_NV_STATUS_READ 0xD2 -#define ILI9341_READ_ID4 0xD3 -#define ILI9341_POSITIVE_GAMMA_CORRECTION 0xE0 -#define ILI9341_NEGATIVE_GAMMA_CORRECTION 0xE1 -#define ILI9341_DIGITAL_GAMMA_CONTROL_1 0xE2 -#define ILI9341_DIGITAL_GAMMA_CONTROL_2 0xE3 -#define ILI9341_DTCA 0xE8 -#define ILI9341_DTCB 0xEA -#define ILI9341_POWER_SEQ 0xED -#define ILI9341_3GAMMA_EN 0xF2 -#define ILI9341_INTERFACE_CONTROL 0xF6 -#define ILI9341_PUMP_RATIO_CONTROL 0xF7 +#define ILI9341_NOP 0x00 +#define ILI9341_SOFTWARE_RESET 0x01 +#define ILI9341_READ_IDENTIFICATION 0x04 +#define ILI9341_READ_STATUS 0x09 +#define ILI9341_READ_POWER_MODE 0x0A +#define ILI9341_READ_MADCTL 0x0B +#define ILI9341_READ_PIXEL_FORMAT 0x0C +#define ILI9341_READ_IMAGE_FORMAT 0x0D +#define ILI9341_READ_SIGNAL_MODE 0x0E +#define ILI9341_READ_SELF_DIAGNOSTIC 0x0F +#define ILI9341_SLEEP_IN 0x10 +#define ILI9341_SLEEP_OUT 0x11 +#define ILI9341_PARTIAL_MODE_ON 0x12 +#define ILI9341_NORMAL_DISPLAY_MODE_ON 0x13 +#define ILI9341_INVERSION_OFF 0x20 +#define ILI9341_INVERSION_ON 0x21 +#define ILI9341_GAMMA_SET 0x26 +#define ILI9341_DISPLAY_OFF 0x28 +#define ILI9341_DISPLAY_ON 0x29 +#define ILI9341_COLUMN_ADDRESS_SET 0x2A +#define ILI9341_PAGE_ADDRESS_SET 0x2B +#define ILI9341_MEMORY_WRITE 0x2C +#define ILI9341_COLOR_SET 0x2D +#define ILI9341_MEMORY_READ 0x2E +#define ILI9341_PARTIAL_AREA 0x30 +#define ILI9341_VERTICAL_SCROLLING_DEF 0x33 +#define ILI9341_TEARING_LINE_OFF 0x34 +#define ILI9341_TEARING_LINE_ON 0x35 +#define ILI9341_MEMORY_ACCESS_CONTROL 0x36 +#define ILI9341_VERTICAL_SCROLLING 0x37 +#define ILI9341_IDLE_MODE_OFF 0x38 +#define ILI9341_IDLE_MODE_ON 0x39 +#define ILI9341_PIXEL_FORMAT_SET 0x3A +#define ILI9341_WRITE_MEMORY_CONTINUE 0x3C +#define ILI9341_READ_MEMORY_CONTINUE 0x3E +#define ILI9341_SET_TEAR_SCANLINE 0x44 +#define ILI9341_GET_SCANLINE 0x45 +#define ILI9341_WRITE_BRIGHTNESS 0x51 +#define ILI9341_READ_BRIGHTNESS 0x52 +#define ILI9341_WRITE_CTRL_DISPLAY 0x53 +#define ILI9341_READ_CTRL_DISPLAY 0x54 +#define ILI9341_WRITE_CA_BRIGHTNESS 0x55 +#define ILI9341_READ_CA_BRIGHTNESS 0x56 +#define ILI9341_WRITE_CA_MIN_BRIGHTNESS 0x5E +#define ILI9341_READ_CA_MIN_BRIGHTNESS 0x5F +#define ILI9341_READ_ID1 0xDA +#define ILI9341_READ_ID2 0xDB +#define ILI9341_READ_ID3 0xDC +#define ILI9341_RGB_INTERFACE_CONTROL 0xB0 +#define ILI9341_FRAME_RATE_CONTROL_1 0xB1 +#define ILI9341_FRAME_RATE_CONTROL_2 0xB2 +#define ILI9341_FRAME_RATE_CONTROL_3 0xB3 +#define ILI9341_DISPLAY_INVERSION_CONTROL 0xB4 +#define ILI9341_BLANKING_PORCH_CONTROL 0xB5 +#define ILI9341_DISPLAY_FUNCTION_CONTROL 0xB6 +#define ILI9341_ENTRY_MODE_SET 0xB7 +#define ILI9341_BACKLIGHT_CONTROL_1 0xB8 +#define ILI9341_BACKLIGHT_CONTROL_2 0xB9 +#define ILI9341_BACKLIGHT_CONTROL_3 0xBA +#define ILI9341_BACKLIGHT_CONTROL_4 0xBB +#define ILI9341_BACKLIGHT_CONTROL_5 0xBC +#define ILI9341_BACKLIGHT_CONTROL_7 0xBE +#define ILI9341_BACKLIGHT_CONTROL_8 0xBF +#define ILI9341_POWER_CONTROL_1 0xC0 +#define ILI9341_POWER_CONTROL_2 0xC1 +#define ILI9341_VCOM_CONTROL_1 0xC5 +#define ILI9341_VCOM_CONTROL_2 0xC7 +#define ILI9341_POWERA 0xCB +#define ILI9341_POWERB 0xCF +#define ILI9341_NV_MEMORY_WRITE 0xD0 +#define ILI9341_NV_PROTECTION_KEY 0xD1 +#define ILI9341_NV_STATUS_READ 0xD2 +#define ILI9341_READ_ID4 0xD3 +#define ILI9341_POSITIVE_GAMMA_CORRECTION 0xE0 +#define ILI9341_NEGATIVE_GAMMA_CORRECTION 0xE1 +#define ILI9341_DIGITAL_GAMMA_CONTROL_1 0xE2 +#define ILI9341_DIGITAL_GAMMA_CONTROL_2 0xE3 +#define ILI9341_DTCA 0xE8 +#define ILI9341_DTCB 0xEA +#define ILI9341_POWER_SEQ 0xED +#define ILI9341_3GAMMA_EN 0xF2 +#define ILI9341_INTERFACE_CONTROL 0xF6 +#define ILI9341_PUMP_RATIO_CONTROL 0xF7 // // ILI9341_MEMORY_ACCESS_CONTROL registers @@ -126,20 +126,20 @@ uint16_t background_color=DEFAULT_BG_COLOR; #define ILI9341_MADCTL_MH 0x04 #define ILI9341_MADCTL_RGB 0x00 -#define DISPLAY_ROTATION_270 (ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR) -#define DISPLAY_ROTATION_90 (ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR) -#define DISPLAY_ROTATION_0 (ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR) -#define DISPLAY_ROTATION_180 (ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR) +#define DISPLAY_ROTATION_270 (ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR) +#define DISPLAY_ROTATION_90 (ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR) +#define DISPLAY_ROTATION_0 (ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR) +#define DISPLAY_ROTATION_180 (ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR) // // Pin macros // -#define RESET_ASSERT palClearPad(GPIOA, 15) -#define RESET_NEGATE palSetPad(GPIOA, 15) -#define CS_LOW palClearPad(GPIOB, 6) -#define CS_HIGH palSetPad(GPIOB, 6) -#define DC_CMD palClearPad(GPIOB, 7) -#define DC_DATA palSetPad(GPIOB, 7) +#define RESET_ASSERT palClearPad(GPIOA, 15) +#define RESET_NEGATE palSetPad(GPIOA, 15) +#define CS_LOW palClearPad(GPIOB, 6) +#define CS_HIGH palSetPad(GPIOB, 6) +#define DC_CMD palClearPad(GPIOB, 7) +#define DC_DATA palSetPad(GPIOB, 7) //***************************************************************************** //********************************** SPI bus ********************************** @@ -159,17 +159,17 @@ uint16_t background_color=DEFAULT_BG_COLOR; // The RXNE flag is set depending on the FRXTH bit value in the SPIx_CR2 register: // • If FRXTH is set, RXNE goes high and stays high until the RXFIFO level is greater or equal to 1/4 (8-bit). -#define SPI_RX_IS_NOT_EMPTY (SPI1->SR&SPI_SR_RXNE) +#define SPI_RX_IS_NOT_EMPTY (SPI1->SR&SPI_SR_RXNE) #define SPI_RX_IS_EMPTY (((SPI1->SR&SPI_SR_RXNE) == 0)) // The TXE flag is set when transmission TXFIFO has enough space to store data to send. // 0: Tx buffer not empty, bit is cleared automatically when the TXFIFO level becomes greater than 1/2 // 1: Tx buffer empty, flag goes high and stays high until the TXFIFO level is lower or equal to 1/2 of the FIFO depth -#define SPI_TX_IS_NOT_EMPTY (((SPI1->SR&(SPI_SR_TXE)) == 0)) +#define SPI_TX_IS_NOT_EMPTY (((SPI1->SR&(SPI_SR_TXE)) == 0)) #define SPI_TX_IS_EMPTY (SPI1->SR&SPI_SR_TXE) // When BSY is set, it indicates that a data transfer is in progress on the SPI (the SPI bus is busy). -#define SPI_IS_BUSY (SPI1->SR & SPI_SR_BSY) +#define SPI_IS_BUSY (SPI1->SR & SPI_SR_BSY) // SPI send data macros #define SPI_WRITE_8BIT(data) *(__IO uint8_t*)(&SPI1->DR) = (uint8_t) data @@ -180,11 +180,11 @@ uint16_t background_color=DEFAULT_BG_COLOR; #ifdef __USE_DISPLAY_DMA__ static const stm32_dma_stream_t *dmatx = STM32_DMA_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM); -static uint32_t txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) // Select SPI1 Tx DMA - | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) // Set priority - | STM32_DMA_CR_DIR_M2P // Memory to Spi - | STM32_DMA_CR_DMEIE // - | STM32_DMA_CR_TEIE; +static uint32_t txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) // Select SPI1 Tx DMA + | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) // Set priority + | STM32_DMA_CR_DIR_M2P // Memory to Spi + | STM32_DMA_CR_DMEIE // + | STM32_DMA_CR_TEIE; static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { (void)spip; @@ -193,11 +193,11 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { static const stm32_dma_stream_t *dmarx = STM32_DMA_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM); static uint32_t rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL) - | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) - | STM32_DMA_CR_DIR_P2M - | STM32_DMA_CR_TCIE - | STM32_DMA_CR_DMEIE - | STM32_DMA_CR_TEIE; + | STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) + | STM32_DMA_CR_DIR_P2M + | STM32_DMA_CR_TCIE + | STM32_DMA_CR_DMEIE + | STM32_DMA_CR_TEIE; static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { (void)spip; @@ -205,14 +205,14 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { } static void dmaStreamFlush(uint32_t len){ - while (len){ - // DMA data transfer limited by 65535 - uint16_t tx_size = len > 65535 ? 65535 : len; - dmaStreamSetTransactionSize(dmatx, tx_size); - dmaStreamEnable(dmatx); - len -= tx_size; - dmaWaitCompletion(dmatx); - } + while (len){ + // DMA data transfer limited by 65535 + uint16_t tx_size = len > 65535 ? 65535 : len; + dmaStreamSetTransactionSize(dmatx, tx_size); + dmaStreamEnable(dmatx); + len -= tx_size; + dmaWaitCompletion(dmatx); + } } #endif @@ -221,13 +221,13 @@ static void spi_init(void) rccEnableSPI1(FALSE); SPI1->CR1 = 0; SPI1->CR1 = SPI_CR1_MSTR // SPI is MASTER - | SPI_CR1_SSM // Software slave management (The external NSS pin is free for other application uses) - | SPI_CR1_SSI; // Internal slave select (This bit has an effect only when the SSM bit is set. Allow use NSS pin as I/O) - // | SPI_CR1_BR_1; // Baud rate control + | SPI_CR1_SSM // Software slave management (The external NSS pin is free for other application uses) + | SPI_CR1_SSI; // Internal slave select (This bit has an effect only when the SSM bit is set. Allow use NSS pin as I/O) +// | SPI_CR1_BR_1; // Baud rate control SPI1->CR2 = SPI_CR2_8BIT // SPI data size, set to 8 bit - | SPI_CR2_FRXTH; // SPI_SR_RXNE generated every 8 bit data -// | SPI_CR2_SSOE; // + | SPI_CR2_FRXTH; // SPI_SR_RXNE generated every 8 bit data +// | SPI_CR2_SSOE; // #ifdef __USE_DISPLAY_DMA__ // Tx DMA init @@ -238,7 +238,7 @@ static void spi_init(void) dmaStreamSetPeripheral(dmarx, &SPI1->DR); // Enable DMA on SPI SPI1->CR2|= SPI_CR2_TXDMAEN // Tx DMA enable - | SPI_CR2_RXDMAEN; // Rx DMA enable + | SPI_CR2_RXDMAEN; // Rx DMA enable #endif SPI1->CR1|= SPI_CR1_SPE; //SPI enable } @@ -246,166 +246,166 @@ static void spi_init(void) // Disable inline for this function static void __attribute__ ((noinline)) send_command(uint8_t cmd, uint8_t len, const uint8_t *data) { - CS_LOW; - // while (SPI_TX_IS_NOT_EMPTY); - DC_CMD; - SPI_WRITE_8BIT(cmd); - // Need wait transfer complete and set data bit - while (SPI_IS_BUSY); - // Send command data (if need) - DC_DATA; - while (len-- > 0) { - while (SPI_TX_IS_NOT_EMPTY); - SPI_WRITE_8BIT(*data++); - } - //CS_HIGH; + CS_LOW; + //while (SPI_TX_IS_NOT_EMPTY); + DC_CMD; + SPI_WRITE_8BIT(cmd); + // Need wait transfer complete and set data bit + while (SPI_IS_BUSY); + // Send command data (if need) + DC_DATA; + while (len-- > 0) { + while (SPI_TX_IS_NOT_EMPTY); + SPI_WRITE_8BIT(*data++); + } + //CS_HIGH; } static const uint8_t ili9341_init_seq[] = { - // cmd, len, data..., - // SW reset - ILI9341_SOFTWARE_RESET, 0, - // display off - ILI9341_DISPLAY_OFF, 0, - // Power control B - ILI9341_POWERB, 3, 0x00, 0x83, 0x30, - // Power on sequence control - ILI9341_POWER_SEQ, 4, 0x64, 0x03, 0x12, 0x81, - //ILI9341_POWER_SEQ, 4, 0x55, 0x01, 0x23, 0x01, - // Driver timing control A - ILI9341_DTCA, 3, 0x85, 0x01, 0x79, - //ILI9341_DTCA, 3, 0x84, 0x11, 0x7a, - // Power control A - ILI9341_POWERA, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, - // Pump ratio control - ILI9341_PUMP_RATIO_CONTROL, 1, 0x20, - // Driver timing control B - ILI9341_DTCB, 2, 0x00, 0x00, - // POWER_CONTROL_1 - ILI9341_POWER_CONTROL_1, 1, 0x26, - // POWER_CONTROL_2 - ILI9341_POWER_CONTROL_2, 1, 0x11, - // VCOM_CONTROL_1 - ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E, - // VCOM_CONTROL_2 - ILI9341_VCOM_CONTROL_2, 1, 0xBE, - // MEMORY_ACCESS_CONTROL - //ILI9341_MEMORY_ACCESS_CONTROL, 1, 0x48, // portlait - ILI9341_MEMORY_ACCESS_CONTROL, 1, DISPLAY_ROTATION_0, // landscape - // COLMOD_PIXEL_FORMAT_SET : 16 bit pixel - ILI9341_PIXEL_FORMAT_SET, 1, 0x55, - // Frame Rate - ILI9341_FRAME_RATE_CONTROL_1, 2, 0x00, 0x1B, - // Gamma Function Disable - ILI9341_3GAMMA_EN, 1, 0x08, - // gamma set for curve 01/2/04/08 - ILI9341_GAMMA_SET, 1, 0x01, - // positive gamma correction -// ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00, - // negativ gamma correction -// ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F, - // Column Address Set -// ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320 - // Page Address Set -// ILI9341_PAGE_ADDRESS_SET, 4, 0x00, 0x00, 0x00, 0xef, // height 240 - // entry mode - ILI9341_ENTRY_MODE_SET, 1, 0x06, - // display function control - ILI9341_DISPLAY_FUNCTION_CONTROL, 4, 0x0A, 0x82, 0x27, 0x00, - // Interface Control (set WEMODE=0) - ILI9341_INTERFACE_CONTROL, 3, 0x00, 0x00, 0x00, - // control display - //ILI9341_WRITE_CTRL_DISPLAY, 1, 0x0c, - // diaplay brightness - //ILI9341_WRITE_BRIGHTNESS, 1, 0xff, - // sleep out - ILI9341_SLEEP_OUT, 0, - // display on - ILI9341_DISPLAY_ON, 0, - 0 // sentinel + // cmd, len, data..., + // SW reset + ILI9341_SOFTWARE_RESET, 0, + // display off + ILI9341_DISPLAY_OFF, 0, + // Power control B + ILI9341_POWERB, 3, 0x00, 0x83, 0x30, + // Power on sequence control + ILI9341_POWER_SEQ, 4, 0x64, 0x03, 0x12, 0x81, + //ILI9341_POWER_SEQ, 4, 0x55, 0x01, 0x23, 0x01, + // Driver timing control A + ILI9341_DTCA, 3, 0x85, 0x01, 0x79, + //ILI9341_DTCA, 3, 0x84, 0x11, 0x7a, + // Power control A + ILI9341_POWERA, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, + // Pump ratio control + ILI9341_PUMP_RATIO_CONTROL, 1, 0x20, + // Driver timing control B + ILI9341_DTCB, 2, 0x00, 0x00, + // POWER_CONTROL_1 + ILI9341_POWER_CONTROL_1, 1, 0x26, + // POWER_CONTROL_2 + ILI9341_POWER_CONTROL_2, 1, 0x11, + // VCOM_CONTROL_1 + ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E, + // VCOM_CONTROL_2 + ILI9341_VCOM_CONTROL_2, 1, 0xBE, + // MEMORY_ACCESS_CONTROL + //ILI9341_MEMORY_ACCESS_CONTROL, 1, 0x48, // portlait + ILI9341_MEMORY_ACCESS_CONTROL, 1, DISPLAY_ROTATION_0, // landscape + // COLMOD_PIXEL_FORMAT_SET : 16 bit pixel + ILI9341_PIXEL_FORMAT_SET, 1, 0x55, + // Frame Rate + ILI9341_FRAME_RATE_CONTROL_1, 2, 0x00, 0x1B, + // Gamma Function Disable + ILI9341_3GAMMA_EN, 1, 0x08, + // gamma set for curve 01/2/04/08 + ILI9341_GAMMA_SET, 1, 0x01, + // positive gamma correction +//ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00, + // negativ gamma correction +//ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F, + // Column Address Set +//ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320 + // Page Address Set +//ILI9341_PAGE_ADDRESS_SET, 4, 0x00, 0x00, 0x00, 0xef, // height 240 + // entry mode + ILI9341_ENTRY_MODE_SET, 1, 0x06, + // display function control + ILI9341_DISPLAY_FUNCTION_CONTROL, 4, 0x0A, 0x82, 0x27, 0x00, + // Interface Control (set WEMODE=0) + ILI9341_INTERFACE_CONTROL, 3, 0x00, 0x00, 0x00, + // control display + //ILI9341_WRITE_CTRL_DISPLAY, 1, 0x0c, + // diaplay brightness + //ILI9341_WRITE_BRIGHTNESS, 1, 0xff, + // sleep out + ILI9341_SLEEP_OUT, 0, + // display on + ILI9341_DISPLAY_ON, 0, + 0 // sentinel }; void ili9341_init(void) { - spi_init(); - DC_DATA; - RESET_ASSERT; - chThdSleepMilliseconds(10); - RESET_NEGATE; - const uint8_t *p; - for (p = ili9341_init_seq; *p; ) { - send_command(p[0], p[1], &p[2]); - p += 2 + p[1]; - chThdSleepMilliseconds(5); - } + spi_init(); + DC_DATA; + RESET_ASSERT; + chThdSleepMilliseconds(10); + RESET_NEGATE; + const uint8_t *p; + for (p = ili9341_init_seq; *p; ) { + send_command(p[0], p[1], &p[2]); + p += 2 + p[1]; + chThdSleepMilliseconds(5); + } } #ifndef __USE_DISPLAY_DMA__ void ili9341_fill(int x, int y, int w, int h, int color) { -// uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; -// uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; - uint32_t xx = __REV16(x|((x+w-1)<<16)); - uint32_t yy = __REV16(y|((y+h-1)<<16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_WRITE, 0, NULL); - int32_t len = w * h; - while (len-- > 0){ - while (SPI_TX_IS_NOT_EMPTY); - SPI_WRITE_16BIT(color); - } +//uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; +//uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_WRITE, 0, NULL); + int32_t len = w * h; + while (len-- > 0){ + while (SPI_TX_IS_NOT_EMPTY); + SPI_WRITE_16BIT(color); + } } void ili9341_bulk(int x, int y, int w, int h) { -// uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; -// uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; - uint16_t *buf = spi_buffer; - uint32_t xx = __REV16(x|((x+w-1)<<16)); - uint32_t yy = __REV16(y|((y+h-1)<<16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_WRITE, 0, NULL); - int32_t len = w * h; - while (len-- > 0){ - while (SPI_TX_IS_NOT_EMPTY); - SPI_WRITE_16BIT(*buf++); - } +//uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; +//uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; + uint16_t *buf = spi_buffer; + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_WRITE, 0, NULL); + int32_t len = w * h; + while (len-- > 0){ + while (SPI_TX_IS_NOT_EMPTY); + SPI_WRITE_16BIT(*buf++); + } } static uint8_t ssp_sendrecvdata(void) { - // Start RX clock (by sending data) - SPI_WRITE_8BIT(0); - while(SPI_RX_IS_EMPTY && SPI_IS_BUSY) - ; - return SPI_READ_DATA; + // Start RX clock (by sending data) + SPI_WRITE_8BIT(0); + while(SPI_RX_IS_EMPTY && SPI_IS_BUSY) + ; + return SPI_READ_DATA; } void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) { -// uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; -// uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; - uint32_t xx = __REV16(x|((x+w-1)<<16)); - uint32_t yy = __REV16(y|((y+h-1)<<16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_READ, 0, NULL); - - // Skip data from rx buffer - while (SPI_RX_IS_NOT_EMPTY) - (void) SPI_READ_DATA; - // require 8bit dummy clock - ssp_sendrecvdata(); - while (len-- > 0) { - // read data is always 18bit - uint8_t r = ssp_sendrecvdata(); - uint8_t g = ssp_sendrecvdata(); - uint8_t b = ssp_sendrecvdata(); - *out++ = RGB565(r,g,b); - } - CS_HIGH; +//uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; +//uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_READ, 0, NULL); + + // Skip data from rx buffer + while (SPI_RX_IS_NOT_EMPTY) + (void) SPI_READ_DATA; + // require 8bit dummy clock + ssp_sendrecvdata(); + while (len-- > 0) { + // read data is always 18bit + uint8_t r = ssp_sendrecvdata(); + uint8_t g = ssp_sendrecvdata(); + uint8_t b = ssp_sendrecvdata(); + *out++ = RGB565(r,g,b); + } + CS_HIGH; } #else // @@ -415,162 +415,179 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) // Fill region by some color void ili9341_fill(int x, int y, int w, int h, int color) { - uint32_t xx = __REV16(x|((x+w-1)<<16)); - uint32_t yy = __REV16(y|((y+h-1)<<16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_WRITE, 0, NULL); - - dmaStreamSetMemory0(dmatx, &color); - dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD); - dmaStreamFlush(w * h); + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_WRITE, 0, NULL); + + dmaStreamSetMemory0(dmatx, &color); + dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD); + dmaStreamFlush(w * h); +} + +void ili9341_bulk_8bit(int x, int y, int w, int h, uint16_t *palette){ + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_WRITE, 0, NULL); + + uint8_t *buf = (uint8_t *)spi_buffer; + int32_t len = w * h; + while (len-- > 0){ + uint16_t color = palette[*buf++]; + while (SPI_TX_IS_NOT_EMPTY); + SPI_WRITE_16BIT(color); + } } + // Copy spi_buffer to region void ili9341_bulk(int x, int y, int w, int h) { - uint32_t xx = __REV16(x|((x+w-1)<<16)); - uint32_t yy = __REV16(y|((y+h-1)<<16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_WRITE, 0, NULL); - - // Init Tx DMA mem->spi, set size, mode (spi and mem data size is 16 bit) - dmaStreamSetMemory0(dmatx, spi_buffer); - dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC); - dmaStreamFlush(w * h); + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_WRITE, 0, NULL); + + // Init Tx DMA mem->spi, set size, mode (spi and mem data size is 16 bit) + dmaStreamSetMemory0(dmatx, spi_buffer); + dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC); + dmaStreamFlush(w * h); } // Copy screen data to buffer // Warning!!! buffer size must be greater then 3*len + 1 bytes void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) { - uint8_t dummy_tx = 0; - uint8_t *rgbbuf=(uint8_t *)out; - uint16_t data_size = len * 3 + 1; - uint32_t xx = __REV16(x|((x+w-1)<<16)); - uint32_t yy = __REV16(y|((y+h-1)<<16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_READ, 0, NULL); - // Skip SPI rx buffer - while (SPI_RX_IS_NOT_EMPTY) - (void) SPI_READ_DATA; - // Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit) - dmaStreamSetMemory0(dmarx, rgbbuf); - dmaStreamSetTransactionSize(dmarx, data_size); - dmaStreamSetMode(dmarx, rxdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MINC); - // Init dummy Tx DMA (for rx clock), size, mode (spi and mem data size is 8 bit) - dmaStreamSetMemory0(dmatx, &dummy_tx); - dmaStreamSetTransactionSize(dmatx, data_size); - dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE); - - // Start DMA exchange - dmaStreamEnable(dmatx); - dmaStreamEnable(dmarx); - // Wait DMA completion - dmaWaitCompletion(dmatx); - dmaWaitCompletion(dmarx); - CS_HIGH; - - // Parce recived data - // Skip dummy 8-bit read - rgbbuf++; - while (len-- > 0) { - uint8_t r, g, b; - // read data is always 18bit - r = rgbbuf[0]; - g = rgbbuf[1]; - b = rgbbuf[2]; - *out++ = RGB565(r,g,b); - rgbbuf+=3; - } + uint8_t dummy_tx = 0; + uint8_t *rgbbuf=(uint8_t *)out; + uint16_t data_size = len * 3 + 1; + uint32_t xx = __REV16(x|((x+w-1)<<16)); + uint32_t yy = __REV16(y|((y+h-1)<<16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_READ, 0, NULL); + // Skip SPI rx buffer + while (SPI_RX_IS_NOT_EMPTY) + (void) SPI_READ_DATA; + // Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit) + dmaStreamSetMemory0(dmarx, rgbbuf); + dmaStreamSetTransactionSize(dmarx, data_size); + dmaStreamSetMode(dmarx, rxdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MINC); + // Init dummy Tx DMA (for rx clock), size, mode (spi and mem data size is 8 bit) + dmaStreamSetMemory0(dmatx, &dummy_tx); + dmaStreamSetTransactionSize(dmatx, data_size); + dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE); + + // Start DMA exchange + dmaStreamEnable(dmatx); + dmaStreamEnable(dmarx); + // Wait DMA completion + dmaWaitCompletion(dmatx); + dmaWaitCompletion(dmarx); + CS_HIGH; + + // Parce recived data + // Skip dummy 8-bit read + rgbbuf++; + while (len-- > 0) { + uint8_t r, g, b; + // read data is always 18bit + r = rgbbuf[0]; + g = rgbbuf[1]; + b = rgbbuf[2]; + *out++ = RGB565(r,g,b); + rgbbuf+=3; + } } #endif void clearScreen(void){ - ili9341_fill(0, 0, ILI9341_WIDTH, ILI9341_HEIGHT, background_color); + ili9341_fill(0, 0, ILI9341_WIDTH, ILI9341_HEIGHT, background_color); } void setForegroundColor(uint16_t fg) {foreground_color = fg;} void setBackgroundColor(uint16_t bg) {background_color = bg;} void ili9341_setRotation(uint8_t r) { -// static const uint8_t rotation_const[]={DISPLAY_ROTATION_0, DISPLAY_ROTATION_90, DISPLAY_ROTATION_180, DISPLAY_ROTATION_270}; - send_command(ILI9341_MEMORY_ACCESS_CONTROL, 1, &r); +// static const uint8_t rotation_const[]={DISPLAY_ROTATION_0, DISPLAY_ROTATION_90, DISPLAY_ROTATION_180, DISPLAY_ROTATION_270}; + send_command(ILI9341_MEMORY_ACCESS_CONTROL, 1, &r); } void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap){ - uint16_t *buf = spi_buffer; - for(uint16_t c = 0; c < height; c++) { - uint8_t bits = *bitmap++; - for (uint16_t r = 0; r < width; r++) { - *buf++ = (0x80 & bits) ? foreground_color : background_color; - bits <<= 1; - } - } - ili9341_bulk(x, y, width, height); + uint16_t *buf = spi_buffer; + for(uint16_t c = 0; c < height; c++) { + uint8_t bits = *bitmap++; + for (uint16_t r = 0; r < width; r++) { + *buf++ = (0x80 & bits) ? foreground_color : background_color; + bits <<= 1; + } + } + ili9341_bulk(x, y, width, height); } void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap){ - uint16_t *buf = spi_buffer; - for(uint16_t c = 0; c < height; c++) { - uint16_t bits = *bitmap++; - for (uint16_t r = 0; r < width; r++) { - *buf++ = (0x8000 & bits) ? foreground_color : background_color; - bits <<= 1; - } + uint16_t *buf = spi_buffer; + for(uint16_t c = 0; c < height; c++) { + uint16_t bits = *bitmap++; + for (uint16_t r = 0; r < width; r++) { + *buf++ = (0x8000 & bits) ? foreground_color : background_color; + bits <<= 1; } - ili9341_bulk(x, y, width, height); + } + ili9341_bulk(x, y, width, height); } void ili9341_drawchar(uint8_t ch, int x, int y) { - blit8BitWidthBitmap(x, y, FONT_GET_WIDTH(ch), FONT_GET_HEIGHT, FONT_GET_DATA(ch)); + blit8BitWidthBitmap(x, y, FONT_GET_WIDTH(ch), FONT_GET_HEIGHT, FONT_GET_DATA(ch)); } void ili9341_drawstring(const char *str, int x, int y) { - while (*str) { - uint8_t ch = *str++; - const uint8_t *char_buf = FONT_GET_DATA(ch); - uint16_t w = FONT_GET_WIDTH(ch); - blit8BitWidthBitmap(x, y, w, FONT_GET_HEIGHT, char_buf); - x+=w; - } + while (*str) { + uint8_t ch = *str++; + const uint8_t *char_buf = FONT_GET_DATA(ch); + uint16_t w = FONT_GET_WIDTH(ch); + blit8BitWidthBitmap(x, y, w, FONT_GET_HEIGHT, char_buf); + x+=w; + } } void ili9341_drawstringV(const char *str, int x, int y){ - ili9341_setRotation(DISPLAY_ROTATION_270); - ili9341_drawstring(str, ILI9341_HEIGHT-y, x); - ili9341_setRotation(DISPLAY_ROTATION_0); + ili9341_setRotation(DISPLAY_ROTATION_270); + ili9341_drawstring(str, ILI9341_HEIGHT-y, x); + ili9341_setRotation(DISPLAY_ROTATION_0); } int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size) { - uint16_t *buf = spi_buffer; - const uint8_t *char_buf = FONT_GET_DATA(ch); - uint16_t w=FONT_GET_WIDTH(ch); - for(int c = 0; c < FONT_GET_HEIGHT; c++, char_buf++){ - for (int i=0;i x1) { - SWAP(x0, x1); - SWAP(y0, y1); - } + if (x0 > x1) { + SWAP(x0, x1); + SWAP(y0, y1); + } - while (x0 <= x1) { - int dx = x1 - x0 + 1; - int dy = y1 - y0; - if (dy >= 0) { - dy++; - if (dy > dx) { - dy /= dx; dx = 1; - } else { - dx /= dy; dy = 1; - } - } else { - dy--; - if (-dy > dx) { - dy /= dx; dx = 1; - } else { - dx /= -dy;dy = -1; - } - } - if (dy > 0) - ili9341_fill(x0, y0, dx, dy, foreground_color); - else - ili9341_fill(x0, y0+dy, dx, -dy, foreground_color); - x0 += dx; - y0 += dy; + while (x0 <= x1) { + int dx = x1 - x0 + 1; + int dy = y1 - y0; + if (dy >= 0) { + dy++; + if (dy > dx) { + dy /= dx; dx = 1; + } else { + dx /= dy; dy = 1; + } + } else { + dy--; + if (-dy > dx) { + dy /= dx; dx = 1; + } else { + dx /= -dy;dy = -1; + } } + if (dy > 0) + ili9341_fill(x0, y0, dx, dy, foreground_color); + else + ili9341_fill(x0, y0+dy, dx, -dy, foreground_color); + x0 += dx; + y0 += dy; + } } #if 0 static const uint16_t colormap[] = { - RGBHEX(0x00ff00), RGBHEX(0x0000ff), RGBHEX(0xff0000), - RGBHEX(0x00ffff), RGBHEX(0xff00ff), RGBHEX(0xffff00) + RGBHEX(0x00ff00), RGBHEX(0x0000ff), RGBHEX(0xff0000), + RGBHEX(0x00ffff), RGBHEX(0xff00ff), RGBHEX(0xffff00) }; void ili9341_test(int mode) { - int x, y; - int i; - switch (mode) { - default: + int x, y; + int i; + switch (mode) { + default: #if 1 - ili9341_fill(0, 0, 320, 240, 0); - for (y = 0; y < 240; y++) { - ili9341_fill(0, y, 320, 1, RGB(240-y, y, (y + 120) % 256)); - } - break; - case 1: - ili9341_fill(0, 0, 320, 240, 0); - for (y = 0; y < 240; y++) { - for (x = 0; x < 320; x++) { - ili9341_pixel(x, y, (y<<8)|x); - } - } - break; - case 2: - //send_command16(0x55, 0xff00); - ili9341_pixel(64, 64, 0xaa55); - break; + ili9341_fill(0, 0, 320, 240, 0); + for (y = 0; y < 240; y++) { + ili9341_fill(0, y, 320, 1, RGB(240-y, y, (y + 120) % 256)); + } + break; + case 1: + ili9341_fill(0, 0, 320, 240, 0); + for (y = 0; y < 240; y++) { + for (x = 0; x < 320; x++) { + ili9341_pixel(x, y, (y<<8)|x); + } + } + break; + case 2: + //send_command16(0x55, 0xff00); + ili9341_pixel(64, 64, 0xaa55); + break; #endif #if 1 - case 3: - for (i = 0; i < 10; i++) - ili9341_drawfont(i, i*20, 120); - break; + case 3: + for (i = 0; i < 10; i++) + ili9341_drawfont(i, i*20, 120); + break; #endif #if 0 - case 4: - draw_grid(10, 8, 29, 29, 15, 0, 0xffff, 0); - break; + case 4: + draw_grid(10, 8, 29, 29, 15, 0, 0xffff, 0); + break; #endif - case 4: - ili9341_line(0, 0, 15, 100); - ili9341_line(0, 0, 100, 100); - ili9341_line(0, 15, 100, 0); - ili9341_line(0, 100, 100, 0); - break; - } + case 4: + ili9341_line(0, 0, 15, 100); + ili9341_line(0, 0, 100, 100); + ili9341_line(0, 15, 100, 0); + ili9341_line(0, 100, 100, 0); + break; + } } #endif diff --git a/main.c b/main.c index 243f2ab0..e903394e 100644 --- a/main.c +++ b/main.c @@ -518,7 +518,7 @@ VNA_SHELL_FUNCTION(cmd_dac) "current value: %d\r\n", config.dac_value); return; } - value = my_atoi(argv[0]); + value = my_atoui(argv[0]); config.dac_value = value; dacPutChannelX(&DACD2, 0, value); } @@ -2177,8 +2177,9 @@ static void VNAShell_executeLine(char *line){ if (scp->flags&CMD_WAIT_MUTEX){ shell_function= scp->sc_function; // Wait execute command in sweep thread - while(shell_function) - osalThreadSleepMilliseconds(100); + do{ + osalThreadSleepMilliseconds(100);} + while(shell_function); } else scp->sc_function(shell_nargs-1, &shell_args[1]); diff --git a/nanovna.h b/nanovna.h index 826a0f29..0fbab6d9 100644 --- a/nanovna.h +++ b/nanovna.h @@ -27,6 +27,7 @@ */ #define START_MIN 50000 #define STOP_MAX 2700000000U +#define SPEED_OF_LIGHT 299792458 #define POINTS_COUNT 101 extern float measured[2][POINTS_COUNT][2]; @@ -211,6 +212,7 @@ typedef struct trace { #define FREQ_MODE_START_STOP 0x0 #define FREQ_MODE_CENTER_SPAN 0x1 +#define FREQ_MODE_DOTTED_GRID 0x2 typedef struct config { int32_t magic; diff --git a/plot.c b/plot.c index 0975bb4e..1ebf2b27 100644 --- a/plot.c +++ b/plot.c @@ -8,13 +8,17 @@ static void cell_draw_marker_info(int x0, int y0); static void draw_battery_status(void); -int16_t grid_offset; -int16_t grid_width; +static int16_t grid_offset; +static int16_t grid_width; int16_t area_width = AREA_WIDTH_NORMAL; int16_t area_height = AREA_HEIGHT_NORMAL; -// Depends from spi_buffer size, CELLWIDTH*CELLHEIGHT <= sizeof(spi_buffer) +// Cell render use spi buffer +typedef uint16_t pixel; +pixel *cell_buffer = (pixel *)spi_buffer; +// Cell size +// Depends from spi_buffer size, CELLWIDTH*CELLHEIGHT*sizeof(pixel) <= sizeof(spi_buffer) #define CELLWIDTH (64) #define CELLHEIGHT (32) // Check buffer size @@ -46,7 +50,6 @@ static index_t trace_index[TRACES_MAX][POINTS_COUNT]; #define INDEX(x, y) ((((index_t)x)<<16)|(((index_t)y))) #define CELL_X(i) (int)(((i)>>16)) #define CELL_Y(i) (int)(((i)&0xFFFF)) -//#define CELL_P(i, x, y) (((((x)&0x03e0UL)<<22) | (((y)&0x03e0UL)<<17)) == ((i)&0xffc00000UL)) //#define floatToInt(v) ((int)(v)) static int @@ -755,7 +758,6 @@ static float time_of_index(int idx) { } static float distance_of_index(int idx) { -#define SPEED_OF_LIGHT 299792458 float distance = ((float)idx * (float)SPEED_OF_LIGHT) / ( (float)(frequencies[1] - frequencies[0]) * (float)FFT_SIZE * 2.0); return distance * velocity_factor; } @@ -852,7 +854,7 @@ cell_drawline(int x0, int y0, int x1, int y1, int c) while (1){ if (y0>=0 && y0=0 && x0= 0 && x0 < CELLWIDTH) - spi_buffer[y0*CELLWIDTH+x0] = (bits&0x80) ? c : DEFAULT_BG_COLOR; + cell_buffer[y0*CELLWIDTH+x0] = (bits&0x80) ? c : DEFAULT_BG_COLOR; x0++; bits<<=1; } @@ -999,9 +1001,9 @@ draw_marker(int x, int y, int c, int ch) force_color = true; if (x0 >= 0 && x0 < CELLWIDTH && y0 >= 0 && y0 < CELLHEIGHT){ if (bits&0x80) - spi_buffer[y0*CELLWIDTH+x0] = c; + cell_buffer[y0*CELLWIDTH+x0] = c; else if (force_color) - spi_buffer[y0*CELLWIDTH+x0] = DEFAULT_BG_COLOR; + cell_buffer[y0*CELLWIDTH+x0] = DEFAULT_BG_COLOR; } x0++; bits<<=1; @@ -1153,7 +1155,6 @@ search_nearest_index(int x, int y, int t) min_i = i; } } - return min_i; } @@ -1210,8 +1211,8 @@ draw_cell(int m, int n) #error "CELLWIDTH % 8 should be == 0 for speed, or need rewrite cell cleanup" #endif // Set DEFAULT_BG_COLOR for 8 pixels in one cycle - int count = h*CELLWIDTH / 8; - uint32_t *p = (uint32_t *)spi_buffer; + int count = h*CELLWIDTH / (16/sizeof(pixel)); + uint32_t *p = (uint32_t *)cell_buffer; while (count--) { p[0] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); p[1] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); @@ -1234,14 +1235,14 @@ draw_cell(int m, int n) for (x = 0; x < w; x++) { if (rectangular_grid_x(x+x0)){ for (y = 0; y < h; y++) - spi_buffer[y * CELLWIDTH + x] = c; + cell_buffer[y * CELLWIDTH + x] = c; } } for (y = 0; y < h; y++) { if (rectangular_grid_y(y+y0)){ for (x = 0; x < w; x++) if (x+x0 >= CELLOFFSETX && x+x0 <= WIDTH+CELLOFFSETX) - spi_buffer[y * CELLWIDTH + x] = c; + cell_buffer[y * CELLWIDTH + x] = c; } } } @@ -1250,22 +1251,22 @@ draw_cell(int m, int n) for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (smith_grid(x+x0, y+y0)) - spi_buffer[y * CELLWIDTH + x] = c; + cell_buffer[y * CELLWIDTH + x] = c; } // Polar greed line (800 system ticks for all screen calls) else if(trace_type&(1<= 0 && (x+r) < CELLWIDTH && (0x80 & bits)) - spi_buffer[(y+c)*CELLWIDTH + (x+r)] = foreground_color; + cell_buffer[(y+c)*CELLWIDTH + (x+r)] = foreground_color; bits <<= 1; } } @@ -1578,9 +1579,9 @@ cell_draw_marker_info(int x0, int y0) cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; - float light_speed_ps = 299792458e-12; //(m/ps) + float light_speed_ps = SPEED_OF_LIGHT*1e-12; //(m/ps) plot_printf(buf, sizeof buf, "Edelay %Fs %Fm", electrical_delay * 1e-12, - electrical_delay * light_speed_ps * velocity_factor); + electrical_delay * light_speed_ps * velocity_factor); cell_drawstring(buf, xpos, ypos); } } diff --git a/si5351.c b/si5351.c index 96c82a2a..7cd37daa 100644 --- a/si5351.c +++ b/si5351.c @@ -41,7 +41,7 @@ static uint32_t current_freq = 0; // Minimum value is 2, freq change apply at next dsp measure, and need skip it #define DELAY_NORMAL 2 -// Delay for bands (depend set band 1 more fast (can change before next dsp bufer ready, need wait additional interval) +// Delay for bands (depend set band 1 more fast (can change before next dsp buffer ready, need wait additional interval) #define DELAY_BAND_1 3 #define DELAY_BAND_2 2 // Band changes need set delay after reset PLL From 922b66abdba87324d2476be8dddec8c399ec9c64 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 14 Mar 2020 15:18:14 +0300 Subject: [PATCH 17/24] Move offset variable to si5351.c (better use it as independent library) Define and move constants in nanovna.h, and use it Fix command 'marker' - display marker freq (not current freq) --- fft.h | 4 ++-- main.c | 30 ++++++++++++------------------ nanovna.h | 14 +++++++++++--- plot.c | 10 +++++----- si5351.c | 20 ++++++++++++++------ si5351.h | 6 +++++- 6 files changed, 49 insertions(+), 35 deletions(-) diff --git a/fft.h b/fft.h index 0c367b72..dbaa32f5 100644 --- a/fft.h +++ b/fft.h @@ -68,8 +68,8 @@ static void fft256(float array[][2], const uint8_t dir) { uint16_t j, k; for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) { uint16_t l = j + halfsize; - float tpre = array[l][real] * cos(2 * M_PI * k / 256) + array[l][imag] * sin(2 * M_PI * k / 256); - float tpim = -array[l][real] * sin(2 * M_PI * k / 256) + array[l][imag] * cos(2 * M_PI * k / 256); + float tpre = array[l][real] * cos(2 * VNA_PI * k / 256) + array[l][imag] * sin(2 * VNA_PI * k / 256); + float tpim = -array[l][real] * sin(2 * VNA_PI * k / 256) + array[l][imag] * cos(2 * VNA_PI * k / 256); array[l][real] = array[j][real] - tpre; array[l][imag] = array[j][imag] - tpim; array[j][real] += tpre; diff --git a/main.c b/main.c index e903394e..37485799 100644 --- a/main.c +++ b/main.c @@ -72,8 +72,8 @@ static volatile vna_shellcmd_t shell_function = 0; static void apply_error_term_at(int i); static void apply_edelay_at(int i); static void cal_interpolate(int s); -void update_frequencies(void); -void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); +static void update_frequencies(void); +static void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); static bool sweep(bool break_on_operation); static void transform_domain(void); @@ -83,8 +83,6 @@ static void transform_domain(void); // Obsolete, always use interpolate #define cal_auto_interpolate TRUE -static int32_t frequency_offset = 5000; -static uint32_t frequency = 10000000; static int8_t drive_strength = DRIVE_STRENGTH_AUTO; int8_t sweep_mode = SWEEP_ENABLE; volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags @@ -330,7 +328,7 @@ static int adjust_gain(uint32_t newfreq) { int new_order = newfreq / FREQ_HARMONICS; - int old_order = frequency / FREQ_HARMONICS; + int old_order = si5351_getFrequency() / FREQ_HARMONICS; if (new_order != old_order) { tlv320aic3204_set_gain(gain_table[new_order], gain_table[new_order]); return DELAY_GAIN_CHANGE; @@ -345,9 +343,7 @@ int set_frequency(uint32_t freq) if (ds == DRIVE_STRENGTH_AUTO) { ds = freq > FREQ_HARMONICS ? SI5351_CLK_DRIVE_STRENGTH_8MA : SI5351_CLK_DRIVE_STRENGTH_2MA; } - delay += si5351_set_frequency_with_offset(freq, frequency_offset, ds); - - frequency = freq; + delay += si5351_set_frequency_with_offset(freq, ds); return delay; } @@ -468,8 +464,7 @@ VNA_SHELL_FUNCTION(cmd_offset) shell_printf("usage: offset {frequency offset(Hz)}\r\n"); return; } - frequency_offset = my_atoui(argv[0]); - set_frequency(frequency); + si5351_set_frequency_offset(my_atoi(argv[0])); } VNA_SHELL_FUNCTION(cmd_freq) @@ -493,7 +488,7 @@ VNA_SHELL_FUNCTION(cmd_power) return; } drive_strength = my_atoi(argv[0]); - set_frequency(frequency); +// set_frequency(frequency); } #ifdef ENABLE_TIME_COMMAND @@ -901,7 +896,7 @@ update_marker_index(void) } } -void +static void set_frequencies(uint32_t start, uint32_t stop, uint16_t points) { uint32_t i; @@ -923,7 +918,7 @@ set_frequencies(uint32_t start, uint32_t stop, uint16_t points) frequencies[i] = 0; } -void +static void update_frequencies(void) { uint32_t start, stop; @@ -1100,7 +1095,7 @@ adjust_ed(void) // prepare 1/s11ao to avoid dividing complex float c = 1000e-15; float z0 = 50; - //float z = 2 * M_PI * frequencies[i] * c * z0; + //float z = 2 * VNA_PI * frequencies[i] * c * z0; float z = 0.02; cal_data[ETERM_ED][i][0] += z; } @@ -1118,7 +1113,7 @@ eterm_calc_es(void) float c = 50e-15; //float c = 1.707e-12; float z0 = 50; - float z = 2 * M_PI * frequencies[i] * c * z0; + float z = 2 * VNA_PI * frequencies[i] * c * z0; float sq = 1 + z*z; float s11aor = (1 - z*z) / sq; float s11aoi = 2*z / sq; @@ -1254,7 +1249,7 @@ static void apply_error_term_at(int i) static void apply_edelay_at(int i) { - float w = 2 * M_PI * electrical_delay * frequencies[i] * 1E-12; + float w = 2 * VNA_PI * electrical_delay * frequencies[i] * 1E-12; float s = sin(w); float c = cos(w); float real = measured[0][i][0]; @@ -1667,7 +1662,7 @@ VNA_SHELL_FUNCTION(cmd_marker) if (t < 0 || t >= MARKERS_MAX) goto usage; if (argc == 1) { - shell_printf("%d %d %d\r\n", t+1, markers[t].index, frequency); + shell_printf("%d %d %d\r\n", t+1, markers[t].index, markers[t].frequency); active_marker = t; // select active marker markers[t].enabled = TRUE; @@ -1893,7 +1888,6 @@ VNA_SHELL_FUNCTION(cmd_stat) // shell_printf("awd: %d\r\n", awd_count); } - #ifndef VERSION #define VERSION "unknown" #endif diff --git a/nanovna.h b/nanovna.h index 0fbab6d9..5fddc788 100644 --- a/nanovna.h +++ b/nanovna.h @@ -25,9 +25,17 @@ /* * main.c */ -#define START_MIN 50000 -#define STOP_MAX 2700000000U -#define SPEED_OF_LIGHT 299792458 + +// Minimum frequency set +#define START_MIN 50000 +// Maximum frequency set +#define STOP_MAX 2700000000U +// Frequency offset (sin_cos table in dsp.c generated for this offset, if change need create new table) +#define FREQUENCY_OFFSET 5000 +// Speed of light const +#define SPEED_OF_LIGHT 299792458 +// pi const +#define VNA_PI 3.14159265358979323846 #define POINTS_COUNT 101 extern float measured[2][POINTS_COUNT][2]; diff --git a/plot.c b/plot.c index 1ebf2b27..fd2f8cf8 100644 --- a/plot.c +++ b/plot.c @@ -425,7 +425,7 @@ logmag(const float *v) static float phase(const float *v) { - return 2 * atan2f(v[1], v[0]) / M_PI * 90; + return 2 * atan2f(v[1], v[0]) / VNA_PI * 90; } /* @@ -438,9 +438,9 @@ groupdelay(const float *v, const float *w, float deltaf) // atan(w)-atan(v) = atan((w-v)/(1+wv)) float r = w[0]*v[1] - w[1]*v[0]; float i = w[0]*v[0] + w[1]*v[1]; - return atan2f(r, i) / (2 * M_PI * deltaf); + return atan2f(r, i) / (2 * VNA_PI * deltaf); #else - return (atan2f(w[0], w[1]) - atan2f(v[0], v[1])) / (2 * M_PI * deltaf); + return (atan2f(w[0], w[1]) - atan2f(v[0], v[1])) / (2 * VNA_PI * deltaf); #endif } @@ -605,11 +605,11 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) case MS_RLC: if (zi < 0){// Capacity prefix = 'F'; - value = -1 / (2 * M_PI * frequency * zi); + value = -1 / (2 * VNA_PI * frequency * zi); } else { prefix = 'H'; - value = zi / (2 * M_PI * frequency); + value = zi / (2 * VNA_PI * frequency); } plot_printf(buf, len, "%F"S_OHM" %F%c", zr, value, prefix); break; diff --git a/si5351.c b/si5351.c index 7cd37daa..fefffb0e 100644 --- a/si5351.c +++ b/si5351.c @@ -36,8 +36,9 @@ // I2C address on bus (only 0x60 for Si5351A in 10-Pin MSOP) #define SI5351_I2C_ADDR 0x60 -static uint8_t current_band = 0; -static uint32_t current_freq = 0; +static uint8_t current_band = 0; +static uint32_t current_freq = 0; +static int32_t current_offset = FREQUENCY_OFFSET; // Minimum value is 2, freq change apply at next dsp measure, and need skip it #define DELAY_NORMAL 2 @@ -50,6 +51,13 @@ static uint32_t current_freq = 0; // Delay after set new PLL values, and send reset (on band 1 unstable if less then 900, on 4000-5000 no amplitude spike on change) #define DELAY_RESET_PLL 5000 +uint32_t si5351_getFrequency(void) {return current_freq;} + +void si5351_set_frequency_offset(int32_t offset) { + current_offset = offset; + current_freq = 0; // reset freq, for +} + static void si5351_bulk_write(const uint8_t *buf, int len) { @@ -354,15 +362,17 @@ static inline uint8_t si5351_getBand(uint32_t freq){ * CLK2: fixed 8MHz */ int -si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength){ +si5351_set_frequency_with_offset(uint32_t freq, uint8_t drive_strength){ uint8_t band; int delay = DELAY_NORMAL; if (freq == current_freq) return delay; - uint32_t ofreq = freq + offset; + uint32_t ofreq = freq + current_offset; uint32_t mul = 1, omul = 1; uint32_t rdiv = SI5351_R_DIV_1; uint32_t fdiv; + // Fix possible uncorrect input + drive_strength&=SI5351_CLK_DRIVE_STRENGTH_MASK; current_freq = freq; if (freq >= config.harmonic_freq_threshold * 7U) { mul = 9; @@ -386,7 +396,6 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng freq<<= 3; ofreq<<= 3; } - band = si5351_getBand(freq/mul); switch (band) { case 1: @@ -420,7 +429,6 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng si5351_set_frequency_fixedpll(2, (uint64_t)freq*fdiv, CLK2_FREQUENCY*mul, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA|SI5351_CLK_PLL_SELECT_B); break; } - if (current_band != band) { si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B); current_band = band; diff --git a/si5351.h b/si5351.h index 6b5bdf5e..42a7d99e 100644 --- a/si5351.h +++ b/si5351.h @@ -72,4 +72,8 @@ void si5351_init(void); void si5351_disable_output(void); void si5351_enable_output(void); //void si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength); -int si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength); + +void si5351_set_frequency_offset(int32_t offset); +int si5351_set_frequency_with_offset(uint32_t freq, uint8_t drive_strength); +uint32_t si5351_getFrequency(void); + From ec81a01226e9e09bd2be8fbc107d3334665b8809 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 14 Mar 2020 15:21:26 +0300 Subject: [PATCH 18/24] Not use float in vbat measure (faster, less size), yes get little error (but less then 1mV) --- adc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/adc.c b/adc.c index 24862105..53ede93e 100644 --- a/adc.c +++ b/adc.c @@ -79,20 +79,23 @@ uint16_t adc_single_read(uint32_t chsel) int16_t adc_vbat_read(void) { +// 13.9 Temperature sensor and internal reference voltage +// VREFINT_CAL calibrated on 3.3V, need get value in mV #define ADC_FULL_SCALE 3300 #define VREFINT_CAL (*((uint16_t*)0x1FFFF7BA)) adc_stop(); - float vbat = 0; - float vrefint = 0; ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN; // VREFINT == ADC_IN17 - vrefint = adc_single_read(ADC_CHSELR_CHSEL17); + uint32_t vrefint = adc_single_read(ADC_CHSELR_CHSEL17); // VBAT == ADC_IN18 // VBATEN enables resiter devider circuit. It consume vbat power. - vbat = adc_single_read(ADC_CHSELR_CHSEL18); + uint32_t vbat = adc_single_read(ADC_CHSELR_CHSEL18); ADC->CCR &= ~(ADC_CCR_VREFEN | ADC_CCR_VBATEN); touch_start_watchdog(); - uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * vbat * 2 / (vrefint * ((1<<12)-1))); + // vbat_raw = (3300 * 2 * vbat / 4095) * (VREFINT_CAL / vrefint) + // uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * (float)vbat * 2 / (vrefint * ((1<<12)-1))); + // For speed divide not on 4095, divide on 4096, get little error, but no matter + uint16_t vbat_raw = ((ADC_FULL_SCALE * 2 * vbat)>>12) * VREFINT_CAL / vrefint; if (vbat_raw < 100) { // maybe D2 is not installed return -1; From 8a11eaa76468d153ad0f375e77f3c445e23e599f Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 14 Mar 2020 16:05:26 +0300 Subject: [PATCH 19/24] Extend scan command, now in have additional input variable (optional), allow more faster get measured data usage: scan {start(Hz)} {stop(Hz)} [points] [outmask] [outmask] - optional, allow output measured data, its a mask (allow dec, hex, bin, oct) 0b001 - output frequency 0b010 - output CH0 data 0b100 - output CH1 data Example: 'scan 1000000 5000000 101 0b111' - output data in format: freq ch0[0] ch0[1] ch1[0] ch1[1] 'scan 1000000 5000000 101 0b101' - output data in format: freq ch1[0] ch1[1] 'scan 1000000 5000000 101 0x7' - output data as 0b111 --- main.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 37485799..1335bfcf 100644 --- a/main.c +++ b/main.c @@ -841,9 +841,9 @@ VNA_SHELL_FUNCTION(cmd_scan) { uint32_t start, stop; int16_t points = sweep_points; - - if (argc != 2 && argc != 3) { - shell_printf("usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); + int i; + if (argc < 2 || argc > 4) { + shell_printf("usage: scan {start(Hz)} {stop(Hz)} [points] [outmask]\r\n"); return; } @@ -866,6 +866,20 @@ VNA_SHELL_FUNCTION(cmd_scan) cal_interpolate(lastsaveid); pause_sweep(); sweep(false); + // Output data after if set (faster data recive) + if (argc == 4){ + uint16_t mask = my_atoui(argv[3]); + if (mask) + for (i = 0; i < points; i++){ + if (mask&1) + shell_printf("%u ", frequencies[i]); + if (mask&2) + shell_printf("%f %f ", measured[0][i][0], measured[0][i][1]); + if (mask&4) + shell_printf("%f %f ", measured[1][i][0], measured[1][i][1]); + shell_printf("\r\n"); + } + } } static void @@ -1719,7 +1733,7 @@ VNA_SHELL_FUNCTION(cmd_frequencies) (void)argv; for (i = 0; i < sweep_points; i++) { if (frequencies[i] != 0) - shell_printf("%d\r\n", frequencies[i]); + shell_printf("%u\r\n", frequencies[i]); } } From 45dfd7d970f5186dc69cfddacfdd660c4aabcb77 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 14 Mar 2020 16:48:36 +0300 Subject: [PATCH 20/24] Fix sweep if points < maximum (mot sweep if frequency[i] == 0) Fix my tupo in extended scan command (not correctly parse point count) --- main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index 1335bfcf..99394732 100644 --- a/main.c +++ b/main.c @@ -803,6 +803,7 @@ bool sweep(bool break_on_operation) palClearPad(GPIOC, GPIOC_LED); // Power stabilization after LED off, also align timings on i == 0 for (i = 0; i < sweep_points; i++) { // 5300 + if (frequencies[i] == 0) break; delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure DSP_START(delay+((i==0)?2:0)); // 1900 @@ -853,10 +854,10 @@ VNA_SHELL_FUNCTION(cmd_scan) shell_printf("frequency range is invalid\r\n"); return; } - if (argc == 3) { + if (argc >= 3) { points = my_atoi(argv[2]); if (points <= 0 || points > sweep_points) { - shell_printf("sweep points exceeds range\r\n"); + shell_printf("sweep points exceeds range "define_to_STR(POINTS_COUNT)"\r\n"); return; } } @@ -2148,9 +2149,6 @@ static int VNAShell_readLine(char *line, int max_size){ return 0; } -// Macros for convert define value to string -#define STR1(x) #x -#define define_to_STR(x) STR1(x) // // Parse and run command line // From fdb3886b0f904af9776d2c7eee1c331044a77f3e Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 14 Mar 2020 16:50:35 +0300 Subject: [PATCH 21/24] Move define to str macro in nanovna.h (it allow output define valuer in error messages) --- nanovna.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nanovna.h b/nanovna.h index 5fddc788..281fa264 100644 --- a/nanovna.h +++ b/nanovna.h @@ -490,4 +490,7 @@ int plot_printf(char *str, int, const char *fmt, ...); // Speed profile definition #define START_PROFILE systime_t time = chVTGetSystemTimeX(); #define STOP_PROFILE {char string_buf[12];plot_printf(string_buf, sizeof string_buf, "T:%06d", chVTGetSystemTimeX() - time);ili9341_drawstringV(string_buf, 1, 60);} +// Macros for convert define value to string +#define STR1(x) #x +#define define_to_STR(x) STR1(x) /*EOF*/ From 3eb8a4cfe9d8b4b0ce7575c228a8863cb5f4e823 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 14 Mar 2020 21:23:02 +0300 Subject: [PATCH 22/24] Fix interpolation range if sweep_points!=source calibration points count use sweep_points exept POINTS_COUNT on marker search and so Now possible change sweep_points in process (for faster sweep) --- main.c | 8 ++++---- plot.c | 10 +++++----- ui.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 99394732..6a922681 100644 --- a/main.c +++ b/main.c @@ -856,7 +856,7 @@ VNA_SHELL_FUNCTION(cmd_scan) } if (argc >= 3) { points = my_atoi(argv[2]); - if (points <= 0 || points > sweep_points) { + if (points <= 0 || points > POINTS_COUNT) { shell_printf("sweep points exceeds range "define_to_STR(POINTS_COUNT)"\r\n"); return; } @@ -929,7 +929,7 @@ set_frequencies(uint32_t start, uint32_t stop, uint16_t points) } } // disable at out of sweep range - for (; i < sweep_points; i++) + for (; i < POINTS_COUNT; i++) frequencies[i] = 0; } @@ -1360,7 +1360,7 @@ cal_interpolate(int s) for (; i < sweep_points; i++) { uint32_t f = frequencies[i]; - for (; j < sweep_points-1; j++) { + for (; j < src->_sweep_points-1; j++) { if (src->_frequencies[j] <= f && f < src->_frequencies[j+1]) { // found f between freqs at j and j+1 float k1 = (float)(f - src->_frequencies[j]) @@ -1380,7 +1380,7 @@ cal_interpolate(int s) break; } } - if (j == sweep_points-1) + if (j == src->_sweep_points-1) break; } diff --git a/plot.c b/plot.c index fd2f8cf8..a510b5b7 100644 --- a/plot.c +++ b/plot.c @@ -499,7 +499,7 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]) { int bottom = (i == 0) ? 0 : i - 1; - int top = (i == POINTS_COUNT-1) ? POINTS_COUNT-1 : i + 1; + int top = (i == sweep_points-1) ? sweep_points-1 : i + 1; float deltaf = frequencies[top] - frequencies[bottom]; return groupdelay(array[bottom], array[top], deltaf); } @@ -1062,7 +1062,7 @@ marker_search(void) return -1; int value = CELL_Y(trace_index[uistat.current_trace][0]); - for (i = 0; i < POINTS_COUNT; i++) { + for (i = 0; i < sweep_points; i++) { index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(value, CELL_Y(index))) { value = CELL_Y(index); @@ -1117,14 +1117,14 @@ marker_search_right(int from) return -1; int value = CELL_Y(trace_index[uistat.current_trace][from]); - for (i = from + 1; i < POINTS_COUNT; i++) { + for (i = from + 1; i < sweep_points; i++) { index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(value, CELL_Y(index))) break; value = CELL_Y(index); } - for (; i < POINTS_COUNT; i++) { + for (; i < sweep_points; i++) { index_t index = trace_index[uistat.current_trace][i]; if ((*compare)(CELL_Y(index), value)) { break; @@ -1603,7 +1603,7 @@ draw_frequencies(void) } } else { plot_printf(buf1, sizeof(buf1), " START 0s"); - plot_printf(buf2, sizeof(buf2), "STOP %Fs (%Fm)", time_of_index(POINTS_COUNT-1), distance_of_index(POINTS_COUNT-1)); + plot_printf(buf2, sizeof(buf2), "STOP %Fs (%Fm)", time_of_index(sweep_points-1), distance_of_index(sweep_points-1)); } setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); diff --git a/ui.c b/ui.c index 8d82c359..ae251265 100644 --- a/ui.c +++ b/ui.c @@ -1641,7 +1641,7 @@ lever_move_marker(int status) markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } - if ((status & EVT_UP) && markers[active_marker].index < 100) { + if ((status & EVT_UP) && markers[active_marker].index < sweep_points-1) { markers[active_marker].index++; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); From 23c765b7191fb55136ec9773e2869da0415dd3e8 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 15 Mar 2020 14:14:52 +0300 Subject: [PATCH 23/24] Fix very strange bug, on band 2 !!!!! Don`t understand why si5351 non stable on band 2 then change from band 3 It fixed if set before sweep one frequency from band 1 (for example 50MHz) Possibly problem in tlv320aic3204_set_gain, call only si5351_set_frequency_with_offset not work Little faster call command from shell Fix interpolation if points < POINTS_COUNT --- main.c | 23 ++++++++++++++++------- si5351.c | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 6a922681..069abb29 100644 --- a/main.c +++ b/main.c @@ -120,6 +120,8 @@ static THD_FUNCTION(Thread1, arg) if (shell_function){ shell_function(shell_nargs-1, &shell_args[1]); shell_function = 0; + osalThreadSleepMilliseconds(10); + continue; } // Process UI inputs ui_process(); @@ -802,11 +804,18 @@ bool sweep(bool break_on_operation) // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); // Power stabilization after LED off, also align timings on i == 0 + + // !!!!! Don`t understand why si5351 non stable on band 2 then change from band 3 + // It fixed if set before one band 1 frequency + // Possibly problem in gain, call only si5351_set_frequency_with_offset not work + // Also it allow align sweep timings + set_frequency(50000000); + DSP_START(1);DSP_WAIT_READY; for (i = 0; i < sweep_points; i++) { // 5300 if (frequencies[i] == 0) break; delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure - DSP_START(delay+((i==0)?2:0)); // 1900 + DSP_START(delay); // 1900 //================================================ // Place some code thats need execute while delay //================================================ @@ -1359,7 +1368,7 @@ cal_interpolate(int s) j = 0; for (; i < sweep_points; i++) { uint32_t f = frequencies[i]; - + if (f == 0) goto interpolate_finish; for (; j < src->_sweep_points-1; j++) { if (src->_frequencies[j] <= f && f < src->_frequencies[j+1]) { // found f between freqs at j and j+1 @@ -1388,11 +1397,11 @@ cal_interpolate(int s) for (; i < sweep_points; i++) { // fill cal_data at tail of src for (eterm = 0; eterm < 5; eterm++) { - cal_data[eterm][i][0] = src->_cal_data[eterm][sweep_points-1][0]; - cal_data[eterm][i][1] = src->_cal_data[eterm][sweep_points-1][1]; + cal_data[eterm][i][0] = src->_cal_data[eterm][src->_sweep_points-1][0]; + cal_data[eterm][i][1] = src->_cal_data[eterm][src->_sweep_points-1][1]; } } - +interpolate_finish: cal_status |= src->_cal_status | CALSTAT_APPLY | CALSTAT_INTERPOLATED; redraw_request |= REDRAW_CAL_STATUS; } @@ -2184,8 +2193,8 @@ static void VNAShell_executeLine(char *line){ shell_function= scp->sc_function; // Wait execute command in sweep thread do{ - osalThreadSleepMilliseconds(100);} - while(shell_function); + osalThreadSleepMilliseconds(100); + } while(shell_function); } else scp->sc_function(shell_nargs-1, &shell_args[1]); diff --git a/si5351.c b/si5351.c index fefffb0e..1d589b3c 100644 --- a/si5351.c +++ b/si5351.c @@ -65,13 +65,26 @@ si5351_bulk_write(const uint8_t *buf, int len) (void)i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, buf, len, NULL, 0, 1000); i2cReleaseBus(&I2CD1); } + #if 0 -static void si5351_bulk_read(uint8_t reg, uint8_t* buf, int len) +static bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len) { - int addr = SI5351_I2C_ADDR>>1; i2cAcquireBus(&I2CD1); - msg_t mr = i2cMasterTransmitTimeout(&I2CD1, addr, ®, 1, buf, len, 1000); + msg_t mr = i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, ®, 1, buf, len, 1000); i2cReleaseBus(&I2CD1); + return mr == MSG_OK; +} + +static void si5351_wait_pll_lock(void) +{ + uint8_t status; + int count = 100; + do{ + status=0xFF; + si5351_bulk_read(0, &status, 1); + if ((status & 0x60) == 0) // PLLA and PLLB locked + return; + }while (--count); } #endif From 597c2c2958fef95951ec512616dc50a6dcba3269 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 15 Mar 2020 16:02:22 +0300 Subject: [PATCH 24/24] Better solutiom of prev fixes (reload si5351 settings on sweep begin) --- main.c | 9 +-------- si5351.c | 7 +++++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 069abb29..69245fd1 100644 --- a/main.c +++ b/main.c @@ -804,18 +804,11 @@ bool sweep(bool break_on_operation) // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); // Power stabilization after LED off, also align timings on i == 0 - - // !!!!! Don`t understand why si5351 non stable on band 2 then change from band 3 - // It fixed if set before one band 1 frequency - // Possibly problem in gain, call only si5351_set_frequency_with_offset not work - // Also it allow align sweep timings - set_frequency(50000000); - DSP_START(1);DSP_WAIT_READY; for (i = 0; i < sweep_points; i++) { // 5300 if (frequencies[i] == 0) break; delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure - DSP_START(delay); // 1900 + DSP_START(delay+((i==0)?1:0)); // 1900 //================================================ // Place some code thats need execute while delay //================================================ diff --git a/si5351.c b/si5351.c index 1d589b3c..aee7ba8c 100644 --- a/si5351.c +++ b/si5351.c @@ -380,13 +380,16 @@ si5351_set_frequency_with_offset(uint32_t freq, uint8_t drive_strength){ int delay = DELAY_NORMAL; if (freq == current_freq) return delay; + else if (current_freq > freq) // Reset band on sweep begin (if set range 150-600, fix error then 600 MHz band 2 or 3 go back) + current_band = 0; + current_freq = freq; uint32_t ofreq = freq + current_offset; uint32_t mul = 1, omul = 1; uint32_t rdiv = SI5351_R_DIV_1; uint32_t fdiv; - // Fix possible uncorrect input + // Fix possible incorrect input drive_strength&=SI5351_CLK_DRIVE_STRENGTH_MASK; - current_freq = freq; + if (freq >= config.harmonic_freq_threshold * 7U) { mul = 9; omul = 11;