From 9e287c0fe0fd77ef54b63dac4555ada5ff2f0956 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 11 Mar 2021 08:21:09 +0100 Subject: [PATCH] Merge DiSlor speed improvements --- chprintf.c | 14 +++++--------- ili9341.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- main.c | 11 ++++++----- nanovna.h | 5 ++--- plot.c | 36 ++++++++++-------------------------- sa_cmd.c | 2 +- sa_core.c | 18 +++++++++--------- ui.c | 4 ++-- ui_sa.c | 13 +++++++------ 9 files changed, 81 insertions(+), 76 deletions(-) diff --git a/chprintf.c b/chprintf.c index 92aa1ac..6c0c1cd 100644 --- a/chprintf.c +++ b/chprintf.c @@ -42,19 +42,15 @@ #define MAX_FILLER 11 #define FLOAT_PRECISION 9 -#pragma pack(push, 2) - static const uint32_t pow10[FLOAT_PRECISION+1] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; // Prefixes for values bigger then 1000.0 -// 1 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24 -static char bigPrefix[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0}; +// 1 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24 +static const char bigPrefix[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0}; // Prefixes for values less then 1.0 -// 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18, 1e-21, 1e-24 -static char smallPrefix[] = {'m', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0}; - -#pragma pack(pop) +// 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18, 1e-21, 1e-24 +static const char smallPrefix[] = {'m', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0}; #ifdef TINYSA4 typedef uint64_t ulong_t; @@ -189,7 +185,7 @@ static char *ftoa(char *p, float num, uint32_t precision) { static char *ftoaS(char *p, float num, int precision) { char prefix=0; - char *ptr; + const char *ptr; if (num > 1000.0){ for (ptr = bigPrefix+1; *ptr && num > 1000.0; num/=1000, ptr++) ; diff --git a/ili9341.c b/ili9341.c index 586fb6b..1a99aa4 100644 --- a/ili9341.c +++ b/ili9341.c @@ -280,8 +280,14 @@ void spi_DMATxBuffer(uint8_t *buffer, uint16_t len) { dmaStreamFlush(len); } +static void dmaWaitCompletionRxTx(void){ + // Wait DMA completion + dmaWaitCompletion(dmatx); + dmaWaitCompletion(dmarx); +} + // SPI transmit byte buffer use DMA -void spi_DMARxBuffer(uint8_t *buffer, uint16_t len) { +void spi_DMARxBuffer(uint8_t *buffer, uint16_t len, bool wait) { uint8_t dummy_tx = 0xFF; // Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit) dmaStreamSetMemory0(dmarx, buffer); @@ -296,9 +302,8 @@ void spi_DMARxBuffer(uint8_t *buffer, uint16_t len) { // Start DMA exchange dmaStreamEnable(dmarx); dmaStreamEnable(dmatx); - // Wait DMA completion - dmaWaitCompletion(dmatx); - dmaWaitCompletion(dmarx); + if (wait) + dmaWaitCompletionRxTx(); } #endif // __USE_DISPLAY_DMA__ @@ -643,17 +648,9 @@ void ili9341_read_memory(int x, int y, int w, int h, uint16_t *out) // receive pixel data to buffer #ifndef __USE_DISPLAY_DMA_RX__ spi_RxBuffer((uint8_t *)out, len * 3); -#else - spi_DMARxBuffer((uint8_t *)out, len * 3); -#endif - // restore speed if need -#ifdef LCD_SPI_RX_SPEED - SPI_BR_SET(LCD_SPI, LCD_SPI_SPEED); -#endif - LCD_CS_HIGH; // Parse received data to RGB565 format uint8_t *rgbbuf = (uint8_t *)out; - while (len-- > 0) { + do { uint8_t r, g, b; // read data is always 18bit r = rgbbuf[0]; @@ -661,7 +658,34 @@ void ili9341_read_memory(int x, int y, int w, int h, uint16_t *out) b = rgbbuf[2]; *out++ = RGB565(r, g, b); rgbbuf += 3; - } + }while(--len); +#else + // Set data size for DMA read + len*=3; + // Start DMA read, and not wait completion + spi_DMARxBuffer((uint8_t *)out, len, false); + // Parse received data to RGB565 format while data receive by DMA + uint8_t *rgbbuf = (uint8_t *)out; + do { + uint16_t left = dmaStreamGetTransactionSize(dmarx); // Get DMA data left + if (left+3 > len) continue;// Next pixel RGB data not ready + while (left < len){ // Process completed by DMA data + uint8_t r, g, b; // read data is always 18bit in RGB888 format + r = rgbbuf[0]; + g = rgbbuf[1]; + b = rgbbuf[2]; + *out++ = RGB565(r, g, b); + rgbbuf+= 3; + len -= 3; + } + } while(len); + dmaWaitCompletionRxTx(); // Wait DMA completion and stop it +#endif + // restore speed if need +#ifdef LCD_SPI_RX_SPEED + SPI_BR_SET(LCD_SPI, LCD_SPI_SPEED); +#endif + LCD_CS_HIGH; } #endif @@ -685,7 +709,7 @@ void ili9341_read_memory(int x, int y, int w, int h, uint16_t *out) #ifndef __USE_DISPLAY_DMA_RX__ spi_RxBuffer((uint8_t *)out, len * 2); #else - spi_DMARxBuffer((uint8_t *)out, len * 2); + spi_DMARxBuffer((uint8_t *)out, len * 2, true); #endif // restore speed if need #ifdef LCD_SPI_RX_SPEED diff --git a/main.c b/main.c index 67cd44d..e5a32f7 100644 --- a/main.c +++ b/main.c @@ -896,16 +896,16 @@ VNA_SHELL_FUNCTION(cmd_capture) } } -void send_region(const char *t, int x, int y, int w, int h) +void send_region(const char *t, int16_t x, int16_t y, int16_t w, int16_t h) { if (SDU1.config->usbp->state == USB_ACTIVE) { shell_printf(t); struct { char new_str[2]; - uint16_t x; - uint16_t y; - uint16_t w; - uint16_t h; + int16_t x; + int16_t y; + int16_t w; + int16_t h; } region={"\r\n", x,y,w,h}; streamWrite(shell_stream, (void*)®ion, sizeof(region)); } @@ -1060,6 +1060,7 @@ void load_LCD_properties(void) #endif setting.trace_scale = 10.0; setting.trace_refpos = 0; + setting.waterfall = W_OFF; memcpy(setting._trace, def_trace, sizeof(def_trace)); memcpy(setting._markers, def_markers, sizeof(def_markers)); #ifdef __VNA__ diff --git a/nanovna.h b/nanovna.h index a09f41c..9543618 100644 --- a/nanovna.h +++ b/nanovna.h @@ -205,7 +205,7 @@ void my_microsecond_delay(int t); float my_atof(const char *p); int shell_printf(const char *fmt, ...); #ifdef __REMOTE_DESKTOP__ -void send_region(const char *t, int x, int y, int w, int h); +void send_region(const char *t, int16_t x, int16_t y, int16_t w, int16_t h); void send_buffer(uint8_t * buf, int s); #endif void set_marker_frequency(int m, freq_t f); @@ -998,7 +998,7 @@ enum {W_OFF, W_SMALL, W_BIG}; extern freq_t frequencies[POINTS_COUNT]; extern const float unit_scale_value[]; -extern const char * const unit_scale_text[]; +extern const char unit_scale_text[]; #ifdef TINYSA4 extern int debug_frequencies; #endif @@ -1256,7 +1256,6 @@ typedef int16_t pureRSSI_t; extern uint16_t actual_rbw_x10; -int get_waterfall(void); void toggle_tracking(void); void toggle_hambands(void); void reset_calibration(void); diff --git a/plot.c b/plot.c index 0232c05..befa178 100644 --- a/plot.c +++ b/plot.c @@ -154,10 +154,8 @@ void update_grid(void) grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); grid_width = (WIDTH) * (grid / 100) / (fspan / 1000); - if (get_waterfall()){ - ili9341_set_background(LCD_BG_COLOR); - ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom); - } + if (setting.waterfall) + toggle_waterfall(); redraw_request |= REDRAW_FREQUENCY | REDRAW_AREA; } @@ -1634,11 +1632,6 @@ static void update_waterfall(void){ // STOP_PROFILE; } -int get_waterfall(void) -{ - return(setting.waterfall); -} - //extern float peakLevel; //extern float min_level; //int w_max = -130; @@ -1646,30 +1639,21 @@ int get_waterfall(void) void toggle_waterfall(void) { - if (setting.waterfall == W_OFF) { -// w_min = (int)min_level; -// w_max = (int)peakLevel; -// if (w_max < w_min + 20) -// w_max = w_min + 20; - graph_bottom = SMALL_WATERFALL; - setting.waterfall = W_SMALL; - } else if (setting.waterfall == W_SMALL) { - graph_bottom = BIG_WATERFALL; - setting.waterfall = W_BIG; - } else { - graph_bottom = NO_WATERFALL; - setting.waterfall = W_OFF; - } + if (setting.waterfall == W_SMALL) graph_bottom = SMALL_WATERFALL; + else if (setting.waterfall == W_BIG) graph_bottom = BIG_WATERFALL; + else /*if (setting.waterfall == W_OFF)*/graph_bottom = NO_WATERFALL; _grid_y = graph_bottom / NGRIDY; - ili9341_set_background(LCD_BG_COLOR); - ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom); + if (setting.waterfall != W_OFF){ + ili9341_set_background(LCD_BG_COLOR); + ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom); + } request_to_redraw_grid(); } void disable_waterfall(void) { - setting.waterfall = W_BIG; + setting.waterfall = W_OFF; toggle_waterfall(); } diff --git a/sa_cmd.c b/sa_cmd.c index a4d0f0d..7e509be 100644 --- a/sa_cmd.c +++ b/sa_cmd.c @@ -870,7 +870,7 @@ VNA_SHELL_FUNCTION(cmd_scanraw) points = my_atoi(argv[2]); } - if (get_waterfall()) + if (setting.waterfall) disable_waterfall(); // display dma hangs when waterfall is enabled freq_t old_step = setting.frequency_step; diff --git a/sa_core.c b/sa_core.c index b4f917e..7a6160c 100644 --- a/sa_core.c +++ b/sa_core.c @@ -193,7 +193,6 @@ void reset_settings(int m) setting.auto_attenuation = false; setting.subtract_stored = false; setting.normalize_level = 0.0; - setting.waterfall = W_OFF; #ifdef TINYSA4 setting.lo_drive=1; #else @@ -1091,8 +1090,9 @@ void set_unit(int u) redraw_request|=REDRAW_AREA; //dirty = true; // No HW update required, only status panel refresh } -float const unit_scale_value[]={1,0.001,0.000001,0.000000001,0.000000000001}; -const char * const unit_scale_text[]= {"","m", "\035", "n", "p"}; + +const float unit_scale_value[]={ 1, 0.001, 0.000001, 0.000000001, 0.000000000001}; +const char unit_scale_text[]= {' ', 'm', '\035', 'n', 'p'}; void user_set_reflevel(float level) { @@ -1117,7 +1117,7 @@ void set_reflevel(float level) setting.unit_scale_index = 0; setting.unit_scale = 1.0; - while (UNIT_IS_LINEAR(setting.unit) && setting.unit_scale_index < sizeof(unit_scale_value)/sizeof(float) - 1) { + while (UNIT_IS_LINEAR(setting.unit) && setting.unit_scale_index < ARRAY_COUNT(unit_scale_value) - 1) { if (level > unit_scale_value[setting.unit_scale_index]) break; setting.unit_scale_index++; @@ -1436,7 +1436,7 @@ float min_level; freq_t peakFreq; int peakIndex; float temppeakLevel; -int temppeakIndex; +uint16_t temppeakIndex; // volatile int t; void setup_sa(void) @@ -3044,11 +3044,11 @@ modulation_again: } #define MAX_MAX 4 -int16_t max_index[MAX_MAX]; -int16_t cur_max = 0; +static uint16_t max_index[MAX_MAX]; +static uint16_t cur_max = 0; -static int low_count = 0; -static int sweep_counter = 0; // Only used for HW refresh +static uint8_t low_count = 0; +static uint8_t sweep_counter = 0; // Only used for HW refresh // main loop for measurement static bool sweep(bool break_on_operation) diff --git a/ui.c b/ui.c index 31b06d5..8a6d778 100644 --- a/ui.c +++ b/ui.c @@ -2231,8 +2231,8 @@ leave_ui_mode() // Erase bottom area (not redraw on area update) if (MENU_BUTTON_HEIGHT*MENU_BUTTON_MAX - area_height > 0) ili9341_fill(LCD_WIDTH-MENU_BUTTON_WIDTH, area_height, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*MENU_BUTTON_MAX - area_height); - if (get_waterfall()) - ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom); + if (setting.waterfall) + toggle_waterfall(); redraw_request|=REDRAW_AREA | REDRAW_FREQUENCY | REDRAW_CAL_STATUS | REDRAW_BATTERY; } diff --git a/ui_sa.c b/ui_sa.c index e625f36..56f9bab 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1118,9 +1118,10 @@ static UI_FUNCTION_ADV_CALLBACK(menu_waterfall_acb){ (void)item; (void)data; if (b){ - b->icon = get_waterfall() ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; + b->icon = setting.waterfall ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; return; } + setting.waterfall++; if (setting.waterfall>W_BIG)setting.waterfall = W_OFF; toggle_waterfall(); ui_mode_normal(); } @@ -2619,7 +2620,7 @@ redraw_cal_status: ili9341_drawstring("AUTO", x, y); } #endif - plot_printf(buf, BLEN, "%s%s",unit_scale_text[setting.unit_scale_index], unit); + plot_printf(buf, BLEN, "%c%s",unit_scale_text[setting.unit_scale_index], unit); y = add_quick_menu(buf, x, y, (menuitem_t *)menu_unit); // Scale @@ -2627,10 +2628,10 @@ redraw_cal_status: ili9341_set_foreground(color); #if 1 unsigned int i = 0; - while (i < sizeof(scale_value)/sizeof(float)) { - float t = (setting.scale/setting.unit_scale) / scale_value[i];; + while (i < ARRAY_COUNT(scale_value)) { + float t = (setting.scale/setting.unit_scale) / scale_value[i]; if (t > 0.9 && t < 1.1){ - plot_printf(buf, BLEN, "%s%s/",scale_vtext[i],unit_scale_text[setting.unit_scale_index]); + plot_printf(buf, BLEN, "%s%c/",scale_vtext[i],unit_scale_text[setting.unit_scale_index]); break; } i++; @@ -2889,7 +2890,7 @@ redraw_cal_status: } // ili9341_set_background(LCD_BG_COLOR); - if (!get_waterfall()) { // Do not draw bottom level if in waterfall mode + if (!setting.waterfall) { // Do not draw bottom level if in waterfall mode // Bottom level y = area_height + OFFSETY; if (rounding)