From e9f65b142605ea818c5faf82f2ab28e1e757949f Mon Sep 17 00:00:00 2001 From: DiSlord Date: Tue, 11 Feb 2020 11:54:05 +0300 Subject: [PATCH 01/65] Huge rework chsnprintf function (basic functional more compact and faster): I can`t upload my version chprintf.c to ChibiOS\os\hal\lib\streams upload it to root :( now support print float and Suffix if use example %.1F on 1.234e-3 print 1.234m, %F print 1.23m now support + flag %+d on 8 print +8, %+d on -8 print -8 now support freq output if use %q example %q on 1234567890 print 1.234 567 890 GHz, %.8q print 1.234567GHz fix rounding errors on print float example if print use %.2f on 2.199 print 2.20 (before 2.19) Use it in code - made more compact (save about 2k bytes) and easy display values (set output more digits after . for some values) Made some font glyph more compact, allow 3px glyph More correct create frequencies table on big span (not use float operations), also produce more compact code Use double value input from keyboard (not lost Hz on input) Set sweep_points as uint Optimize set_sweep_frequency size Fix freq commands broken after freq set as uint32 (add str to uint32 functions for freq bigger then 2 147 483 647): cmd_freq cmd_offset cmd_threshold cmd_scan cmd_sweep Define _isdigit macro (replace isdigit() function, its too big) Rewrite std universal atoi() to more compact my_atoi and write new unsigned variant my_atoui --- Font5x7.c | 75 ++++---- chprintf.c | 534 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 322 ++++++++++++++++---------------- nanovna.h | 6 +- plot.c | 485 +++++++++++++++++------------------------------- ui.c | 6 +- 6 files changed, 912 insertions(+), 516 deletions(-) create mode 100644 chprintf.c diff --git a/Font5x7.c b/Font5x7.c index 63f66bd..0a3a828 100644 --- a/Font5x7.c +++ b/Font5x7.c @@ -10,14 +10,17 @@ */ #define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) -#define FONT_GET_WIDTH(ch) (7-x5x7_bits[ch*7]&3) +#define FONT_GET_WIDTH(ch) (8-x5x7_bits[ch*7]&7) #define FONT_GET_HEIGHT 7 -#define CHAR5x7_WIDTH_MASK 0x03 -#define CHAR5x7_WIDTH_4px 0x03 -#define CHAR5x7_WIDTH_5px 0x02 -#define CHAR5x7_WIDTH_6px 0x01 -#define CHAR5x7_WIDTH_7px 0x00 +#define CHAR5x7_WIDTH_1px 0x07 +#define CHAR5x7_WIDTH_2px 0x06 +#define CHAR5x7_WIDTH_3px 0x05 +#define CHAR5x7_WIDTH_4px 0x04 +#define CHAR5x7_WIDTH_5px 0x03 +#define CHAR5x7_WIDTH_6px 0x02 +#define CHAR5x7_WIDTH_7px 0x01 +#define CHAR5x7_WIDTH_8px 0x00 /* Font character bitmap data. */ const uint8_t x5x7_bits[127*7] = @@ -100,23 +103,23 @@ const uint8_t x5x7_bits[127*7] = 0b00100000, /* Character (0x04): - width=7 + width=6 +--------+ | | - | ** | - | ** | - | * * | - | * * | - |* * | - |****** | + | * | + | * | + | * * | + | * * | + |* * | + |***** | +--------+ */ - 0b00000000|CHAR5x7_WIDTH_7px, - 0b00110000, - 0b00110000, - 0b01001000, - 0b01001000, - 0b10000100, - 0b11111100, + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b00100000, + 0b01010000, + 0b01010000, + 0b10001000, + 0b11111000, /* Character (0x05): width=5 @@ -575,22 +578,22 @@ const uint8_t x5x7_bits[127*7] = 0b10011000, /* Character (0x1d): - width=7 + width=6 +--------+ | | | | - | * * | - | * * | - | ** ** | - | * * * | + |* * | + |* * | + |** ** | + |* * * | |* | +--------+ */ - 0b00000000|CHAR5x7_WIDTH_7px, + 0b00000000|CHAR5x7_WIDTH_6px, 0b00000000, - 0b01000100, - 0b01000100, - 0b01101100, - 0b01010100, + 0b10001000, + 0b10001000, + 0b11011000, + 0b10101000, 0b10000000, /* Character (0x1e): @@ -632,7 +635,7 @@ const uint8_t x5x7_bits[127*7] = 0b00000000, /* Character (0x20): ' ' - width=4 + width=3 +--------+ | | | | @@ -642,7 +645,7 @@ const uint8_t x5x7_bits[127*7] = | | | | +--------+ */ - 0b00000000|CHAR5x7_WIDTH_4px, + 0b00000000|CHAR5x7_WIDTH_3px, 0b00000000, 0b00000000, 0b00000000, @@ -651,7 +654,7 @@ const uint8_t x5x7_bits[127*7] = 0b00000000, /* Character (0x21): '!' - width=4 + width=3 +--------+ | * | | * | @@ -661,7 +664,7 @@ const uint8_t x5x7_bits[127*7] = | | | * | +--------+ */ - 0b01000000|CHAR5x7_WIDTH_4px, + 0b01000000|CHAR5x7_WIDTH_3px, 0b01000000, 0b01000000, 0b01000000, @@ -870,7 +873,7 @@ const uint8_t x5x7_bits[127*7] = | * | |* | +--------+ */ - 0b00000000|CHAR5x7_WIDTH_4px, + 0b00000000|CHAR5x7_WIDTH_3px, 0b00000000, 0b00000000, 0b00000000, @@ -908,7 +911,7 @@ const uint8_t x5x7_bits[127*7] = |** | |** | +--------+ */ - 0b00000000|CHAR5x7_WIDTH_4px, + 0b00000000|CHAR5x7_WIDTH_3px, 0b00000000, 0b00000000, 0b00000000, diff --git a/chprintf.c b/chprintf.c new file mode 100644 index 0000000..8c75b29 --- /dev/null +++ b/chprintf.c @@ -0,0 +1,534 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + Concepts and parts of this file have been contributed by Fabio Utzig, + chvprintf() added by Brent Roman. + */ + +/** + * @file chprintf.c + * @brief Mini printf-like functionality. + * + * @addtogroup chprintf + * @{ + */ + +#include "hal.h" +#include "chprintf.h" +#include "memstreams.h" +#include + +// Enable [flags], support: +// ' ' Prepends a space for positive signed-numeric types. positive = ' ', negative = '-'. This flag is ignored if the + flag exists. +//#define CHPRINTF_USE_SPACE_FLAG + +#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}; +// 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) + +//86066 5116 11456 102622 190de build/ch.elf +static char *long_to_string_with_divisor(char *p, + uint32_t num, + uint32_t radix, + uint32_t precision) { + char *q = p + MAX_FILLER; + char *b = q; + // convert to string from end buffer to begin + do { + uint8_t c = num % radix; + num /= radix; + *--q = c + ((c > 9) ? 'A' : '0'); + }while((precision && --precision) || num); + // copy string at begin + int i = (int)(b - q); + do + *p++ = *q++; + while (--i); + return p; +} + +// default prescision = 13 +// g.mmm kkk hhh +#define MAX_FREQ_PRESCISION 13 +#define FREQ_PSET 1 +#define FREQ_NO_SPACE 2 +#define FREQ_PREFIX_SPACE 4 + +static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ + uint8_t flag = FREQ_PSET; + if (precision == 0) + flag|=FREQ_PREFIX_SPACE; + if (precision == 0 || precision > MAX_FREQ_PRESCISION) + precision = MAX_FREQ_PRESCISION; + char *q = p + MAX_FREQ_PRESCISION; + char *b = q; + // Prefix counter + uint32_t s = 0; + // Set format (every 3 digits add ' ' up to GHz) + uint32_t format=0b00100100100; + do { +#if 0 + uint8_t c = freq % 10; + freq/= 10; +#else + // Fast and compact division uint32_t on 10, using shifts, result: + // c = freq % 10 + // freq = freq / 10; + uint32_t c = freq; + freq>>=1; + freq+=freq>>1; + freq+=freq>>4; + freq+=freq>>8; + freq+=freq>>16; // freq = 858993459*freq/1073741824 = freq * 0,799999999813735485076904296875 + freq>>=3; // freq/=8; freq = freq * 0,09999999997671693563461303710938 + c-= freq*10; // freq*10 = (freq*4+freq)*2 = ((freq<<2)+freq)<<1 + while (c>=10) {freq++;c-=10;} +#endif + *--q = c + '0'; + if (freq==0) + break; + // Add spaces, calculate prefix + if (format&1) {*--q = ' '; s++;} + format>>=1; + } while (1); + s = bigPrefix[s]; + + // Get string size + uint32_t i = (b - q); + // Limit string size, max size is - precision + if (precision && i > precision) { + i = precision; + flag|=FREQ_NO_SPACE; + } + // copy string + // Replace first ' ' by '.', remove ' ' if size too big + do{ + char c = *q++; + // replace first ' ' on '.' + if (c == ' ') { + if (flag&FREQ_PSET){ + c = '.'; + flag&=~FREQ_PSET; + } + else if (flag&FREQ_NO_SPACE) + c = *q++; + } + *p++ = c; + }while (--i); + // Put pref (amd space before it if need) + if (flag&FREQ_PREFIX_SPACE && s!=' ') + *p++ = ' '; + *p++ = s; + return p; +} + +#if CHPRINTF_USE_FLOAT +static char *ftoa(char *p, float num, uint32_t precision) { + // Check precision limit + if (precision > FLOAT_PRECISION) + precision = FLOAT_PRECISION; + uint32_t multi = pow10[precision]; + uint32_t l = num; + // Round value + uint32_t k = ((num-l)*multi+0.5); + // Fix rounding error if get + if (k>=multi){k-=multi;l++;} + p = long_to_string_with_divisor(p, l, 10, 0); + if (precision && k){ + *p++ = '.'; + p=long_to_string_with_divisor(p, k, 10, precision); + // remove zeros at end + while (p[-1]=='0') p--; + if (p[-1]=='.') p--; + } + return p; +} + +static char *ftoaS(char *p, float num, uint32_t precision) { + char prefix=0; + char *ptr; + if (num > 1000.0){ + for (ptr = bigPrefix+1; *ptr && num > 1000.0; num/=1000, ptr++) + ; + prefix = ptr[-1]; + } + else if (num < 1){ + for (ptr = smallPrefix; *ptr && num < 1.0; num*=1000, ptr++) + ; + prefix = num > 1e-3 ? ptr[-1] : 0; + } + // Auto set prescision + uint32_t l = num; + if (l < 10) + precision+=2; + else if (l < 100) + precision+=1; + p=ftoa(p, num, precision); + if (prefix) + *p++ = prefix; + return p; +} +#endif + +/** + * @brief System formatted output function. + * @details This function implements a minimal @p vprintf()-like functionality + * with output on a @p BaseSequentialStream. + * The general parameters format is: %[-][width|*][.precision|*][l|L]p. + * The following parameter types (p) are supported: + * - x hexadecimal integer. + * - X hexadecimal long. + * - o octal integer. + * - O octal long. + * - d decimal signed integer. + * - D decimal signed long. + * - u decimal unsigned integer. + * - U decimal unsigned long. + * - c character. + * - s string. + * . + * + * @param[in] chp pointer to a @p BaseSequentialStream implementing object + * @param[in] fmt formatting string + * @param[in] ap list of parameters + * @return The number of bytes that would have been + * written to @p chp if no stream error occurs + * + * @api + */ +#define IS_LONG 1 +#define LEFT_ALIGN 2 +#define POSITIVE 4 +#define NEGATIVE 8 +#define PAD_ZERO 16 +#define PLUS_SPACE 32 +#define DEFAULT_PRESCISION 64 + +int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { + char *p, *s, c, filler=' '; + int precision, width; + int n = 0; + uint32_t state; + union { + uint32_t u; + int32_t l; + float f; + }value; +#if CHPRINTF_USE_FLOAT + char tmpbuf[2*MAX_FILLER + 1]; +#else + char tmpbuf[MAX_FREQ_PRESCISION + 1]; +#endif + + while (true) { + c = *fmt++; + if (c == 0) + return n; + if (c != '%') { + streamPut(chp, (uint8_t)c); + n++; + continue; + } + // Parse %[flags][width][.precision][length]type + p = tmpbuf; + s = tmpbuf; + state = 0; + width = 0; + precision = 0; + + // Get [flags], support: + // '-' Left-align the output of this placeholder. (The default is to right-align the output.) + // '+' Prepends a plus for positive signed-numeric types. positive = '+', negative = '-'. + // ' ' Prepends a space for positive signed-numeric types. positive = ' ', negative = '-'. This flag is ignored if the + flag exists. + // '0' When the 'width' option is specified, prepends zeros for numeric types. (The default prepends spaces.) + while (true){ + if (*fmt == '-') + state|=LEFT_ALIGN; + else if (*fmt == '+') + state|=POSITIVE; + else if (*fmt == '0') + state|=PAD_ZERO; +#ifdef CHPRINTF_USE_SPACE_FLAG + else if (*fmt == ' ') + state|=PLUS_SPACE; +#endif + else + break; + fmt++; + } + // Get [width] - The Width field specifies a minimum number of characters to output + // if set *, get width as argument + while (true) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + width = width * 10 + c; + } + // Get [.precision] + if (c == '.') { + while (true) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + precision = precision * 10 + c; + } + } + else + state|=DEFAULT_PRESCISION; + //Get [length] + /* + if (c == 'l' || c == 'L') { + state|=IS_LONG; + if (*fmt) + c = *fmt++; + } + else if((c >= 'A') && (c <= 'Z')) + state|=IS_LONG; + */ + // Parse type + switch (c) { + case 'c': + state&=~PAD_ZERO; + *p++ = va_arg(ap, int); + break; + case 's': + state&=~PAD_ZERO; + if ((s = va_arg(ap, char *)) == 0) + s = "(null)"; + if (state&DEFAULT_PRESCISION) + precision = 32767; + for (p = s; *p && (--precision >= 0); p++) + ; + break; + case 'D': + case 'd': + case 'I': + case 'i':/* + if (state & IS_LONG) + value.l = va_arg(ap, long); + else*/ + value.l = va_arg(ap, uint32_t); + if (value.l < 0) { + state|=NEGATIVE; + *p++ = '-'; + value.l = -value.l; + } + else if (state & POSITIVE) + *p++ = '+'; +#ifdef CHPRINTF_USE_SPACE_FLAG + else if (state & PLUS_SPACE) + *p++ = ' '; +#endif + p = long_to_string_with_divisor(p, value.l, 10, 0); + break; + case 'q': + value.u = va_arg(ap, uint32_t); + p=ulong_freq(p, value.u, precision); + break; +#if CHPRINTF_USE_FLOAT + case 'F': + case 'f': + value.f = va_arg(ap, double); + if (value.f < 0) { + state|=NEGATIVE; + *p++ = '-'; + value.f = -value.f; + } + else if (state & POSITIVE) + *p++ = '+'; +#ifdef CHPRINTF_USE_SPACE_FLAG + else if (state & PLUS_SPACE) + *p++ = ' '; +#endif + if (value.f == INFINITY){ + *p++ = 0x19; + break; + } + p = (c=='F') ? ftoaS(p, value.f, precision) : ftoa(p, value.f, state&DEFAULT_PRESCISION ? FLOAT_PRECISION : precision); + break; +#endif + case 'X': + case 'x': + c = 16; + goto unsigned_common; + case 'U': + case 'u': + c = 10; + goto unsigned_common; + case 'O': + case 'o': + c = 8; +unsigned_common:/* + if (state & IS_LONG) + value.u = va_arg(ap, unsigned long); + else*/ + value.u = va_arg(ap, uint32_t); + p = long_to_string_with_divisor(p, value.u, c, 0); + break; + default: + *p++ = c; + break; + } + // Now need print buffer s[{sign}XXXXXXXXXXXX]p and align it on width + // Check filler width (if buffer less then width) and prepare filler if need fill + if ((width -=(int)(p - s)) < 0) + width = 0; + else + filler = (state&PAD_ZERO) ? '0' : ' '; + // if left align, put sign digit, and fill + // [{sign}ffffffXXXXXXXXXXXX] + if (!(state&LEFT_ALIGN)) { + // Put '+' or '-' or ' ' first if need + if ((state&(NEGATIVE|POSITIVE|PLUS_SPACE)) && (state&PAD_ZERO)) { + streamPut(chp, (uint8_t)*s++); + n++; + } + // fill from left + while (width){ + streamPut(chp, (uint8_t)filler); + n++; + width--; + } + } + // put data + while (s < p) { + streamPut(chp, (uint8_t)*s++); + n++; + } + // Put filler from right (if need) + while (width) { + streamPut(chp, (uint8_t)filler); + n++; + width--; + } + } +} + +/** + * @brief System formatted output function. + * @details This function implements a minimal @p printf() like functionality + * with output on a @p BaseSequentialStream. + * The general parameters format is: %[-][width|*][.precision|*][l|L]p. + * The following parameter types (p) are supported: + * - x hexadecimal integer. + * - X hexadecimal long. + * - o octal integer. + * - O octal long. + * - d decimal signed integer. + * - D decimal signed long. + * - u decimal unsigned integer. + * - U decimal unsigned long. + * - c character. + * - s string. + * . + * + * @param[in] chp pointer to a @p BaseSequentialStream implementing object + * @param[in] fmt formatting string + * + * @api + */ +int chprintf(BaseSequentialStream *chp, const char *fmt, ...) { + va_list ap; + int formatted_bytes; + + va_start(ap, fmt); + formatted_bytes = chvprintf(chp, fmt, ap); + va_end(ap); + + return formatted_bytes; +} + +/** + * @brief System formatted output function. + * @details This function implements a minimal @p vprintf()-like functionality + * with output on a @p BaseSequentialStream. + * The general parameters format is: %[-][width|*][.precision|*][l|L]p. + * The following parameter types (p) are supported: + * - x hexadecimal integer. + * - X hexadecimal long. + * - o octal integer. + * - O octal long. + * - d decimal signed integer. + * - D decimal signed long. + * - u decimal unsigned integer. + * - U decimal unsigned long. + * - c character. + * - s string. + * . + * @post @p str is NUL-terminated, unless @p size is 0. + * + * @param[in] str pointer to a buffer + * @param[in] size maximum size of the buffer + * @param[in] fmt formatting string + * @return The number of characters (excluding the + * terminating NUL byte) that would have been + * stored in @p str if there was room. + * + * @api + */ +int chsnprintf(char *str, size_t size, const char *fmt, ...) { + va_list ap; + MemoryStream ms; + BaseSequentialStream *chp; + size_t size_wo_nul; + int retval; + + if (size > 0) + size_wo_nul = size - 1; + else + size_wo_nul = 0; + + /* Memory stream object to be used as a string writer, reserving one + byte for the final zero.*/ + msObjectInit(&ms, (uint8_t *)str, size_wo_nul, 0); + + /* Performing the print operation using the common code.*/ + chp = (BaseSequentialStream *)(void *)&ms; + va_start(ap, fmt); + retval = chvprintf(chp, fmt, ap); + va_end(ap); + + /* Terminate with a zero, unless size==0.*/ + if (ms.eos < size) + str[ms.eos] = 0; + + /* Return number of bytes that would have been written.*/ + return retval; +} + +/** @} */ diff --git a/main.c b/main.c index caf2f60..795d187 100644 --- a/main.c +++ b/main.c @@ -38,7 +38,7 @@ 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, int16_t points); +void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); bool sweep(bool break_on_operation); @@ -57,7 +57,6 @@ int8_t cal_auto_interpolate = TRUE; uint16_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; - static THD_WORKING_AREA(waThread1, 640); static THD_FUNCTION(Thread1, arg) { @@ -308,28 +307,94 @@ int set_frequency(uint32_t freq) return delay; } +// Use macro, std isdigit more big +#define _isdigit(c) (c >= '0' && c <= '9') +// Rewrite universal standart str to value functions to more compact +// +// Convert string to int32 +int32_t my_atoi(const char *p){ + int32_t value = 0; + uint32_t c; + bool neg = false; + + if (*p == '-') {neg = true; p++;} + if (*p == '+') p++; + while ((c = *p++ - '0') < 10) + value = value * 10 + c; + return neg ? -value : value; +} + +// Convert string to uint32 +uint32_t my_atoui(const char *p){ + uint32_t value = 0; + uint32_t c; + if (*p == '+') p++; + while ((c = *p++ - '0') < 10) + value = value * 10 + c; + return value; +} + +double +my_atof(const char *p) +{ + int neg = FALSE; + if (*p == '-') + neg = TRUE; + if (*p == '-' || *p == '+') + p++; + double x = my_atoi(p); + while (_isdigit((int)*p)) + p++; + if (*p == '.') { + double d = 1.0f; + p++; + while (_isdigit((int)*p)) { + d /= 10; + x += d * (*p - '0'); + p++; + } + } + if (*p == 'e' || *p == 'E') { + p++; + int exp = my_atoi(p); + while (exp > 0) { + x *= 10; + exp--; + } + while (exp < 0) { + x /= 10; + exp++; + } + } + if (neg) + x = -x; + return x; +} + static void cmd_offset(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc != 1) { chprintf(chp, "usage: offset {frequency offset(Hz)}\r\n"); return; } - frequency_offset = atoi(argv[0]); + frequency_offset = my_atoui(argv[0]); set_frequency(frequency); } static void cmd_freq(BaseSequentialStream *chp, int argc, char *argv[]) { - int freq; if (argc != 1) { - chprintf(chp, "usage: freq {frequency(Hz)}\r\n"); - return; + goto usage; } + uint32_t freq = my_atoui(argv[0]); + pause_sweep(); chMtxLock(&mutex); - freq = atoi(argv[0]); set_frequency(freq); chMtxUnlock(&mutex); + return; +usage: + chprintf(chp, "usage: freq {frequency(Hz)}\r\n"); } static void cmd_power(BaseSequentialStream *chp, int argc, char *argv[]) @@ -338,7 +403,7 @@ static void cmd_power(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "usage: power {0-3|-1}\r\n"); return; } - drive_strength = atoi(argv[0]); + drive_strength = my_atoi(argv[0]); set_frequency(frequency); } @@ -360,20 +425,20 @@ static void cmd_dac(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "current value: %d\r\n", config.dac_value); return; } - value = atoi(argv[0]); + value = my_atoi(argv[0]); config.dac_value = value; dacPutChannelX(&DACD2, 0, value); } static void cmd_threshold(BaseSequentialStream *chp, int argc, char *argv[]) { - int value; + uint32_t value; if (argc != 1) { chprintf(chp, "usage: threshold {frequency in harmonic mode}\r\n"); chprintf(chp, "current: %d\r\n", config.harmonic_freq_threshold); return; } - value = atoi(argv[0]); + value = my_atoui(argv[0]); config.harmonic_freq_threshold = value; } @@ -490,7 +555,7 @@ static void cmd_data(BaseSequentialStream *chp, int argc, char *argv[]) int sel = 0; if (argc == 1) - sel = atoi(argv[0]); + sel = my_atoi(argv[0]); if (sel == 0 || sel == 1) { chMtxLock(&mutex); for (i = 0; i < sweep_points; i++) { @@ -517,7 +582,7 @@ static void cmd_dump(BaseSequentialStream *chp, int argc, char *argv[]) int len; if (argc == 1) - dump_selection = atoi(argv[0]); + dump_selection = my_atoi(argv[0]); wait_dsp(3); @@ -679,22 +744,22 @@ bool sweep(bool break_on_operation) static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) { - int32_t start, stop; + uint32_t start, stop; int16_t points = sweep_points; if (argc != 2 && argc != 3) { - chprintf(chp, "usage: sweep {start(Hz)} {stop(Hz)} [points]\r\n"); + chprintf(chp, "usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); return; } - start = atoi(argv[0]); - stop = atoi(argv[1]); + start = my_atoui(argv[0]); + stop = my_atoui(argv[1]); if (start == 0 || stop == 0 || start > stop) { chprintf(chp, "frequency range is invalid\r\n"); return; } if (argc == 3) { - points = atoi(argv[2]); + points = my_atoi(argv[2]); if (points <= 0 || points > sweep_points) { chprintf(chp, "sweep points exceeds range\r\n"); return; @@ -747,13 +812,21 @@ update_marker_index(void) } void -set_frequencies(uint32_t start, uint32_t stop, int16_t points) -{ - int i; - float span = stop - start; - for (i = 0; i < points; i++) { - float offset = i * span / (float)(points - 1); - frequencies[i] = start + (uint32_t)offset; +set_frequencies(uint32_t start, uint32_t stop, uint16_t points) +{ + uint32_t i; + uint32_t step = (points - 1); + uint32_t span = stop - start; + uint32_t delta = span / step; + uint32_t error = span % step; + uint32_t f = start, df = step>>1; + for (i = 0; i <= step; i++, f+=delta) { + frequencies[i] = f; + df+=error; + if (df >=step) { + f++; + df-=step; + } } // disable at out of sweep range for (; i < sweep_points; i++) @@ -811,45 +884,35 @@ void set_sweep_frequency(int type, uint32_t freq) { int cal_applied = cal_status & CALSTAT_APPLY; -/* // negative value indicate overflow, do nothing - if (freq < 0) - return;*/ + + // Check frequency for out of bounds (minimum SPAN can be any value) + if (type!=ST_SPAN && freq < START_MIN) + freq = START_MIN; + if (freq > STOP_MAX) + freq = STOP_MAX; + switch (type) { case ST_START: freq_mode_startstop(); - if (freq < START_MIN) - freq = START_MIN; - if (freq > STOP_MAX) - freq = STOP_MAX; if (frequency0 != freq) { ensure_edit_config(); frequency0 = freq; // if start > stop then make start = stop if (frequency1 < freq) frequency1 = freq; - update_frequencies(); } break; case ST_STOP: freq_mode_startstop(); - if (freq > STOP_MAX) - freq = STOP_MAX; - if (freq < START_MIN) - freq = START_MIN; if (frequency1 != freq) { ensure_edit_config(); frequency1 = freq; // if start > stop then make start = stop if (frequency0 > freq) frequency0 = freq; - update_frequencies(); } break; case ST_CENTER: - if (freq < START_MIN) - freq = START_MIN; - if (freq > STOP_MAX) - freq = STOP_MAX; freq_mode_centerspan(); uint32_t center = frequency0/2 + frequency1/2; if (center != freq) { @@ -863,12 +926,9 @@ set_sweep_frequency(int type, uint32_t freq) } frequency0 = freq + span/2; frequency1 = freq - span/2; - update_frequencies(); } break; case ST_SPAN: - if (freq > STOP_MAX) - freq = STOP_MAX; freq_mode_centerspan(); if (frequency0 - frequency1 != freq) { ensure_edit_config(); @@ -881,24 +941,18 @@ set_sweep_frequency(int type, uint32_t freq) } frequency1 = center - freq/2; frequency0 = center + freq/2; - update_frequencies(); } break; case ST_CW: - if (freq < START_MIN) - freq = START_MIN; - if (freq > STOP_MAX) - freq = STOP_MAX; freq_mode_centerspan(); if (frequency0 != freq || frequency1 != freq) { ensure_edit_config(); frequency0 = freq; frequency1 = freq; - update_frequencies(); } break; } - + update_frequencies(); if (cal_auto_interpolate && cal_applied) cal_interpolate(lastsaveid); } @@ -926,7 +980,6 @@ get_sweep_frequency(int type) return 0; } - static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 0) { @@ -935,40 +988,34 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) } else if (argc > 3) { goto usage; } - if (argc >= 2) { - if (strcmp(argv[0], "start") == 0) { - int32_t value = atoi(argv[1]); - set_sweep_frequency(ST_START, value); - return; - } else if (strcmp(argv[0], "stop") == 0) { - int32_t value = atoi(argv[1]); - set_sweep_frequency(ST_STOP, value); - return; - } else if (strcmp(argv[0], "center") == 0) { - int32_t value = atoi(argv[1]); - set_sweep_frequency(ST_CENTER, value); - return; - } else if (strcmp(argv[0], "span") == 0) { - int32_t value = atoi(argv[1]); - set_sweep_frequency(ST_SPAN, value); - return; - } else if (strcmp(argv[0], "cw") == 0) { - int32_t value = atoi(argv[1]); - set_sweep_frequency(ST_CW, value); - return; - } - } - - if (argc >= 1) { - int32_t value = atoi(argv[0]); - if (value == 0) + uint32_t value0 = 0; + uint32_t value1 = 0; + if (argc >=1) value0 = my_atoui(argv[0]); + if (argc >=2) value1 = my_atoui(argv[1]); + + // Parse sweep {start|stop|center|span|cw} {freq(Hz)} + if (argc == 2 && value0 == 0) { + int type; + if (strcmp(argv[0], "start") == 0) + type = ST_START; + else if (strcmp(argv[0], "stop") == 0) + type = ST_STOP; + else if (strcmp(argv[0], "center") == 0) + type = ST_CENTER; + else if (strcmp(argv[0], "span") == 0) + type = ST_SPAN; + else if (strcmp(argv[0], "cw") == 0) + type = ST_CW; + else goto usage; - set_sweep_frequency(ST_START, value); - } - if (argc >= 2) { - int32_t value = atoi(argv[1]); - set_sweep_frequency(ST_STOP, value); + set_sweep_frequency(type, value1); + return; } + // Parse sweep {start(Hz)} [stop(Hz)] + if (value0) + set_sweep_frequency(ST_START, value0); + if (value1) + set_sweep_frequency(ST_STOP, value1); return; usage: chprintf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n"); @@ -1365,7 +1412,7 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) } else if (strcmp(cmd, "in") == 0) { int s = 0; if (argc > 1) - s = atoi(argv[1]); + s = my_atoi(argv[1]); cal_interpolate(s); redraw_request |= REDRAW_CAL_STATUS; return; @@ -1382,7 +1429,7 @@ static void cmd_save(BaseSequentialStream *chp, int argc, char *argv[]) if (argc != 1) goto usage; - int id = atoi(argv[0]); + int id = my_atoi(argv[0]); if (id < 0 || id >= SAVEAREA_MAX) goto usage; caldata_save(id); @@ -1399,7 +1446,7 @@ static void cmd_recall(BaseSequentialStream *chp, int argc, char *argv[]) if (argc != 1) goto usage; - int id = atoi(argv[0]); + int id = my_atoi(argv[0]); if (id < 0 || id >= SAVEAREA_MAX) goto usage; @@ -1507,46 +1554,9 @@ float get_trace_refpos(int t) return trace[t].refpos; } -float -my_atof(const char *p) -{ - int neg = FALSE; - if (*p == '-') - neg = TRUE; - if (*p == '-' || *p == '+') - p++; - float x = atoi(p); - while (isdigit((int)*p)) - p++; - if (*p == '.') { - float d = 1.0f; - p++; - while (isdigit((int)*p)) { - d /= 10; - x += d * (*p - '0'); - p++; - } - } - if (*p == 'e' || *p == 'E') { - p++; - int exp = atoi(p); - while (exp > 0) { - x *= 10; - exp--; - } - while (exp < 0) { - x /= 10; - exp++; - } - } - if (neg) - x = -x; - return x; -} - typedef struct { - char *tracename; - uint8_t type; + char *tracename; + uint8_t type; } type_list; static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) @@ -1574,7 +1584,7 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) goto exit; } - t = atoi(argv[0]); + t = my_atoi(argv[0]); if (t < 0 || t >= 4) goto usage; if (argc == 1) { @@ -1585,27 +1595,27 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) } if (argc > 1) { - static const type_list t_list[] = { - {"logmag", TRC_LOGMAG}, - {"phase", TRC_PHASE}, - {"polar", TRC_POLAR}, - {"smith", TRC_SMITH}, - {"delay", TRC_DELAY}, - {"linear", TRC_LINEAR}, - {"swr", TRC_SWR}, - {"real", TRC_REAL}, - {"imag", TRC_IMAG}, - {"r", TRC_R}, - {"x", TRC_X}, - {"off", TRC_OFF}, - }; - for (uint16_t i=0; i= 3) { + static const type_list t_list[] = { + {"logmag", TRC_LOGMAG}, + {"phase", TRC_PHASE}, + {"polar", TRC_POLAR}, + {"smith", TRC_SMITH}, + {"delay", TRC_DELAY}, + {"linear", TRC_LINEAR}, + {"swr", TRC_SWR}, + {"real", TRC_REAL}, + {"imag", TRC_IMAG}, + {"r", TRC_R}, + {"x", TRC_X}, + {"off", TRC_OFF}, + }; + for (uint16_t i=0; i= 3) { //trace[t].scale = my_atof(argv[2]); set_trace_scale(t, my_atof(argv[2])); goto exit; @@ -1619,7 +1629,7 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) } check_ch_num: if (argc > 2) { - int src = atoi(argv[2]); + int src = my_atoi(argv[2]); if (src != 0 && src != 1) goto usage; trace[t].channel = src; @@ -1676,7 +1686,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) return; } - t = atoi(argv[0])-1; + t = my_atoi(argv[0])-1; if (t < 0 || t >= 4) goto usage; if (argc == 1) { @@ -1700,7 +1710,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) } else { // select active marker and move to index markers[t].enabled = TRUE; - int index = atoi(argv[1]); + int index = my_atoi(argv[1]); markers[t].index = index; markers[t].frequency = frequencies[index]; active_marker = t; @@ -1839,7 +1849,7 @@ static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) int i; int mode = 0; if (argc >= 1) - mode = atoi(argv[0]); + mode = my_atoi(argv[0]); for (i = 0; i < 20; i++) { palClearPad(GPIOC, GPIOC_LED); @@ -1879,9 +1889,9 @@ static void cmd_gain(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "usage: gain {lgain(0-95)} [rgain(0-95)]\r\n"); return; } - rvalue = atoi(argv[0]); + rvalue = my_atoi(argv[0]); if (argc == 2) - lvalue = atoi(argv[1]); + lvalue = my_atoi(argv[1]); tlv320aic3204_set_gain(lvalue, rvalue); } @@ -1892,7 +1902,7 @@ static void cmd_port(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "usage: port {0:TX 1:RX}\r\n"); return; } - port = atoi(argv[0]); + port = my_atoi(argv[0]); tlv320aic3204_select(port); } diff --git a/nanovna.h b/nanovna.h index 800b4e1..a1b490c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -78,7 +78,7 @@ enum { void set_sweep_frequency(int type, uint32_t frequency); uint32_t get_sweep_frequency(int type); -float my_atof(const char *p); +double my_atof(const char *p); void toggle_sweep(void); @@ -152,7 +152,7 @@ extern int16_t area_height; extern const uint8_t x5x7_bits []; #define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) -#define FONT_GET_WIDTH(ch) (7-(x5x7_bits[ch*7]&3)) +#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7)) #define FONT_GET_HEIGHT 7 extern const uint16_t numfont16x22[]; @@ -330,7 +330,7 @@ typedef struct { uint32_t magic; uint32_t _frequency0; uint32_t _frequency1; - int16_t _sweep_points; + uint16_t _sweep_points; uint16_t _cal_status; uint32_t _frequencies[POINTS_COUNT]; diff --git a/plot.c b/plot.c index 14e992e..f5ef8ea 100644 --- a/plot.c +++ b/plot.c @@ -8,8 +8,6 @@ #define SWAP(x,y) do { int z=x; x = y; y = z; } while(0) static void cell_draw_marker_info(int m, int n, int w, int h); -void frequency_string(char *buf, size_t len, uint32_t freq, char *prefix); -void frequency_string_short(char *buf, size_t len, int32_t freq, char prefix); void markmap_all_markers(void); /* indicate dirty cells */ @@ -501,6 +499,22 @@ groupdelay_from_array(int i, float array[POINTS_COUNT][2]) return groupdelay(array[bottom], array[top], deltaf); } +static float +gamma2resistance(const float v[2]) +{ + float z0 = 50; + float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); + return ((1+v[0])*(1-v[0]) - v[1]*v[1]) * d; +} + +static float +gamma2reactance(const float v[2]) +{ + float z0 = 50; + float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); + return 2*v[1] * d; +} + uint32_t trace_into_index(int x, int t, int i, float array[POINTS_COUNT][2]) { @@ -550,65 +564,6 @@ trace_into_index(int x, int t, int i, float array[POINTS_COUNT][2]) return INDEX(x +CELLOFFSETX, y, i); } -static int -string_value_with_prefix(char *buf, int len, float val, char unit) -{ - char prefix; - int n = 0; - if (val < 0) { - val = -val; - *buf = '-'; - n++; - len--; - } - if (val == INFINITY){ - prefix = S_INFINITY[0]; - } - else { - if (val < 1e-12) { - prefix = 'f'; - val *= 1e15; - } else if (val < 1e-9) { - prefix = 'p'; - val *= 1e12; - } else if (val < 1e-6) { - prefix = 'n'; - val *= 1e9; - } else if (val < 1e-3) { - prefix = S_MICRO[0]; - val *= 1e6; - } else if (val < 1) { - prefix = 'm'; - val *= 1e3; - } else if (val < 1e3) { - prefix = 0; - } else if (val < 1e6) { - prefix = 'k'; - val /= 1e3; - } else if (val < 1e9) { - prefix = 'M'; - val /= 1e6; - } else { - prefix = 'G'; - val /= 1e9; - } - - if (val < 10) { - n += chsnprintf(&buf[n], len, "%.2f", val); - } else if (val < 100) { - n += chsnprintf(&buf[n], len, "%.1f", val); - } else { - n += chsnprintf(&buf[n], len, "%d", (int)val); - } - } - if (prefix) - buf[n++] = prefix; - if (unit) - buf[n++] = unit; - buf[n] = '\0'; - return n; -} - #define PI2 6.283184 static void @@ -619,8 +574,8 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) float d = z0 / ((1-coeff[0])*(1-coeff[0])+coeff[1]*coeff[1]); float zr = ((1+coeff[0])*(1-coeff[0]) - coeff[1]*coeff[1]) * d; float zi = 2*coeff[1] * d; - int n; - + char prefix; + float value; switch (marker_smith_format) { case MS_LIN: chsnprintf(buf, len, "%.2f %.1f" S_DEGREE, linear(coeff), phase(coeff)); @@ -634,109 +589,81 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) chsnprintf(buf, len, "%.1fdB %.1f" S_DEGREE, v, phase(coeff)); } break; - case MS_REIM: - n = string_value_with_prefix(buf, len, coeff[0], '\0'); - if (coeff[1] >= 0) buf[n++] = '+'; - string_value_with_prefix(buf+n, len-n, coeff[1], 'j'); + chsnprintf(buf, len, "%F%+Fj", coeff[0], coeff[1]); break; case MS_RX: - n = string_value_with_prefix(buf, len, zr, S_OHM[0]); - if (zi >= 0) - buf[n++] = ' '; - string_value_with_prefix(buf+n, len-n, zi, 'j'); + chsnprintf(buf, len, "%F"S_OHM"%+Fj", zr, zi); break; case MS_RLC: - n = string_value_with_prefix(buf, len, zr, S_OHM[0]); - buf[n++] = ' '; - - char prefix; - float value; if (zi < 0){// Capacity - prefix = 'F'; - value = -1 / (PI2 * frequency * zi); + prefix = 'F'; + value = -1 / (PI2 * frequency * zi); } else { - prefix = 'H'; - value = zi / (PI2 * frequency); + prefix = 'H'; + value = zi / (PI2 * frequency); } - string_value_with_prefix(buf+n, len-n, value, prefix); + chsnprintf(buf, len, "%F"S_OHM" %F%c", zr, value, prefix); break; } } -static void -gamma2resistance(char *buf, int len, const float coeff[2]) -{ - float z0 = 50; - float d = z0 / ((1-coeff[0])*(1-coeff[0])+coeff[1]*coeff[1]); - float zr = ((1+coeff[0])*(1-coeff[0]) - coeff[1]*coeff[1]) * d; - string_value_with_prefix(buf, len, zr, S_OHM[0]); -} - -static void -gamma2reactance(char *buf, int len, const float coeff[2]) -{ - float z0 = 50; - float d = z0 / ((1-coeff[0])*(1-coeff[0])+coeff[1]*coeff[1]); - float zi = 2*coeff[1] * d; - string_value_with_prefix(buf, len, zi, S_OHM[0]); -} - static void trace_get_value_string(int t, char *buf, int len, float array[POINTS_COUNT][2], int i) { float *coeff = array[i]; float v; + char *format; switch (trace[t].type) { case TRC_LOGMAG: + format = "%.2fdB"; v = logmag(coeff); - if (v == -INFINITY) - chsnprintf(buf, len, "-"S_INFINITY" dB"); - else - chsnprintf(buf, len, "%.2fdB", v); break; case TRC_PHASE: + format = "%.3f"S_DEGREE; v = phase(coeff); - chsnprintf(buf, len, "%.2f" S_DEGREE, v); break; case TRC_DELAY: + format = "%.2Fs"; v = groupdelay_from_array(i, array); - string_value_with_prefix(buf, len, v, 's'); break; case TRC_LINEAR: + format = "%.4f"; v = linear(coeff); - chsnprintf(buf, len, "%.2f", v); break; case TRC_SWR: + format = "%.4f"; v = swr(coeff); - if (v == INFINITY) - chsnprintf(buf, len, S_INFINITY); - else - chsnprintf(buf, len, "%.2f", v); - break; - case TRC_SMITH: - format_smith_value(buf, len, coeff, frequencies[i]); break; case TRC_REAL: - chsnprintf(buf, len, "%.2f", coeff[0]); + format = "%.4f"; + v = coeff[0]; break; case TRC_IMAG: - chsnprintf(buf, len, "%.2fj", coeff[1]); + format = "%.4fj"; + v = coeff[1]; break; case TRC_R: - gamma2resistance(buf, len, coeff); + format = "%.2F"S_OHM; + v = gamma2resistance(coeff); break; case TRC_X: - gamma2reactance(buf, len, coeff); + format = "%.2F"S_OHM; + v = gamma2reactance(coeff); break; - //case TRC_ADMIT: + case TRC_SMITH: + format_smith_value(buf, len, coeff, frequencies[i]); + return; + //case TRC_ADMIT: case TRC_POLAR: - chsnprintf(buf, len, "%.2f %.2fj", coeff[0], coeff[1]); - break; + chsnprintf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]); + default: + return; } + chsnprintf(buf, len, format, v); } static void @@ -745,78 +672,80 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT float *coeff = array[index]; float *coeff_ref = array[index_ref]; float v; + char *format; switch (trace[t].type) { case TRC_LOGMAG: + format = S_DELTA"%.2fdB"; v = logmag(coeff) - logmag(coeff_ref); - if (v == -INFINITY) - chsnprintf(buf, len, S_DELTA "-"S_INFINITY" dB"); - else - chsnprintf(buf, len, S_DELTA "%.2fdB", v); break; case TRC_PHASE: + format = S_DELTA"%.2f"S_DEGREE; v = phase(coeff) - phase(coeff_ref); - chsnprintf(buf, len, S_DELTA "%.2f" S_DEGREE, v); break; case TRC_DELAY: + format = "%.2Fs"; v = groupdelay_from_array(index, array) - groupdelay_from_array(index_ref, array); - string_value_with_prefix(buf, len, v, 's'); break; case TRC_LINEAR: + format = S_DELTA"%.3f"; v = linear(coeff) - linear(coeff_ref); - chsnprintf(buf, len, S_DELTA "%.2f", v); break; case TRC_SWR: - v = swr(coeff) - swr(coeff_ref); - chsnprintf(buf, len, S_DELTA "%.2f", v); + format = S_DELTA"%.3f"; + v = swr(coeff); + if (v!=INFINITY) + v-=swr(coeff_ref); break; case TRC_SMITH: format_smith_value(buf, len, coeff, frequencies[index]); - break; + return; case TRC_REAL: - chsnprintf(buf, len, S_DELTA "%.2f", coeff[0] - coeff_ref[0]); + format = S_DELTA"%.3f"; + v = coeff[0] - coeff_ref[0]; break; case TRC_IMAG: - chsnprintf(buf, len, S_DELTA "%.2fj", coeff[1] - coeff_ref[1]); + format = S_DELTA"%.3fj"; + v = coeff[1] - coeff_ref[1]; break; case TRC_R: - gamma2resistance(buf, len, coeff); + format = "%.2F"S_OHM; + v = gamma2resistance(coeff); break; case TRC_X: - gamma2reactance(buf, len, coeff); + format = "%.2F"S_OHM; + v = gamma2reactance(coeff); break; //case TRC_ADMIT: case TRC_POLAR: - chsnprintf(buf, len, "%.2f %.2fj", coeff[0], coeff[1]); - break; + chsnprintf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]); + return; + default: + return; } + chsnprintf(buf, len, format, v); } static int trace_get_info(int t, char *buf, int len) { - strcpy(buf, get_trace_typename(t)); - int n = strlen(buf); - char *p = buf + n; - len -= n; + const char *name = get_trace_typename(t); + float scale = get_trace_scale(t); switch (trace[t].type) { case TRC_LOGMAG: - n += chsnprintf(p, len, " %ddB/", (int)get_trace_scale(t)); - break; + return chsnprintf(buf, len, "%s %ddB/", name, (int)scale); case TRC_PHASE: - n += chsnprintf(p, len, " %d" S_DEGREE "/", (int)get_trace_scale(t)); - break; + return chsnprintf(buf, len, "%s %d" S_DEGREE "/", name, (int)scale); case TRC_SMITH: //case TRC_ADMIT: case TRC_POLAR: - if (get_trace_scale(t) != 1.0) - n += chsnprintf(p, len, " %.1fFS", get_trace_scale(t)); - break; + if (scale != 1.0) + return chsnprintf(buf, len, "%s %.1fFS", name, scale); + else + return chsnprintf(buf, len, name); default: - strcat(p, " "); - string_value_with_prefix(p+1, len-1 , get_trace_scale(t), '/'); - break; + return chsnprintf(buf, len, "%s %F/", name, scale); } - return n; + return 0; } static float time_of_index(int idx) { @@ -1584,43 +1513,32 @@ request_to_draw_cells_behind_numeric_input(void) int -cell_drawchar(int w, int h, uint8_t ch, int x, int y, int invert) -{ - uint8_t bits; - int c, r, ch_size; - const uint8_t *char_buf = FONT_GET_DATA(ch); - ch_size=FONT_GET_WIDTH(ch); - if (y <= -FONT_GET_HEIGHT || y >= h || x <= -ch_size || x >= w) - return ch_size; - for(c = 0; c < FONT_GET_HEIGHT; c++) { - bits = *char_buf++; - if ((y + c) < 0 || (y + c) >= h) - continue; - if (invert) - bits = ~bits; - for (r = 0; r < ch_size; r++) { - if ((x+r) >= 0 && (x+r) < w && (0x80 & bits)) - spi_buffer[(y+c)*w + (x+r)] = foreground_color; - bits <<= 1; - } - } - return ch_size; -} - -void -cell_drawstring(int w, int h, char *str, int x, int y) -{ - while (*str) { - x += cell_drawchar(w, h, *str, x, y, FALSE); - str++; +cell_drawchar(int w, int h, uint8_t ch, int x, int y) +{ + uint8_t bits; + int c, r, ch_size; + const uint8_t *char_buf = FONT_GET_DATA(ch); + ch_size=FONT_GET_WIDTH(ch); + if (y <= -FONT_GET_HEIGHT || y >= h || x <= -ch_size || x >= w) + return ch_size; + for(c = 0; c < FONT_GET_HEIGHT; c++) { + bits = *char_buf++; + if ((y + c) < 0 || (y + c) >= h) + continue; + for (r = 0; r < ch_size; r++) { + if ((x+r) >= 0 && (x+r) < w && (0x80 & bits)) + spi_buffer[(y+c)*w + (x+r)] = foreground_color; + bits <<= 1; + } } + return ch_size; } void -cell_drawstring_invert(int w, int h, char *str, int x, int y, int invert) +cell_drawstring(int w, int h, char *str, int x, int y) { while (*str) { - x += cell_drawchar(w, h, *str, x, y, invert); + x += cell_drawchar(w, h, *str, x, y); str++; } } @@ -1628,7 +1546,7 @@ cell_drawstring_invert(int w, int h, char *str, int x, int y, int invert) static void cell_draw_marker_info(int m, int n, int w, int h) { - char buf[24]; + char buf[32]; int t; if (n != 0) return; @@ -1646,27 +1564,27 @@ cell_draw_marker_info(int m, int n, int w, int h) int ypos = 1 + (j/2)*8; xpos -= m * CELLWIDTH -CELLOFFSETX; ypos -= n * CELLHEIGHT; - - setForegroundColor(config.trace_color[t]); - if (mk == active_marker) - cell_drawstring(w, h, S_SARROW, xpos, ypos); - xpos += 5; + + setForegroundColor(config.trace_color[t]); + if (mk == active_marker) + cell_drawstring(w, h, S_SARROW, xpos, ypos); + xpos += 5; chsnprintf(buf, sizeof buf, "M%d", mk+1); cell_drawstring(w, h, buf, xpos, ypos); - - xpos += 13; + xpos += 13; //trace_get_info(t, buf, sizeof buf); - int32_t freq = frequencies[markers[mk].index]; + uint32_t freq = frequencies[markers[mk].index]; if (uistat.marker_delta && mk != active_marker) { - freq -= frequencies[markers[active_marker].index]; - frequency_string_short(buf, sizeof buf, freq, S_DELTA[0]); + uint32_t freq1 = frequencies[markers[active_marker].index]; + uint32_t delta = freq > freq1 ? freq - freq1 : freq1 - freq; + chsnprintf(buf, sizeof buf, S_DELTA"%.9qHz", delta); } else { - frequency_string_short(buf, sizeof buf, freq, 0); + chsnprintf(buf, sizeof buf, "%.10qHz", freq); } cell_drawstring(w, h, buf, xpos, ypos); - xpos += 64; + xpos += 67; if (uistat.marker_delta && mk != active_marker) - trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); + trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); else trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index); setForegroundColor(DEFAULT_FG_COLOR); @@ -1677,24 +1595,21 @@ cell_draw_marker_info(int m, int n, int w, int h) // draw marker delta if (!uistat.marker_delta && previous_marker >= 0 && active_marker != previous_marker && markers[previous_marker].enabled) { int idx0 = markers[previous_marker].index; - int xpos = 185; + int xpos = 180; int ypos = 1 + (j/2)*8; xpos -= m * CELLWIDTH -CELLOFFSETX; ypos -= n * CELLHEIGHT; - strcpy(buf, S_DELTA "1-1:"); - buf[1] += active_marker; - buf[3] += previous_marker; + chsnprintf(buf, sizeof buf, S_DELTA"%d-%d", active_marker+1, previous_marker+1); setForegroundColor(DEFAULT_FG_COLOR); cell_drawstring(w, h, buf, xpos, ypos); - xpos += 29; + xpos += 24; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { - frequency_string_short(buf, sizeof buf, frequencies[idx] - frequencies[idx0], 0); + uint32_t freq = frequencies[idx]; + uint32_t freq1 = frequencies[idx0]; + uint32_t delta = freq > freq1 ? freq - freq1 : freq1 - freq; + chsnprintf(buf, sizeof buf, "%c%.13qHz", freq >= freq1 ? '+' : '-', delta); } else { - //chsnprintf(buf, sizeof buf, "%d ns %.1f m", (uint16_t)(time_of_index(idx) * 1e9 - time_of_index(idx0) * 1e9), - // distance_of_index(idx) - distance_of_index(idx0)); - int n = string_value_with_prefix(buf, sizeof buf, time_of_index(idx) - time_of_index(idx0), 's'); - buf[n++] = ' '; - string_value_with_prefix(&buf[n], sizeof buf - n, distance_of_index(idx) - distance_of_index(idx0), 'm'); + chsnprintf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx) - time_of_index(idx0), distance_of_index(idx) - distance_of_index(idx0)); } cell_drawstring(w, h, buf, xpos, ypos); } @@ -1706,23 +1621,17 @@ cell_draw_marker_info(int m, int n, int w, int h) int ypos = 1 + (j/2)*8; xpos -= m * CELLWIDTH -CELLOFFSETX; ypos -= n * CELLHEIGHT; -// setForegroundColor(config.trace_color[t]); -// strcpy(buf, "CH0"); -// buf[2] += trace[t].channel; - //chsnprintf(buf, sizeof buf, "CH%d", trace[t].channel); -// cell_drawstring_invert(w, h, buf, xpos, ypos, t == uistat.current_trace); -// xpos += 20; setForegroundColor(config.trace_color[t]); if (t == uistat.current_trace) - cell_drawstring(w, h, S_SARROW, xpos, ypos); + cell_drawstring(w, h, S_SARROW, xpos, ypos); xpos += 5; chsnprintf(buf, sizeof buf, "CH%d", trace[t].channel); cell_drawstring(w, h, buf, xpos, ypos); xpos += 19; - trace_get_info(t, buf, sizeof buf); + int n = trace_get_info(t, buf, sizeof buf); cell_drawstring(w, h, buf, xpos, ypos); - xpos += (strlen(buf) + 1) * 5; + xpos += n * 5 + 2; //xpos += 60; trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], idx); setForegroundColor(DEFAULT_FG_COLOR); @@ -1736,27 +1645,18 @@ cell_draw_marker_info(int m, int n, int w, int h) xpos -= m * CELLWIDTH -CELLOFFSETX; ypos -= n * CELLHEIGHT; setForegroundColor(DEFAULT_FG_COLOR); -// strcpy(buf, "1:"); -// buf[0] += active_marker; -// xpos += 5; -// setForegroundColor(0xffff); -// cell_drawstring_invert(w, h, buf, xpos, ypos, uistat.lever_mode == LM_MARKER); -// xpos += 14; - setForegroundColor(DEFAULT_FG_COLOR); if (uistat.lever_mode == LM_MARKER) - cell_drawstring(w, h, S_SARROW, xpos, ypos); + cell_drawstring(w, h, S_SARROW, xpos, ypos); xpos += 5; chsnprintf(buf, sizeof buf, "M%d:", active_marker+1); cell_drawstring(w, h, buf, xpos, ypos); - xpos += 19; + xpos += 19; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { - frequency_string(buf, sizeof buf, frequencies[idx], ""); + //frequency_string(buf, sizeof buf, frequencies[idx], ""); + chsnprintf(buf, sizeof buf, "%16qHz", frequencies[idx]); } else { - //chsnprintf(buf, sizeof buf, "%d ns %.1f m", (uint16_t)(time_of_index(idx) * 1e9), distance_of_index(idx)); - int n = string_value_with_prefix(buf, sizeof buf, time_of_index(idx), 's'); - buf[n++] = ' '; - string_value_with_prefix(&buf[n], sizeof buf-n, distance_of_index(idx), 'm'); + chsnprintf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx), distance_of_index(idx)); } cell_drawstring(w, h, buf, xpos, ypos); } @@ -1767,85 +1667,32 @@ cell_draw_marker_info(int m, int n, int w, int h) int ypos = 1 + ((j+1)/2)*8; xpos -= m * CELLWIDTH -CELLOFFSETX; ypos -= n * CELLHEIGHT; - chsnprintf(buf, sizeof buf, "Edelay"); - cell_drawstring(w, h, buf, xpos, ypos); - xpos += 7 * 5; - int n = string_value_with_prefix(buf, sizeof buf, electrical_delay * 1e-12, 's'); - cell_drawstring(w, h, buf, xpos, ypos); - xpos += n * 5 + 5; + float light_speed_ps = 299792458e-12; //(m/ps) - string_value_with_prefix(buf, sizeof buf, electrical_delay * light_speed_ps * velocity_factor, 'm'); + chsnprintf(buf, sizeof buf, "Edelay %Fs %Fm", electrical_delay * 1e-12, + electrical_delay * light_speed_ps * velocity_factor); cell_drawstring(w, h, buf, xpos, ypos); } } -void -frequency_string(char *buf, size_t len, uint32_t freq, char *prefix) -{ -/* if (freq < 0) { - freq = -freq; - *buf++ = '-'; - len -= 1; - }*/ - if (freq < 1000) { - chsnprintf(buf, len, "%s%d Hz", prefix, (int)freq); - } else if (freq < 1000000U) { - chsnprintf(buf, len, "%s%d.%03d kHz", prefix, - (freq / 1000U), - (freq % 1000U)); - } else { - chsnprintf(buf, len, "%s%d.%03d %03d MHz", prefix, - (freq / 1000000U), - ((freq / 1000U) % 1000U), - (freq % 1000U)); - } -} - -void -frequency_string_short(char *b, size_t len, int32_t freq, char prefix) -{ - char *buf = b; - if (prefix) { - *buf++ = prefix; - len -= 1; - } - if (freq < 0) { - freq = -freq; - *buf++ = '-'; - len -= 1; - } - if (freq < 1000) { - chsnprintf(buf, len, "%d Hz", (int)freq); - } else if (freq < 1000000) { - chsnprintf(buf, len, "%d.%03dkHz", - (int)(freq / 1000), - (int)(freq % 1000)); - } else { - chsnprintf(buf, len, "%d.%06d", - (int)(freq / 1000000), - (int)(freq % 1000000)); - strcpy(b+9, "MHz"); - } -} - void draw_frequencies(void) { - char buf1[24];buf1[0]=' '; - char buf2[24];buf2[0]=0; + char buf1[32]; + char buf2[32];buf2[0]=0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { if (frequency0 < frequency1) { - frequency_string(buf1+1, sizeof(buf1)-1, frequency0, "START "); - frequency_string(buf2, sizeof buf2, frequency1, "STOP "); + chsnprintf(buf1, sizeof(buf1), " START %16qHz", frequency0); + chsnprintf(buf2, sizeof(buf2), "STOP %16qHz", frequency1); } else if (frequency0 > frequency1) { - frequency_string(buf1+1, sizeof(buf1)-1, frequency0/2 + frequency1/2, "CENTER "); - frequency_string(buf2, sizeof buf2, frequency0 - frequency1, "SPAN "); + chsnprintf(buf1, sizeof(buf1), " CENTER %16qHz", frequency0/2 + frequency1/2); + chsnprintf(buf2, sizeof(buf2), "SPAN %16qHz", frequency0 - frequency1); } else { - frequency_string(buf1+1, sizeof(buf1)-1, frequency0, "CW "); + chsnprintf(buf1, sizeof(buf1), " CW %16qHz", frequency0); } } else { - chsnprintf(buf1+1, sizeof(buf1)-1, "START 0s"); - chsnprintf(buf2, sizeof buf2, "%s%dns (%.2fm)", "STOP ", (uint16_t)(time_of_index(POINTS_COUNT-1) * 1e9), distance_of_index(POINTS_COUNT-1)); + chsnprintf(buf1, sizeof(buf1), " START 0s"); + chsnprintf(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); @@ -1853,7 +1700,7 @@ draw_frequencies(void) if (uistat.lever_mode == LM_SPAN || uistat.lever_mode == LM_CENTER) buf1[0] = S_SARROW[0]; ili9341_drawstring(buf1, OFFSETX, 232); - ili9341_drawstring(buf2, 205, 232); + ili9341_drawstring(buf2, 200, 232); } void @@ -1906,28 +1753,30 @@ draw_cal_status(void) void draw_battery_status(void) { - uint8_t string_buf[25]; - // Set battery color - setForegroundColor(vbat < BATTERY_WARNING_LEVEL ? DEFAULT_LOW_BAT_COLOR : DEFAULT_NORMAL_BAT_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); -// chsnprintf(string_buf, sizeof string_buf, "V:%d", vbat); -// ili9341_drawstringV(string_buf, 1, 60); - // Prepare battery bitmap image - // Battery top - int x=0; - string_buf[x++] = 0b00111100; - string_buf[x++] = 0b00100100; - string_buf[x++] = 0b11111111; -// string_buf[x++] = 0b10000001; - // Fill battery status - for (int power=BATTERY_TOP_LEVEL; power > BATTERY_BOTTOM_LEVEL; power-=100) - string_buf[x++] = (power > vbat) ? 0b10000001 : // Empty line - 0b11111111; // Full line - // Battery bottom -// string_buf[x++] = 0b10000001; - string_buf[x++] = 0b11111111; - // Draw battery - blit8BitWidthBitmap(0, 1, 8, x, string_buf); + if (vbat<=0) + return; + uint8_t string_buf[25]; + // Set battery color + setForegroundColor(vbat < BATTERY_WARNING_LEVEL ? DEFAULT_LOW_BAT_COLOR : DEFAULT_NORMAL_BAT_COLOR); + setBackgroundColor(DEFAULT_BG_COLOR); +// chsnprintf(string_buf, sizeof string_buf, "V:%d", vbat); +// ili9341_drawstringV(string_buf, 1, 60); + // Prepare battery bitmap image + // Battery top + int x=0; + string_buf[x++] = 0b00111100; + string_buf[x++] = 0b00100100; + string_buf[x++] = 0b11111111; +// string_buf[x++] = 0b10000001; + // Fill battery status + for (int power=BATTERY_TOP_LEVEL; power > BATTERY_BOTTOM_LEVEL; power-=100) + string_buf[x++] = (power > vbat) ? 0b10000001 : // Empty line + 0b11111111; // Full line + // Battery bottom +// string_buf[x++] = 0b10000001; + string_buf[x++] = 0b11111111; + // Draw battery + blit8BitWidthBitmap(0, 1, 8, x, string_buf); } void diff --git a/ui.c b/ui.c index f35f504..c27b354 100644 --- a/ui.c +++ b/ui.c @@ -106,7 +106,7 @@ int awd_count; #define KP_DONE 1 #define KP_CANCEL 2 -char kp_buf[11]; +char kp_buf[NUMINPUT_LEN+1]; int8_t kp_index = 0; void ui_mode_normal(void); @@ -1791,7 +1791,7 @@ keypad_click(int key) { int c = keypads[key].c; if ((c >= KP_X1 && c <= KP_G) || c == KP_N || c == KP_P) { - float scale = 1; + int32_t scale = 1; if (c >= KP_X1 && c <= KP_G) { int n = c - KP_X1; while (n-- > 0) @@ -1800,7 +1800,7 @@ keypad_click(int key) scale *= 1000; } /* numeric input done */ - float value = my_atof(kp_buf) * scale; + double value = my_atof(kp_buf) * scale; switch (keypad_mode) { case KM_START: set_sweep_frequency(ST_START, value); From 2381e338eb4575508eb2c5a8ed929fb4da2b71e6 Mon Sep 17 00:00:00 2001 From: TT Date: Sat, 22 Feb 2020 12:24:32 +0900 Subject: [PATCH 02/65] fix: adjust spaces frequency and marker values --- plot.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/plot.c b/plot.c index f5ef8ea..c175874 100644 --- a/plot.c +++ b/plot.c @@ -741,7 +741,7 @@ trace_get_info(int t, char *buf, int len) if (scale != 1.0) return chsnprintf(buf, len, "%s %.1fFS", name, scale); else - return chsnprintf(buf, len, name); + return chsnprintf(buf, len, "%s ", name); default: return chsnprintf(buf, len, "%s %F/", name, scale); } @@ -1584,7 +1584,7 @@ cell_draw_marker_info(int m, int n, int w, int h) cell_drawstring(w, h, buf, xpos, ypos); xpos += 67; if (uistat.marker_delta && mk != active_marker) - trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); + trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); else trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index); setForegroundColor(DEFAULT_FG_COLOR); @@ -1654,7 +1654,7 @@ cell_draw_marker_info(int m, int n, int w, int h) if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { //frequency_string(buf, sizeof buf, frequencies[idx], ""); - chsnprintf(buf, sizeof buf, "%16qHz", frequencies[idx]); + chsnprintf(buf, sizeof buf, "%qHz", frequencies[idx]); } else { chsnprintf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx), distance_of_index(idx)); } @@ -1682,13 +1682,13 @@ draw_frequencies(void) char buf2[32];buf2[0]=0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { if (frequency0 < frequency1) { - chsnprintf(buf1, sizeof(buf1), " START %16qHz", frequency0); - chsnprintf(buf2, sizeof(buf2), "STOP %16qHz", frequency1); + chsnprintf(buf1, sizeof(buf1), " START %qHz", frequency0); + chsnprintf(buf2, sizeof(buf2), " STOP %qHz", frequency1); } else if (frequency0 > frequency1) { - chsnprintf(buf1, sizeof(buf1), " CENTER %16qHz", frequency0/2 + frequency1/2); - chsnprintf(buf2, sizeof(buf2), "SPAN %16qHz", frequency0 - frequency1); + chsnprintf(buf1, sizeof(buf1), " CENTER %qHz", frequency0/2 + frequency1/2); + chsnprintf(buf2, sizeof(buf2), " SPAN %qHz", frequency0 - frequency1); } else { - chsnprintf(buf1, sizeof(buf1), " CW %16qHz", frequency0); + chsnprintf(buf1, sizeof(buf1), " CW %qHz", frequency0); } } else { chsnprintf(buf1, sizeof(buf1), " START 0s"); @@ -1697,8 +1697,10 @@ draw_frequencies(void) setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); ili9341_fill(0, 232, 320, 8, DEFAULT_BG_COLOR); - if (uistat.lever_mode == LM_SPAN || uistat.lever_mode == LM_CENTER) + if (uistat.lever_mode == LM_CENTER) buf1[0] = S_SARROW[0]; + if (uistat.lever_mode == LM_SPAN) + buf2[0] = S_SARROW[0]; ili9341_drawstring(buf1, OFFSETX, 232); ili9341_drawstring(buf2, 200, 232); } From 02a5715bb49037319a4eb7ba693e4076c5db0c77 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 22 Feb 2020 10:50:54 +0300 Subject: [PATCH 03/65] Big code redisign (increase CELL draw size, more faster screen render), also save about 4-5kB flash size Try remove all hardcoded values from code (use definition if set) Some error fix main.c: Rewrite Shell, now it run on main thread and require less RAM (not need stack) (possible run it as thread if define VNA_SHELL_THREAD Remove not used trace_info[].scale_unit in set_trace_scale/get_trace_scale (it just divede on set and multiple on get, better use it for default scale set) Replace some hardcoded values MARKERS_MAX SAVEAREA_MAX TRACES_MAX plot.c Rewrite CELLWIDTH and CELLHEIGHT use, now possible set any CELL width and height (CELLWIDTH * CELLHEIGHT <= spi_buffer size) Free RAM from shell stack use fore increase spi_buffer size now it have 2048 pixel (64x32) Rewrite cell index and markmap use (now correct use cell size, and more faster), correct use CELLWIDTH and CELLHEIGHT in calculation Fore set update area use invalidateRect (still need use some hardcoded values :( ) Rewrite cell_draw_line Rewrite many hardcoded size definitions Refrence point now draw as bitmap (less size, more costumable) Fix drag marker (now correct search closest index in search_nearest_index) Rewrite plot_into_index, now correct use size definitions, moe ui.c Small rewrite keyboard definitions, for use less flash size Define KP_WIDTH, KP_HEIGHT for set key size Better look some big font symvols All: use static fore some local functions (use less space on calls) replace tabs on spaces (code style) Use M_PI from math.h fore define pi value Fix printf on print HEX values --- chprintf.c | 2 +- ili9341.c | 39 ++- main.c | 600 ++++++++++++++++++++++------------ nanovna.h | 39 ++- numfont20x22.c | 70 ++-- plot.c | 871 +++++++++++++++++++++++-------------------------- ui.c | 393 +++++++++++----------- 7 files changed, 1062 insertions(+), 952 deletions(-) diff --git a/chprintf.c b/chprintf.c index 8c75b29..6ba7efd 100644 --- a/chprintf.c +++ b/chprintf.c @@ -64,7 +64,7 @@ static char *long_to_string_with_divisor(char *p, do { uint8_t c = num % radix; num /= radix; - *--q = c + ((c > 9) ? 'A' : '0'); + *--q = c + ((c > 9) ? ('A'-10) : '0'); }while((precision && --precision) || num); // copy string at begin int i = (int)(b - q); diff --git a/ili9341.c b/ili9341.c index 12edc9c..e134025 100644 --- a/ili9341.c +++ b/ili9341.c @@ -21,7 +21,7 @@ #include "hal.h" #include "nanovna.h" -uint16_t spi_buffer[1024]; +uint16_t spi_buffer[2048]; // Default foreground & background colors uint16_t foreground_color=DEFAULT_FG_COLOR; uint16_t background_color=DEFAULT_BG_COLOR; @@ -568,10 +568,34 @@ void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size) while (*str) x += ili9341_drawchar_size(*str++, x, y, size); } +#if 0 +static void ili9341_pixel(int x, int y, uint16_t color) +{ + uint32_t xx = __REV16(x|((x)<<16)); + uint32_t yy = __REV16(y|((y)<<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, 2, &color); +} +#endif #define SWAP(x,y) { int z=x; x = y; y = z; } void ili9341_line(int x0, int y0, int x1, int y1) { +#if 0 + // modifed Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int dx = x1 - x0, sx = 1; if (dx < 0) {dx = -dx; sx = -1;} + int dy = y1 - y0, sy = 1; if (dy < 0) {dy = -dy; sy = -1;} + int err = (dx > dy ? dx : -dy) / 2; + while (1){ + ili9341_pixel(x0, y0, DEFAULT_FG_COLOR); + if (x0 == x1 && y0 == y1) + break; + int e2 = err; + if (e2 > -dx) { err -= dy; x0 += sx; } + if (e2 < dy) { err += dx; y0 += sy; } + } +#endif if (x0 > x1) { SWAP(x0, x1); @@ -611,20 +635,8 @@ static const uint16_t colormap[] = { RGBHEX(0x00ffff), RGBHEX(0xff00ff), RGBHEX(0xffff00) }; -static void ili9341_pixel(int x, int y, int color) -{ - uint8_t xx[4] = { x >> 8, x, (x+1) >> 8, (x+1) }; - uint8_t yy[4] = { y >> 8, y, (y+1) >> 8, (y+1) }; - uint8_t cc[2] = { color >> 8, color }; - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, yy); - send_command(ILI9341_MEMORY_WRITE, 2, cc); - //send_command16(ILI9341_MEMORY_WRITE, color); -} - void ili9341_test(int mode) { - chMtxLock(&mutex_ili9341); int x, y; int i; switch (mode) { @@ -666,6 +678,5 @@ void ili9341_test(int mode) ili9341_line(0, 100, 100, 0); break; } - chMtxUnlock(&mutex_ili9341); } #endif diff --git a/main.c b/main.c index 795d187..1a06fa7 100644 --- a/main.c +++ b/main.c @@ -26,13 +26,34 @@ #include "fft.h" #include -#include -#include +//#include #include -#include +//#include #include +/* + * Shell settings + */ +// If need run shell as thread (use more amount of memory fore stack), after enable this need reduce spi_buffer size, by default shell run in main thread +//#define VNA_SHELL_THREAD + +static BaseSequentialStream *shell_stream = (BaseSequentialStream *)&SDU1; + +// Shell new line +#define VNA_SHELL_NEWLINE_STR "\r\n" +// Shell command promt +#define VNA_SHELL_PROMPT_STR "ch> " +// Shell max arguments +#define VNA_SHELL_MAX_ARGUMENTS 4 +// Shell max command line size +#define VNA_SHELL_MAX_LENGTH 64 +// Shell command functions prototypes +typedef void (*vna_shellcmd_t)(BaseSequentialStream *chp, int argc, char *argv[]); +#define VNA_SHELL_FUNCTION(command_name) static void command_name(BaseSequentialStream *chp, int argc, char *argv[]) + //#define ENABLED_DUMP +//#define ENABLE_THREADS_COMMAND + static void apply_error_term_at(int i); static void apply_edelay_at(int i); @@ -124,30 +145,30 @@ toggle_sweep(void) sweep_enabled = !sweep_enabled; } -float bessel0(float x) { - const float eps = 0.0001; - - float ret = 0; - float term = 1; - float m = 0; +static float +bessel0(float x) { + const float eps = 0.0001; - while (term > eps * ret) { - ret += term; - ++m; - term *= (x*x) / (4*m*m); - } + float ret = 0; + float term = 1; + float m = 0; - return ret; + while (term > eps * ret) { + ret += term; + ++m; + term *= (x*x) / (4*m*m); + } + return ret; } -float kaiser_window(float k, float n, float beta) { - if (beta == 0.0) return 1.0; - float r = (2 * k) / (n - 1) - 1; - return bessel0(beta * sqrt(1 - r * r)) / bessel0(beta); +static float +kaiser_window(float k, float n, float beta) { + if (beta == 0.0) return 1.0; + float r = (2 * k) / (n - 1) - 1; + return bessel0(beta * sqrt(1 - r * r)) / bessel0(beta); } -static -void +static void transform_domain(void) { if ((domain_mode & DOMAIN_MODE) != DOMAIN_TIME) return; // nothing to do for freq domain @@ -220,6 +241,16 @@ transform_domain(void) } } +// Shell commands output +static int shell_printf(BaseSequentialStream *chp, const char *fmt, ...) { + va_list ap; + int formatted_bytes; + va_start(ap, fmt); + formatted_bytes = chvprintf(chp, fmt, ap); + va_end(ap); + return formatted_bytes; +} + static void cmd_pause(BaseSequentialStream *chp, int argc, char *argv[]) { (void)chp; @@ -249,13 +280,13 @@ static void cmd_reset(BaseSequentialStream *chp, int argc, char *argv[]) if (argc == 1) { if (strcmp(argv[0], "dfu") == 0) { - chprintf(chp, "Performing reset to DFU mode\r\n"); + shell_printf(chp, "Performing reset to DFU mode\r\n"); enter_dfu(); return; } } - chprintf(chp, "Performing reset\r\n"); + shell_printf(chp, "Performing reset\r\n"); rccEnableWWDG(FALSE); @@ -312,7 +343,7 @@ int set_frequency(uint32_t freq) // Rewrite universal standart str to value functions to more compact // // Convert string to int32 -int32_t my_atoi(const char *p){ +static int32_t my_atoi(const char *p){ int32_t value = 0; uint32_t c; bool neg = false; @@ -374,7 +405,7 @@ my_atof(const char *p) static void cmd_offset(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc != 1) { - chprintf(chp, "usage: offset {frequency offset(Hz)}\r\n"); + shell_printf(chp, "usage: offset {frequency offset(Hz)}\r\n"); return; } frequency_offset = my_atoui(argv[0]); @@ -394,13 +425,13 @@ static void cmd_freq(BaseSequentialStream *chp, int argc, char *argv[]) chMtxUnlock(&mutex); return; usage: - chprintf(chp, "usage: freq {frequency(Hz)}\r\n"); + shell_printf(chp, "usage: freq {frequency(Hz)}\r\n"); } static void cmd_power(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc != 1) { - chprintf(chp, "usage: power {0-3|-1}\r\n"); + shell_printf(chp, "usage: power {0-3|-1}\r\n"); return; } drive_strength = my_atoi(argv[0]); @@ -413,7 +444,7 @@ static void cmd_time(BaseSequentialStream *chp, int argc, char *argv[]) (void)argc; (void)argv; rtcGetTime(&RTCD1, ×pec); - chprintf(chp, "%d/%d/%d %d\r\n", timespec.year+1980, timespec.month, timespec.day, timespec.millisecond); + shell_printf(chp, "%d/%d/%d %d\r\n", timespec.year+1980, timespec.month, timespec.day, timespec.millisecond); } @@ -421,8 +452,8 @@ static void cmd_dac(BaseSequentialStream *chp, int argc, char *argv[]) { int value; if (argc != 1) { - chprintf(chp, "usage: dac {value(0-4095)}\r\n"); - chprintf(chp, "current value: %d\r\n", config.dac_value); + shell_printf(chp, "usage: dac {value(0-4095)}\r\n"\ + "current value: %d\r\n", config.dac_value); return; } value = my_atoi(argv[0]); @@ -434,8 +465,8 @@ static void cmd_threshold(BaseSequentialStream *chp, int argc, char *argv[]) { uint32_t value; if (argc != 1) { - chprintf(chp, "usage: threshold {frequency in harmonic mode}\r\n"); - chprintf(chp, "current: %d\r\n", config.harmonic_freq_threshold); + shell_printf(chp, "usage: threshold {frequency in harmonic mode}\r\n"\ + "current: %d\r\n", config.harmonic_freq_threshold); return; } value = my_atoui(argv[0]); @@ -447,24 +478,24 @@ static void cmd_saveconfig(BaseSequentialStream *chp, int argc, char *argv[]) (void)argc; (void)argv; config_save(); - chprintf(chp, "Config saved.\r\n"); + shell_printf(chp, "Config saved.\r\n"); } static void cmd_clearconfig(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc != 1) { - chprintf(chp, "usage: clearconfig {protection key}\r\n"); + shell_printf(chp, "usage: clearconfig {protection key}\r\n"); return; } if (strcmp(argv[0], "1234") != 0) { - chprintf(chp, "Key unmatched.\r\n"); + shell_printf(chp, "Key unmatched.\r\n"); return; } clear_all_config_prop_data(); - chprintf(chp, "Config and all cal data cleared.\r\n"); - chprintf(chp, "Do reset manually to take effect. Then do touch cal and save.\r\n"); + shell_printf(chp, "Config and all cal data cleared.\r\n"\ + "Do reset manually to take effect. Then do touch cal and save.\r\n"); } static struct { @@ -560,18 +591,18 @@ static void cmd_data(BaseSequentialStream *chp, int argc, char *argv[]) chMtxLock(&mutex); for (i = 0; i < sweep_points; i++) { if (frequencies[i] != 0) - chprintf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]); + shell_printf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]); } chMtxUnlock(&mutex); } else if (sel >= 2 && sel < 7) { chMtxLock(&mutex); for (i = 0; i < sweep_points; i++) { if (frequencies[i] != 0) - chprintf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]); + shell_printf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]); } chMtxUnlock(&mutex); } else { - chprintf(chp, "usage: data [array]\r\n"); + shell_printf(chp, "usage: data [array]\r\n"); } } @@ -591,9 +622,9 @@ static void cmd_dump(BaseSequentialStream *chp, int argc, char *argv[]) len /= 2; for (i = 0; i < len; ) { for (j = 0; j < 16; j++, i++) { - chprintf(chp, "%04x ", 0xffff & (int)dump_buffer[i]); + shell_printf(chp, "%04x ", 0xffff & (int)dump_buffer[i]); } - chprintf(chp, "\r\n"); + shell_printf(chp, "\r\n"); } } #endif @@ -609,12 +640,12 @@ static void cmd_capture(BaseSequentialStream *chp, int argc, char *argv[]) // read 2 row pixel time (read buffer limit by 2/3 + 1 from spi_buffer size) for (int y=0; y < 240; y+=2) { - // use uint16_t spi_buffer[1024] (defined in ili9341) for read buffer - uint8_t *buf = (uint8_t *)spi_buffer; - ili9341_read_memory(0, y, 320, 2, 2*320, spi_buffer); - for (int i = 0; i < 4*320; i++) { - streamPut(chp, *buf++); - } + // use uint16_t spi_buffer[2048] (defined in ili9341) for read buffer + uint8_t *buf = (uint8_t *)spi_buffer; + ili9341_read_memory(0, y, 320, 2, 2*320, spi_buffer); + for (int i = 0; i < 4*320; i++) { + streamPut(chp, *buf++); + } } chMtxUnlock(&mutex); @@ -633,7 +664,7 @@ static void cmd_gamma(BaseSequentialStream *chp, int argc, char *argv[]) calculate_gamma(gamma); chMtxUnlock(&mutex); - chprintf(chp, "%d %d\r\n", gamma[0], gamma[1]); + shell_printf(chp, "%d %d\r\n", gamma[0], gamma[1]); } #endif @@ -653,7 +684,7 @@ static void cmd_sample(BaseSequentialStream *chp, int argc, char *argv[]) return; } } - chprintf(chp, "usage: sample {gamma|ampl|ref}\r\n"); + shell_printf(chp, "usage: sample {gamma|ampl|ref}\r\n"); } config_t config = { @@ -674,10 +705,10 @@ properties_t current_props = { ._frequency0 = 50000, // start = 50kHz ._frequency1 = 900000000, // end = 900MHz ._sweep_points = POINTS_COUNT, - ._trace = {/*enable, type, channel, polar, scale, refpos*/ + ._trace = {/*enable, type, channel, reserved, scale, refpos*/ { 1, TRC_LOGMAG, 0, 0, 1.0, 9.0 }, { 1, TRC_LOGMAG, 1, 0, 1.0, 9.0 }, - { 1, TRC_SMITH, 0, 1, 1.0, 0.0 }, + { 1, TRC_SMITH, 0, 0, 1.0, 0.0 }, { 1, TRC_PHASE, 1, 0, 1.0, 5.0 } }, ._markers = { @@ -748,20 +779,20 @@ static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) int16_t points = sweep_points; if (argc != 2 && argc != 3) { - chprintf(chp, "usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); + shell_printf(chp, "usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); return; } start = my_atoui(argv[0]); stop = my_atoui(argv[1]); if (start == 0 || stop == 0 || start > stop) { - chprintf(chp, "frequency range is invalid\r\n"); + shell_printf(chp, "frequency range is invalid\r\n"); return; } if (argc == 3) { points = my_atoi(argv[2]); if (points <= 0 || points > sweep_points) { - chprintf(chp, "sweep points exceeds range\r\n"); + shell_printf(chp, "sweep points exceeds range\r\n"); return; } } @@ -785,7 +816,7 @@ update_marker_index(void) { int m; int i; - for (m = 0; m < 4; m++) { + for (m = 0; m < MARKERS_MAX; m++) { if (!markers[m].enabled) continue; uint32_t f = markers[m].frequency; @@ -854,7 +885,7 @@ update_frequencies(void) update_grid(); } -void +static void freq_mode_startstop(void) { if (frequency0 > frequency1) { @@ -865,7 +896,7 @@ freq_mode_startstop(void) } } -void +static void freq_mode_centerspan(void) { if (frequency0 <= frequency1) { @@ -876,7 +907,6 @@ freq_mode_centerspan(void) } } - #define START_MIN 50000 #define STOP_MAX 2700000000U @@ -983,7 +1013,7 @@ get_sweep_frequency(int type) static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 0) { - chprintf(chp, "%d %d %d\r\n", frequency0, frequency1, sweep_points); + shell_printf(chp, "%d %d %d\r\n", frequency0, frequency1, sweep_points); return; } else if (argc > 3) { goto usage; @@ -1018,8 +1048,8 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) set_sweep_frequency(ST_STOP, value1); return; usage: - chprintf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n"); - chprintf(chp, "\tsweep {start|stop|center|span|cw} {freq(Hz)}\r\n"); + shell_printf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n"\ + "\tsweep {start|stop|center|span|cw} {freq(Hz)}\r\n"); } @@ -1058,7 +1088,7 @@ adjust_ed(void) // prepare 1/s11ao to avoid dividing complex float c = 1000e-15; float z0 = 50; - //float z = 6.2832 * frequencies[i] * c * z0; + //float z = 2 * M_PI * frequencies[i] * c * z0; float z = 0.02; cal_data[ETERM_ED][i][0] += z; } @@ -1076,7 +1106,7 @@ eterm_calc_es(void) float c = 50e-15; //float c = 1.707e-12; float z0 = 50; - float z = 6.2832 * frequencies[i] * c * z0; + float z = 2 * M_PI * frequencies[i] * c * z0; float sq = 1 + z*z; float s11aor = (1 - z*z) / sq; float s11aoi = 2*z / sq; @@ -1181,7 +1211,7 @@ void apply_error_term(void) } #endif -void apply_error_term_at(int i) +static void apply_error_term_at(int i) { // S11m' = S11m - Ed // S11a = S11m' / (Er + Es S11m') @@ -1298,7 +1328,7 @@ cal_done(void) redraw_request |= REDRAW_CAL_STATUS; } -void +static void cal_interpolate(int s) { const properties_t *src = caldata_ref(s); @@ -1370,9 +1400,9 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) int i; for (i = 0; i < 9; i++) { if (cal_status & (1< 1 && strcmp(argv[1], "off") == 0) { - set_trace_type(0, TRC_OFF); - set_trace_type(1, TRC_OFF); - set_trace_type(2, TRC_OFF); - set_trace_type(3, TRC_OFF); + for (t = 0; t < TRACES_MAX; t++) + set_trace_type(t, TRC_OFF); goto exit; } t = my_atoi(argv[0]); - if (t < 0 || t >= 4) + if (t < 0 || t >= TRACES_MAX) goto usage; if (argc == 1) { const char *type = get_trace_typename(t); const char *channel = trc_channel_name[trace[t].channel]; - chprintf(chp, "%d %s %s\r\n", t, type, channel); + shell_printf(chp, "%d %s %s\r\n", t, type, channel); return; } - - if (argc > 1) { - static const type_list t_list[] = { - {"logmag", TRC_LOGMAG}, - {"phase", TRC_PHASE}, - {"polar", TRC_POLAR}, - {"smith", TRC_SMITH}, - {"delay", TRC_DELAY}, - {"linear", TRC_LINEAR}, - {"swr", TRC_SWR}, - {"real", TRC_REAL}, - {"imag", TRC_IMAG}, - {"r", TRC_R}, - {"x", TRC_X}, - {"off", TRC_OFF}, - }; - for (uint16_t i=0; i= 3) { - //trace[t].scale = my_atof(argv[2]); - set_trace_scale(t, my_atof(argv[2])); - goto exit; - } else if (strcmp(argv[1], "refpos") == 0 && argc >= 3) { - //trace[t].refpos = my_atof(argv[2]); - set_trace_refpos(t, my_atof(argv[2])); - goto exit; - } else { + } + if (strcmp(argv[1], "scale") == 0 && argc >= 3) { + //trace[t].scale = my_atof(argv[2]); + set_trace_scale(t, my_atof(argv[2])); + goto exit; + } else if (strcmp(argv[1], "refpos") == 0 && argc >= 3) { + //trace[t].refpos = my_atof(argv[2]); + set_trace_refpos(t, my_atof(argv[2])); + goto exit; + } else { goto usage; - } } + check_ch_num: if (argc > 2) { int src = my_atoi(argv[2]); @@ -1637,8 +1656,8 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) exit: return; usage: - chprintf(chp, "trace {0|1|2|3|all} [logmag|phase|polar|smith|linear|delay|swr|real|imag|r|x|off] [src]\r\n"); - chprintf(chp, "trace {0|1|2|3} {scale|refpos} {value}\r\n"); + shell_printf(chp, "trace {0|1|2|3|all} [logmag|phase|polar|smith|linear|delay|swr|real|imag|r|x|off] [src]\r\n"\ + "trace {0|1|2|3} {scale|refpos} {value}\r\n"); } @@ -1658,7 +1677,7 @@ float get_electrical_delay(void) static void cmd_edelay(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc == 0) { - chprintf(chp, "%f\r\n", electrical_delay); + shell_printf(chp, "%f\r\n", electrical_delay); return; } if (argc > 0) { @@ -1671,26 +1690,26 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) { int t; if (argc == 0) { - for (t = 0; t < 4; t++) { + for (t = 0; t < MARKERS_MAX; t++) { if (markers[t].enabled) { - chprintf(chp, "%d %d %d\r\n", t+1, markers[t].index, markers[t].frequency); + shell_printf(chp, "%d %d %d\r\n", t+1, markers[t].index, markers[t].frequency); } } return; } if (strcmp(argv[0], "off") == 0) { active_marker = -1; - for (t = 0; t < 4; t++) + for (t = 0; t < MARKERS_MAX; t++) markers[t].enabled = FALSE; redraw_request |= REDRAW_MARKER; return; } t = my_atoi(argv[0])-1; - if (t < 0 || t >= 4) + if (t < 0 || t >= MARKERS_MAX) goto usage; if (argc == 1) { - chprintf(chp, "%d %d %d\r\n", t+1, markers[t].index, frequency); + shell_printf(chp, "%d %d %d\r\n", t+1, markers[t].index, frequency); active_marker = t; // select active marker markers[t].enabled = TRUE; @@ -1719,7 +1738,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) } return; usage: - chprintf(chp, "marker [n] [off|{index}]\r\n"); + shell_printf(chp, "marker [n] [off|{index}]\r\n"); } static void cmd_touchcal(BaseSequentialStream *chp, int argc, char *argv[]) @@ -1730,15 +1749,15 @@ static void cmd_touchcal(BaseSequentialStream *chp, int argc, char *argv[]) int i; chMtxLock(&mutex); - chprintf(chp, "first touch upper left, then lower right..."); + shell_printf(chp, "first touch upper left, then lower right..."); touch_cal_exec(); - chprintf(chp, "done\r\n"); + shell_printf(chp, "done\r\n"); - chprintf(chp, "touch cal params: "); + shell_printf(chp, "touch cal params: "); for (i = 0; i < 4; i++) { - chprintf(chp, "%d ", config.touch_cal[i]); + shell_printf(chp, "%d ", config.touch_cal[i]); } - chprintf(chp, "\r\n"); + shell_printf(chp, "\r\n"); chMtxUnlock(&mutex); } @@ -1763,7 +1782,7 @@ static void cmd_frequencies(BaseSequentialStream *chp, int argc, char *argv[]) (void)argv; for (i = 0; i < sweep_points; i++) { if (frequencies[i] != 0) - chprintf(chp, "%d\r\n", frequencies[i]); + shell_printf(chp, "%d\r\n", frequencies[i]); } } @@ -1821,7 +1840,7 @@ static void cmd_transform(BaseSequentialStream *chp, int argc, char *argv[]) return; usage: - chprintf(chp, "usage: transform {on|off|impulse|step|bandpass|minimum|normal|maximum} [...]\r\n"); + shell_printf(chp, "usage: transform {on|off|impulse|step|bandpass|minimum|normal|maximum} [...]\r\n"); } static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) @@ -1861,22 +1880,22 @@ static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) #if 0 //extern adcsample_t adc_samples[2]; - //chprintf(chp, "adc: %d %d\r\n", adc_samples[0], adc_samples[1]); + //shell_printf(chp, "adc: %d %d\r\n", adc_samples[0], adc_samples[1]); int i; int x, y; for (i = 0; i < 50; i++) { test_touch(&x, &y); - chprintf(chp, "adc: %d %d\r\n", x, y); + shell_printf(chp, "adc: %d %d\r\n", x, y); chThdSleepMilliseconds(200); } //extern int touch_x, touch_y; - //chprintf(chp, "adc: %d %d\r\n", touch_x, touch_y); + //shell_printf(chp, "adc: %d %d\r\n", touch_x, touch_y); #endif while (argc > 1) { int x, y; touch_position(&x, &y); - chprintf(chp, "touch: %d %d\r\n", x, y); + shell_printf(chp, "touch: %d %d\r\n", x, y); chThdSleepMilliseconds(200); } } @@ -1886,7 +1905,7 @@ static void cmd_gain(BaseSequentialStream *chp, int argc, char *argv[]) int rvalue; int lvalue = 0; if (argc != 1 && argc != 2) { - chprintf(chp, "usage: gain {lgain(0-95)} [rgain(0-95)]\r\n"); + shell_printf(chp, "usage: gain {lgain(0-95)} [rgain(0-95)]\r\n"); return; } rvalue = my_atoi(argv[0]); @@ -1899,7 +1918,7 @@ static void cmd_port(BaseSequentialStream *chp, int argc, char *argv[]) { int port; if (argc != 1) { - chprintf(chp, "usage: port {0:TX 1:RX}\r\n"); + shell_printf(chp, "usage: port {0:TX 1:RX}\r\n"); return; } port = my_atoi(argv[0]); @@ -1932,14 +1951,14 @@ static void cmd_stat(BaseSequentialStream *chp, int argc, char *argv[]) stat.ave[0] = ave0; stat.ave[1] = ave1; - chprintf(chp, "average: %d %d\r\n", stat.ave[0], stat.ave[1]); - chprintf(chp, "rms: %d %d\r\n", stat.rms[0], stat.rms[1]); - chprintf(chp, "callback count: %d\r\n", stat.callback_count); - //chprintf(chp, "interval cycle: %d\r\n", stat.interval_cycles); - //chprintf(chp, "busy cycle: %d\r\n", stat.busy_cycles); - //chprintf(chp, "load: %d\r\n", stat.busy_cycles * 100 / stat.interval_cycles); + shell_printf(chp, "average: %d %d\r\n", stat.ave[0], stat.ave[1]); + shell_printf(chp, "rms: %d %d\r\n", stat.rms[0], stat.rms[1]); + shell_printf(chp, "callback count: %d\r\n", stat.callback_count); + //shell_printf(chp, "interval cycle: %d\r\n", stat.interval_cycles); + //shell_printf(chp, "busy cycle: %d\r\n", stat.busy_cycles); + //shell_printf(chp, "load: %d\r\n", stat.busy_cycles * 100 / stat.interval_cycles); extern int awd_count; - chprintf(chp, "awd: %d\r\n", awd_count); + shell_printf(chp, "awd: %d\r\n", awd_count); } @@ -1953,64 +1972,207 @@ static void cmd_version(BaseSequentialStream *chp, int argc, char *argv[]) { (void)argc; (void)argv; - chprintf(chp, "%s\r\n", NANOVNA_VERSION); + shell_printf(chp, "%s\r\n", NANOVNA_VERSION); } static void cmd_vbat(BaseSequentialStream *chp, int argc, char *argv[]) { (void)argc; (void)argv; - chprintf(chp, "%d mV\r\n", vbat); + shell_printf(chp, "%d mV\r\n", vbat); } -static THD_WORKING_AREA(waThread2, /* cmd_* max stack size + alpha */442); +#ifdef ENABLE_THREADS_COMMAND +#if CH_CFG_USE_REGISTRY == FALSE +#error "Threads Requite enabled CH_CFG_USE_REGISTRY in chconf.h" +#endif +static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { + static const char *states[] = {CH_STATE_NAMES}; + thread_t *tp; -static const ShellCommand commands[] = -{ - { "version", cmd_version }, - { "reset", cmd_reset }, - { "freq", cmd_freq }, - { "offset", cmd_offset }, - { "time", cmd_time }, - { "dac", cmd_dac }, - { "saveconfig", cmd_saveconfig }, - { "clearconfig", cmd_clearconfig }, - { "data", cmd_data }, + (void)argv; + if (argc > 0) { + shellUsage(chp, "threads"); + return; + } + chprintf(chp, "stklimit stack addr refs prio state name\r\n"SHELL_NEWLINE_STR); + tp = chRegFirstThread(); + do { + uint32_t stklimit = (uint32_t)tp->wabase; + shell_printf(chp, "%08x %08x %08x %4u %4u %9s %12s"SHELL_NEWLINE_STR, + stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp, + (uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state], + tp->name == NULL ? "" : tp->name); + tp = chRegNextThread(tp); + } while (tp != NULL); +} +#endif + +//============================================================================= +static void cmd_help(BaseSequentialStream *chp, int argc, char *argv[]); +typedef struct { + const char *sc_name; + vna_shellcmd_t sc_function; +} VNAShellCommand; + +static const VNAShellCommand commands[] = +{ + { "version" , cmd_version }, + { "reset" , cmd_reset }, + { "freq" , cmd_freq }, + { "offset" , cmd_offset }, + { "time" , cmd_time }, + { "dac" , cmd_dac }, + { "saveconfig" , cmd_saveconfig }, + { "clearconfig" , cmd_clearconfig }, + { "data" , cmd_data }, #ifdef ENABLED_DUMP - { "dump", cmd_dump }, + { "dump" , cmd_dump }, +#endif + { "frequencies" , cmd_frequencies }, + { "port" , cmd_port }, + { "stat" , cmd_stat }, + { "gain" , cmd_gain }, + { "power" , cmd_power }, + { "sample" , cmd_sample }, +// { "gamma" , cmd_gamma }, + { "scan" , cmd_scan }, + { "sweep" , cmd_sweep }, + { "test" , cmd_test }, + { "touchcal" , cmd_touchcal }, + { "touchtest" , cmd_touchtest }, + { "pause" , cmd_pause }, + { "resume" , cmd_resume }, + { "cal" , cmd_cal }, + { "save" , cmd_save }, + { "recall" , cmd_recall }, + { "trace" , cmd_trace }, + { "marker" , cmd_marker }, + { "edelay" , cmd_edelay }, + { "capture" , cmd_capture }, + { "vbat" , cmd_vbat }, + { "transform" , cmd_transform }, + { "threshold" , cmd_threshold }, + { "help" , cmd_help }, +#ifdef ENABLE_THREADS_COMMAND +// { "threads" , cmd_threads }, #endif - { "frequencies", cmd_frequencies }, - { "port", cmd_port }, - { "stat", cmd_stat }, - { "gain", cmd_gain }, - { "power", cmd_power }, - { "sample", cmd_sample }, - //{ "gamma", cmd_gamma }, - { "scan", cmd_scan }, - { "sweep", cmd_sweep }, - { "test", cmd_test }, - { "touchcal", cmd_touchcal }, - { "touchtest", cmd_touchtest }, - { "pause", cmd_pause }, - { "resume", cmd_resume }, - { "cal", cmd_cal }, - { "save", cmd_save }, - { "recall", cmd_recall }, - { "trace", cmd_trace }, - { "marker", cmd_marker }, - { "edelay", cmd_edelay }, - { "capture", cmd_capture }, - { "vbat", cmd_vbat }, - { "transform", cmd_transform }, - { "threshold", cmd_threshold }, - { NULL, NULL } + { NULL , NULL } }; -static const ShellConfig shell_cfg1 = +static void cmd_help(BaseSequentialStream *chp, int argc, char *argv[]) { - (BaseSequentialStream *)&SDU1, - commands -}; + (void)argc; + (void)argv; + const VNAShellCommand *scp = commands; + shell_printf(chp, "Commands:"); + while (scp->sc_name != NULL) { + shell_printf(chp, " %s", scp->sc_name); + scp++; + } + shell_printf(chp, VNA_SHELL_NEWLINE_STR); + return; +} + +/* + * VNA shell functions + */ + +// +// Read command line from shell_stream +// +static int VNAShell_readLine(char *line, int max_size){ + // Read line from input stream + uint8_t c; + char *ptr = line; + while (1){ + // Return 0 only if stream not active + if (streamRead(shell_stream, &c, 1) == 0) + return 0; + // Backspace + if (c == 8) { + if (ptr != line) { + static const char backspace[] = {0x08,0x20,0x08,0x00}; + shell_printf(shell_stream, backspace); + ptr--; + } + continue; + } + // New line (Enter) + if (c == '\r') { + shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR); + *ptr = 0; + return 1; + } + // Others (skip) + if (c < 0x20) + continue; + // Store + if (ptr < line + max_size - 1) { + streamPut(shell_stream, c); // Echo + *ptr++ = (char)c; + } + } + return 0; +} + +// +// Parse and run command line +// +static void VNAShell_executeLine(char *line){ + // Parse and execute line + char *args[VNA_SHELL_MAX_ARGUMENTS + 1]; + int n = 0; + char *lp = line, *ep; + 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; + // Stop, end of input string + if ((lp = ep) == NULL) + break; + // Argument limits check + if (n > VNA_SHELL_MAX_ARGUMENTS) { + shell_printf(shell_stream, "too many arguments, max 4"VNA_SHELL_NEWLINE_STR); + return; + } + // Set zero at the end of string and continue check + *lp++ = 0; + } + if (n == 0) + return; + // Execute line + const VNAShellCommand *scp; + for (scp = commands; scp->sc_name!=NULL;scp++) { + if (strcmp(scp->sc_name, args[0]) == 0) { +// chMtxLock(&mutex); + scp->sc_function(shell_stream, n-1, &args[1]); +// chMtxUnlock(&mutex); + return; + } + } + shell_printf(shell_stream, "%s?"VNA_SHELL_NEWLINE_STR, args[0]); +} + +#ifdef VNA_SHELL_THREAD +static THD_WORKING_AREA(waThread2, /* cmd_* max stack size + alpha */442); +THD_FUNCTION(myshellThread, p) { + (void)p; + chRegSetThreadName("shell"); + char line[VNA_SHELL_MAX_LENGTH]; + shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); + while (true) { + shell_printf(shell_stream, VNA_SHELL_PROMPT_STR); + if (VNAShell_readLine(line, VNA_SHELL_MAX_LENGTH)) + VNAShell_executeLine(line); + else // Putting a delay in order to avoid an endless loop trying to read an unavailable stream. + osalThreadSleepMilliseconds(100); + } +} +#endif static const I2CConfig i2ccfg = { 0x00300506, //voodoo magic 400kHz @ HSI 8MHz @@ -2094,23 +2256,29 @@ int main(void) ui_init(); - /* - * Shell manager initialization. - */ - shellInit(); - - chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); - - while (1) { - if (SDU1.config->usbp->state == USB_ACTIVE) { - thread_t *shelltp = chThdCreateStatic(waThread2, sizeof(waThread2), - NORMALPRIO + 1, - shellThread, (void *)&shell_cfg1); - chThdWait(shelltp); /* Waiting termination. */ - } - - chThdSleepMilliseconds(1000); + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO-1, Thread1, NULL); + + while (1) { + if (SDU1.config->usbp->state == USB_ACTIVE) { +#ifdef VNA_SHELL_THREAD + thread_t *shelltp = chThdCreateStatic(waThread2, sizeof(waThread2), + NORMALPRIO + 1, + myshellThread, NULL); + chThdWait(shelltp); +#else + char line[VNA_SHELL_MAX_LENGTH]; + shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); + do { + shell_printf(shell_stream, VNA_SHELL_PROMPT_STR); + if (VNAShell_readLine(line, VNA_SHELL_MAX_LENGTH)) + VNAShell_executeLine(line); + else + chThdSleepMilliseconds(200); + } while (SDU1.config->usbp->state == USB_ACTIVE); +#endif } + chThdSleepMilliseconds(1000); + } } /* The prototype shows it is a naked function - in effect this is just an diff --git a/nanovna.h b/nanovna.h index a1b490c..7df26ec 100644 --- a/nanovna.h +++ b/nanovna.h @@ -126,30 +126,35 @@ extern void tlv320aic3204_init(void); extern void tlv320aic3204_set_gain(int lgain, int rgain); extern void tlv320aic3204_select(int channel); - /* * plot.c */ -#define OFFSETX 15 -#define OFFSETY 0 -#define WIDTH 291 -#define HEIGHT 230 +// GRIDX calculated depends from frequency span +#define GRIDY 23 -// Smith/polar chart -#define P_CENTER_X 145 -#define P_CENTER_Y 115 -#define P_RADIUS 115 +// Offset of plot area +#define OFFSETX 10 +#define OFFSETY 0 + +// WIDTH better be n*(POINTS_COUNT-1) +#define WIDTH 300 +// HEIGHT = 10*GRIDY +#define HEIGHT 230 +// #define CELLOFFSETX 5 -#define AREA_WIDTH_NORMAL (WIDTH + CELLOFFSETX*2) +#define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH + 1 + 4) +#define AREA_HEIGHT_NORMAL ( HEIGHT + 1) + +// Smith/polar chart +#define P_CENTER_X (CELLOFFSETX + WIDTH/2) +#define P_CENTER_Y (HEIGHT/2) +#define P_RADIUS (HEIGHT/2) extern int16_t area_width; extern int16_t area_height; -#define GRIDY 23 - // font - extern const uint8_t x5x7_bits []; #define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) #define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7)) @@ -176,6 +181,8 @@ extern const uint16_t numfont16x22[]; enum { TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF }; +// Mask for define rectangular plot +#define RECTANGULAR_GRID_MASK ((1<>5)&0x1f) | (((i)>>22)&0x03e0)) -#define CELL_Y(i) (int)(((i)&0x1f) | (((i)>>17)&0x03e0)) -#define CELL_N(i) (int)(((i)>>10)&0xfff) +// 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 CELL_X0(i) (int)(((i)>>22)&0x03e0) -#define CELL_Y0(i) (int)(((i)>>17)&0x03e0) +// 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]; -#define CELL_P(i, x, y) (((((x)&0x03e0UL)<<22) | (((y)&0x03e0UL)<<17)) == ((i)&0xffc00000UL)) +#define INDEX(x, y) ((((uint32_t)x)<<16)|(((uint32_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)) -int floatToInt(float v){ - if (v < 0) return v-0.5; - if (v > 0) return v+0.5; - return 0; +static int +floatToInt(float v){ + if (v < 0) return v-0.5; + if (v > 0) return v+0.5; + return 0; } void update_grid(void) { uint32_t gdigit = 100000000; - uint32_t fstart, fspan; + uint32_t fstart = get_sweep_frequency(ST_START); + uint32_t fspan = get_sweep_frequency(ST_SPAN); uint32_t grid; - if (frequency0 <= frequency1) { - fstart = frequency0; - fspan = frequency1 - frequency0; - } else { - fstart = frequency1; - fspan = frequency0 - frequency1; - } while (gdigit > 100) { grid = 5 * gdigit; @@ -84,8 +61,8 @@ void update_grid(void) gdigit /= 10; } - grid_offset = (WIDTH-1) * ((fstart % grid) / 100) / (fspan / 100); - grid_width = (WIDTH-1) * (grid / 100) / (fspan / 1000); + grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); + grid_width = (WIDTH) * (grid / 100) / (fspan / 1000); force_set_markmap(); redraw_request |= REDRAW_FREQUENCY; @@ -95,9 +72,9 @@ static inline int circle_inout(int x, int y, int r) { int d = x*x + y*y - r*r; - if (d <= -r) + if (d < -r) return 1; - if (d > r) + if (d > r) return -1; return 0; } @@ -145,7 +122,7 @@ polar_grid(int x, int y) * Constant Resistance circle: (u - r/(r+1))^2 + v^2 = 1/(r+1)^2 * Constant Reactance circle: (u - 1)^2 + (v-1/x)^2 = 1/x^2 */ -int +static int smith_grid(int x, int y) { int d; @@ -203,7 +180,7 @@ smith_grid(int x, int y) } #if 0 -int +static int smith_grid2(int x, int y, float scale) { int d; @@ -286,6 +263,7 @@ smith_grid2(int x, int y, float scale) } #endif +#if 0 const int cirs[][4] = { { 0, 58/2, 58/2, 0 }, // Constant Reactance Circle: 2j : R/2 = 58 { 29/2, 0, 29/2, 1 }, // Constant Resistance Circle: 3 : R/4 = 29 @@ -299,7 +277,7 @@ const int cirs[][4] = { { 0, 0, 0, 0 } // sentinel }; -int +static int smith_grid3(int x, int y) { int d; @@ -333,9 +311,10 @@ smith_grid3(int x, int y) } return 0; } +#endif #if 0 -int +static int rectangular_grid(int x, int y) { //#define FREQ(x) (((x) * (fspan / 1000) / (WIDTH-1)) * 1000 + fstart) @@ -357,9 +336,10 @@ rectangular_grid(int x, int y) static int rectangular_grid_x(int x) { + x-=CELLOFFSETX; if (x < 0) return 0; - if (x == 0 || x == WIDTH-1) + if (x == 0 || x == WIDTH) return 1; if ((((x + grid_offset) * 10) % grid_width) < 10) return 1; @@ -415,7 +395,8 @@ draw_on_strut(int v0, int d, int color) /* * calculate log10(abs(gamma)) */ -float logmag(const float *v) +static float +logmag(const float *v) { return log10f(v[0]*v[0] + v[1]*v[1]) * 10; } @@ -423,7 +404,8 @@ float logmag(const float *v) /* * calculate phase[-2:2] of coefficient */ -float phase(const float *v) +static float +phase(const float *v) { return 2 * atan2f(v[1], v[0]) / M_PI * 90; } @@ -431,7 +413,8 @@ float phase(const float *v) /* * calculate groupdelay */ -float groupdelay(const float *v, const float *w, float deltaf) +static float +groupdelay(const float *v, const float *w, float deltaf) { #if 1 // atan(w)-atan(v) = atan((w-v)/(1+wv)) @@ -446,7 +429,8 @@ float groupdelay(const float *v, const float *w, float deltaf) /* * calculate abs(gamma) */ -float linear(const float *v) +static float +linear(const float *v) { return - sqrtf(v[0]*v[0] + v[1]*v[1]); } @@ -454,7 +438,8 @@ float linear(const float *v) /* * calculate vswr; (1+gamma)/(1-gamma) */ -float swr(const float *v) +static float +swr(const float *v) { float x = sqrtf(v[0]*v[0] + v[1]*v[1]); if (x >= 1) @@ -462,30 +447,32 @@ float swr(const float *v) return (1 + x)/(1 - x); } -float resitance(const float *v) { +static float +resitance(const float *v) { float z0 = 50; float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); float zr = ((1+v[0])*(1-v[0]) - v[1]*v[1]) * d; return zr; } -float reactance(const float *v) { +static float +reactance(const float *v) { float z0 = 50; float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); float zi = 2*v[1] * d; return zi; } -void +static void cartesian_scale(float re, float im, int *xp, int *yp, float scale) { //float scale = 4e-3; int x = floatToInt(re * P_RADIUS * scale); int y = floatToInt(im * P_RADIUS * scale); - if (x < -P_RADIUS) x = -P_RADIUS; - if (y < -P_RADIUS) y = -P_RADIUS; - if (x > P_RADIUS) x = P_RADIUS; - if (y > P_RADIUS) y = P_RADIUS; + if (x < -P_RADIUS) x = -P_RADIUS; + else if (x > P_RADIUS) x = P_RADIUS; + if (y < -P_RADIUS) y = -P_RADIUS; + else if (y > P_RADIUS) y = P_RADIUS; *xp = P_CENTER_X + x; *yp = P_CENTER_Y - y; } @@ -515,57 +502,57 @@ gamma2reactance(const float v[2]) return 2*v[1] * d; } -uint32_t -trace_into_index(int x, int t, int i, float array[POINTS_COUNT][2]) +static uint32_t +trace_into_index(int t, int i, float array[POINTS_COUNT][2]) { - int y = 0; - float v = 0; + int y, x; + float *coeff = array[i]; float refpos = 10 - get_trace_refpos(t); + float v = refpos; float scale = 1 / get_trace_scale(t); switch (trace[t].type) { case TRC_LOGMAG: - v = refpos - logmag(coeff) * scale; + v-= logmag(coeff) * scale; break; case TRC_PHASE: - v = refpos - phase(coeff) * scale; + v-= phase(coeff) * scale; break; case TRC_DELAY: - v = refpos - groupdelay_from_array(i, array) * scale; + v-= groupdelay_from_array(i, array) * scale; break; case TRC_LINEAR: - v = refpos + linear(coeff) * scale; + v+= linear(coeff) * scale; break; case TRC_SWR: - v = refpos+ (1 - swr(coeff)) * scale; + v+= (1 - swr(coeff)) * scale; break; case TRC_REAL: - v = refpos - coeff[0] * scale; + v-= coeff[0] * scale; break; case TRC_IMAG: - v = refpos - coeff[1] * scale; + v-= coeff[1] * scale; break; case TRC_R: - v = refpos - resitance(coeff) * scale; + v-= resitance(coeff) * scale; break; case TRC_X: - v = refpos - reactance(coeff) * scale; + v-= reactance(coeff) * scale; break; case TRC_SMITH: //case TRC_ADMIT: case TRC_POLAR: cartesian_scale(coeff[0], coeff[1], &x, &y, scale); - return INDEX(x +CELLOFFSETX, y, i); - break; + goto set_index; } - if (v < 0) v = 0; + if (v < 0) v = 0; if (v > 10) v = 10; + x = (i * (WIDTH) + (sweep_points-1)/2) / (sweep_points-1) + CELLOFFSETX; y = floatToInt(v * GRIDY); - return INDEX(x +CELLOFFSETX, y, i); +set_index: + return INDEX(x, y); } -#define PI2 6.283184 - static void format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) { @@ -600,11 +587,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 / (PI2 * frequency * zi); + value = -1 / (2 * M_PI * frequency * zi); } else { prefix = 'H'; - value = zi / (PI2 * frequency); + value = zi / (2 * M_PI * frequency); } chsnprintf(buf, len, "%F"S_OHM" %F%c", zr, value, prefix); break; @@ -758,46 +745,44 @@ static float distance_of_index(int idx) { return distance * velocity_factor; } - static inline void mark_map(int x, int y) { - if (y >= 0 && y < 8 && x >= 0 && x < 16) + if (y >= 0 && y < MAX_MARKMAP_Y && x >= 0 && x < MAX_MARKMAP_X) markmap[current_mappage][y] |= 1<> 5; - int n0 = y0 >> 5; + int m0 = x0 / CELLWIDTH; + int n0 = y0 / CELLHEIGHT; int i; mark_map(m0, n0); for (i = 1; i < sweep_points; i++) { int x1 = CELL_X(trace_index[t][i]); int y1 = CELL_Y(trace_index[t][i]); - int m1 = x1 >> 5; - int n1 = y1 >> 5; + int m1 = x1 / CELLWIDTH; + int n1 = y1 / CELLHEIGHT; while (m0 != m1 || n0 != n1) { if (m0 == m1) { if (n0 < n1) n0++; else n0--; } else if (n0 == n1) { if (m0 < m1) m0++; else m0--; } else { - int x = (m0 < m1) ? (m0 + 1)<<5 : m0<<5; - int y = (n0 < n1) ? (n0 + 1)<<5 : n0<<5; + int x = ((m0 < m1) ? (m0 + 1) : m0) * CELLWIDTH; + int y = ((n0 < n1) ? (n0 + 1) : n0) * CELLHEIGHT; int sgn = (n0 < n1) ? 1 : -1; if (sgn*(y-y0)*(x1-x0) < sgn*(x-x0)*(y1-y0)) { if (m0 < m1) m0++; @@ -843,38 +828,23 @@ mark_cells_from_index(void) } } -void plot_into_index(float measured[2][POINTS_COUNT][2]) +static inline void +markmap_upperarea(void) { - int i, t; - for (i = 0; i < sweep_points; i++) { - int x = (i * (WIDTH-1) + sweep_points/2) / (sweep_points-1); - for (t = 0; t < TRACES_MAX; t++) { - if (!trace[t].enabled) - continue; - int n = trace[t].channel; - trace_index[t][i] = trace_into_index(x, t, i, measured[n]); - } - } -#if 0 - for (t = 0; t < TRACES_MAX; t++) - if (trace[t].enabled && trace[t].polar) - quicksort(trace_index[t], 0, sweep_points); -#endif - - mark_cells_from_index(); - markmap_all_markers(); + // Hardcoded, Text info from upper area + invalidateRect(0, 0, AREA_WIDTH_NORMAL, 31); } -const uint8_t INSIDE = 0b0000; -const uint8_t LEFT = 0b0001; -const uint8_t RIGHT = 0b0010; -const uint8_t BOTTOM = 0b0100; -const uint8_t TOP = 0b1000; +#define INSIDE 0b0000; +#define LEFT 0b0001; +#define RIGHT 0b0010; +#define BOTTOM 0b0100; +#define TOP 0b1000; -inline static uint8_t +static uint32_t _compute_outcode(int w, int h, int x, int y) { - uint8_t code = 0; + uint32_t code = INSIDE; if (x < 0) { code |= LEFT; } else @@ -893,53 +863,32 @@ _compute_outcode(int w, int h, int x, int y) static void cell_drawline(int w, int h, int x0, int y0, int x1, int y1, int c) { - uint8_t outcode0 = _compute_outcode(w, h, x0, y0); - uint8_t outcode1 = _compute_outcode(w, h, x1, y1); - - if (outcode0 & outcode1) { + uint32_t outcode1 = _compute_outcode(w, h, x0, y0); + uint32_t outcode2 = _compute_outcode(w, h, x1, y1); + if (outcode1 & outcode2) { // this line is out of requested area. early return return; } - - if (x0 > x1) { - SWAP(x0, x1); - SWAP(y0, y1); - } - - int dx = x1 - x0; - int dy = y1 - y0; - int sy = dy > 0 ? 1 : -1; - int e = 0; - - dy *= sy; - - if (dx >= dy) { - e = dy * 2 - dx; - while (x0 != x1) { - if (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w) spi_buffer[y0*w+x0] |= c; - x0++; - e += dy * 2; - if (e >= 0) { - e -= dx * 2; - y0 += sy; - } - } - if (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w) spi_buffer[y0*w+x0] |= c; - } else { - e = dx * 2 - dy; - while (y0 != y1) { - if (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w) spi_buffer[y0*w+x0] |= c; - y0 += sy; - e += dx * 2; - if (e >= 0) { - e -= dy * 2; - x0++; - } - } - if (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w) spi_buffer[y0*w+x0] |= c; + // If outcode1 == 0 && outcode2 == 0, no clipping, not need check + //outcode1+=outcode2; + // modifed Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + int dx = x1 - x0, sx = 1; if (dx < 0) {dx = -dx; sx = -1;} + int dy = y1 - y0, sy = 1; if (dy < 0) {dy = -dy; sy = -1;} + int err = (dx > dy ? dx : -dy) / 2; + + while (1){ + if (//outcode1 == 0 || + (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w)) + spi_buffer[y0*w+x0] |= c; + if (x0 == x1 && y0 == y1) + break; + int e2 = err; + if (e2 > -dx) { err -= dy; x0 += sx; } + if (e2 < dy) { err += dx; y0 += sy; } } } +#if 0 int search_index_range(int x, int y, uint32_t index[POINTS_COUNT], int *i0, int *i1) { @@ -976,157 +925,180 @@ search_index_range(int x, int y, uint32_t index[POINTS_COUNT], int *i0, int *i1) *i1 = j; return TRUE; } +#endif static int -search_index_range_x(int x, uint32_t index[POINTS_COUNT], int *i0, int *i1) +search_index_range_x(int x1, int x2, uint32_t index[POINTS_COUNT], int *i0, int *i1) { int i, j; int head = 0; int tail = sweep_points; - x &= 0x03e0; - i = 0; - while (head < tail) { + int idx_x; + + // Search index point in cell + while (1) { i = (head + tail) / 2; - if (x == CELL_X0(index[i])) - break; - else if (x < CELL_X0(index[i])) { - if (tail == i+1) - break; - tail = i+1; - } else { + idx_x = CELL_X(index[i]); + if (idx_x >= x2){ // index after cell + if (tail == i) + return false; + tail = i; + } + else if (idx_x < x1){ // index before cell if (head == i) - break; + return false; head = i; } + else // index in cell (x =< idx_x < cell_end) + break; } - - if (x != CELL_X0(index[i])) - return FALSE; - j = i; - while (j > 0 && x == CELL_X0(index[j-1])) + // Search index left from point + do{ j--; + }while (j > 0 && x1 <= CELL_X(index[j])); *i0 = j; - j = i; - while (j < POINTS_COUNT-1 && x == CELL_X0(index[j+1])) - j++; - *i1 = j; + // Search index right from point + do{ + i++; + }while (i < sweep_points-1 && CELL_X(index[i]) < x2); + *i1 = i; + return TRUE; } -void +#define REFERENCE_WIDTH 5 +#define REFERENCE_HEIGHT 5 +#define REFERENCE_X_OFFSET 5 +#define REFERENCE_Y_OFFSET 2 + +// Reference bitmap +static const uint8_t reference_bitmap[]={ + 0b11000000, + 0b11110000, + 0b11111100, + 0b11110000, + 0b11000000, +}; + +static void draw_refpos(int w, int h, int x, int y, int c) { - // draw triangle - int i, j; - if (y < -3 || y > 32 + 3) - return; - for (j = 0; j < 3; j++) { - int j0 = 6 - j*2; - for (i = 0; i < j0; i++) { - int x0 = x + i-5; - int y0 = y - j; - int y1 = y + j; - if (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w) - spi_buffer[y0*w+x0] = c; - if (j != 0 && y1 >= 0 && y1 < h && x0 >= 0 && x0 < w) - spi_buffer[y1*w+x0] = c; + int y0=y, j; + for (j=0; j= h) + continue; + int x0=x; + uint8_t bits = reference_bitmap[j]; + while (bits){ + if (x0 >= 0 && x0 < w) + spi_buffer[y0*w+x0] = (bits&0x80) ? c : DEFAULT_BG_COLOR; + x0++; + bits<<=1; } } } +#define MARKER_WIDTH 7 +#define MARKER_HEIGHT 10 +#define X_MARKER_OFFSET 3 +#define Y_MARKER_OFFSET 10 +static const uint8_t marker_bitmap[]={ + // Marker 1 + 0b11111110, + 0b11101110, + 0b11001110, + 0b11101110, + 0b11101110, + 0b11101110, + 0b11000110, + 0b01111100, + 0b00111000, + 0b00010000, + // Marker 2 + 0b11111110, + 0b11000110, + 0b10111010, + 0b11111010, + 0b11000110, + 0b10111110, + 0b10000010, + 0b01111100, + 0b00111000, + 0b00010000, + // Marker 3 + 0b11111110, + 0b11000110, + 0b10111010, + 0b11100110, + 0b11111010, + 0b10111010, + 0b11000110, + 0b01111100, + 0b00111000, + 0b00010000, + // Marker 4 + 0b11111110, + 0b11110110, + 0b11100110, + 0b11010110, + 0b10110110, + 0b10110110, + 0b10000010, + 0b01110100, + 0b00111000, + 0b00010000, +}; -void -cell_draw_refpos(int m, int n, int w, int h) +static void +draw_marker(int w, int h, int x, int y, int c, int ch) +{ + int y0=y, j; + for (j=0;j= 0 && x0 < w && y0 >= 0 && y0 < h){ + if (bits&0x80) + spi_buffer[y0*w+x0] = c; + else if (force_color) + spi_buffer[y0*w+x0] = DEFAULT_BG_COLOR; + } + x0++; + bits<<=1; + } + } +} + +static void +markmap_marker(int marker) { - int x0 = m * CELLWIDTH; - int y0 = n * CELLHEIGHT; int t; + if (!markers[marker].enabled) + return; for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - if (trace[t].type == TRC_SMITH || trace[t].type == TRC_POLAR) - continue; - int x = 0 - x0 +CELLOFFSETX; - int y = 10*GRIDY - floatToInt((get_trace_refpos(t) * GRIDY)) - y0; - if (x > -5 && x < w && y >= -3 && y < h+3) - draw_refpos(w, h, x, y, config.trace_color[t]); + uint32_t index = trace_index[t][markers[marker].index]; + int x = CELL_X(index) - X_MARKER_OFFSET; + int y = CELL_Y(index) - Y_MARKER_OFFSET; + invalidateRect(x, y, x+MARKER_WIDTH-1, y+MARKER_HEIGHT-1); } } -#define MARKER_WIDTH 7 -#define MARKER_HEIGHT 10 -#define X_MARKER_OFFSET 3 -#define Y_MARKER_OFFSET 10 -static const uint8_t marker_bitmap[]={ - // Marker 1 - 0b11111110, - 0b11101110, - 0b11001110, - 0b11101110, - 0b11101110, - 0b11101110, - 0b11000110, - 0b01111100, - 0b00111000, - 0b00010000, - // Marker 2 - 0b11111110, - 0b11000110, - 0b10111010, - 0b11111010, - 0b11000110, - 0b10111110, - 0b10000010, - 0b01111100, - 0b00111000, - 0b00010000, - // Marker 3 - 0b11111110, - 0b11000110, - 0b10111010, - 0b11100110, - 0b11111010, - 0b10111010, - 0b11000110, - 0b01111100, - 0b00111000, - 0b00010000, - // Marker 4 - 0b11111110, - 0b11110110, - 0b11100110, - 0b11010110, - 0b10110110, - 0b10110110, - 0b10000010, - 0b01110100, - 0b00111000, - 0b00010000, -}; - -static void draw_marker(int w, int h, int x, int y, int c, int ch) +static void +markmap_all_markers(void) { - int y0=y; - for (int j=0;j= 0 && x0 < w && y0 >= 0 && y0 < h) - { - if (bits&0x80) - spi_buffer[y0*w+x0] = c; - else if (force_color) - spi_buffer[y0*w+x0] = DEFAULT_BG_COLOR; - } - x0++; - bits<<=1; - } - } + int i; + for (i = 0; i < MARKERS_MAX; i++) { + if (!markers[i].enabled) + continue; + markmap_marker(i); + } + markmap_upperarea(); } void @@ -1167,10 +1139,7 @@ marker_search(void) void set_marker_search(int mode) { - if (mode == 0) - compare = greater; - else - compare = lesser; + compare = (mode == 0) ? greater : lesser; } int @@ -1237,14 +1206,15 @@ search_nearest_index(int x, int y, int t) int min_d = 1000; int i; for (i = 0; i < sweep_points; i++) { - int16_t dx = x - CELL_X(index[i]) - OFFSETX; - int16_t dy = y - CELL_Y(index[i]) - OFFSETY; + int16_t dx = x - CELL_X(index[i]); + int16_t dy = y - CELL_Y(index[i]); if (dx < 0) dx = -dx; if (dy < 0) dy = -dy; if (dx > 20 || dy > 20) continue; int d = dx*dx + dy*dy; if (d < min_d) { + min_d = d; min_i = i; } } @@ -1253,207 +1223,172 @@ search_nearest_index(int x, int y, int t) } void -cell_draw_markers(int m, int n, int w, int h) +plot_into_index(float measured[2][POINTS_COUNT][2]) { - int t, i; - for (i = 0; i < MARKERS_MAX; i++) { - if (!markers[i].enabled) - continue; - for (t = 0; t < TRACES_MAX; t++) { - if (!trace[t].enabled) - continue; - uint32_t index = trace_index[t][markers[i].index]; - int x = CELL_X(index) - m * CELLWIDTH - X_MARKER_OFFSET; - int y = CELL_Y(index) - n * CELLHEIGHT - Y_MARKER_OFFSET; - - if (x >=-MARKER_WIDTH && x < w + MARKER_WIDTH && y >= -MARKER_HEIGHT && y < h + MARKER_HEIGHT) - draw_marker(w, h, x, y, config.trace_color[t], i); - } - } -} - -void -markmap_marker(int marker) -{ - int t; - if (!markers[marker].enabled) - return; + int t, i; for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - uint32_t index = trace_index[t][markers[marker].index]; - int x = CELL_X(index); - int y = CELL_Y(index); - int m = x>>5; - int n = y>>5; - mark_map(m, n); - if ((x&31) < 6) - mark_map(m-1, n); - if ((x&31) > 32-6) - mark_map(m+1, n); - if ((y&31) < 12) { - mark_map(m, n-1); - if ((x&31) < 6) - mark_map(m-1, n-1); - if ((x&31) > 32-6) - mark_map(m+1, n-1); - } + int ch = trace[t].channel; + for (i = 0; i < sweep_points; i++) + trace_index[t][i] = trace_into_index(t, i, measured[ch]); } -} +#if 0 + for (t = 0; t < TRACES_MAX; t++) + if (trace[t].enabled && trace[t].polar) + quicksort(trace_index[t], 0, sweep_points); +#endif -void -markmap_all_markers(void) -{ - int i; - for (i = 0; i < MARKERS_MAX; i++) { - if (!markers[i].enabled) - continue; - markmap_marker(i); - } - markmap_upperarea(); + mark_cells_from_index(); + markmap_all_markers(); } - static void draw_cell(int m, int n) { int x0 = m * CELLWIDTH; int y0 = n * CELLHEIGHT; - int x0off = x0 - CELLOFFSETX; int w = CELLWIDTH; int h = CELLHEIGHT; int x, y; - int i0, i1; - int i; + int i0, i1, i; int t; - - if (x0off + w > area_width) - w = area_width - x0off; + // Clip cell by area + if (x0 + w > area_width) + w = area_width - x0; if (y0 + h > area_height) h = area_height - y0; if (w <= 0 || h <= 0) return; - uint16_t grid_mode = 0; - for (t = 0; t < TRACES_MAX; t++) { - if (!trace[t].enabled) - continue; - - if (trace[t].type == TRC_SMITH) - grid_mode |= GRID_SMITH; - //else if (trace[t].type == TRC_ADMIT) - // grid_mode |= GRID_ADMIT; - else if (trace[t].type == TRC_POLAR) - grid_mode |= GRID_POLAR; - else - grid_mode |= GRID_RECTANGULAR; - } - PULSE; + // Clear buffer memset(spi_buffer, DEFAULT_BG_COLOR, sizeof spi_buffer); uint16_t c = config.grid_color; - /* draw grid */ - if (grid_mode & GRID_RECTANGULAR) { - for (x = 0; x < w; x++) { - if (rectangular_grid_x(x+x0off)){ - for (y = 0; y < h; y++) - spi_buffer[y * w + x] = c; + // Draw grid + for (t = 0; t < TRACES_MAX; t++) { + if (!trace[t].enabled) + continue; + uint32_t trace_type = (1<= 0 && x+x0off < WIDTH) - spi_buffer[y * w + 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 * w + x] = c; + } } + continue; } - } - if (grid_mode & (GRID_SMITH|GRID_ADMIT|GRID_POLAR)) { - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - int n = 0; - if (grid_mode & GRID_SMITH) - n = smith_grid(x+x0off, y+y0); - else if (grid_mode & GRID_ADMIT) - n = smith_grid3(x+x0off, y+y0); - //n = smith_grid2(x+x0, y+y0, 0.5); - else if (grid_mode & GRID_POLAR) - n = polar_grid(x+x0off, y+y0); - if (n) - spi_buffer[y * w + x] = c; - } + if(trace_type&(1< 0) - i0--; - if (i1 < POINTS_COUNT-1) - i1++; - for (i = i0; i < i1; i++) { - int x1 = CELL_X(trace_index[t][i]); - int x2 = CELL_X(trace_index[t][i+1]); - int y1 = CELL_Y(trace_index[t][i]); - int y2 = CELL_Y(trace_index[t][i+1]); - int c = config.trace_color[t]; - cell_drawline(w, h, x1 - x0, y1 - y0, x2 - x0, y2 - y0, c); - } + c = config.trace_color[t]; + // draw polar plot (check all points) + i0 = 0; i1=0; + uint32_t trace_type = (1<=0 && x-MARKER_WIDTH=0 && y-MARKER_HEIGHT=0 && x-REFERENCE_WIDTH=0 && y-REFERENCE_HEIGHT +//#include #include @@ -106,28 +106,29 @@ int awd_count; #define KP_DONE 1 #define KP_CANCEL 2 -char kp_buf[NUMINPUT_LEN+1]; -int8_t kp_index = 0; - -void ui_mode_normal(void); -void ui_mode_menu(void); -void ui_mode_numeric(int _keypad_mode); -void ui_mode_keypad(int _keypad_mode); -void draw_menu(void); -void leave_ui_mode(void); -void erase_menu_buttons(void); -void ui_process_keypad(void); +static char kp_buf[NUMINPUT_LEN+1]; +static int8_t kp_index = 0; + +static void ui_mode_normal(void); +static void ui_mode_menu(void); +static void ui_mode_numeric(int _keypad_mode); +static void ui_mode_keypad(int _keypad_mode); +static void draw_menu(void); +static void leave_ui_mode(void); +static void erase_menu_buttons(void); +static void ui_process_keypad(void); static void ui_process_numeric(void); +static void menu_move_back(void); static void menu_push_submenu(const menuitem_t *submenu); static int btn_check(void) { int cur_button = READ_PORT() & BUTTON_MASK; - int changed = last_button ^ cur_button; - int status = 0; + int changed = last_button ^ cur_button; + int status = 0; uint32_t ticks = chVTGetSystemTime(); - if (changed & (1<= BUTTON_DEBOUNCE_TICKS) { if (cur_button & (1< TOUCH_THRESHOLD; } -int touch_check(void) +static int +touch_check(void) { int stat = touch_status(); if (stat) { @@ -298,7 +300,8 @@ int touch_check(void) } } -void touch_wait_release(void) +static void +touch_wait_release(void) { int status; /* wait touch release */ @@ -451,10 +454,6 @@ enum { typedef void (*menuaction_cb_t)(int item, uint8_t data); - -static void menu_move_back(void); - - static void menu_calop_cb(int item, uint8_t data) { @@ -563,7 +562,7 @@ choose_active_trace(void) if (trace[uistat.current_trace].enabled) // do nothing return; - for (i = 0; i < 4; i++) + for (i = 0; i < TRACES_MAX; i++) if (trace[i].enabled) { uistat.current_trace = i; return; @@ -669,7 +668,7 @@ menu_scale_cb(int item, uint8_t data) { (void)item; if (data == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { - data = KM_SCALEDELAY; + data = KM_SCALEDELAY; } int status = btn_wait_release(); if (status & EVT_BUTTON_DOWN_LONG) { @@ -815,7 +814,7 @@ menu_marker_smith_cb(int item, uint8_t data) draw_menu(); } -void +static void active_marker_select(int item) { if (item == -1) { @@ -863,7 +862,7 @@ menu_marker_sel_cb(int item, uint8_t data) uistat.lever_mode = LM_MARKER; } -const menuitem_t menu_calop[] = { +static const menuitem_t menu_calop[] = { { MT_CALLBACK, CAL_OPEN, "OPEN", menu_calop_cb }, { MT_CALLBACK, CAL_SHORT, "SHORT", menu_calop_cb }, { MT_CALLBACK, CAL_LOAD, "LOAD", menu_calop_cb }, @@ -1085,7 +1084,8 @@ ensure_selection(void) selection = i-1; } -static void menu_move_back(void) +static void +menu_move_back(void) { if (menu_current_level == 0) return; @@ -1095,7 +1095,8 @@ static void menu_move_back(void) draw_menu(); } -static void menu_push_submenu(const menuitem_t *submenu) +static void +menu_push_submenu(const menuitem_t *submenu) { if (menu_current_level < MENU_STACK_DEPTH_MAX-1) menu_current_level++; @@ -1106,7 +1107,8 @@ static void menu_push_submenu(const menuitem_t *submenu) } /* -static void menu_move_top(void) +static void +menu_move_top(void) { if (menu_current_level == 0) return; @@ -1117,7 +1119,8 @@ static void menu_move_top(void) } */ -void menu_invoke(int item) +static void +menu_invoke(int item) { const menuitem_t *menu = menu_stack[menu_current_level]; menu = &menu[item]; @@ -1147,91 +1150,103 @@ void menu_invoke(int item) } } -#define KP_X(x) (48*(x) + 2 + (320-64-192)) -#define KP_Y(y) (48*(y) + 2) - -#define KP_PERIOD 10 -#define KP_MINUS 11 -#define KP_X1 12 -#define KP_K 13 -#define KP_M 14 -#define KP_G 15 -#define KP_BS 16 -#define KP_INF 17 -#define KP_DB 18 +#define KP_WIDTH 48 +#define KP_HEIGHT 48 +// Key x, y position (0 - 15) on screen +#define KP_GET_X(posx) ((posx)*KP_WIDTH + (320-64-KP_WIDTH*4)) +#define KP_GET_Y(posy) ((posy)*KP_HEIGHT + 12 ) + +// Key names +#define KP_0 0 +#define KP_1 1 +#define KP_2 2 +#define KP_3 3 +#define KP_4 4 +#define KP_5 5 +#define KP_6 6 +#define KP_7 7 +#define KP_8 8 +#define KP_9 9 +#define KP_PERIOD 10 +#define KP_MINUS 11 +#define KP_X1 12 +#define KP_K 13 +#define KP_M 14 +#define KP_G 15 +#define KP_BS 16 +#define KP_INF 17 +#define KP_DB 18 #define KP_PLUSMINUS 19 -#define KP_KEYPAD 20 -#define KP_N 21 -#define KP_P 22 +#define KP_KEYPAD 20 +#define KP_N 21 +#define KP_P 22 -// Set struct data align as BYTE for save flash memory -#pragma pack(push, 1) typedef struct { - uint16_t x, y; - int8_t c; + uint8_t x:4; + uint8_t y:4; + int8_t c; } keypads_t; -#pragma pack(pop) -const keypads_t *keypads; -uint8_t keypads_last_index; - -const keypads_t keypads_freq[] = { - { KP_X(1), KP_Y(3), KP_PERIOD }, - { KP_X(0), KP_Y(3), 0 }, - { KP_X(0), KP_Y(2), 1 }, - { KP_X(1), KP_Y(2), 2 }, - { KP_X(2), KP_Y(2), 3 }, - { KP_X(0), KP_Y(1), 4 }, - { KP_X(1), KP_Y(1), 5 }, - { KP_X(2), KP_Y(1), 6 }, - { KP_X(0), KP_Y(0), 7 }, - { KP_X(1), KP_Y(0), 8 }, - { KP_X(2), KP_Y(0), 9 }, - { KP_X(3), KP_Y(0), KP_G }, - { KP_X(3), KP_Y(1), KP_M }, - { KP_X(3), KP_Y(2), KP_K }, - { KP_X(3), KP_Y(3), KP_X1 }, - { KP_X(2), KP_Y(3), KP_BS }, +static const keypads_t *keypads; +static uint8_t keypads_last_index; + +static const keypads_t keypads_freq[] = { + { 1, 3, KP_PERIOD }, + { 0, 3, KP_0 }, + { 0, 2, KP_1 }, + { 1, 2, KP_2 }, + { 2, 2, KP_3 }, + { 0, 1, KP_4 }, + { 1, 1, KP_5 }, + { 2, 1, KP_6 }, + { 0, 0, KP_7 }, + { 1, 0, KP_8 }, + { 2, 0, KP_9 }, + { 3, 0, KP_G }, + { 3, 1, KP_M }, + { 3, 2, KP_K }, + { 3, 3, KP_X1 }, + { 2, 3, KP_BS }, { 0, 0, -1 } }; -const keypads_t keypads_scale[] = { - { KP_X(1), KP_Y(3), KP_PERIOD }, - { KP_X(0), KP_Y(3), 0 }, - { KP_X(0), KP_Y(2), 1 }, - { KP_X(1), KP_Y(2), 2 }, - { KP_X(2), KP_Y(2), 3 }, - { KP_X(0), KP_Y(1), 4 }, - { KP_X(1), KP_Y(1), 5 }, - { KP_X(2), KP_Y(1), 6 }, - { KP_X(0), KP_Y(0), 7 }, - { KP_X(1), KP_Y(0), 8 }, - { KP_X(2), KP_Y(0), 9 }, - { KP_X(3), KP_Y(3), KP_X1 }, - { KP_X(2), KP_Y(3), KP_BS }, +static const keypads_t keypads_scale[] = { + { 1, 3, KP_PERIOD }, + { 0, 3, KP_0 }, + { 0, 2, KP_1 }, + { 1, 2, KP_2 }, + { 2, 2, KP_3 }, + { 0, 1, KP_4 }, + { 1, 1, KP_5 }, + { 2, 1, KP_6 }, + { 0, 0, KP_7 }, + { 1, 0, KP_8 }, + { 2, 0, KP_9 }, + { 3, 3, KP_X1 }, + { 2, 3, KP_BS }, { 0, 0, -1 } }; -const keypads_t keypads_time[] = { - { KP_X(1), KP_Y(3), KP_PERIOD }, - { KP_X(0), KP_Y(3), 0 }, - { KP_X(0), KP_Y(2), 1 }, - { KP_X(1), KP_Y(2), 2 }, - { KP_X(2), KP_Y(2), 3 }, - { KP_X(0), KP_Y(1), 4 }, - { KP_X(1), KP_Y(1), 5 }, - { KP_X(2), KP_Y(1), 6 }, - { KP_X(0), KP_Y(0), 7 }, - { KP_X(1), KP_Y(0), 8 }, - { KP_X(2), KP_Y(0), 9 }, - { KP_X(3), KP_Y(1), KP_N }, - { KP_X(3), KP_Y(2), KP_P }, - { KP_X(3), KP_Y(3), KP_MINUS }, - { KP_X(2), KP_Y(3), KP_BS }, +static const keypads_t keypads_time[] = { + { 1, 3, KP_PERIOD }, + { 0, 3, KP_0 }, + { 0, 2, KP_1 }, + { 1, 2, KP_2 }, + { 2, 2, KP_3 }, + { 0, 1, KP_4 }, + { 1, 1, KP_5 }, + { 2, 1, KP_6 }, + { 0, 0, KP_7 }, + { 1, 0, KP_8 }, + { 2, 0, KP_9 }, + { 3, 1, KP_N }, + { 3, 2, KP_P }, + { 3, 3, KP_MINUS }, + { 2, 3, KP_BS }, { 0, 0, -1 } }; -const keypads_t * const keypads_mode_tbl[] = { +static const keypads_t * const keypads_mode_tbl[] = { keypads_freq, // start keypads_freq, // stop keypads_freq, // center @@ -1244,27 +1259,29 @@ const keypads_t * const keypads_mode_tbl[] = { keypads_time // scale of delay }; -const char * const keypad_mode_label[] = { +static const char * const keypad_mode_label[] = { "START", "STOP", "CENTER", "SPAN", "CW FREQ", "SCALE", "REFPOS", "EDELAY", "VELOCITY%", "DELAY" }; -void +static void draw_keypad(void) { int i = 0; - while (keypads[i].x) { + while (keypads[i].c>=0) { uint16_t bg = config.menu_normal_color; if (i == selection) bg = config.menu_active_color; setForegroundColor(DEFAULT_MENU_TEXT_COLOR); setBackgroundColor(bg); - ili9341_fill(keypads[i].x, keypads[i].y, 44, 44, bg); - ili9341_drawfont(keypads[i].c, keypads[i].x+14, keypads[i].y+10); + int x = KP_GET_X(keypads[i].x); + int y = KP_GET_Y(keypads[i].y); + ili9341_fill(x+2, y+2, KP_WIDTH-4, KP_HEIGHT-4, bg); + ili9341_drawfont(keypads[i].c, x+(KP_WIDTH-NUM_FONT_GET_WIDTH)/2, y+(KP_HEIGHT-NUM_FONT_GET_HEIGHT)/2); i++; } } -void +static void draw_numeric_area_frame(void) { ili9341_fill(0, 208, 320, 32, DEFAULT_MENU_COLOR); @@ -1274,15 +1291,15 @@ draw_numeric_area_frame(void) //ili9341_drawfont(KP_KEYPAD, 300, 216); } -void +static void draw_numeric_input(const char *buf) { - int i = 0; - int x = 64; + int i; + int x; int focused = FALSE; uint16_t xsim = 0b0010010000000000; - for (i = 0; i < 10 && buf[i]; i++, xsim<<=1) { + 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; int c = buf[i]; @@ -1290,12 +1307,10 @@ draw_numeric_input(const char *buf) c = KP_PERIOD; else if (c == '-') c = KP_MINUS; - else if (c >= '0' && c <= '9') + else// if (c >= '0' && c <= '9') c = c - '0'; - else - c = -1; - if (uistat.digit == 8-i) { + if (ui_mode == UI_NUMERIC && uistat.digit == 8-i) { fg = DEFAULT_SPEC_INPUT_COLOR; focused = TRUE; if (uistat.digit_mode) @@ -1303,18 +1318,17 @@ draw_numeric_input(const char *buf) } setForegroundColor(fg); setBackgroundColor(bg); - if (c >= 0) + if (c >= 0) // c is number ili9341_drawfont(c, x, 208+4); - else if (focused) + else if (focused) // c not number, but focused ili9341_drawfont(0, x, 208+4); - else + else // erase ili9341_fill(x, 208+4, 20, 24, bg); - x += xsim&0x8000 ? 18+8 : 18; - } - if (i < 10) { - ili9341_fill(x, 208+4, 20*(10-i), 24, DEFAULT_MENU_COLOR); + x += xsim&0x8000 ? NUM_FONT_GET_WIDTH+2+8 : NUM_FONT_GET_WIDTH+2; } + // erase last + ili9341_fill(x, 208+4, NUM_FONT_GET_WIDTH+2+8, 24, DEFAULT_MENU_COLOR); } static int @@ -1398,7 +1412,7 @@ menu_item_modify_attribute(const menuitem_t *menu, int item, } } -void +static void draw_menu_buttons(const menuitem_t *menu) { int i = 0; @@ -1430,7 +1444,7 @@ draw_menu_buttons(const menuitem_t *menu) } } -void +static void menu_select_touch(int i) { selection = i; @@ -1440,7 +1454,7 @@ menu_select_touch(int i) menu_invoke(i); } -void +static void menu_apply_touch(void) { int touch_x, touch_y; @@ -1465,25 +1479,25 @@ menu_apply_touch(void) ui_mode_normal(); } -void +static void draw_menu(void) { draw_menu_buttons(menu_stack[menu_current_level]); } -void +static void erase_menu_buttons(void) { ili9341_fill(320-60, 0, 60, 32*7, DEFAULT_BG_COLOR); } -void +static void erase_numeric_input(void) { ili9341_fill(0, 240-32, 320, 32, DEFAULT_BG_COLOR); } -void +static void leave_ui_mode() { if (ui_mode == UI_MENU) { @@ -1496,7 +1510,7 @@ leave_ui_mode() } } -void +static void fetch_numeric_target(void) { switch (keypad_mode) { @@ -1542,7 +1556,8 @@ fetch_numeric_target(void) uistat.previous_value = uistat.value; } -void set_numeric_value(void) +static void +set_numeric_value(void) { switch (keypad_mode) { case KM_START: @@ -1575,7 +1590,7 @@ void set_numeric_value(void) } } -void +static void draw_numeric_area(void) { char buf[10]; @@ -1583,7 +1598,7 @@ draw_numeric_area(void) draw_numeric_input(buf); } -void +static void ui_mode_menu(void) { if (ui_mode == UI_MENU) @@ -1591,13 +1606,13 @@ ui_mode_menu(void) ui_mode = UI_MENU; /* narrowen plotting area */ - area_width = AREA_WIDTH_NORMAL - (64-8); - area_height = HEIGHT+1; + area_width = AREA_WIDTH_NORMAL - 60; + area_height = AREA_HEIGHT_NORMAL; ensure_selection(); draw_menu(); } -void +static void ui_mode_numeric(int _keypad_mode) { if (ui_mode == UI_NUMERIC) @@ -1609,14 +1624,14 @@ ui_mode_numeric(int _keypad_mode) keypad_mode = _keypad_mode; ui_mode = UI_NUMERIC; area_width = AREA_WIDTH_NORMAL; - area_height = 240-32;//HEIGHT - 32; + area_height = 240-32;//AREA_HEIGHT_NORMAL - 32; draw_numeric_area_frame(); fetch_numeric_target(); draw_numeric_area(); } -void +static void ui_mode_keypad(int _keypad_mode) { if (ui_mode == UI_KEYPAD) @@ -1631,7 +1646,7 @@ ui_mode_keypad(int _keypad_mode) keypads_last_index = i; ui_mode = UI_KEYPAD; - area_width = AREA_WIDTH_NORMAL - (64-8); + area_width = AREA_WIDTH_NORMAL - 60; area_height = HEIGHT - 32; draw_menu(); draw_keypad(); @@ -1639,14 +1654,14 @@ ui_mode_keypad(int _keypad_mode) draw_numeric_input(""); } -void +static void ui_mode_normal(void) { if (ui_mode == UI_NORMAL) return; - area_width = AREA_WIDTH_NORMAL; - area_height = HEIGHT+1; + area_width = AREA_WIDTH_NORMAL; + area_height = AREA_HEIGHT_NORMAL; leave_ui_mode(); ui_mode = UI_NORMAL; } @@ -1676,16 +1691,14 @@ lever_move_marker(int status) static void lever_search_marker(int status) { + int i = -1; if (active_marker >= 0) { - if (status & EVT_DOWN) { - int i = marker_search_left(markers[active_marker].index); - if (i != -1) - markers[active_marker].index = i; - } else if (status & EVT_UP) { - int i = marker_search_right(markers[active_marker].index); - if (i != -1) - markers[active_marker].index = i; - } + if (status & EVT_DOWN) + i = marker_search_left(markers[active_marker].index); + else if (status & EVT_UP) + i = marker_search_right(markers[active_marker].index); + if (i != -1) + markers[active_marker].index = i; redraw_marker(active_marker, TRUE); } } @@ -1748,7 +1761,7 @@ ui_process_normal(void) case LM_MARKER: lever_move_marker(status); break; case LM_SEARCH: lever_search_marker(status); break; case LM_CENTER: lever_move_center(status); break; - case LM_SPAN: lever_zoom_span(status); break; + case LM_SPAN: lever_zoom_span(status); break; } } } @@ -1768,14 +1781,13 @@ ui_process_menu(void) if (menu_stack[menu_current_level][selection+1].type == MT_NONE) goto menuclose; selection++; - draw_menu(); } if (status & EVT_DOWN) { if (selection == 0) goto menuclose; selection--; - draw_menu(); } + draw_menu(); status = btn_wait_release(); } while (status != 0); } @@ -1867,9 +1879,11 @@ keypad_apply_touch(void) touch_position(&touch_x, &touch_y); - while (keypads[i].x) { - if (keypads[i].x-2 < touch_x && touch_x < keypads[i].x+44+2 - && keypads[i].y-2 < touch_y && touch_y < keypads[i].y+44+2) { + while (keypads[i].c>=0) { + int x = KP_GET_X(keypads[i].x); + int y = KP_GET_Y(keypads[i].y); + if (x < touch_x && touch_x < x+KP_WIDTH + && y < touch_y && touch_y < y+KP_HEIGHT) { // draw focus selection = i; draw_keypad(); @@ -1951,35 +1965,28 @@ ui_process_numeric(void) do { if (uistat.digit_mode) { if (status & EVT_DOWN) { - if (uistat.digit < 8) { + if (uistat.digit < 8) uistat.digit++; - draw_numeric_area(); - } else { + else goto exit; - } } if (status & EVT_UP) { - if (uistat.digit > 0) { + if (uistat.digit > 0) uistat.digit--; - draw_numeric_area(); - } else { + else goto exit; - } } } else { int32_t step = 1; int n; for (n = uistat.digit; n > 0; n--) step *= 10; - if (status & EVT_DOWN) { + if (status & EVT_DOWN) uistat.value += step; - draw_numeric_area(); - } - if (status & EVT_UP) { + if (status & EVT_UP) uistat.value -= step; - draw_numeric_area(); - } } + draw_numeric_area(); status = btn_wait_release(); } while (status != 0); } @@ -1992,7 +1999,7 @@ ui_process_numeric(void) ui_mode_normal(); } -void +static void ui_process_keypad(void) { int status; @@ -2004,20 +2011,13 @@ ui_process_keypad(void) if (status & (EVT_UP|EVT_DOWN)) { int s = status; do { - if (s & EVT_UP) { - selection--; - if (selection < 0) + if (s & EVT_UP) + if (--selection < 0) selection = keypads_last_index; - draw_keypad(); - } - if (s & EVT_DOWN) { - selection++; - if (keypads[selection].c < 0) { - // reaches to tail + if (s & EVT_DOWN) + if (++selection > keypads_last_index) selection = 0; - } - draw_keypad(); - } + draw_keypad(); s = btn_wait_release(); } while (s != 0); } @@ -2086,12 +2086,6 @@ drag_marker(int t, int m) } while(status != EVT_TOUCH_RELEASED); } -static int -sq_distance(int x0, int y0) -{ - return x0*x0 + y0*y0; -} - static int touch_pickup_marker(void) { @@ -2101,18 +2095,19 @@ touch_pickup_marker(void) touch_x -= OFFSETX; touch_y -= OFFSETY; - for (m = 0; m < 4; m++) { + for (m = 0; m < MARKERS_MAX; m++) { if (!markers[m].enabled) continue; - for (t = 0; t < 4; t++) { + for (t = 0; t < TRACES_MAX; t++) { int x, y; if (!trace[t].enabled) continue; marker_position(m, t, &x, &y); - - if (sq_distance(x - touch_x, y - touch_y) < 400) { + x-=touch_x; + y-=touch_y; + if ((x*x+y*y) < 20*20) { if (active_marker != m) { previous_marker = active_marker; active_marker = m; @@ -2223,7 +2218,7 @@ static const GPTConfig gpt3cfg = { 0 }; -void +static void test_touch(int *x, int *y) { adc_stop(ADC1); From 863691c554606713cd37072e06e0af58676448bb Mon Sep 17 00:00:00 2001 From: TT Date: Sat, 22 Feb 2020 12:24:32 +0900 Subject: [PATCH 04/65] fix: adjust spaces frequency and marker values --- plot.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/plot.c b/plot.c index f5ef8ea..f580cf4 100644 --- a/plot.c +++ b/plot.c @@ -623,7 +623,7 @@ trace_get_value_string(int t, char *buf, int len, float array[POINTS_COUNT][2], v = logmag(coeff); break; case TRC_PHASE: - format = "%.3f"S_DEGREE; + format = "%.1f"S_DEGREE; v = phase(coeff); break; case TRC_DELAY: @@ -741,7 +741,7 @@ trace_get_info(int t, char *buf, int len) if (scale != 1.0) return chsnprintf(buf, len, "%s %.1fFS", name, scale); else - return chsnprintf(buf, len, name); + return chsnprintf(buf, len, "%s ", name); default: return chsnprintf(buf, len, "%s %F/", name, scale); } @@ -1584,7 +1584,7 @@ cell_draw_marker_info(int m, int n, int w, int h) cell_drawstring(w, h, buf, xpos, ypos); xpos += 67; if (uistat.marker_delta && mk != active_marker) - trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); + trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); else trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index); setForegroundColor(DEFAULT_FG_COLOR); @@ -1654,7 +1654,7 @@ cell_draw_marker_info(int m, int n, int w, int h) if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { //frequency_string(buf, sizeof buf, frequencies[idx], ""); - chsnprintf(buf, sizeof buf, "%16qHz", frequencies[idx]); + chsnprintf(buf, sizeof buf, "%qHz", frequencies[idx]); } else { chsnprintf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx), distance_of_index(idx)); } @@ -1682,13 +1682,13 @@ draw_frequencies(void) char buf2[32];buf2[0]=0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { if (frequency0 < frequency1) { - chsnprintf(buf1, sizeof(buf1), " START %16qHz", frequency0); - chsnprintf(buf2, sizeof(buf2), "STOP %16qHz", frequency1); + chsnprintf(buf1, sizeof(buf1), " START %qHz", frequency0); + chsnprintf(buf2, sizeof(buf2), " STOP %qHz", frequency1); } else if (frequency0 > frequency1) { - chsnprintf(buf1, sizeof(buf1), " CENTER %16qHz", frequency0/2 + frequency1/2); - chsnprintf(buf2, sizeof(buf2), "SPAN %16qHz", frequency0 - frequency1); + chsnprintf(buf1, sizeof(buf1), " CENTER %qHz", frequency0/2 + frequency1/2); + chsnprintf(buf2, sizeof(buf2), " SPAN %qHz", frequency0 - frequency1); } else { - chsnprintf(buf1, sizeof(buf1), " CW %16qHz", frequency0); + chsnprintf(buf1, sizeof(buf1), " CW %qHz", frequency0); } } else { chsnprintf(buf1, sizeof(buf1), " START 0s"); @@ -1697,8 +1697,10 @@ draw_frequencies(void) setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); ili9341_fill(0, 232, 320, 8, DEFAULT_BG_COLOR); - if (uistat.lever_mode == LM_SPAN || uistat.lever_mode == LM_CENTER) + if (uistat.lever_mode == LM_CENTER) buf1[0] = S_SARROW[0]; + if (uistat.lever_mode == LM_SPAN) + buf2[0] = S_SARROW[0]; ili9341_drawstring(buf1, OFFSETX, 232); ili9341_drawstring(buf2, 200, 232); } From fb3c9cf82ff2e354f1b560131c76c08e11518678 Mon Sep 17 00:00:00 2001 From: TT Date: Sat, 22 Feb 2020 22:40:06 +0900 Subject: [PATCH 05/65] fix: adjust width of space and triangle --- Font5x7.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Font5x7.c b/Font5x7.c index 0a3a828..a69bcc7 100644 --- a/Font5x7.c +++ b/Font5x7.c @@ -493,7 +493,7 @@ const uint8_t x5x7_bits[127*7] = |** | |* | +--------+ */ - 0b10000000|CHAR5x7_WIDTH_5px, + 0b10000000|CHAR5x7_WIDTH_4px, 0b11000000, 0b11100000, 0b11110000, @@ -645,7 +645,7 @@ const uint8_t x5x7_bits[127*7] = | | | | +--------+ */ - 0b00000000|CHAR5x7_WIDTH_3px, + 0b00000000|CHAR5x7_WIDTH_4px, 0b00000000, 0b00000000, 0b00000000, From 93d1233d8b72d6c68a7dd3d8dd77b98e048e28c9 Mon Sep 17 00:00:00 2001 From: TT Date: Sat, 22 Feb 2020 22:41:50 +0900 Subject: [PATCH 06/65] feat: change the operations to select lever mode --- main.c | 4 ++-- nanovna.h | 8 +++++++ plot.c | 12 ++++++----- ui.c | 62 +++++++++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/main.c b/main.c index 795d187..c8e6369 100644 --- a/main.c +++ b/main.c @@ -914,9 +914,9 @@ set_sweep_frequency(int type, uint32_t freq) break; case ST_CENTER: freq_mode_centerspan(); - uint32_t center = frequency0/2 + frequency1/2; + uint32_t center = FREQ_CENTER(); if (center != freq) { - uint32_t span = frequency0 - frequency1; + uint32_t span = FREQ_SPAN(); ensure_edit_config(); if (freq < START_MIN + span/2) { span = (freq - START_MIN) * 2; diff --git a/nanovna.h b/nanovna.h index a1b490c..badde52 100644 --- a/nanovna.h +++ b/nanovna.h @@ -371,6 +371,14 @@ 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_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); const properties_t *caldata_ref(int id); diff --git a/plot.c b/plot.c index f580cf4..901c248 100644 --- a/plot.c +++ b/plot.c @@ -1467,7 +1467,9 @@ draw_all_cells(bool flush_markmap) void draw_all(bool flush) { - if (redraw_request & REDRAW_CELLS) + if (redraw_request & REDRAW_MARKER) + markmap_upperarea(); + if (redraw_request & (REDRAW_CELLS | REDRAW_MARKER)) draw_all_cells(flush); if (redraw_request & REDRAW_FREQUENCY) draw_frequencies(); @@ -1681,12 +1683,12 @@ draw_frequencies(void) char buf1[32]; char buf2[32];buf2[0]=0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { - if (frequency0 < frequency1) { + if (FREQ_IS_STARTSTOP()) { chsnprintf(buf1, sizeof(buf1), " START %qHz", frequency0); chsnprintf(buf2, sizeof(buf2), " STOP %qHz", frequency1); - } else if (frequency0 > frequency1) { - chsnprintf(buf1, sizeof(buf1), " CENTER %qHz", frequency0/2 + frequency1/2); - chsnprintf(buf2, sizeof(buf2), " SPAN %qHz", frequency0 - frequency1); + } else if (FREQ_IS_CENTERSPAN()) { + chsnprintf(buf1, sizeof(buf1), " CENTER %qHz", FREQ_CENTER()); + chsnprintf(buf2, sizeof(buf2), " SPAN %qHz", FREQ_SPAN()); } else { chsnprintf(buf1, sizeof(buf1), " CW %qHz", frequency0); } diff --git a/ui.c b/ui.c index c27b354..d367ef6 100644 --- a/ui.c +++ b/ui.c @@ -439,6 +439,15 @@ enter_dfu(void) NVIC_SystemReset(); } +static void +select_lever_mode(int mode) +{ + if (uistat.lever_mode != mode) { + uistat.lever_mode = mode; + redraw_request |= REDRAW_FREQUENCY | REDRAW_MARKER; + } +} + // type of menu item enum { MT_NONE, @@ -625,7 +634,7 @@ menu_transform_cb(int item, uint8_t data) (void)item; (void)data; domain_mode ^= DOMAIN_TIME; - uistat.lever_mode = LM_MARKER; + select_lever_mode(LM_MARKER); draw_frequencies(); ui_mode_normal(); } @@ -692,7 +701,6 @@ menu_stimulus_cb(int item, uint8_t data) case 2: /* CENTER */ case 3: /* SPAN */ case 4: /* CW */ - uistat.lever_mode = item == 3 ? LM_SPAN : LM_CENTER; status = btn_wait_release(); if (status & EVT_BUTTON_DOWN_LONG) { ui_mode_numeric(item); @@ -803,7 +811,7 @@ menu_marker_search_cb(int item, uint8_t data) } draw_menu(); redraw_marker(active_marker, TRUE); - uistat.lever_mode = LM_SEARCH; + select_lever_mode(LM_SEARCH); } static void @@ -860,7 +868,6 @@ menu_marker_sel_cb(int item, uint8_t data) } redraw_marker(active_marker, TRUE); draw_menu(); - uistat.lever_mode = LM_MARKER; } const menuitem_t menu_calop[] = { @@ -1724,15 +1731,15 @@ lever_zoom_span(int status) } static void -lever_move_center(int status) +lever_move(int status, int mode) { - uint32_t center = get_sweep_frequency(ST_CENTER); + uint32_t center = get_sweep_frequency(mode); uint32_t span = get_sweep_frequency(ST_SPAN); span = step_round(span / 3); if (status & EVT_UP) { - set_sweep_frequency(ST_CENTER, center + span); + set_sweep_frequency(mode, center + span); } else if (status & EVT_DOWN) { - set_sweep_frequency(ST_CENTER, center - span); + set_sweep_frequency(mode, center - span); } } @@ -1747,8 +1754,15 @@ ui_process_normal(void) switch (uistat.lever_mode) { case LM_MARKER: lever_move_marker(status); break; case LM_SEARCH: lever_search_marker(status); break; - case LM_CENTER: lever_move_center(status); break; - case LM_SPAN: lever_zoom_span(status); break; + case LM_CENTER: + lever_move(status, FREQ_IS_STARTSTOP() ? ST_START : ST_CENTER); + break; + case LM_SPAN: + if (FREQ_IS_STARTSTOP()) + lever_move(status, ST_STOP); + else + lever_zoom_span(status); + break; } } } @@ -2120,7 +2134,8 @@ touch_pickup_marker(void) } // select trace uistat.current_trace = t; - + select_lever_mode(LM_MARKER); + // drag marker until release drag_marker(t, m); return TRUE; @@ -2131,6 +2146,27 @@ touch_pickup_marker(void) return FALSE; } +static int +touch_lever_mode_select(void) +{ + int touch_x, touch_y; + touch_position(&touch_x, &touch_y); + if (touch_y > HEIGHT) { + if (touch_x < 160) { + select_lever_mode(LM_CENTER); + } else { + select_lever_mode(LM_SPAN); + } + return TRUE; + } + + if (touch_y < 15) { + select_lever_mode(LM_MARKER); + return TRUE; + } + + return FALSE; + } static void ui_process_touch(void) @@ -2145,6 +2181,10 @@ void ui_process_touch(void) if (touch_pickup_marker()) { break; + } else if (touch_lever_mode_select()) { + draw_all(FALSE); + touch_wait_release(); + break; } touch_wait_release(); From 39f997f7d43a9627e917e8526ec341079a88dd6b Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 23 Feb 2020 00:16:54 +0900 Subject: [PATCH 07/65] fix: default scale factor --- main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index c9c7e83..d0bc1f3 100644 --- a/main.c +++ b/main.c @@ -706,10 +706,10 @@ properties_t current_props = { ._frequency1 = 900000000, // end = 900MHz ._sweep_points = POINTS_COUNT, ._trace = {/*enable, type, channel, reserved, scale, refpos*/ - { 1, TRC_LOGMAG, 0, 0, 1.0, 9.0 }, - { 1, TRC_LOGMAG, 1, 0, 1.0, 9.0 }, + { 1, TRC_LOGMAG, 0, 0, 10.0, 9.0 }, + { 1, TRC_LOGMAG, 1, 0, 10.0, 9.0 }, { 1, TRC_SMITH, 0, 0, 1.0, 0.0 }, - { 1, TRC_PHASE, 1, 0, 1.0, 5.0 } + { 1, TRC_PHASE, 1, 0, 90.0, 5.0 } }, ._markers = { { 1, 30, 0 }, { 0, 40, 0 }, { 0, 60, 0 }, { 0, 80, 0 } From 8e8bc6924e1556974ef2859e29178bb2be3e3e91 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 23 Feb 2020 01:48:22 +0900 Subject: [PATCH 08/65] fix: update checksum --- flash.c | 12 ++++++------ nanovna.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/flash.c b/flash.c index 01f58f1..ee63668 100644 --- a/flash.c +++ b/flash.c @@ -64,6 +64,7 @@ void flash_unlock(void) FLASH->KEYR = 0xCDEF89AB; } +#define rotate(x) ((x<<1) | (x&(1<<31)?1:0)) static uint32_t checksum(const void *start, size_t len) @@ -72,7 +73,7 @@ checksum(const void *start, size_t len) uint32_t *tail = (uint32_t*)(start + len); uint32_t value = 0; while (p < tail) - value ^= *p++; + value = rotate(value) | *p++; return value; } @@ -89,8 +90,7 @@ config_save(void) int count = sizeof(config_t) / sizeof(uint16_t); config.magic = CONFIG_MAGIC; - config.checksum = 0; - config.checksum = checksum(&config, sizeof config); + config.checksum = checksum(&config, sizeof config - sizeof config.checksum); flash_unlock(); @@ -114,7 +114,7 @@ config_recall(void) if (src->magic != CONFIG_MAGIC) return -1; - if (checksum(src, sizeof(config_t)) != 0) + if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) return -1; /* duplicated saved data onto sram to be able to modify marker/trace */ @@ -182,7 +182,7 @@ caldata_recall(int id) if (src->magic != CONFIG_MAGIC) return -1; - if (checksum(src, sizeof(properties_t)) != 0) + if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) return -1; /* active configuration points to save data on flash memory */ @@ -205,7 +205,7 @@ caldata_ref(int id) if (src->magic != CONFIG_MAGIC) return NULL; - if (checksum(src, sizeof(properties_t)) != 0) + if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) return NULL; return src; } diff --git a/nanovna.h b/nanovna.h index 17add41..a19d6fa 100644 --- a/nanovna.h +++ b/nanovna.h @@ -215,7 +215,7 @@ typedef struct { uint32_t harmonic_freq_threshold; uint8_t _reserved[24]; - int32_t checksum; + uint32_t checksum; } config_t; extern config_t config; @@ -352,7 +352,7 @@ typedef struct { uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */ uint8_t _marker_smith_format; uint8_t _reserved[50]; - int32_t checksum; + uint32_t checksum; } properties_t; //sizeof(properties_t) == 0x1200 From 1b62741a3dcdf647c528c1797e2aabf40d0fe39b Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 23 Feb 2020 08:20:01 +0900 Subject: [PATCH 09/65] fix: erase on DEL key in the vna shell --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index d0bc1f3..af76608 100644 --- a/main.c +++ b/main.c @@ -2090,7 +2090,7 @@ static int VNAShell_readLine(char *line, int max_size){ if (streamRead(shell_stream, &c, 1) == 0) return 0; // Backspace - if (c == 8) { + if (c == 8 || c == 0x7f) { if (ptr != line) { static const char backspace[] = {0x08,0x20,0x08,0x00}; shell_printf(shell_stream, backspace); From 681272c2535be34d005604885975446ea522a0e0 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 23 Feb 2020 10:43:46 +0900 Subject: [PATCH 10/65] fix: update year of the copyright --- ui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui.c b/ui.c index 232a5b6..4177c97 100644 --- a/ui.c +++ b/ui.c @@ -403,7 +403,7 @@ show_version(void) ili9341_drawstring_size(BOARD_NAME, x, y, 4); y += 25; - ili9341_drawstring("2016-2019 Copyright @edy555", x, y += 10); + ili9341_drawstring("2016-2020 Copyright @edy555", x, y += 10); ili9341_drawstring("Licensed under GPL. See: https://github.com/ttrftech/NanoVNA", x, y += 10); ili9341_drawstring("Version: " VERSION, x, y += 10); ili9341_drawstring("Build Time: " __DATE__ " - " __TIME__, x, y += 10); From c89cd36f194f6549094ef25cb25a2ff6c3413689 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 23 Feb 2020 11:36:05 +0900 Subject: [PATCH 11/65] fix: checksum --- flash.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/flash.c b/flash.c index ee63668..79ab95e 100644 --- a/flash.c +++ b/flash.c @@ -64,7 +64,7 @@ void flash_unlock(void) FLASH->KEYR = 0xCDEF89AB; } -#define rotate(x) ((x<<1) | (x&(1<<31)?1:0)) +#define rotate(x) (((x)<<1) | ((x)&(1<<31)?1:0)) static uint32_t checksum(const void *start, size_t len) @@ -73,7 +73,7 @@ checksum(const void *start, size_t len) uint32_t *tail = (uint32_t*)(start + len); uint32_t value = 0; while (p < tail) - value = rotate(value) | *p++; + value = rotate(value) + *p++; return value; } @@ -142,8 +142,7 @@ caldata_save(int id) dst = (uint16_t*)saveareas[id]; current_props.magic = CONFIG_MAGIC; - current_props.checksum = 0; - current_props.checksum = checksum(¤t_props, sizeof current_props); + current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum); flash_unlock(); From 7d2708afcefea51a70d363209bb84f2aa6f6f85d Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 23 Feb 2020 11:37:41 +0900 Subject: [PATCH 12/65] feat: paramterize number of y-grid, revert to 8 --- main.c | 8 ++++---- nanovna.h | 17 +++++++++++++---- plot.c | 12 ++++++------ ui.c | 2 ++ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/main.c b/main.c index af76608..c34d85c 100644 --- a/main.c +++ b/main.c @@ -706,10 +706,10 @@ properties_t current_props = { ._frequency1 = 900000000, // end = 900MHz ._sweep_points = POINTS_COUNT, ._trace = {/*enable, type, channel, reserved, scale, refpos*/ - { 1, TRC_LOGMAG, 0, 0, 10.0, 9.0 }, - { 1, TRC_LOGMAG, 1, 0, 10.0, 9.0 }, - { 1, TRC_SMITH, 0, 0, 1.0, 0.0 }, - { 1, TRC_PHASE, 1, 0, 90.0, 5.0 } + { 1, TRC_LOGMAG, 0, 0, 10.0, NGRIDY-1 }, + { 1, TRC_LOGMAG, 1, 0, 10.0, NGRIDY-1 }, + { 1, TRC_SMITH, 0, 0, 1.0, 0 }, + { 1, TRC_PHASE, 1, 0, 90.0, NGRIDY/2 } }, ._markers = { { 1, 30, 0 }, { 0, 40, 0 }, { 0, 60, 0 }, { 0, 80, 0 } diff --git a/nanovna.h b/nanovna.h index a19d6fa..f0a903d 100644 --- a/nanovna.h +++ b/nanovna.h @@ -129,8 +129,6 @@ extern void tlv320aic3204_select(int channel); /* * plot.c */ -// GRIDX calculated depends from frequency span -#define GRIDY 23 // Offset of plot area #define OFFSETX 10 @@ -138,8 +136,19 @@ extern void tlv320aic3204_select(int channel); // WIDTH better be n*(POINTS_COUNT-1) #define WIDTH 300 -// HEIGHT = 10*GRIDY -#define HEIGHT 230 +// HEIGHT = 8*GRIDY +#define HEIGHT 232 + +//#define NGRIDY 10 +#define NGRIDY 8 + +#define FREQUENCIES_XPOS1 OFFSETX +#define FREQUENCIES_XPOS2 200 +#define FREQUENCIES_YPOS (HEIGHT+1) + +// GRIDX calculated depends from frequency span +//#define GRIDY 29 +#define GRIDY (HEIGHT / NGRIDY) // #define CELLOFFSETX 5 diff --git a/plot.c b/plot.c index eb3de6d..3c48dd4 100644 --- a/plot.c +++ b/plot.c @@ -508,7 +508,7 @@ trace_into_index(int t, int i, float array[POINTS_COUNT][2]) int y, x; float *coeff = array[i]; - float refpos = 10 - get_trace_refpos(t); + float refpos = NGRIDY - get_trace_refpos(t); float v = refpos; float scale = 1 / get_trace_scale(t); switch (trace[t].type) { @@ -545,8 +545,8 @@ trace_into_index(int t, int i, float array[POINTS_COUNT][2]) cartesian_scale(coeff[0], coeff[1], &x, &y, scale); goto set_index; } - if (v < 0) v = 0; - if (v > 10) v = 10; + if (v < 0) v = 0; + if (v > NGRIDY) v = NGRIDY; x = (i * (WIDTH) + (sweep_points-1)/2) / (sweep_points-1) + CELLOFFSETX; y = floatToInt(v * GRIDY); set_index: @@ -1367,7 +1367,7 @@ draw_cell(int m, int n) continue; int x = 0 - x0 + CELLOFFSETX - REFERENCE_X_OFFSET; if (x+REFERENCE_WIDTH>=0 && x-REFERENCE_WIDTH=0 && y-REFERENCE_HEIGHT Date: Sun, 23 Feb 2020 15:45:37 +0300 Subject: [PATCH 13/65] Increase main thread stack size (if used as shell, if run some commands get stack limit, example "trace 0 x" command) Decrease interrupt stack size Use __ROR instruction in flash.c for checksum rotate Fix erase background for frequencies string in plot.c Implement getStringIndex function for parse string arguments, now Usage show correct information about used arg, and more easy use strings definitions Example: Need check if string "on" in avaible arguments list "load|open|short|thru|isoln|done|on|off|reset|data|in" getStringIndex("on", "load|open|short|thru|isoln|done|on|off|reset|data|in") return 6 If not found return -1 Not need use if (strcmp() == ...) else .... This usage save some amount of size --- Makefile | 4 +- flash.c | 26 +++-- main.c | 300 +++++++++++++++++++++++++----------------------------- nanovna.h | 6 +- plot.c | 8 +- 5 files changed, 159 insertions(+), 185 deletions(-) diff --git a/Makefile b/Makefile index 73ebbd9..7c8be0c 100644 --- a/Makefile +++ b/Makefile @@ -64,13 +64,13 @@ endif # Stack size to be allocated to the Cortex-M process stack. This stack is # the stack used by the main() thread. ifeq ($(USE_PROCESS_STACKSIZE),) - USE_PROCESS_STACKSIZE = 0x200 + USE_PROCESS_STACKSIZE = 0x280 endif # Stack size to the allocated to the Cortex-M main/exceptions stack. This # stack is used for processing interrupts and exceptions. ifeq ($(USE_EXCEPTIONS_STACKSIZE),) - USE_EXCEPTIONS_STACKSIZE = 0x200 + USE_EXCEPTIONS_STACKSIZE = 0x180 endif # diff --git a/flash.c b/flash.c index 79ab95e..12f2182 100644 --- a/flash.c +++ b/flash.c @@ -32,12 +32,12 @@ static int flash_wait_for_last_operation(void) static void flash_erase_page0(uint32_t page_address) { - flash_wait_for_last_operation(); - FLASH->CR |= FLASH_CR_PER; - FLASH->AR = page_address; - FLASH->CR |= FLASH_CR_STRT; - flash_wait_for_last_operation(); - FLASH->CR &= ~FLASH_CR_PER; + flash_wait_for_last_operation(); + FLASH->CR |= FLASH_CR_PER; + FLASH->AR = page_address; + FLASH->CR |= FLASH_CR_STRT; + flash_wait_for_last_operation(); + FLASH->CR &= ~FLASH_CR_PER; } int flash_erase_page(uint32_t page_address) @@ -50,11 +50,11 @@ int flash_erase_page(uint32_t page_address) void flash_program_half_word(uint32_t address, uint16_t data) { - flash_wait_for_last_operation(); - FLASH->CR |= FLASH_CR_PG; - *(__IO uint16_t*)address = data; - flash_wait_for_last_operation(); - FLASH->CR &= ~FLASH_CR_PG; + flash_wait_for_last_operation(); + FLASH->CR |= FLASH_CR_PG; + *(__IO uint16_t*)address = data; + flash_wait_for_last_operation(); + FLASH->CR &= ~FLASH_CR_PG; } void flash_unlock(void) @@ -64,8 +64,6 @@ void flash_unlock(void) FLASH->KEYR = 0xCDEF89AB; } -#define rotate(x) (((x)<<1) | ((x)&(1<<31)?1:0)) - static uint32_t checksum(const void *start, size_t len) { @@ -73,7 +71,7 @@ checksum(const void *start, size_t len) uint32_t *tail = (uint32_t*)(start + len); uint32_t value = 0; while (p < tail) - value = rotate(value) + *p++; + value = __ROR(value, 31) + *p++; return value; } diff --git a/main.c b/main.c index c34d85c..bac6e3d 100644 --- a/main.c +++ b/main.c @@ -402,6 +402,36 @@ my_atof(const char *p) return x; } +// +// Function used for search substring v in list +// Example need search parameter "center" in "start|stop|center|span|cw" getStringIndex return 2 +// If not found return -1 +// Used for easy parse command arguments +static int getStringIndex(char *v, const char *list){ + int i = 0; + while(1){ + char *p = v; + while (1){ + char c = *list; if (c == '|') c = 0; + if (c == *p++){ + // Found, return index + if (c == 0) return i; + list++; // Compare next symbol + continue; + } + break; // Not equal, break + } + // Set new substring ptr + while (1){ + // End of string, not found + if (*list == 0 ) return -1; + if (*list++ == '|') break; + } + i++; + } + return -1; +} + static void cmd_offset(BaseSequentialStream *chp, int argc, char *argv[]) { if (argc != 1) { @@ -672,19 +702,17 @@ static void (*sample_func)(float *gamma) = calculate_gamma; static void cmd_sample(BaseSequentialStream *chp, int argc, char *argv[]) { - if (argc == 1) { - if (strcmp(argv[0], "ref") == 0) { - sample_func = fetch_amplitude_ref; - return; - } else if (strcmp(argv[0], "ampl") == 0) { - sample_func = fetch_amplitude; - return; - } else if (strcmp(argv[0], "gamma") == 0) { - sample_func = calculate_gamma; - return; - } + if (argc!=1) goto usage; + // 0 1 2 + static const char cmd_sample_list[] = "gamma|ampl|ref"; + switch (getStringIndex(argv[1], cmd_sample_list)){ + case 0:sample_func = calculate_gamma; return; + case 1:sample_func = fetch_amplitude; return; + case 2:sample_func = fetch_amplitude_ref; return; + default:break; } - shell_printf(chp, "usage: sample {gamma|ampl|ref}\r\n"); +usage: + shell_printf(chp, "usage: sample {%s}\r\n", cmd_sample_list); } config_t config = { @@ -1022,21 +1050,15 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) uint32_t value1 = 0; if (argc >=1) value0 = my_atoui(argv[0]); if (argc >=2) value1 = my_atoui(argv[1]); - +#if MAX_FREQ_TYPE!=5 +#error "Sweep mode possibly changed, check cmd_sweep function" +#endif // Parse sweep {start|stop|center|span|cw} {freq(Hz)} + // get enum ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW + static const char sweep_cmd[] = "start|stop|center|span|cw"; if (argc == 2 && value0 == 0) { - int type; - if (strcmp(argv[0], "start") == 0) - type = ST_START; - else if (strcmp(argv[0], "stop") == 0) - type = ST_STOP; - else if (strcmp(argv[0], "center") == 0) - type = ST_CENTER; - else if (strcmp(argv[0], "span") == 0) - type = ST_SPAN; - else if (strcmp(argv[0], "cw") == 0) - type = ST_CW; - else + int type = getStringIndex(argv[0], sweep_cmd); + if (type == -1) goto usage; set_sweep_frequency(type, value1); return; @@ -1049,7 +1071,7 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) return; usage: shell_printf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n"\ - "\tsweep {start|stop|center|span|cw} {freq(Hz)}\r\n"); + "\tsweep {%s} {freq(Hz)}\r\n", sweep_cmd); } @@ -1069,13 +1091,14 @@ eterm_copy(int dst, int src) memcpy(cal_data[dst], cal_data[src], sizeof cal_data[dst]); } - +#if 0 const struct open_model { float c0; float c1; float c2; float c3; } open_model = { 50, 0, -300, 27 }; +#endif #if 0 static void @@ -1405,51 +1428,33 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) shell_printf(chp, "\r\n"); return; } - - char *cmd = argv[0]; - if (strcmp(cmd, "load") == 0) { - cal_collect(CAL_LOAD); - } else if (strcmp(cmd, "open") == 0) { - cal_collect(CAL_OPEN); - } else if (strcmp(cmd, "short") == 0) { - cal_collect(CAL_SHORT); - } else if (strcmp(cmd, "thru") == 0) { - cal_collect(CAL_THRU); - } else if (strcmp(cmd, "isoln") == 0) { - cal_collect(CAL_ISOLN); - } else if (strcmp(cmd, "done") == 0) { - cal_done(); - return; - } else if (strcmp(cmd, "on") == 0) { - cal_status |= CALSTAT_APPLY; - redraw_request |= REDRAW_CAL_STATUS; - return; - } else if (strcmp(cmd, "off") == 0) { - cal_status &= ~CALSTAT_APPLY; - redraw_request |= REDRAW_CAL_STATUS; - return; - } else if (strcmp(cmd, "reset") == 0) { - cal_status = 0; - redraw_request |= REDRAW_CAL_STATUS; - return; - } else if (strcmp(cmd, "data") == 0) { - shell_printf(chp, "%f %f\r\n", cal_data[CAL_LOAD][0][0], cal_data[CAL_LOAD][0][1]); - shell_printf(chp, "%f %f\r\n", cal_data[CAL_OPEN][0][0], cal_data[CAL_OPEN][0][1]); - shell_printf(chp, "%f %f\r\n", cal_data[CAL_SHORT][0][0], cal_data[CAL_SHORT][0][1]); - shell_printf(chp, "%f %f\r\n", cal_data[CAL_THRU][0][0], cal_data[CAL_THRU][0][1]); - shell_printf(chp, "%f %f\r\n", cal_data[CAL_ISOLN][0][0], cal_data[CAL_ISOLN][0][1]); - return; - } else if (strcmp(cmd, "in") == 0) { - int s = 0; - if (argc > 1) - s = my_atoi(argv[1]); - cal_interpolate(s); - redraw_request |= REDRAW_CAL_STATUS; - return; - } else { - shell_printf(chp, "usage: cal [load|open|short|thru|isoln|done|reset|on|off|in]\r\n"); - return; + // 0 1 2 3 4 5 6 7 8 9 10 + static const char cmd_cal_list[] = "load|open|short|thru|isoln|done|on|off|reset|data|in"; + switch (getStringIndex(argv[0], cmd_cal_list)){ + case 0:cal_collect(CAL_LOAD ); return; + case 1:cal_collect(CAL_OPEN ); return; + case 2:cal_collect(CAL_SHORT); return; + case 3:cal_collect(CAL_THRU ); return; + case 4:cal_collect(CAL_ISOLN); return; + case 5:cal_done(); return; + case 6:cal_status|= CALSTAT_APPLY;redraw_request|=REDRAW_CAL_STATUS; return; + case 7:cal_status&=~CALSTAT_APPLY;redraw_request|=REDRAW_CAL_STATUS; return; + case 8:cal_status = 0; redraw_request|=REDRAW_CAL_STATUS; return; + case 9: + shell_printf(chp, "%f %f\r\n", cal_data[CAL_LOAD ][0][0], cal_data[CAL_LOAD ][0][1]); + shell_printf(chp, "%f %f\r\n", cal_data[CAL_OPEN ][0][0], cal_data[CAL_OPEN ][0][1]); + shell_printf(chp, "%f %f\r\n", cal_data[CAL_SHORT][0][0], cal_data[CAL_SHORT][0][1]); + shell_printf(chp, "%f %f\r\n", cal_data[CAL_THRU ][0][0], cal_data[CAL_THRU ][0][1]); + shell_printf(chp, "%f %f\r\n", cal_data[CAL_ISOLN][0][0], cal_data[CAL_ISOLN][0][1]); + return; + case 10: + cal_interpolate((argc > 1) ? my_atoi(argv[1]) : 0); + redraw_request|=REDRAW_CAL_STATUS; + return; + default:break; } + + shell_printf(chp, "usage: cal [%s]\r\n", cmd_cal_list); } static void cmd_save(BaseSequentialStream *chp, int argc, char *argv[]) @@ -1577,11 +1582,6 @@ float get_trace_refpos(int t) return trace[t].refpos; } -typedef struct { - char *tracename; - uint8_t type; -} type_list; - static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) { int t; @@ -1614,50 +1614,44 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) shell_printf(chp, "%d %s %s\r\n", t, type, channel); return; } - static const type_list t_list[] = { - {"logmag", TRC_LOGMAG}, - {"phase", TRC_PHASE}, - {"delay", TRC_DELAY}, - {"smith", TRC_SMITH}, - {"polar", TRC_POLAR}, - {"linear", TRC_LINEAR}, - {"swr", TRC_SWR}, - {"real", TRC_REAL}, - {"imag", TRC_IMAG}, - {"r", TRC_R}, - {"x", TRC_X}, - {"off", TRC_OFF}, - }; - for (uint16_t i=0; i= 0){ + set_trace_type(t, type); + goto check_ch_num; + } + // 0 1 + static const char cmd_scale_ref_list[] = "scale|refpos"; + if (argc >= 3){ + switch (getStringIndex(argv[1], cmd_scale_ref_list)){ + case 0: + //trace[t].scale = my_atof(argv[2]); + set_trace_scale(t, my_atof(argv[2])); + goto exit; + case 1: + //trace[t].refpos = my_atof(argv[2]); + set_trace_refpos(t, my_atof(argv[2])); + goto exit; + default: + goto usage; } } - if (strcmp(argv[1], "scale") == 0 && argc >= 3) { - //trace[t].scale = my_atof(argv[2]); - set_trace_scale(t, my_atof(argv[2])); - goto exit; - } else if (strcmp(argv[1], "refpos") == 0 && argc >= 3) { - //trace[t].refpos = my_atof(argv[2]); - set_trace_refpos(t, my_atof(argv[2])); - goto exit; - } else { - goto usage; - } - - check_ch_num: +check_ch_num: if (argc > 2) { int src = my_atoi(argv[2]); if (src != 0 && src != 1) goto usage; trace[t].channel = src; } - exit: +exit: return; - usage: - shell_printf(chp, "trace {0|1|2|3|all} [logmag|phase|polar|smith|linear|delay|swr|real|imag|r|x|off] [src]\r\n"\ - "trace {0|1|2|3} {scale|refpos} {value}\r\n"); +usage: + shell_printf(chp, "trace {0|1|2|3|all} [%s] [src]\r\n"\ + "trace {0|1|2|3} {%s} {value}\r\n", cmd_type_list, cmd_scale_ref_list); } @@ -1696,7 +1690,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) } } return; - } + } if (strcmp(argv[0], "off") == 0) { active_marker = -1; for (t = 0; t < MARKERS_MAX; t++) @@ -1716,17 +1710,11 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) redraw_request |= REDRAW_MARKER; return; } - if (argc > 1) { - if (strcmp(argv[1], "off") == 0) { - markers[t].enabled = FALSE; - if (active_marker == t) - active_marker = -1; - redraw_request |= REDRAW_MARKER; - } else if (strcmp(argv[1], "on") == 0) { - markers[t].enabled = TRUE; - active_marker = t; - redraw_request |= REDRAW_MARKER; - } else { + static const char cmd_marker_list[] = "on|off"; + switch (getStringIndex(argv[1], cmd_marker_list)){ + case 0: markers[t].enabled = TRUE; active_marker = t; redraw_request |= REDRAW_MARKER; return; + case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = -1; redraw_request|=REDRAW_MARKER; return; + default: // select active marker and move to index markers[t].enabled = TRUE; int index = my_atoi(argv[1]); @@ -1734,11 +1722,10 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) markers[t].frequency = frequencies[index]; active_marker = t; redraw_request |= REDRAW_MARKER; - } + return; } - return; usage: - shell_printf(chp, "marker [n] [off|{index}]\r\n"); + shell_printf(chp, "marker [n] [%s|{index}]\r\n", cmd_marker_list); } static void cmd_touchcal(BaseSequentialStream *chp, int argc, char *argv[]) @@ -1814,33 +1801,24 @@ static void cmd_transform(BaseSequentialStream *chp, int argc, char *argv[]) if (argc == 0) { goto usage; } - + // 0 1 2 3 4 5 6 7 + static const char cmd_transform_list[] = "on|off|impulse|step|bandpass|minimum|normal|maximum"; for (i = 0; i < argc; i++) { - char *cmd = argv[i]; - if (strcmp(cmd, "on") == 0) { - set_domain_mode(DOMAIN_TIME); - } else if (strcmp(cmd, "off") == 0) { - set_domain_mode(DOMAIN_FREQ); - } else if (strcmp(cmd, "impulse") == 0) { - set_timedomain_func(TD_FUNC_LOWPASS_IMPULSE); - } else if (strcmp(cmd, "step") == 0) { - set_timedomain_func(TD_FUNC_LOWPASS_STEP); - } else if (strcmp(cmd, "bandpass") == 0) { - set_timedomain_func(TD_FUNC_BANDPASS); - } else if (strcmp(cmd, "minimum") == 0) { - set_timedomain_window(TD_WINDOW_MINIMUM); - } else if (strcmp(cmd, "normal") == 0) { - set_timedomain_window(TD_WINDOW_NORMAL); - } else if (strcmp(cmd, "maximum") == 0) { - set_timedomain_window(TD_WINDOW_MAXIMUM); - } else { - goto usage; + switch (getStringIndex(argv[i], cmd_transform_list)){ + case 0:set_domain_mode(DOMAIN_TIME);return; + case 1:set_domain_mode(DOMAIN_FREQ);return; + case 2:set_timedomain_func(TD_FUNC_LOWPASS_IMPULSE);return; + case 3:set_timedomain_func(TD_FUNC_LOWPASS_STEP);return; + case 4:set_timedomain_func(TD_FUNC_BANDPASS);return; + case 5:set_timedomain_window(TD_WINDOW_MINIMUM);return; + case 6:set_timedomain_window(TD_WINDOW_NORMAL);return; + case 7:set_timedomain_window(TD_WINDOW_MAXIMUM);return; + default: goto usage; } } return; - usage: - shell_printf(chp, "usage: transform {on|off|impulse|step|bandpass|minimum|normal|maximum} [...]\r\n"); + shell_printf(chp, "usage: transform {%s} [...]\r\n", cmd_transform_list); } static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) @@ -1989,17 +1967,13 @@ static void cmd_vbat(BaseSequentialStream *chp, int argc, char *argv[]) static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { static const char *states[] = {CH_STATE_NAMES}; thread_t *tp; - + (void)argc; (void)argv; - if (argc > 0) { - shellUsage(chp, "threads"); - return; - } - chprintf(chp, "stklimit stack addr refs prio state name\r\n"SHELL_NEWLINE_STR); + chprintf(chp, "stklimit stack addr refs prio state name"VNA_SHELL_NEWLINE_STR); tp = chRegFirstThread(); do { uint32_t stklimit = (uint32_t)tp->wabase; - shell_printf(chp, "%08x %08x %08x %4u %4u %9s %12s"SHELL_NEWLINE_STR, + shell_printf(chp, "%08x %08x %08x %4u %4u %9s %12s"VNA_SHELL_NEWLINE_STR, stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp, (uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state], tp->name == NULL ? "" : tp->name); @@ -2055,7 +2029,7 @@ static const VNAShellCommand commands[] = { "threshold" , cmd_threshold }, { "help" , cmd_help }, #ifdef ENABLE_THREADS_COMMAND -// { "threads" , cmd_threads }, + { "threads" , cmd_threads }, #endif { NULL , NULL } }; @@ -2089,7 +2063,7 @@ static int VNAShell_readLine(char *line, int max_size){ // Return 0 only if stream not active if (streamRead(shell_stream, &c, 1) == 0) return 0; - // Backspace + // Backspace or Delete if (c == 8 || c == 0x7f) { if (ptr != line) { static const char backspace[] = {0x08,0x20,0x08,0x00}; @@ -2162,12 +2136,12 @@ static THD_WORKING_AREA(waThread2, /* cmd_* max stack size + alpha */442); THD_FUNCTION(myshellThread, p) { (void)p; chRegSetThreadName("shell"); - char line[VNA_SHELL_MAX_LENGTH]; + char shell_line[VNA_SHELL_MAX_LENGTH]; shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); while (true) { shell_printf(shell_stream, VNA_SHELL_PROMPT_STR); - if (VNAShell_readLine(line, VNA_SHELL_MAX_LENGTH)) - VNAShell_executeLine(line); + if (VNAShell_readLine(shell_line, VNA_SHELL_MAX_LENGTH)) + VNAShell_executeLine(shell_line); else // Putting a delay in order to avoid an endless loop trying to read an unavailable stream. osalThreadSleepMilliseconds(100); } @@ -2266,12 +2240,12 @@ int main(void) myshellThread, NULL); chThdWait(shelltp); #else - char line[VNA_SHELL_MAX_LENGTH]; + char shell_line[VNA_SHELL_MAX_LENGTH]; shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); do { shell_printf(shell_stream, VNA_SHELL_PROMPT_STR); - if (VNAShell_readLine(line, VNA_SHELL_MAX_LENGTH)) - VNAShell_executeLine(line); + if (VNAShell_readLine(shell_line, VNA_SHELL_MAX_LENGTH)) + VNAShell_executeLine(shell_line); else chThdSleepMilliseconds(200); } while (SDU1.config->usbp->state == USB_ACTIVE); diff --git a/nanovna.h b/nanovna.h index f0a903d..b516545 100644 --- a/nanovna.h +++ b/nanovna.h @@ -71,8 +71,9 @@ extern float measured[2][POINTS_COUNT][2]; void cal_collect(int type); void cal_done(void); +#define MAX_FREQ_TYPE 5 enum { - ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW + ST_START=0, ST_STOP, ST_CENTER, ST_SPAN, ST_CW }; void set_sweep_frequency(int type, uint32_t frequency); @@ -187,8 +188,9 @@ extern const uint16_t numfont16x22[]; #define TRACES_MAX 4 +#define MAX_TRACE_TYPE 12 enum { - TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF + TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF }; // Mask for define rectangular plot #define RECTANGULAR_GRID_MASK ((1< Date: Sun, 23 Feb 2020 15:58:12 +0300 Subject: [PATCH 14/65] Fix default trace refpos set (use NGRIDY value) --- main.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index bac6e3d..b7b0f26 100644 --- a/main.c +++ b/main.c @@ -1505,17 +1505,17 @@ static const struct { uint16_t refpos; float scale_unit; } trace_info[] = { - { "LOGMAG", 9, 10 }, - { "PHASE", 5, 90 }, - { "DELAY", 5, 1e-9 }, - { "SMITH", 0, 1 }, - { "POLAR", 0, 1 }, - { "LINEAR", 0, 0.125 }, - { "SWR", 0, 1 }, - { "REAL", 5, 0.25 }, - { "IMAG", 5, 0.25 }, - { "R", 0, 100 }, - { "X", 5, 100 } + { "LOGMAG", NGRIDY-1, 10.0 }, + { "PHASE", NGRIDY/2, 90.0 }, + { "DELAY", NGRIDY/2, 1e-9 }, + { "SMITH", 0, 1.00 }, + { "POLAR", 0, 1.00 }, + { "LINEAR", 0, 0.125}, + { "SWR", 0, 1.00 }, + { "REAL", NGRIDY/2, 0.25 }, + { "IMAG", NGRIDY/2, 0.25 }, + { "R", NGRIDY/2, 100.0 }, + { "X", NGRIDY/2, 100.0 } }; const char * const trc_channel_name[] = { From 5ee23be06fa1e71b19a5a1c1c3c6c1ec226314ae Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 23 Feb 2020 17:13:52 +0300 Subject: [PATCH 15/65] Add definition of spi_buffer size Add check cell and spi_buffer size --- ili9341.c | 2 +- nanovna.h | 5 ++++- plot.c | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ili9341.c b/ili9341.c index e134025..6372f1c 100644 --- a/ili9341.c +++ b/ili9341.c @@ -21,7 +21,7 @@ #include "hal.h" #include "nanovna.h" -uint16_t spi_buffer[2048]; +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; diff --git a/nanovna.h b/nanovna.h index b516545..97522ec 100644 --- a/nanovna.h +++ b/nanovna.h @@ -300,6 +300,9 @@ extern int16_t vbat; #define RGB565(r,g,b) ( (((g)&0x1c)<<11) | (((b)&0xf8)<<5) | ((r)&0xf8) | (((g)&0xe0)>>5) ) #define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) ) +// Define size of screen buffer in pixels (one pixel 16bit size) +#define SPI_BUFFER_SIZE 2048 + #define DEFAULT_FG_COLOR RGB565(255,255,255) #define DEFAULT_BG_COLOR RGB565( 0, 0, 0) #define DEFAULT_GRID_COLOR RGB565(128,128,128) @@ -317,7 +320,7 @@ extern int16_t vbat; extern uint16_t foreground_color; extern uint16_t background_color; -extern uint16_t spi_buffer[2048]; +extern uint16_t spi_buffer[SPI_BUFFER_SIZE]; void ili9341_init(void); //void ili9341_setRotation(uint8_t r); diff --git a/plot.c b/plot.c index b514311..0e67fbd 100644 --- a/plot.c +++ b/plot.c @@ -16,6 +16,10 @@ int16_t area_height = AREA_HEIGHT_NORMAL; // Depends from spi_buffer size, CELLWIDTH*CELLHEIGHT <= sizeof(spi_buffer) #define CELLWIDTH (64) #define CELLHEIGHT (32) +// Check buffer size +#if CELLWIDTH*CELLHEIGHT > SPI_BUFFER_SIZE +#error "Too small spi_buffer size SPI_BUFFER_SIZE < CELLWIDTH*CELLHEIGH" +#endif // indicate dirty cells (not redraw if cell data not changed) #define MAX_MARKMAP_X ((320+CELLWIDTH-1)/CELLWIDTH) From d2431f0cdc7979536372333c731f846ce0f51b80 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 24 Feb 2020 22:47:52 +0300 Subject: [PATCH 16/65] Increase screen render (in some cases up to 2x speedup), decrease stack usage (code size less on 1500 bytes) Write simple profiling definitions START_PROFILE STOP_PROFILE Use it for detect sys tick amount and output to screen main.c Reduce VNA_SHELL_MAX_LENGTH to 48, and made shell_line as static (reduce stack usage) Remove BaseSequentialStream *chp from command calls (use static shell_stream), it reduce code size and stack usage Use VNA_SHELL_FUNCTION definition for all commands Remove chMtxLock(&mutex);chMtxUnlock(&mutex); from commands, and define command flag for use it in calls Apply default scale from trace_info on trace change Led blink outside from main sweep cycle (better look, and less noise) Some size fixes chprintf.c Implement small memory stream object, only put function and plot_printf(char *str, int size, const char *fmt, ...) Use it in all code (little increase speed, and huge decrease size) Restore USE_EXCEPTIONS_STACKSIZE = 0x180 (possible not need, but not good tested) plot.c Made huge screen render profile (add some comments) Not use cell clipping on draw cell data (use constants increase speed, decrease stack usage (not need put it to stack)) Clip cell if need only on screen flush Use new plot_printf, remove chsnprintf usage Apply code style ============================================================================================================ Interesting fact Usage memset(spi_buffer, DEFAULT_BG_COLOR, (h*CELLWIDTH)*sizeof(uint16_t)); dramatically decrease render speed possibly it fill buffer by 8 bit data, so slow Usage uint32_t *p = (uint32_t *)spi_buffer; while (count--) { p[0] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); p[1] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); p[2] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); p[3] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); p+=4; } gives x10 speed perfomance Draw polar and smit grid very slow (but i don`t know how increase it except use bitmaps, but it need about 5-8k flash size and file prepare) On long lines render slow down, but clipping use more calculation, and not give good result Need made stack usage check --- Font5x7.c | 1 + Makefile | 2 +- chprintf.c | 124 ++++++++---- main.c | 579 ++++++++++++++++++++++++++--------------------------- nanovna.h | 5 + plot.c | 459 ++++++++++++++++++++---------------------- ui.c | 12 +- 7 files changed, 592 insertions(+), 590 deletions(-) diff --git a/Font5x7.c b/Font5x7.c index a69bcc7..87b9127 100644 --- a/Font5x7.c +++ b/Font5x7.c @@ -11,6 +11,7 @@ #define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) #define FONT_GET_WIDTH(ch) (8-x5x7_bits[ch*7]&7) +#define FONT_MAX_WIDTH 7 #define FONT_GET_HEIGHT 7 #define CHAR5x7_WIDTH_1px 0x07 diff --git a/Makefile b/Makefile index 7c8be0c..766ae71 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ endif # Stack size to the allocated to the Cortex-M main/exceptions stack. This # stack is used for processing interrupts and exceptions. ifeq ($(USE_EXCEPTIONS_STACKSIZE),) - USE_EXCEPTIONS_STACKSIZE = 0x180 + USE_EXCEPTIONS_STACKSIZE = 0x200 endif # diff --git a/chprintf.c b/chprintf.c index 6ba7efd..c9aae43 100644 --- a/chprintf.c +++ b/chprintf.c @@ -29,7 +29,7 @@ #include "hal.h" #include "chprintf.h" -#include "memstreams.h" +//#include "memstreams.h" #include // Enable [flags], support: @@ -53,7 +53,6 @@ static char smallPrefix[]= { 'm', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', #pragma pack(pop) -//86066 5116 11456 102622 190de build/ch.elf static char *long_to_string_with_divisor(char *p, uint32_t num, uint32_t radix, @@ -63,7 +62,7 @@ static char *long_to_string_with_divisor(char *p, // convert to string from end buffer to begin do { uint8_t c = num % radix; - num /= radix; + num /= radix; *--q = c + ((c > 9) ? ('A'-10) : '0'); }while((precision && --precision) || num); // copy string at begin @@ -103,7 +102,7 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ // freq = freq / 10; uint32_t c = freq; freq>>=1; - freq+=freq>>1; + freq+=freq>>1; freq+=freq>>4; freq+=freq>>8; freq+=freq>>16; // freq = 858993459*freq/1073741824 = freq * 0,799999999813735485076904296875 @@ -111,12 +110,12 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ c-= freq*10; // freq*10 = (freq*4+freq)*2 = ((freq<<2)+freq)<<1 while (c>=10) {freq++;c-=10;} #endif - *--q = c + '0'; - if (freq==0) - break; - // Add spaces, calculate prefix - if (format&1) {*--q = ' '; s++;} - format>>=1; + *--q = c + '0'; + if (freq==0) + break; + // Add spaces, calculate prefix + if (format&1) {*--q = ' '; s++;} + format>>=1; } while (1); s = bigPrefix[s]; @@ -144,7 +143,7 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ }while (--i); // Put pref (amd space before it if need) if (flag&FREQ_PREFIX_SPACE && s!=' ') - *p++ = ' '; + *p++ = ' '; *p++ = s; return p; } @@ -162,9 +161,9 @@ static char *ftoa(char *p, float num, uint32_t precision) { if (k>=multi){k-=multi;l++;} p = long_to_string_with_divisor(p, l, 10, 0); if (precision && k){ - *p++ = '.'; - p=long_to_string_with_divisor(p, k, 10, precision); - // remove zeros at end + *p++ = '.'; + p=long_to_string_with_divisor(p, k, 10, precision); + // remove zeros at end while (p[-1]=='0') p--; if (p[-1]=='.') p--; } @@ -175,14 +174,14 @@ static char *ftoaS(char *p, float num, uint32_t precision) { char prefix=0; char *ptr; if (num > 1000.0){ - for (ptr = bigPrefix+1; *ptr && num > 1000.0; num/=1000, ptr++) - ; - prefix = ptr[-1]; + for (ptr = bigPrefix+1; *ptr && num > 1000.0; num/=1000, ptr++) + ; + prefix = ptr[-1]; } else if (num < 1){ - for (ptr = smallPrefix; *ptr && num < 1.0; num*=1000, ptr++) - ; - prefix = num > 1e-3 ? ptr[-1] : 0; + for (ptr = smallPrefix; *ptr && num < 1.0; num*=1000, ptr++) + ; + prefix = num > 1e-3 ? ptr[-1] : 0; } // Auto set prescision uint32_t l = num; @@ -274,13 +273,13 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { else if (*fmt == '+') state|=POSITIVE; else if (*fmt == '0') - state|=PAD_ZERO; + state|=PAD_ZERO; #ifdef CHPRINTF_USE_SPACE_FLAG else if (*fmt == ' ') - state|=PLUS_SPACE; + state|=PLUS_SPACE; #endif else - break; + break; fmt++; } // Get [width] - The Width field specifies a minimum number of characters to output @@ -309,7 +308,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { } } else - state|=DEFAULT_PRESCISION; + state|=DEFAULT_PRESCISION; //Get [length] /* if (c == 'l' || c == 'L') { @@ -342,42 +341,42 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { if (state & IS_LONG) value.l = va_arg(ap, long); else*/ - value.l = va_arg(ap, uint32_t); + value.l = va_arg(ap, uint32_t); if (value.l < 0) { - state|=NEGATIVE; + state|=NEGATIVE; *p++ = '-'; value.l = -value.l; } else if (state & POSITIVE) - *p++ = '+'; + *p++ = '+'; #ifdef CHPRINTF_USE_SPACE_FLAG else if (state & PLUS_SPACE) - *p++ = ' '; + *p++ = ' '; #endif p = long_to_string_with_divisor(p, value.l, 10, 0); break; - case 'q': - value.u = va_arg(ap, uint32_t); - p=ulong_freq(p, value.u, precision); - break; + case 'q': + value.u = va_arg(ap, uint32_t); + p=ulong_freq(p, value.u, precision); + break; #if CHPRINTF_USE_FLOAT case 'F': case 'f': value.f = va_arg(ap, double); if (value.f < 0) { - state|=NEGATIVE; + state|=NEGATIVE; *p++ = '-'; value.f = -value.f; } else if (state & POSITIVE) - *p++ = '+'; + *p++ = '+'; #ifdef CHPRINTF_USE_SPACE_FLAG else if (state & PLUS_SPACE) *p++ = ' '; #endif if (value.f == INFINITY){ - *p++ = 0x19; - break; + *p++ = 0x19; + break; } p = (c=='F') ? ftoaS(p, value.f, precision) : ftoa(p, value.f, state&DEFAULT_PRESCISION ? FLOAT_PRECISION : precision); break; @@ -422,7 +421,7 @@ unsigned_common:/* while (width){ streamPut(chp, (uint8_t)filler); n++; - width--; + width--; } } // put data @@ -462,6 +461,7 @@ unsigned_common:/* * * @api */ +#if 0 int chprintf(BaseSequentialStream *chp, const char *fmt, ...) { va_list ap; int formatted_bytes; @@ -472,7 +472,7 @@ int chprintf(BaseSequentialStream *chp, const char *fmt, ...) { return formatted_bytes; } - +#endif /** * @brief System formatted output function. * @details This function implements a minimal @p vprintf()-like functionality @@ -501,6 +501,7 @@ int chprintf(BaseSequentialStream *chp, const char *fmt, ...) { * * @api */ +#if 0 int chsnprintf(char *str, size_t size, const char *fmt, ...) { va_list ap; MemoryStream ms; @@ -530,5 +531,52 @@ int chsnprintf(char *str, size_t size, const char *fmt, ...) { /* Return number of bytes that would have been written.*/ return retval; } +#endif + +// +// Small memory stream object, only put function +// +struct printStreamVMT { + _base_sequential_stream_methods +}; + +typedef struct { + const struct printStreamVMT *vmt; + uint8_t *buffer; + uint16_t size; +} printStream; + +static msg_t put(void *ip, uint8_t b) { + printStream *ps = ip; + if (ps->size > 1){ + *(ps->buffer++) = b; + ps->size--; + } + return MSG_OK; +} + +static const struct printStreamVMT vmt = {NULL, NULL, put, NULL}; +void printObjectInit(printStream *ps, int size, uint8_t *buffer){ + ps->vmt = &vmt; + ps->buffer = buffer; + ps->size = size; +} +// Simple print in buffer function +int plot_printf(char *str, int size, const char *fmt, ...) { + va_list ap; + printStream ps; + int retval; + if (size <= 0) return 0; + // Init small memory stream for print + printObjectInit(&ps, size, (uint8_t *)str); + // Performing the print operation using the common code. + va_start(ap, fmt); + retval = chvprintf((BaseSequentialStream *)(void *)&ps, fmt, ap); + va_end(ap); + *(ps.buffer)=0; + if (retval > size-1) retval = size-1; + // Return number of bytes that would have been written. + return retval; +} /** @} */ diff --git a/main.c b/main.c index b7b0f26..bfbdee2 100644 --- a/main.c +++ b/main.c @@ -46,15 +46,17 @@ static BaseSequentialStream *shell_stream = (BaseSequentialStream *)&SDU1; // Shell max arguments #define VNA_SHELL_MAX_ARGUMENTS 4 // Shell max command line size -#define VNA_SHELL_MAX_LENGTH 64 +#define VNA_SHELL_MAX_LENGTH 48 // Shell command functions prototypes -typedef void (*vna_shellcmd_t)(BaseSequentialStream *chp, int argc, char *argv[]); -#define VNA_SHELL_FUNCTION(command_name) static void command_name(BaseSequentialStream *chp, int argc, char *argv[]) +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 +static char shell_line[VNA_SHELL_MAX_LENGTH]; //#define ENABLED_DUMP //#define ENABLE_THREADS_COMMAND - static void apply_error_term_at(int i); static void apply_edelay_at(int i); static void cal_interpolate(int s); @@ -88,6 +90,7 @@ static THD_FUNCTION(Thread1, arg) bool completed = false; if (sweep_enabled || sweep_once) { chMtxLock(&mutex); + // Sweep require 8367 system tick completed = sweep(true); sweep_once = FALSE; chMtxUnlock(&mutex); @@ -96,6 +99,7 @@ static THD_FUNCTION(Thread1, arg) } chMtxLock(&mutex); + // Ui and render require 800 system tick ui_process(); if (sweep_enabled) { @@ -171,7 +175,6 @@ kaiser_window(float k, float n, float beta) { static void transform_domain(void) { - if ((domain_mode & DOMAIN_MODE) != DOMAIN_TIME) return; // nothing to do for freq domain // use spi_buffer as temporary buffer // and calculate ifft for time domain float* tmp = (float*)spi_buffer; @@ -204,7 +207,6 @@ transform_domain(void) break; } - for (int ch = 0; ch < 2; ch++) { memcpy(tmp, measured[ch], sizeof(measured[0])); for (int i = 0; i < POINTS_COUNT; i++) { @@ -242,60 +244,56 @@ transform_domain(void) } // Shell commands output -static int shell_printf(BaseSequentialStream *chp, const char *fmt, ...) { +static int shell_printf(const char *fmt, ...) { va_list ap; int formatted_bytes; va_start(ap, fmt); - formatted_bytes = chvprintf(chp, fmt, ap); + formatted_bytes = chvprintf(shell_stream, fmt, ap); va_end(ap); return formatted_bytes; } -static void cmd_pause(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_pause) { - (void)chp; - (void)argc; - (void)argv; - pause_sweep(); + (void)argc; + (void)argv; + pause_sweep(); } -static void cmd_resume(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_resume) { - (void)chp; - (void)argc; - (void)argv; + (void)argc; + (void)argv; - // restore frequencies array and cal - update_frequencies(); - if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) - cal_interpolate(lastsaveid); + // restore frequencies array and cal + update_frequencies(); + if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) + cal_interpolate(lastsaveid); - resume_sweep(); + resume_sweep(); } -static void cmd_reset(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_reset) { - (void)argc; - (void)argv; + (void)argc; + (void)argv; - if (argc == 1) { - if (strcmp(argv[0], "dfu") == 0) { - shell_printf(chp, "Performing reset to DFU mode\r\n"); - enter_dfu(); - return; - } + if (argc == 1) { + if (strcmp(argv[0], "dfu") == 0) { + shell_printf("Performing reset to DFU mode\r\n"); + enter_dfu(); + return; } + } + shell_printf("Performing reset\r\n"); - shell_printf(chp, "Performing reset\r\n"); - - rccEnableWWDG(FALSE); - - WWDG->CFR = 0x60; - WWDG->CR = 0xff; + rccEnableWWDG(FALSE); + WWDG->CFR = 0x60; + WWDG->CR = 0xff; - /* wait forever */ - while (1) - ; + /* wait forever */ + while (1) + ; } const int8_t gain_table[] = { @@ -327,15 +325,15 @@ adjust_gain(int newfreq) int set_frequency(uint32_t freq) { - int delay = adjust_gain(freq); - int8_t ds = drive_strength; - 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); + int delay = adjust_gain(freq); + int8_t ds = drive_strength; + 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; - return delay; + frequency = freq; + return delay; } // Use macro, std isdigit more big @@ -432,17 +430,17 @@ static int getStringIndex(char *v, const char *list){ return -1; } -static void cmd_offset(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_offset) { if (argc != 1) { - shell_printf(chp, "usage: offset {frequency offset(Hz)}\r\n"); + shell_printf("usage: offset {frequency offset(Hz)}\r\n"); return; } frequency_offset = my_atoui(argv[0]); set_frequency(frequency); } -static void cmd_freq(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_freq) { if (argc != 1) { goto usage; @@ -450,82 +448,80 @@ static void cmd_freq(BaseSequentialStream *chp, int argc, char *argv[]) uint32_t freq = my_atoui(argv[0]); pause_sweep(); - chMtxLock(&mutex); set_frequency(freq); - chMtxUnlock(&mutex); return; usage: - shell_printf(chp, "usage: freq {frequency(Hz)}\r\n"); + shell_printf("usage: freq {frequency(Hz)}\r\n"); } -static void cmd_power(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_power) { - if (argc != 1) { - shell_printf(chp, "usage: power {0-3|-1}\r\n"); - return; - } - drive_strength = my_atoi(argv[0]); - set_frequency(frequency); + if (argc != 1) { + shell_printf("usage: power {0-3|-1}\r\n"); + return; + } + drive_strength = my_atoi(argv[0]); + set_frequency(frequency); } -static void cmd_time(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_time) { - RTCDateTime timespec; - (void)argc; - (void)argv; - rtcGetTime(&RTCD1, ×pec); - shell_printf(chp, "%d/%d/%d %d\r\n", timespec.year+1980, timespec.month, timespec.day, timespec.millisecond); + RTCDateTime timespec; + (void)argc; + (void)argv; + rtcGetTime(&RTCD1, ×pec); + shell_printf("%d/%d/%d %d\r\n", timespec.year+1980, timespec.month, timespec.day, timespec.millisecond); } -static void cmd_dac(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_dac) { - int value; - if (argc != 1) { - shell_printf(chp, "usage: dac {value(0-4095)}\r\n"\ - "current value: %d\r\n", config.dac_value); - return; - } - value = my_atoi(argv[0]); - config.dac_value = value; - dacPutChannelX(&DACD2, 0, value); + int value; + if (argc != 1) { + shell_printf("usage: dac {value(0-4095)}\r\n"\ + "current value: %d\r\n", config.dac_value); + return; + } + value = my_atoi(argv[0]); + config.dac_value = value; + dacPutChannelX(&DACD2, 0, value); } -static void cmd_threshold(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_threshold) { - uint32_t value; - if (argc != 1) { - shell_printf(chp, "usage: threshold {frequency in harmonic mode}\r\n"\ - "current: %d\r\n", config.harmonic_freq_threshold); - return; - } - value = my_atoui(argv[0]); - config.harmonic_freq_threshold = value; + uint32_t value; + if (argc != 1) { + shell_printf("usage: threshold {frequency in harmonic mode}\r\n"\ + "current: %d\r\n", config.harmonic_freq_threshold); + return; + } + value = my_atoui(argv[0]); + config.harmonic_freq_threshold = value; } -static void cmd_saveconfig(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_saveconfig) { (void)argc; (void)argv; config_save(); - shell_printf(chp, "Config saved.\r\n"); + shell_printf("Config saved.\r\n"); } -static void cmd_clearconfig(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_clearconfig) { if (argc != 1) { - shell_printf(chp, "usage: clearconfig {protection key}\r\n"); + shell_printf("usage: clearconfig {protection key}\r\n"); return; } if (strcmp(argv[0], "1234") != 0) { - shell_printf(chp, "Key unmatched.\r\n"); + shell_printf("Key unmatched.\r\n"); return; } clear_all_config_prop_data(); - shell_printf(chp, "Config and all cal data cleared.\r\n"\ - "Do reset manually to take effect. Then do touch cal and save.\r\n"); + shell_printf("Config and all cal data cleared.\r\n"\ + "Do reset manually to take effect. Then do touch cal and save.\r\n"); } static struct { @@ -610,34 +606,29 @@ static const I2SConfig i2sconfig = { 2 // i2spr }; -static void cmd_data(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_data) { int i; int sel = 0; - + float (*array)[2]; if (argc == 1) sel = my_atoi(argv[0]); - if (sel == 0 || sel == 1) { - chMtxLock(&mutex); - for (i = 0; i < sweep_points; i++) { - if (frequencies[i] != 0) - shell_printf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]); - } - chMtxUnlock(&mutex); - } else if (sel >= 2 && sel < 7) { - chMtxLock(&mutex); - for (i = 0; i < sweep_points; i++) { - if (frequencies[i] != 0) - shell_printf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]); - } - chMtxUnlock(&mutex); - } else { - shell_printf(chp, "usage: data [array]\r\n"); - } + + if (sel == 0 || sel == 1) + array = measured[sel]; + else if (sel >= 2 && sel < 7) + array = cal_data[sel-2]; + else + goto usage; + for (i = 0; i < sweep_points; i++) + shell_printf("%f %f\r\n", array[i][0], array[i][1]); + return; +usage: + shell_printf("usage: data [array]\r\n"); } #ifdef ENABLED_DUMP -static void cmd_dump(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_dump) { int i, j; int len; @@ -652,37 +643,35 @@ static void cmd_dump(BaseSequentialStream *chp, int argc, char *argv[]) len /= 2; for (i = 0; i < len; ) { for (j = 0; j < 16; j++, i++) { - shell_printf(chp, "%04x ", 0xffff & (int)dump_buffer[i]); + shell_printf("%04x ", 0xffff & (int)dump_buffer[i]); } - shell_printf(chp, "\r\n"); + shell_printf("\r\n"); } } #endif -static void cmd_capture(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_capture) { // read pixel count at one time (PART*2 bytes required for read buffer) - (void)argc; - (void)argv; - - chMtxLock(&mutex); - - // read 2 row pixel time (read buffer limit by 2/3 + 1 from spi_buffer size) - for (int y=0; y < 240; y+=2) - { - // use uint16_t spi_buffer[2048] (defined in ili9341) for read buffer - uint8_t *buf = (uint8_t *)spi_buffer; - ili9341_read_memory(0, y, 320, 2, 2*320, spi_buffer); - for (int i = 0; i < 4*320; i++) { - streamPut(chp, *buf++); - } + (void)argc; + (void)argv; + int i, y; +#if SPI_BUFFER_SIZE < (3*320 + 1) +#error "Low size of spi_buffer for cmd_capture" +#endif + // read 2 row pixel time (read buffer limit by 2/3 + 1 from spi_buffer size) + for (y=0; y < 240; y+=2){ + // use uint16_t spi_buffer[2048] (defined in ili9341) for read buffer + uint8_t *buf = (uint8_t *)spi_buffer; + ili9341_read_memory(0, y, 320, 2, 2*320, spi_buffer); + for (i = 0; i < 4*320; i++) { + streamPut(shell_stream, *buf++); } - - chMtxUnlock(&mutex); + } } #if 0 -static void cmd_gamma(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_gamma) { float gamma[2]; (void)argc; @@ -694,13 +683,13 @@ static void cmd_gamma(BaseSequentialStream *chp, int argc, char *argv[]) calculate_gamma(gamma); chMtxUnlock(&mutex); - shell_printf(chp, "%d %d\r\n", gamma[0], gamma[1]); + shell_printf("%d %d\r\n", gamma[0], gamma[1]); } #endif static void (*sample_func)(float *gamma) = calculate_gamma; -static void cmd_sample(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_sample) { if (argc!=1) goto usage; // 0 1 2 @@ -712,7 +701,7 @@ static void cmd_sample(BaseSequentialStream *chp, int argc, char *argv[]) default:break; } usage: - shell_printf(chp, "usage: sample {%s}\r\n", cmd_sample_list); + shell_printf("usage: sample {%s}\r\n", cmd_sample_list); } config_t config = { @@ -765,27 +754,22 @@ ensure_edit_config(void) bool sweep(bool break_on_operation) { int i; - + // blink LED while scanning + palClearPad(GPIOC, GPIOC_LED); for (i = 0; i < sweep_points; i++) { int delay = set_frequency(frequencies[i]); tlv320aic3204_select(0); // CH0:REFLECT wait_dsp(delay); - // blink LED while scanning - palClearPad(GPIOC, GPIOC_LED); - - /* calculate reflection coeficient */ + /* calculate reflection coefficient */ (*sample_func)(measured[0][i]); tlv320aic3204_select(1); // CH1:TRANSMISSION wait_dsp(DELAY_CHANNEL_CHANGE); - /* calculate transmission coeficient */ + /* calculate transmission coefficient */ (*sample_func)(measured[1][i]); - // blink LED while scanning - palSetPad(GPIOC, GPIOC_LED); - if (cal_status & CALSTAT_APPLY) apply_error_term_at(i); @@ -796,31 +780,33 @@ bool sweep(bool break_on_operation) if (operation_requested && break_on_operation) return false; } - - transform_domain(); + // blink LED while scanning + palSetPad(GPIOC, GPIOC_LED); + if ((domain_mode & DOMAIN_MODE) == DOMAIN_TIME) + transform_domain(); return true; } -static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_scan) { uint32_t start, stop; int16_t points = sweep_points; if (argc != 2 && argc != 3) { - shell_printf(chp, "usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); + shell_printf("usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); return; } start = my_atoui(argv[0]); stop = my_atoui(argv[1]); if (start == 0 || stop == 0 || start > stop) { - shell_printf(chp, "frequency range is invalid\r\n"); + shell_printf("frequency range is invalid\r\n"); return; } if (argc == 3) { points = my_atoi(argv[2]); if (points <= 0 || points > sweep_points) { - shell_printf(chp, "sweep points exceeds range\r\n"); + shell_printf("sweep points exceeds range\r\n"); return; } } @@ -848,21 +834,18 @@ update_marker_index(void) if (!markers[m].enabled) continue; uint32_t f = markers[m].frequency; - if (f < frequencies[0]) { + uint32_t fstart = get_sweep_frequency(ST_START); + uint32_t fstop = get_sweep_frequency(ST_STOP); + if (f < fstart) { markers[m].index = 0; - markers[m].frequency = frequencies[0]; - } else if (f >= frequencies[sweep_points-1]) { + markers[m].frequency = fstart; + } else if (f >= fstop) { markers[m].index = sweep_points-1; - markers[m].frequency = frequencies[sweep_points-1]; + markers[m].frequency = fstop; } else { for (i = 0; i < sweep_points-1; i++) { if (frequencies[i] <= f && f < frequencies[i+1]) { - uint32_t mid = (frequencies[i] + frequencies[i+1])/2; - if (f < mid) { - markers[m].index = i; - } else { - markers[m].index = i + 1; - } + markers[m].index = f < (frequencies[i]/2 + frequencies[i+1]/2) ? i : i+1; break; } } @@ -1038,10 +1021,10 @@ get_sweep_frequency(int type) return 0; } -static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_sweep) { if (argc == 0) { - shell_printf(chp, "%d %d %d\r\n", frequency0, frequency1, sweep_points); + shell_printf("%d %d %d\r\n", frequency0, frequency1, sweep_points); return; } else if (argc > 3) { goto usage; @@ -1070,8 +1053,8 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) set_sweep_frequency(ST_STOP, value1); return; usage: - shell_printf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n"\ - "\tsweep {%s} {freq(Hz)}\r\n", sweep_cmd); + shell_printf("usage: sweep {start(Hz)} [stop(Hz)]\r\n"\ + "\tsweep {%s} {freq(Hz)}\r\n", sweep_cmd); } @@ -1282,7 +1265,6 @@ void cal_collect(int type) { ensure_edit_config(); - chMtxLock(&mutex); switch (type) { case CAL_LOAD: @@ -1312,7 +1294,6 @@ cal_collect(int type) memcpy(cal_data[CAL_ISOLN], measured[1], sizeof measured[0]); break; } - chMtxUnlock(&mutex); redraw_request |= REDRAW_CAL_STATUS; } @@ -1415,17 +1396,17 @@ cal_interpolate(int s) redraw_request |= REDRAW_CAL_STATUS; } -static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_cal) { - const char *items[] = { "load", "open", "short", "thru", "isoln", "Es", "Er", "Et", "cal'ed" }; + static const char *items[] = { "load", "open", "short", "thru", "isoln", "Es", "Er", "Et", "cal'ed" }; if (argc == 0) { int i; for (i = 0; i < 9; i++) { if (cal_status & (1< 1) ? my_atoi(argv[1]) : 0); @@ -1454,13 +1435,11 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) default:break; } - shell_printf(chp, "usage: cal [%s]\r\n", cmd_cal_list); + shell_printf("usage: cal [%s]\r\n", cmd_cal_list); } -static void cmd_save(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_save) { - (void)chp; - if (argc != 1) goto usage; @@ -1472,12 +1451,11 @@ static void cmd_save(BaseSequentialStream *chp, int argc, char *argv[]) return; usage: - shell_printf(chp, "save {id}\r\n"); + shell_printf("save {id}\r\n"); } -static void cmd_recall(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_recall) { - (void)chp; if (argc != 1) goto usage; @@ -1486,18 +1464,16 @@ static void cmd_recall(BaseSequentialStream *chp, int argc, char *argv[]) goto usage; pause_sweep(); - chMtxLock(&mutex); if (caldata_recall(id) == 0) { // success update_frequencies(); redraw_request |= REDRAW_CAL_STATUS; } - chMtxUnlock(&mutex); resume_sweep(); return; usage: - shell_printf(chp, "recall {id}\r\n"); + shell_printf("recall {id}\r\n"); } static const struct { @@ -1511,14 +1487,14 @@ static const struct { { "SMITH", 0, 1.00 }, { "POLAR", 0, 1.00 }, { "LINEAR", 0, 0.125}, - { "SWR", 0, 1.00 }, + { "SWR", 0, 0.25 }, { "REAL", NGRIDY/2, 0.25 }, { "IMAG", NGRIDY/2, 0.25 }, { "R", NGRIDY/2, 100.0 }, { "X", NGRIDY/2, 100.0 } }; -const char * const trc_channel_name[] = { +static const char * const trc_channel_name[] = { "CH0", "CH1" }; @@ -1538,7 +1514,10 @@ void set_trace_type(int t, int type) } if (trace[t].type != type) { trace[t].type = type; + // Set default trace refpos trace[t].refpos = trace_info[type].refpos; + // Set default trace scale + trace[t].scale = trace_info[type].scale_unit; force = TRUE; } if (force) { @@ -1557,7 +1536,6 @@ void set_trace_channel(int t, int channel) void set_trace_scale(int t, float scale) { -// scale /= trace_info[trace[t].type].scale_unit; if (trace[t].scale != scale) { trace[t].scale = scale; force_set_markmap(); @@ -1566,7 +1544,7 @@ void set_trace_scale(int t, float scale) float get_trace_scale(int t) { - return trace[t].scale;// * trace_info[trace[t].type].scale_unit; + return trace[t].scale; } void set_trace_refpos(int t, float refpos) @@ -1582,17 +1560,17 @@ float get_trace_refpos(int t) return trace[t].refpos; } -static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_trace) { int t; if (argc == 0) { for (t = 0; t < TRACES_MAX; t++) { if (trace[t].enabled) { - const char *type = trace_info[trace[t].type].name; + const char *type = get_trace_typename(t); const char *channel = trc_channel_name[trace[t].channel]; float scale = get_trace_scale(t); float refpos = get_trace_refpos(t); - shell_printf(chp, "%d %s %s %f %f\r\n", t, type, channel, scale, refpos); + shell_printf("%d %s %s %f %f\r\n", t, type, channel, scale, refpos); } } return; @@ -1611,7 +1589,7 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) if (argc == 1) { const char *type = get_trace_typename(t); const char *channel = trc_channel_name[trace[t].channel]; - shell_printf(chp, "%d %s %s\r\n", t, type, channel); + shell_printf("%d %s %s\r\n", t, type, channel); return; } #if MAX_TRACE_TYPE!=12 @@ -1650,8 +1628,8 @@ check_ch_num: exit: return; usage: - shell_printf(chp, "trace {0|1|2|3|all} [%s] [src]\r\n"\ - "trace {0|1|2|3} {%s} {value}\r\n", cmd_type_list, cmd_scale_ref_list); + shell_printf("trace {0|1|2|3|all} [%s] [src]\r\n"\ + "trace {0|1|2|3} {%s} {value}\r\n", cmd_type_list, cmd_scale_ref_list); } @@ -1668,10 +1646,10 @@ float get_electrical_delay(void) return electrical_delay; } -static void cmd_edelay(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_edelay) { if (argc == 0) { - shell_printf(chp, "%f\r\n", electrical_delay); + shell_printf("%f\r\n", electrical_delay); return; } if (argc > 0) { @@ -1680,13 +1658,13 @@ static void cmd_edelay(BaseSequentialStream *chp, int argc, char *argv[]) } -static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_marker) { int t; if (argc == 0) { for (t = 0; t < MARKERS_MAX; t++) { if (markers[t].enabled) { - shell_printf(chp, "%d %d %d\r\n", t+1, markers[t].index, markers[t].frequency); + shell_printf("%d %d %d\r\n", t+1, markers[t].index, markers[t].frequency); } } return; @@ -1703,7 +1681,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) if (t < 0 || t >= MARKERS_MAX) goto usage; if (argc == 1) { - shell_printf(chp, "%d %d %d\r\n", t+1, markers[t].index, frequency); + shell_printf("%d %d %d\r\n", t+1, markers[t].index, frequency); active_marker = t; // select active marker markers[t].enabled = TRUE; @@ -1725,51 +1703,44 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) return; } usage: - shell_printf(chp, "marker [n] [%s|{index}]\r\n", cmd_marker_list); + shell_printf("marker [n] [%s|{index}]\r\n", cmd_marker_list); } -static void cmd_touchcal(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_touchcal) { (void)argc; (void)argv; //extern int16_t touch_cal[4]; int i; - chMtxLock(&mutex); - shell_printf(chp, "first touch upper left, then lower right..."); + shell_printf("first touch upper left, then lower right..."); touch_cal_exec(); - shell_printf(chp, "done\r\n"); + shell_printf("done\r\n"); - shell_printf(chp, "touch cal params: "); + shell_printf("touch cal params: "); for (i = 0; i < 4; i++) { - shell_printf(chp, "%d ", config.touch_cal[i]); + shell_printf("%d ", config.touch_cal[i]); } - shell_printf(chp, "\r\n"); - chMtxUnlock(&mutex); + shell_printf("\r\n"); } -static void cmd_touchtest(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_touchtest) { - (void)chp; (void)argc; (void)argv; - chMtxLock(&mutex); do { touch_draw_test(); } while(argc); - chMtxUnlock(&mutex); - } -static void cmd_frequencies(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_frequencies) { int i; - (void)chp; (void)argc; (void)argv; for (i = 0; i < sweep_points; i++) { if (frequencies[i] != 0) - shell_printf(chp, "%d\r\n", frequencies[i]); + shell_printf("%d\r\n", frequencies[i]); } } @@ -1795,7 +1766,7 @@ set_timedomain_window(int func) // accept TD_WINDOW_MINIMUM/TD_WINDOW_NORMAL/TD_ domain_mode = (domain_mode & ~TD_WINDOW) | (func & TD_WINDOW); } -static void cmd_transform(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_transform) { int i; if (argc == 0) { @@ -1818,12 +1789,11 @@ static void cmd_transform(BaseSequentialStream *chp, int argc, char *argv[]) } return; usage: - shell_printf(chp, "usage: transform {%s} [...]\r\n", cmd_transform_list); + shell_printf("usage: transform {%s} [...]\r\n", cmd_transform_list); } -static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_test) { - (void)chp; (void)argc; (void)argv; @@ -1858,32 +1828,32 @@ static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) #if 0 //extern adcsample_t adc_samples[2]; - //shell_printf(chp, "adc: %d %d\r\n", adc_samples[0], adc_samples[1]); + //shell_printf("adc: %d %d\r\n", adc_samples[0], adc_samples[1]); int i; int x, y; for (i = 0; i < 50; i++) { test_touch(&x, &y); - shell_printf(chp, "adc: %d %d\r\n", x, y); + shell_printf("adc: %d %d\r\n", x, y); chThdSleepMilliseconds(200); } //extern int touch_x, touch_y; - //shell_printf(chp, "adc: %d %d\r\n", touch_x, touch_y); + //shell_printf("adc: %d %d\r\n", touch_x, touch_y); #endif while (argc > 1) { int x, y; touch_position(&x, &y); - shell_printf(chp, "touch: %d %d\r\n", x, y); + shell_printf("touch: %d %d\r\n", x, y); chThdSleepMilliseconds(200); } } -static void cmd_gain(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_gain) { int rvalue; int lvalue = 0; if (argc != 1 && argc != 2) { - shell_printf(chp, "usage: gain {lgain(0-95)} [rgain(0-95)]\r\n"); + shell_printf("usage: gain {lgain(0-95)} [rgain(0-95)]\r\n"); return; } rvalue = my_atoi(argv[0]); @@ -1892,18 +1862,18 @@ static void cmd_gain(BaseSequentialStream *chp, int argc, char *argv[]) tlv320aic3204_set_gain(lvalue, rvalue); } -static void cmd_port(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_port) { int port; if (argc != 1) { - shell_printf(chp, "usage: port {0:TX 1:RX}\r\n"); + shell_printf("usage: port {0:TX 1:RX}\r\n"); return; } port = my_atoi(argv[0]); tlv320aic3204_select(port); } -static void cmd_stat(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_stat) { int16_t *p = &rx_buffer[0]; int32_t acc0, acc1; @@ -1929,14 +1899,14 @@ static void cmd_stat(BaseSequentialStream *chp, int argc, char *argv[]) stat.ave[0] = ave0; stat.ave[1] = ave1; - shell_printf(chp, "average: %d %d\r\n", stat.ave[0], stat.ave[1]); - shell_printf(chp, "rms: %d %d\r\n", stat.rms[0], stat.rms[1]); - shell_printf(chp, "callback count: %d\r\n", stat.callback_count); - //shell_printf(chp, "interval cycle: %d\r\n", stat.interval_cycles); - //shell_printf(chp, "busy cycle: %d\r\n", stat.busy_cycles); - //shell_printf(chp, "load: %d\r\n", stat.busy_cycles * 100 / stat.interval_cycles); + shell_printf("average: %d %d\r\n", stat.ave[0], stat.ave[1]); + shell_printf("rms: %d %d\r\n", stat.rms[0], stat.rms[1]); + shell_printf("callback count: %d\r\n", stat.callback_count); + //shell_printf("interval cycle: %d\r\n", stat.interval_cycles); + //shell_printf("busy cycle: %d\r\n", stat.busy_cycles); + //shell_printf("load: %d\r\n", stat.busy_cycles * 100 / stat.interval_cycles); extern int awd_count; - shell_printf(chp, "awd: %d\r\n", awd_count); + shell_printf("awd: %d\r\n", awd_count); } @@ -1946,25 +1916,25 @@ static void cmd_stat(BaseSequentialStream *chp, int argc, char *argv[]) const char NANOVNA_VERSION[] = VERSION; -static void cmd_version(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_version) { (void)argc; (void)argv; - shell_printf(chp, "%s\r\n", NANOVNA_VERSION); + shell_printf("%s\r\n", NANOVNA_VERSION); } -static void cmd_vbat(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_vbat) { (void)argc; (void)argv; - shell_printf(chp, "%d mV\r\n", vbat); + shell_printf("%d mV\r\n", vbat); } #ifdef ENABLE_THREADS_COMMAND #if CH_CFG_USE_REGISTRY == FALSE #error "Threads Requite enabled CH_CFG_USE_REGISTRY in chconf.h" #endif -static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { +VNA_SHELL_FUNCTION(cmd_threads) { static const char *states[] = {CH_STATE_NAMES}; thread_t *tp; (void)argc; @@ -1973,7 +1943,7 @@ static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { tp = chRegFirstThread(); do { uint32_t stklimit = (uint32_t)tp->wabase; - shell_printf(chp, "%08x %08x %08x %4u %4u %9s %12s"VNA_SHELL_NEWLINE_STR, + shell_printf("%08x %08x %08x %4u %4u %9s %12s"VNA_SHELL_NEWLINE_STR, stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp, (uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state], tp->name == NULL ? "" : tp->name); @@ -1983,68 +1953,74 @@ static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { #endif //============================================================================= -static void cmd_help(BaseSequentialStream *chp, int argc, char *argv[]); +VNA_SHELL_FUNCTION(cmd_help); + +#pragma pack(push, 2) typedef struct { const char *sc_name; vna_shellcmd_t sc_function; + uint16_t flags; } VNAShellCommand; +#pragma pack(pop) +// Some commands can executed only if process thread not in main cycle +#define CMD_WAIT_MUTEX 1 static const VNAShellCommand commands[] = { - { "version" , cmd_version }, - { "reset" , cmd_reset }, - { "freq" , cmd_freq }, - { "offset" , cmd_offset }, - { "time" , cmd_time }, - { "dac" , cmd_dac }, - { "saveconfig" , cmd_saveconfig }, - { "clearconfig" , cmd_clearconfig }, - { "data" , cmd_data }, + {"version" , cmd_version , 0}, + {"reset" , cmd_reset , 0}, + {"freq" , cmd_freq , CMD_WAIT_MUTEX}, + {"offset" , cmd_offset , 0}, + {"time" , cmd_time , 0}, + {"dac" , cmd_dac , 0}, + {"saveconfig" , cmd_saveconfig , 0}, + {"clearconfig" , cmd_clearconfig , 0}, + {"data" , cmd_data , CMD_WAIT_MUTEX}, #ifdef ENABLED_DUMP - { "dump" , cmd_dump }, + {"dump" , cmd_dump , 0}, #endif - { "frequencies" , cmd_frequencies }, - { "port" , cmd_port }, - { "stat" , cmd_stat }, - { "gain" , cmd_gain }, - { "power" , cmd_power }, - { "sample" , cmd_sample }, -// { "gamma" , cmd_gamma }, - { "scan" , cmd_scan }, - { "sweep" , cmd_sweep }, - { "test" , cmd_test }, - { "touchcal" , cmd_touchcal }, - { "touchtest" , cmd_touchtest }, - { "pause" , cmd_pause }, - { "resume" , cmd_resume }, - { "cal" , cmd_cal }, - { "save" , cmd_save }, - { "recall" , cmd_recall }, - { "trace" , cmd_trace }, - { "marker" , cmd_marker }, - { "edelay" , cmd_edelay }, - { "capture" , cmd_capture }, - { "vbat" , cmd_vbat }, - { "transform" , cmd_transform }, - { "threshold" , cmd_threshold }, - { "help" , cmd_help }, + {"frequencies" , cmd_frequencies , 0}, + {"port" , cmd_port , 0}, + {"stat" , cmd_stat , 0}, + {"gain" , cmd_gain , 0}, + {"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 + {"sweep" , cmd_sweep , 0}, + {"test" , cmd_test , 0}, + {"touchcal" , cmd_touchcal , CMD_WAIT_MUTEX}, + {"touchtest" , cmd_touchtest , CMD_WAIT_MUTEX}, + {"pause" , cmd_pause , 0}, + {"resume" , cmd_resume , 0}, + {"cal" , cmd_cal , CMD_WAIT_MUTEX}, + {"save" , cmd_save , 0}, + {"recall" , cmd_recall , CMD_WAIT_MUTEX}, + {"trace" , cmd_trace , 0}, + {"marker" , cmd_marker , 0}, + {"edelay" , cmd_edelay , 0}, + {"capture" , cmd_capture , CMD_WAIT_MUTEX}, + {"vbat" , cmd_vbat , 0}, + {"transform" , cmd_transform , 0}, + {"threshold" , cmd_threshold , 0}, + {"help" , cmd_help , 0}, #ifdef ENABLE_THREADS_COMMAND - { "threads" , cmd_threads }, + {"threads" , cmd_threads , 0}, #endif - { NULL , NULL } + {NULL , NULL , 0} }; -static void cmd_help(BaseSequentialStream *chp, int argc, char *argv[]) +VNA_SHELL_FUNCTION(cmd_help) { (void)argc; (void)argv; const VNAShellCommand *scp = commands; - shell_printf(chp, "Commands:"); + shell_printf("Commands:"); while (scp->sc_name != NULL) { - shell_printf(chp, " %s", scp->sc_name); + shell_printf(" %s", scp->sc_name); scp++; } - shell_printf(chp, VNA_SHELL_NEWLINE_STR); + shell_printf(VNA_SHELL_NEWLINE_STR); return; } @@ -2067,14 +2043,14 @@ static int VNAShell_readLine(char *line, int max_size){ if (c == 8 || c == 0x7f) { if (ptr != line) { static const char backspace[] = {0x08,0x20,0x08,0x00}; - shell_printf(shell_stream, backspace); + shell_printf(backspace); ptr--; } continue; } // New line (Enter) if (c == '\r') { - shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR); + shell_printf(VNA_SHELL_NEWLINE_STR); *ptr = 0; return 1; } @@ -2090,6 +2066,9 @@ 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 // @@ -2110,7 +2089,7 @@ static void VNAShell_executeLine(char *line){ break; // Argument limits check if (n > VNA_SHELL_MAX_ARGUMENTS) { - shell_printf(shell_stream, "too many arguments, max 4"VNA_SHELL_NEWLINE_STR); + 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 @@ -2122,13 +2101,17 @@ static void VNAShell_executeLine(char *line){ const VNAShellCommand *scp; for (scp = commands; scp->sc_name!=NULL;scp++) { if (strcmp(scp->sc_name, args[0]) == 0) { -// chMtxLock(&mutex); - scp->sc_function(shell_stream, n-1, &args[1]); -// chMtxUnlock(&mutex); + if (scp->flags&CMD_WAIT_MUTEX) { + chMtxLock(&mutex); + scp->sc_function(n-1, &args[1]); + chMtxUnlock(&mutex); + } + else + scp->sc_function(n-1, &args[1]); return; } } - shell_printf(shell_stream, "%s?"VNA_SHELL_NEWLINE_STR, args[0]); + shell_printf("%s?"VNA_SHELL_NEWLINE_STR, args[0]); } #ifdef VNA_SHELL_THREAD @@ -2136,10 +2119,9 @@ static THD_WORKING_AREA(waThread2, /* cmd_* max stack size + alpha */442); THD_FUNCTION(myshellThread, p) { (void)p; chRegSetThreadName("shell"); - char shell_line[VNA_SHELL_MAX_LENGTH]; - shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); + shell_printf(VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); while (true) { - shell_printf(shell_stream, VNA_SHELL_PROMPT_STR); + shell_printf(VNA_SHELL_PROMPT_STR); if (VNAShell_readLine(shell_line, VNA_SHELL_MAX_LENGTH)) VNAShell_executeLine(shell_line); else // Putting a delay in order to avoid an endless loop trying to read an unavailable stream. @@ -2240,10 +2222,9 @@ int main(void) myshellThread, NULL); chThdWait(shelltp); #else - char shell_line[VNA_SHELL_MAX_LENGTH]; - shell_printf(shell_stream, VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); + shell_printf(VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); do { - shell_printf(shell_stream, VNA_SHELL_PROMPT_STR); + shell_printf(VNA_SHELL_PROMPT_STR); if (VNAShell_readLine(shell_line, VNA_SHELL_MAX_LENGTH)) VNAShell_executeLine(shell_line); else diff --git a/nanovna.h b/nanovna.h index 97522ec..b1dc275 100644 --- a/nanovna.h +++ b/nanovna.h @@ -168,6 +168,7 @@ extern int16_t area_height; extern const uint8_t x5x7_bits []; #define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) #define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7)) +#define FONT_MAX_WIDTH 7 #define FONT_GET_HEIGHT 7 extern const uint16_t numfont16x22[]; @@ -463,6 +464,10 @@ int16_t adc_vbat_read(ADC_TypeDef *adc); /* * misclinous */ +int plot_printf(char *str, int, const char *fmt, ...); #define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0) +// 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);} /*EOF*/ diff --git a/plot.c b/plot.c index 0e67fbd..c909e09 100644 --- a/plot.c +++ b/plot.c @@ -5,7 +5,7 @@ #include "chprintf.h" #include "nanovna.h" -static void cell_draw_marker_info(int m, int n, int w, int h); +static void cell_draw_marker_info(int x0, int y0); int16_t grid_offset; int16_t grid_width; @@ -569,23 +569,23 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) float value; switch (marker_smith_format) { case MS_LIN: - chsnprintf(buf, len, "%.2f %.1f" S_DEGREE, linear(coeff), phase(coeff)); + plot_printf(buf, len, "%.2f %.1f" S_DEGREE, linear(coeff), phase(coeff)); break; case MS_LOG: { float v = logmag(coeff); if (v == -INFINITY) - chsnprintf(buf, len, "-"S_INFINITY" dB"); + plot_printf(buf, len, "-"S_INFINITY" dB"); else - chsnprintf(buf, len, "%.1fdB %.1f" S_DEGREE, v, phase(coeff)); + plot_printf(buf, len, "%.1fdB %.1f" S_DEGREE, v, phase(coeff)); } break; case MS_REIM: - chsnprintf(buf, len, "%F%+Fj", coeff[0], coeff[1]); + plot_printf(buf, len, "%F%+Fj", coeff[0], coeff[1]); break; case MS_RX: - chsnprintf(buf, len, "%F"S_OHM"%+Fj", zr, zi); + plot_printf(buf, len, "%F"S_OHM"%+Fj", zr, zi); break; case MS_RLC: @@ -597,7 +597,7 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) prefix = 'H'; value = zi / (2 * M_PI * frequency); } - chsnprintf(buf, len, "%F"S_OHM" %F%c", zr, value, prefix); + plot_printf(buf, len, "%F"S_OHM" %F%c", zr, value, prefix); break; } } @@ -650,11 +650,11 @@ trace_get_value_string(int t, char *buf, int len, float array[POINTS_COUNT][2], return; //case TRC_ADMIT: case TRC_POLAR: - chsnprintf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]); + plot_printf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]); default: return; } - chsnprintf(buf, len, format, v); + plot_printf(buf, len, format, v); } static void @@ -708,12 +708,12 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT break; //case TRC_ADMIT: case TRC_POLAR: - chsnprintf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]); + plot_printf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]); return; default: return; } - chsnprintf(buf, len, format, v); + plot_printf(buf, len, format, v); } static int @@ -723,18 +723,18 @@ trace_get_info(int t, char *buf, int len) float scale = get_trace_scale(t); switch (trace[t].type) { case TRC_LOGMAG: - return chsnprintf(buf, len, "%s %ddB/", name, (int)scale); + return plot_printf(buf, len, "%s %ddB/", name, (int)scale); case TRC_PHASE: - return chsnprintf(buf, len, "%s %d" S_DEGREE "/", name, (int)scale); + return plot_printf(buf, len, "%s %d" S_DEGREE "/", name, (int)scale); case TRC_SMITH: //case TRC_ADMIT: case TRC_POLAR: if (scale != 1.0) - return chsnprintf(buf, len, "%s %.1fFS", name, scale); + return plot_printf(buf, len, "%s %.1fFS", name, scale); else - return chsnprintf(buf, len, "%s ", name); + return plot_printf(buf, len, "%s ", name); default: - return chsnprintf(buf, len, "%s %F/", name, scale); + return plot_printf(buf, len, "%s %F/", name, scale); } return 0; } @@ -839,98 +839,37 @@ markmap_upperarea(void) invalidateRect(0, 0, AREA_WIDTH_NORMAL, 31); } -#define INSIDE 0b0000; -#define LEFT 0b0001; -#define RIGHT 0b0010; -#define BOTTOM 0b0100; -#define TOP 0b1000; - -static uint32_t -_compute_outcode(int w, int h, int x, int y) +#define SWAP(x,y) {int t=x;x=y;y=t;} +// +// in most cases _compute_outcode clip calculation not give render line speedup +// +static inline void +cell_drawline(int x0, int y0, int x1, int y1, int c) { - uint32_t code = INSIDE; - if (x < 0) { - code |= LEFT; - } else - if (x > w) { - code |= RIGHT; - } - if (y < 0) { - code |= BOTTOM; - } else - if (y > h) { - code |= TOP; - } - return code; -} + if (x0<0 && x1<0) return; + if (y0<0 && y1<0) return; + if (x0>=CELLWIDTH && x1>=CELLWIDTH )return; + if (y0>=CELLHEIGHT && y1>=CELLHEIGHT)return; -static void -cell_drawline(int w, int h, int x0, int y0, int x1, int y1, int c) -{ - uint32_t outcode1 = _compute_outcode(w, h, x0, y0); - uint32_t outcode2 = _compute_outcode(w, h, x1, y1); - if (outcode1 & outcode2) { - // this line is out of requested area. early return - return; - } - // If outcode1 == 0 && outcode2 == 0, no clipping, not need check - //outcode1+=outcode2; // modifed Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm - int dx = x1 - x0, sx = 1; if (dx < 0) {dx = -dx; sx = -1;} + if (x1 < x0) {SWAP(x0,x1);SWAP(y0,y1);} + int dx = x1 - x0; int dy = y1 - y0, sy = 1; if (dy < 0) {dy = -dy; sy = -1;} int err = (dx > dy ? dx : -dy) / 2; while (1){ - if (//outcode1 == 0 || - (y0 >= 0 && y0 < h && x0 >= 0 && x0 < w)) - spi_buffer[y0*w+x0] |= c; + if (y0>=0 && y0=0 && x0 -dx) { err -= dy; x0 += sx; } - if (e2 < dy) { err += dx; y0 += sy; } + if (e2 > -dx) { err -= dy; x0++; } + if (e2 < dy) { err += dx; y0+=sy;} } } -#if 0 -int -search_index_range(int x, int y, uint32_t index[POINTS_COUNT], int *i0, int *i1) -{ - int i, j; - int head = 0; - int tail = sweep_points; - i = 0; - x &= 0x03e0; - y &= 0x03e0; - while (head < tail) { - i = (head + tail) / 2; - if (x < CELL_X0(index[i])) - tail = i+1; - else if (x > CELL_X0(index[i])) - head = i; - else if (y < CELL_Y0(index[i])) - tail = i+1; - else if (y > CELL_Y0(index[i])) - head = i; - else - break; - } - - if (x != CELL_X0(index[i]) || y != CELL_Y0(index[i])) - return FALSE; - - j = i; - while (j > 0 && x == CELL_X0(index[j-1]) && y == CELL_Y0(index[j-1])) - j--; - *i0 = j; - j = i; - while (j < POINTS_COUNT-1 && x == CELL_X0(index[j+1]) && y == CELL_Y0(index[j+1])) - j++; - *i1 = j; - return TRUE; -} -#endif - +// Give a little speedup then draw rectangular plot (50 systick on all calls, all render req 700 systick) +// Write more difficult algoritm for seach indexes not give speedup static int search_index_range_x(int x1, int x2, uint32_t index[POINTS_COUNT], int *i0, int *i1) { @@ -986,17 +925,17 @@ static const uint8_t reference_bitmap[]={ }; static void -draw_refpos(int w, int h, int x, int y, int c) +draw_refpos(int x, int y, int c) { int y0=y, j; for (j=0; j= h) + if (y0 < 0 || y0 >= CELLHEIGHT) continue; int x0=x; uint8_t bits = reference_bitmap[j]; while (bits){ - if (x0 >= 0 && x0 < w) - spi_buffer[y0*w+x0] = (bits&0x80) ? c : DEFAULT_BG_COLOR; + if (x0 >= 0 && x0 < CELLWIDTH) + spi_buffer[y0*CELLWIDTH+x0] = (bits&0x80) ? c : DEFAULT_BG_COLOR; x0++; bits<<=1; } @@ -1055,21 +994,21 @@ static const uint8_t marker_bitmap[]={ }; static void -draw_marker(int w, int h, int x, int y, int c, int ch) +draw_marker(int x, int y, int c, int ch) { int y0=y, j; for (j=0;j= 0 && x0 < w && y0 >= 0 && y0 < h){ + if (x0 >= 0 && x0 < CELLWIDTH && y0 >= 0 && y0 < CELLHEIGHT){ if (bits&0x80) - spi_buffer[y0*w+x0] = c; + spi_buffer[y0*CELLWIDTH+x0] = c; else if (force_color) - spi_buffer[y0*w+x0] = DEFAULT_BG_COLOR; + spi_buffer[y0*CELLWIDTH+x0] = DEFAULT_BG_COLOR; } x0++; bits<<=1; @@ -1257,6 +1196,7 @@ draw_cell(int m, int n) int x, y; int i0, i1, i; int t; + uint16_t c; // Clip cell by area if (x0 + w > area_width) w = area_width - x0; @@ -1264,62 +1204,81 @@ draw_cell(int m, int n) h = area_height - y0; if (w <= 0 || h <= 0) return; +// PULSE; - PULSE; - // Clear buffer - memset(spi_buffer, DEFAULT_BG_COLOR, sizeof spi_buffer); - uint16_t c = config.grid_color; - // Draw grid - for (t = 0; t < TRACES_MAX; t++) { - if (!trace[t].enabled) - continue; - uint32_t trace_type = (1<= CELLOFFSETX && x+x0 <= WIDTH+CELLOFFSETX) - spi_buffer[y * w + x] = c; - } + // Clear buffer ("0 : height" lines) +#if 0 + // use memset 350 system ticks for all screen calls + // as understand it use 8 bit set, slow down on 32 bit systems + memset(spi_buffer, DEFAULT_BG_COLOR, (h*CELLWIDTH)*sizeof(uint16_t)); +#else + // use direct set 35 system ticks for all screen calls +#if CELLWIDTH%8 != 0 +#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; + while (count--) { + p[0] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); + p[1] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); + p[2] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); + p[3] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); + p+=4; + } +#endif + +// Draw grid +#if 1 + c = config.grid_color; + // Generate grid type list + uint32_t trace_type = 0; + for (t = 0; t < TRACES_MAX; t++) + if (trace[t].enabled) + trace_type|=(1<= CELLOFFSETX && x+x0 <= WIDTH+CELLOFFSETX) + spi_buffer[y * CELLWIDTH + x] = c; + } } + } + // Smith greed line (1000 system ticks for all screen calls) + if(trace_type&(1<=0 && x-MARKER_WIDTH=0 && y-MARKER_HEIGHT=0 && x-MARKER_WIDTH=0 && y-MARKER_HEIGHT=0 && x-REFERENCE_WIDTH=0 && x-REFERENCE_WIDTH=0 && y-REFERENCE_HEIGHT=0 && y-REFERENCE_HEIGHT= h || x <= -ch_size || x >= w) +// if (y <= -FONT_GET_HEIGHT || y >= CELLHEIGHT || x <= -ch_size || x >= CELLWIDTH) +// return ch_size; + if (x <= -ch_size) return ch_size; for(c = 0; c < FONT_GET_HEIGHT; c++) { bits = *char_buf++; - if ((y + c) < 0 || (y + c) >= h) + if ((y + c) < 0 || (y + c) >= CELLHEIGHT) continue; for (r = 0; r < ch_size; r++) { - if ((x+r) >= 0 && (x+r) < w && (0x80 & bits)) - spi_buffer[(y+c)*w + (x+r)] = foreground_color; + if ((x+r) >= 0 && (x+r) < CELLWIDTH && (0x80 & bits)) + spi_buffer[(y+c)*CELLWIDTH + (x+r)] = foreground_color; bits <<= 1; } } @@ -1471,142 +1448,136 @@ cell_drawchar(int w, int h, uint8_t ch, int x, int y) } static void -cell_drawstring(int w, int h, char *str, int x, int y) +cell_drawstring(char *str, int x, int y) { + if (y <= -FONT_GET_HEIGHT || y >= CELLHEIGHT) + return; while (*str) { - x += cell_drawchar(w, h, *str, x, y); - str++; + if (x >= CELLWIDTH) + return; + x += cell_drawchar(*str++, x, y); } } static void -cell_draw_marker_info(int m, int n, int w, int h) +cell_draw_marker_info(int x0, int y0) { char buf[32]; int t; - if (n != 0) - return; if (active_marker < 0) return; int idx = markers[active_marker].index; int j = 0; - if (active_marker != -1 && previous_marker != -1 && uistat.current_trace != -1) { + if (previous_marker != -1 && uistat.current_trace != -1) { int t = uistat.current_trace; int mk; for (mk = 0; mk < MARKERS_MAX; mk++) { if (!markers[mk].enabled) continue; - int xpos = 1 + (j%2)*146; - int ypos = 1 + (j/2)*8; - xpos -= m * CELLWIDTH - CELLOFFSETX; - ypos -= n * CELLHEIGHT; + int xpos = 1 + (j%2)*146 + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*8 - y0; setForegroundColor(config.trace_color[t]); if (mk == active_marker) - cell_drawstring(w, h, S_SARROW, xpos, ypos); + cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; - chsnprintf(buf, sizeof buf, "M%d", mk+1); - cell_drawstring(w, h, buf, xpos, ypos); + plot_printf(buf, sizeof buf, "M%d", mk+1); + cell_drawstring(buf, xpos, ypos); xpos += 13; //trace_get_info(t, buf, sizeof buf); uint32_t freq = frequencies[markers[mk].index]; if (uistat.marker_delta && mk != active_marker) { uint32_t freq1 = frequencies[markers[active_marker].index]; uint32_t delta = freq > freq1 ? freq - freq1 : freq1 - freq; - chsnprintf(buf, sizeof buf, S_DELTA"%.9qHz", delta); + plot_printf(buf, sizeof buf, S_DELTA"%.9qHz", delta); } else { - chsnprintf(buf, sizeof buf, "%.10qHz", freq); + plot_printf(buf, sizeof buf, "%.10qHz", freq); } - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); xpos += 67; if (uistat.marker_delta && mk != active_marker) trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); else trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index); setForegroundColor(DEFAULT_FG_COLOR); - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); j++; } // draw marker delta if (!uistat.marker_delta && previous_marker >= 0 && active_marker != previous_marker && markers[previous_marker].enabled) { int idx0 = markers[previous_marker].index; - int xpos = 180; - int ypos = 1 + (j/2)*8; - xpos -= m * CELLWIDTH -CELLOFFSETX; - ypos -= n * CELLHEIGHT; - chsnprintf(buf, sizeof buf, S_DELTA"%d-%d", active_marker+1, previous_marker+1); + int xpos = 180 + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*8 - y0; + + plot_printf(buf, sizeof buf, S_DELTA"%d-%d", active_marker+1, previous_marker+1); setForegroundColor(DEFAULT_FG_COLOR); - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); xpos += 24; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { uint32_t freq = frequencies[idx]; uint32_t freq1 = frequencies[idx0]; uint32_t delta = freq > freq1 ? freq - freq1 : freq1 - freq; - chsnprintf(buf, sizeof buf, "%c%.13qHz", freq >= freq1 ? '+' : '-', delta); + plot_printf(buf, sizeof buf, "%c%.13qHz", freq >= freq1 ? '+' : '-', delta); } else { - chsnprintf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx) - time_of_index(idx0), distance_of_index(idx) - distance_of_index(idx0)); + plot_printf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx) - time_of_index(idx0), distance_of_index(idx) - distance_of_index(idx0)); } - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); } } else { for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - int xpos = 1 + (j%2)*146; - int ypos = 1 + (j/2)*8; - xpos -= m * CELLWIDTH -CELLOFFSETX; - ypos -= n * CELLHEIGHT; + int xpos = 1 + (j%2)*146 + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*8 - y0; + setForegroundColor(config.trace_color[t]); if (t == uistat.current_trace) - cell_drawstring(w, h, S_SARROW, xpos, ypos); + cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; - chsnprintf(buf, sizeof buf, "CH%d", trace[t].channel); - cell_drawstring(w, h, buf, xpos, ypos); + plot_printf(buf, sizeof buf, "CH%d", trace[t].channel); + cell_drawstring(buf, xpos, ypos); xpos += 19; int n = trace_get_info(t, buf, sizeof buf); - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); xpos += n * 5 + 2; //xpos += 60; trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], idx); setForegroundColor(DEFAULT_FG_COLOR); - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); j++; } // draw marker frequency - int xpos = 185; - int ypos = 1 + (j/2)*8; - xpos -= m * CELLWIDTH -CELLOFFSETX; - ypos -= n * CELLHEIGHT; + int xpos = 185 + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*8 - y0; + setForegroundColor(DEFAULT_FG_COLOR); if (uistat.lever_mode == LM_MARKER) - cell_drawstring(w, h, S_SARROW, xpos, ypos); + cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; - chsnprintf(buf, sizeof buf, "M%d:", active_marker+1); - cell_drawstring(w, h, buf, xpos, ypos); + plot_printf(buf, sizeof buf, "M%d:", active_marker+1); + cell_drawstring(buf, xpos, ypos); xpos += 19; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { - chsnprintf(buf, sizeof buf, "%qHz", frequencies[idx]); + plot_printf(buf, sizeof buf, "%qHz", frequencies[idx]); } else { - chsnprintf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx), distance_of_index(idx)); + plot_printf(buf, sizeof buf, "%Fs (%Fm)", time_of_index(idx), distance_of_index(idx)); } - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); } setForegroundColor(DEFAULT_FG_COLOR); if (electrical_delay != 0) { // draw electrical delay - int xpos = 21; - int ypos = 1 + ((j+1)/2)*8; - xpos -= m * CELLWIDTH -CELLOFFSETX; - ypos -= n * CELLHEIGHT; + int xpos = 21 + CELLOFFSETX - x0; + int ypos = 1 + ((j+1)/2)*8 - y0; float light_speed_ps = 299792458e-12; //(m/ps) - chsnprintf(buf, sizeof buf, "Edelay %Fs %Fm", electrical_delay * 1e-12, + plot_printf(buf, sizeof buf, "Edelay %Fs %Fm", electrical_delay * 1e-12, electrical_delay * light_speed_ps * velocity_factor); - cell_drawstring(w, h, buf, xpos, ypos); + cell_drawstring(buf, xpos, ypos); } } @@ -1617,17 +1588,17 @@ draw_frequencies(void) char buf2[32];buf2[0]=0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { if (FREQ_IS_STARTSTOP()) { - chsnprintf(buf1, sizeof(buf1), " START %qHz", frequency0); - chsnprintf(buf2, sizeof(buf2), " STOP %qHz", frequency1); + plot_printf(buf1, sizeof(buf1), " START %qHz", frequency0); + plot_printf(buf2, sizeof(buf2), " STOP %qHz", frequency1); } else if (FREQ_IS_CENTERSPAN()) { - chsnprintf(buf1, sizeof(buf1), " CENTER %qHz", FREQ_CENTER()); - chsnprintf(buf2, sizeof(buf2), " SPAN %qHz", FREQ_SPAN()); + plot_printf(buf1, sizeof(buf1), " CENTER %qHz", FREQ_CENTER()); + plot_printf(buf2, sizeof(buf2), " SPAN %qHz", FREQ_SPAN()); } else { - chsnprintf(buf1, sizeof(buf1), " CW %qHz", frequency0); + plot_printf(buf1, sizeof(buf1), " CW %qHz", frequency0); } } else { - chsnprintf(buf1, sizeof(buf1), " START 0s"); - chsnprintf(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); @@ -1696,7 +1667,7 @@ draw_battery_status(void) // Set battery color setForegroundColor(vbat < BATTERY_WARNING_LEVEL ? DEFAULT_LOW_BAT_COLOR : DEFAULT_NORMAL_BAT_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); -// chsnprintf(string_buf, sizeof string_buf, "V:%d", vbat); +// plot_printf(string_buf, sizeof string_buf, "V:%d", vbat); // ili9341_drawstringV(string_buf, 1, 60); // Prepare battery bitmap image // Battery top @@ -1713,7 +1684,7 @@ draw_battery_status(void) // string_buf[x++] = 0b10000001; string_buf[x++] = 0b11111111; // Draw battery - blit8BitWidthBitmap(0, 1, 8, x, string_buf); + blit8BitWidthBitmap(1, 1, 8, x, string_buf); } void diff --git a/ui.c b/ui.c index bd00964..01ece2d 100644 --- a/ui.c +++ b/ui.c @@ -782,7 +782,7 @@ static void menu_marker_search_cb(int item, uint8_t data) { (void)data; - int i; + int i = -1; if (active_marker == -1) return; @@ -791,23 +791,19 @@ menu_marker_search_cb(int item, uint8_t data) case 1: /* minimum */ set_marker_search(item); i = marker_search(); - if (i != -1) - markers[active_marker].index = i; break; case 2: /* search Left */ i = marker_search_left(markers[active_marker].index); - if (i != -1) - markers[active_marker].index = i; break; case 3: /* search right */ i = marker_search_right(markers[active_marker].index); - if (i != -1) - markers[active_marker].index = i; break; case 4: /* tracking */ marker_tracking = !marker_tracking; break; } + if (i != -1) + markers[active_marker].index = i; draw_menu(); redraw_marker(active_marker, TRUE); select_lever_mode(LM_SEARCH); @@ -1601,7 +1597,7 @@ static void draw_numeric_area(void) { char buf[10]; - chsnprintf(buf, sizeof buf, "%9d", uistat.value); + plot_printf(buf, sizeof buf, "%9d", uistat.value); draw_numeric_input(buf); } From 48ff4893d34eece1f7a59c649aa580f66d9573a9 Mon Sep 17 00:00:00 2001 From: TT Date: Tue, 25 Feb 2020 08:41:22 +0900 Subject: [PATCH 17/65] feat: force putting trailing zeros on float value --- chprintf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/chprintf.c b/chprintf.c index 6ba7efd..39b4fc9 100644 --- a/chprintf.c +++ b/chprintf.c @@ -36,6 +36,9 @@ // ' ' Prepends a space for positive signed-numeric types. positive = ' ', negative = '-'. This flag is ignored if the + flag exists. //#define CHPRINTF_USE_SPACE_FLAG +// Force putting trailing zeros on float value +#define CHPRINTF_FORCE_TRAILING_ZEROS + #define MAX_FILLER 11 #define FLOAT_PRECISION 9 @@ -161,12 +164,14 @@ static char *ftoa(char *p, float num, uint32_t precision) { // Fix rounding error if get if (k>=multi){k-=multi;l++;} p = long_to_string_with_divisor(p, l, 10, 0); - if (precision && k){ + if (precision){ *p++ = '.'; p=long_to_string_with_divisor(p, k, 10, precision); +#ifndef CHPRINTF_FORCE_TRAILING_ZEROS // remove zeros at end while (p[-1]=='0') p--; if (p[-1]=='.') p--; +#endif } return p; } From b7934745cac4ff5c7cc83ec0c34aa4a0f4870cf8 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 26 Feb 2020 23:30:50 +0300 Subject: [PATCH 18/65] Restore main thread stack size (stack usage code optimization give good result) Decrease sweep thread stack size from 640 to 512 (also stack usage code optimization give good result) Little change 16x22 font ui.c Use definition for some hard coded values Fix button "Correction" not reset after use "reset" Define menu button and input num size #define MENU_BUTTON_WIDTH 60 #define MENU_BUTTON_HEIGHT 30 #define NUM_INPUT_HEIGHT 30 Reduce button height from 32 to 30 pixels (fix in stimulus menu "= 4) + if (marker < 0 || marker >= MARKERS_MAX) return 0; if (!markers[marker].enabled) return 0; @@ -838,7 +817,8 @@ static void menu_marker_sel_cb(int item, uint8_t data) { (void)data; - if (item >= 0 && item < 4) { + int t; + if (item >= 0 && item < MARKERS_MAX) { if (markers[item].enabled) { if (item == active_marker) { // disable if active trace is selected @@ -852,10 +832,8 @@ menu_marker_sel_cb(int item, uint8_t data) active_marker_select(item); } } else if (item == 4) { /* all off */ - markers[0].enabled = FALSE; - markers[1].enabled = FALSE; - markers[2].enabled = FALSE; - markers[3].enabled = FALSE; + for (t = 0; t < MARKERS_MAX; t++) + markers[t].enabled = FALSE; previous_marker = -1; active_marker = -1; } else if (item == 5) { /* marker delta */ @@ -1072,7 +1050,7 @@ const menuitem_t menu_top[] = { #define MENU_STACK_DEPTH_MAX 4 uint8_t menu_current_level = 0; -const menuitem_t *menu_stack[4] = { +const menuitem_t *menu_stack[MENU_STACK_DEPTH_MAX] = { menu_top, NULL, NULL, NULL }; @@ -1153,6 +1131,10 @@ menu_invoke(int item) } } +#define MENU_BUTTON_WIDTH 60 +#define MENU_BUTTON_HEIGHT 30 +#define NUM_INPUT_HEIGHT 30 + #define KP_WIDTH 48 #define KP_HEIGHT 48 // Key x, y position (0 - 15) on screen @@ -1287,10 +1269,10 @@ draw_keypad(void) static void draw_numeric_area_frame(void) { - ili9341_fill(0, 208, 320, 32, DEFAULT_MENU_COLOR); + ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, DEFAULT_MENU_COLOR); setForegroundColor(DEFAULT_MENU_TEXT_COLOR); setBackgroundColor(DEFAULT_MENU_COLOR); - ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 220); + ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-FONT_GET_HEIGHT-(NUM_INPUT_HEIGHT-FONT_GET_HEIGHT)/2); //ili9341_drawfont(KP_KEYPAD, 300, 216); } @@ -1322,16 +1304,16 @@ draw_numeric_input(const char *buf) setForegroundColor(fg); setBackgroundColor(bg); if (c >= 0) // c is number - ili9341_drawfont(c, x, 208+4); + ili9341_drawfont(c, x, 240-NUM_INPUT_HEIGHT+4); else if (focused) // c not number, but focused - ili9341_drawfont(0, x, 208+4); + ili9341_drawfont(0, x, 240-NUM_INPUT_HEIGHT+4); else // erase - ili9341_fill(x, 208+4, 20, 24, bg); + ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, 20, 24, bg); x += xsim&0x8000 ? NUM_FONT_GET_WIDTH+2+8 : NUM_FONT_GET_WIDTH+2; } // erase last - ili9341_fill(x, 208+4, NUM_FONT_GET_WIDTH+2+8, 24, DEFAULT_MENU_COLOR); + ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, 24, DEFAULT_MENU_COLOR); } static int @@ -1349,7 +1331,7 @@ static void menu_item_modify_attribute(const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) { - if (menu == menu_trace && item < 4) { + if (menu == menu_trace && item < TRACES_MAX) { if (trace[item].enabled) *bg = config.trace_color[item]; } else if (menu == menu_marker_sel) { @@ -1423,26 +1405,26 @@ draw_menu_buttons(const menuitem_t *menu) const char *l1, *l2; if (menu[i].type == MT_NONE) break; - if (menu[i].type == MT_BLANK) + if (menu[i].type == MT_BLANK) continue; - int y = 32*i; + int y = MENU_BUTTON_HEIGHT*i; uint16_t bg = config.menu_normal_color; uint16_t fg = DEFAULT_MENU_TEXT_COLOR; // focus only in MENU mode but not in KEYPAD mode if (ui_mode == UI_MENU && i == selection) bg = config.menu_active_color; - ili9341_fill(320-60, y, 60, 30, bg); + ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); menu_item_modify_attribute(menu, i, &fg, &bg); setForegroundColor(fg); setBackgroundColor(bg); if (menu_is_multiline(menu[i].label, &l1, &l2)) { - ili9341_fill(320-57, y+6, 54, 19, bg); - ili9341_drawstring(l1, 320-55, y+8); - ili9341_drawstring(l2, 320-55, y+16); + ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+5, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(l1, 320-MENU_BUTTON_WIDTH+5, y+7); + ili9341_drawstring(l2, 320-MENU_BUTTON_WIDTH+5, y+7+FONT_GET_HEIGHT+1); } else { - ili9341_fill(320-57, y+10, 54, 11, bg); - ili9341_drawstring(menu[i].label, 320-55, y+12); + ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+8, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(menu[i].label, 320-MENU_BUTTON_WIDTH+5, y+10); } } } @@ -1470,9 +1452,8 @@ menu_apply_touch(void) break; if (menu[i].type == MT_BLANK) continue; - int y = 32*i; - if (y-2 < touch_y && touch_y < y+30+2 - && 320-60 < touch_x) { + int y = MENU_BUTTON_HEIGHT*i; + if (y < touch_y && touch_y < y+MENU_BUTTON_HEIGHT && 320-MENU_BUTTON_WIDTH < touch_x) { menu_select_touch(i); return; } @@ -1491,7 +1472,7 @@ draw_menu(void) static void erase_menu_buttons(void) { - ili9341_fill(320-60, 0, 60, 32*7, DEFAULT_BG_COLOR); + ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*7, DEFAULT_BG_COLOR); } static void @@ -1609,7 +1590,7 @@ ui_mode_menu(void) ui_mode = UI_MENU; /* narrowen plotting area */ - area_width = AREA_WIDTH_NORMAL - 60; + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; area_height = AREA_HEIGHT_NORMAL; ensure_selection(); draw_menu(); @@ -1714,7 +1695,7 @@ step_round(uint32_t v) { // decade step uint32_t x = 1; - for (x = 1; x*10 < v; x *= 10) + for (x = 1; x*10 < v; x*= 10) ; // 1-2-5 step @@ -1892,8 +1873,7 @@ keypad_apply_touch(void) while (keypads[i].c>=0) { int x = KP_GET_X(keypads[i].x); int y = KP_GET_Y(keypads[i].y); - if (x < touch_x && touch_x < x+KP_WIDTH - && y < touch_y && touch_y < y+KP_HEIGHT) { + if (x < touch_x && touch_x < x+KP_WIDTH && y < touch_y && touch_y < y+KP_HEIGHT) { // draw focus selection = i; draw_keypad(); @@ -2038,8 +2018,7 @@ ui_process_keypad(void) break; } - status = touch_check(); - if (status == EVT_TOUCH_PRESSED) { + if (touch_check() == EVT_TOUCH_PRESSED) { int key = keypad_apply_touch(); if (key >= 0 && keypad_click(key)) /* exit loop on done or cancel */ @@ -2077,7 +2056,6 @@ ui_process_lever(void) static void drag_marker(int t, int m) { - int status; /* wait touch release */ do { int touch_x, touch_y; @@ -2091,9 +2069,7 @@ drag_marker(int t, int m) markers[m].frequency = frequencies[index]; redraw_marker(m, TRUE); } - - status = touch_check(); - } while(status != EVT_TOUCH_RELEASED); + } while(touch_check()!=EVT_TOUCH_RELEASED); } static int @@ -2143,21 +2119,15 @@ touch_lever_mode_select(void) int touch_x, touch_y; touch_position(&touch_x, &touch_y); if (touch_y > HEIGHT) { - if (touch_x < 160) { - select_lever_mode(LM_CENTER); - } else { - select_lever_mode(LM_SPAN); - } + select_lever_mode(touch_x < FREQUENCIES_XPOS2 ? LM_CENTER : LM_SPAN); return TRUE; } - if (touch_y < 15) { select_lever_mode(LM_MARKER); return TRUE; } - - return FALSE; - } + return FALSE; +} static void ui_process_touch(void) @@ -2169,10 +2139,9 @@ void ui_process_touch(void) if (status == EVT_TOUCH_PRESSED || status == EVT_TOUCH_DOWN) { switch (ui_mode) { case UI_NORMAL: - - if (touch_pickup_marker()) { + if (touch_pickup_marker()) break; - } else if (touch_lever_mode_select()) { + if (touch_lever_mode_select()) { draw_all(FALSE); touch_wait_release(); break; From d386b0823c30a70f4fbd336738785ceb2307e47a Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 26 Feb 2020 23:55:06 +0300 Subject: [PATCH 19/65] Write clearScreen and use it in code More hard coded values fixes --- ili9341.c | 4 ++++ nanovna.h | 1 + ui.c | 17 ++++++++--------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ili9341.c b/ili9341.c index 6372f1c..3c7568b 100644 --- a/ili9341.c +++ b/ili9341.c @@ -487,6 +487,10 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) } #endif +void clearScreen(void){ + 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;} diff --git a/nanovna.h b/nanovna.h index 7894a3b..e256269 100644 --- a/nanovna.h +++ b/nanovna.h @@ -330,6 +330,7 @@ void ili9341_bulk(int x, int y, int w, int h); void ili9341_fill(int x, int y, int w, int h, int color); void setForegroundColor(uint16_t fg); void setBackgroundColor(uint16_t fg); +void clearScreen(void); void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap); void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap); void ili9341_drawchar(uint8_t ch, int x, int y); diff --git a/ui.c b/ui.c index 998386a..d5c2d83 100644 --- a/ui.c +++ b/ui.c @@ -311,7 +311,7 @@ touch_cal_exec(void) adc_stop(ADC1); setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); - ili9341_fill(0, 0, 320, 240, DEFAULT_BG_COLOR); + clearScreen(); ili9341_line(0, 0, 0, 32); ili9341_line(0, 0, 32, 0); ili9341_drawstring("TOUCH UPPER LEFT", 10, 10); @@ -320,7 +320,7 @@ touch_cal_exec(void) x1 = last_touch_x; y1 = last_touch_y; - ili9341_fill(0, 0, 320, 240, DEFAULT_BG_COLOR); + clearScreen(); ili9341_line(320-1, 240-1, 320-1, 240-32); ili9341_line(320-1, 240-1, 320-32, 240-1); ili9341_drawstring("TOUCH LOWER RIGHT", 230, 220); @@ -346,9 +346,9 @@ touch_draw_test(void) adc_stop(ADC1); - ili9341_fill(0, 0, 320, 240, DEFAULT_BG_COLOR); setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); + clearScreen(); ili9341_drawstring("TOUCH TEST: DRAG PANEL", OFFSETX, 233); touch_wait_pressed(); @@ -378,12 +378,11 @@ void show_version(void) { int x = 5, y = 5; - adc_stop(ADC1); - ili9341_fill(0, 0, 320, 240, DEFAULT_BG_COLOR); - setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); + + clearScreen(); ili9341_drawstring_size(BOARD_NAME, x, y, 4); y += 25; @@ -417,7 +416,7 @@ enter_dfu(void) setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); // leave a last message - ili9341_fill(0, 0, 320, 240, DEFAULT_BG_COLOR); + clearScreen(); ili9341_drawstring("DFU: Device Firmware Update Mode", x, y += 10); ili9341_drawstring("To exit DFU mode, please reset device yourself.", x, y += 10); @@ -647,7 +646,7 @@ static void choose_active_marker(void) { int i; - for (i = 0; i < 4; i++) + for (i = 0; i < MARKERS_MAX; i++) if (markers[i].enabled) { active_marker = i; return; @@ -1478,7 +1477,7 @@ erase_menu_buttons(void) static void erase_numeric_input(void) { - ili9341_fill(0, 240-32, 320, 32, DEFAULT_BG_COLOR); + ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, DEFAULT_BG_COLOR); } static void From 17734f257ded04cdb577402f5a5741f650090465 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 27 Feb 2020 20:53:45 +0300 Subject: [PATCH 20/65] Disable unused ChibiOS options: CH_CFG_USE_WAITEXIT (used only is Shell run as thread) CH_CFG_USE_EVENTS (NanoVNA not use events) CH_CFG_USE_EVENTS_TIMEOUT (NanoVNA not use events) Implement stack use check in "threads" command, now free stack space show in table as "stk free" in hex Check stack usage by sweep, and main threads (seems all ok, but add 64 bytes to sweep) Replace some const values to defined --- chconf.h | 6 +- main.c | 198 ++++++++++++++++++++++++++++++------------------------- plot.c | 29 ++++---- ui.c | 17 +++-- 4 files changed, 133 insertions(+), 117 deletions(-) diff --git a/chconf.h b/chconf.h index 34e6afe..09a6139 100644 --- a/chconf.h +++ b/chconf.h @@ -156,7 +156,7 @@ * * @note The default is @p TRUE. */ -#define CH_CFG_USE_WAITEXIT TRUE +#define CH_CFG_USE_WAITEXIT FALSE /** * @brief Semaphores APIs. @@ -221,7 +221,7 @@ * * @note The default is @p TRUE. */ -#define CH_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS FALSE /** * @brief Events Flags APIs with timeout. @@ -231,7 +231,7 @@ * @note The default is @p TRUE. * @note Requires @p CH_CFG_USE_EVENTS. */ -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#define CH_CFG_USE_EVENTS_TIMEOUT FALSE /** * @brief Synchronous Messages APIs. diff --git a/main.c b/main.c index 8c2c5fe..0ebbd40 100644 --- a/main.c +++ b/main.c @@ -80,55 +80,58 @@ int8_t cal_auto_interpolate = TRUE; uint16_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; -static THD_WORKING_AREA(waThread1, 512); +// +// Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show: +// Stack maximum usage = 480 bytes, free stack = 32+64 bytes +// +static THD_WORKING_AREA(waThread1, 512+64); static THD_FUNCTION(Thread1, arg) { - (void)arg; - chRegSetThreadName("sweep"); + (void)arg; + chRegSetThreadName("sweep"); - while (1) { - bool completed = false; - if (sweep_enabled || sweep_once) { - chMtxLock(&mutex); - // Sweep require 8367 system tick - completed = sweep(true); - sweep_once = FALSE; - chMtxUnlock(&mutex); - } else { - __WFI(); + while (1) { + bool completed = false; + if (sweep_enabled || sweep_once) { + chMtxLock(&mutex); + // Sweep require 8367 system tick + completed = sweep(true); + sweep_once = FALSE; + chMtxUnlock(&mutex); + } else { + __WFI(); + } + + chMtxLock(&mutex); + // Ui and render require 800 system tick + ui_process(); + + if (sweep_enabled) { + if (vbat != -1) { + adc_stop(ADC1); + vbat = adc_vbat_read(ADC1); + touch_start_watchdog(); + draw_battery_status(); } - chMtxLock(&mutex); - // Ui and render require 800 system tick - ui_process(); - - if (sweep_enabled) { - if (vbat != -1) { - adc_stop(ADC1); - vbat = adc_vbat_read(ADC1); - touch_start_watchdog(); - draw_battery_status(); - } + // calculate trace coordinates and plot only if scan completed + if (completed) { + plot_into_index(measured); + redraw_request |= REDRAW_CELLS; - /* calculate trace coordinates and plot only if scan completed */ - if (completed) { - plot_into_index(measured); - redraw_request |= REDRAW_CELLS; - - if (marker_tracking) { - int i = marker_search(); - if (i != -1 && active_marker != -1) { - markers[active_marker].index = i; - redraw_request |= REDRAW_MARKER; - } + if (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); } + // plot trace and other indications as raster + draw_all(completed); // flush markmap only if scan completed to prevent remaining traces + chMtxUnlock(&mutex); + } } void @@ -207,6 +210,7 @@ transform_domain(void) break; } + for (int ch = 0; ch < 2; ch++) { memcpy(tmp, measured[ch], sizeof(measured[0])); for (int i = 0; i < POINTS_COUNT; i++) { @@ -1939,12 +1943,22 @@ VNA_SHELL_FUNCTION(cmd_threads) { thread_t *tp; (void)argc; (void)argv; - chprintf(chp, "stklimit stack addr refs prio state name"VNA_SHELL_NEWLINE_STR); + shell_printf("stklimit| stack|stk free| addr|refs|prio| state| name"VNA_SHELL_NEWLINE_STR); tp = chRegFirstThread(); do { + uint32_t max_stack_use = 0U; +#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) uint32_t stklimit = (uint32_t)tp->wabase; - shell_printf("%08x %08x %08x %4u %4u %9s %12s"VNA_SHELL_NEWLINE_STR, - stklimit, (uint32_t)tp->ctx.sp, (uint32_t)tp, +#if CH_DBG_FILL_THREADS == TRUE + uint8_t *p = (uint8_t *)tp->wabase; while(p[max_stack_use]==CH_DBG_STACK_FILL_VALUE) max_stack_use++; +#endif +#else + uint32_t stklimit = 0U; +#endif + + + shell_printf("%08x|%08x|%08x|%08x|%4u|%4u|%9s|%12s"VNA_SHELL_NEWLINE_STR, + stklimit, (uint32_t)tp->ctx.sp, max_stack_use, (uint32_t)tp, (uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state], tp->name == NULL ? "" : tp->name); tp = chRegNextThread(tp); @@ -2142,68 +2156,65 @@ static DACConfig dac1cfg1 = { datamode: DAC_DHRM_12BIT_RIGHT }; + +// Main thread stack size defined in makefile USE_PROCESS_STACKSIZE = 0x200 +// Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show: +// Stack maximum usage = 472 bytes (need test more and run all commands), free stack = 40 bytes +// 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); - si5351_init(); - - // MCO on PA8 - //palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(0)); - /* - * Initializes a serial-over-USB CDC driver. - */ - sduObjectInit(&SDU1); - sduStart(&SDU1, &serusbcfg); - - /* - * Activates the USB driver and then the USB bus pull-up on D+. - * Note, a delay is inserted in order to not have to disconnect the cable - * after a reset. - */ - usbDisconnectBus(serusbcfg.usbp); - chThdSleepMilliseconds(100); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); - - /* - * SPI LCD Initialize - */ - ili9341_init(); + halInit(); + chSysInit(); - /* - * Initialize graph plotting - */ - plot_init(); + 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); + si5351_init(); + + // MCO on PA8 + //palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(0)); +/* + * Initializes a serial-over-USB CDC driver. + */ + sduObjectInit(&SDU1); + sduStart(&SDU1, &serusbcfg); +/* + * Activates the USB driver and then the USB bus pull-up on D+. + * Note, a delay is inserted in order to not have to disconnect the cable + * after a reset. + */ + usbDisconnectBus(serusbcfg.usbp); + chThdSleepMilliseconds(100); + usbStart(serusbcfg.usbp, &usbcfg); + usbConnectBus(serusbcfg.usbp); - /* restore config */ +/* + * SPI LCD Initialize + */ + ili9341_init(); + +/* restore config */ config_recall(); dac1cfg1.init = config.dac_value; - /* - * Starting DAC1 driver, setting up the output pin as analog as suggested - * by the Reference Manual. - */ +/* + * Starting DAC1 driver, setting up the output pin as analog as suggested + * by the Reference Manual. + */ dacStart(&DACD2, &dac1cfg1); - /* initial frequencies */ +/* initial frequencies */ update_frequencies(); - /* restore frequencies and calibration properties from flash memory */ +/* restore frequencies and calibration properties from flash memory */ if (config.default_loadcal >= 0) caldata_recall(config.default_loadcal); - redraw_frame(); - - /* - * I2S Initialize - */ +/* + * I2S Initialize + */ tlv320aic3204_init(); i2sInit(); i2sObjectInit(&I2SD2); @@ -2211,12 +2222,17 @@ int main(void) i2sStartExchange(&I2SD2); ui_init(); - + //Initialize graph plotting + plot_init(); + redraw_frame(); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO-1, Thread1, NULL); while (1) { if (SDU1.config->usbp->state == USB_ACTIVE) { #ifdef VNA_SHELL_THREAD +#if CH_CFG_USE_WAITEXIT == FALSE +#error "VNA_SHELL_THREAD use chThdWait, need enable CH_CFG_USE_WAITEXIT in chconf.h" +#endif thread_t *shelltp = chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO + 1, myshellThread, NULL); diff --git a/plot.c b/plot.c index c909e09..b696397 100644 --- a/plot.c +++ b/plot.c @@ -1462,7 +1462,7 @@ cell_drawstring(char *str, int x, int y) static void cell_draw_marker_info(int x0, int y0) { - char buf[32]; + char buf[24]; int t; if (active_marker < 0) return; @@ -1474,8 +1474,8 @@ cell_draw_marker_info(int x0, int y0) for (mk = 0; mk < MARKERS_MAX; mk++) { if (!markers[mk].enabled) continue; - int xpos = 1 + (j%2)*146 + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*8 - y0; + int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; setForegroundColor(config.trace_color[t]); if (mk == active_marker) @@ -1507,13 +1507,13 @@ cell_draw_marker_info(int x0, int y0) // draw marker delta if (!uistat.marker_delta && previous_marker >= 0 && active_marker != previous_marker && markers[previous_marker].enabled) { int idx0 = markers[previous_marker].index; - int xpos = 180 + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*8 - y0; + int xpos = (WIDTH/2+30) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; - plot_printf(buf, sizeof buf, S_DELTA"%d-%d", active_marker+1, previous_marker+1); + plot_printf(buf, sizeof buf, S_DELTA"%d-%d:", active_marker+1, previous_marker+1); setForegroundColor(DEFAULT_FG_COLOR); cell_drawstring(buf, xpos, ypos); - xpos += 24; + xpos += 27; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { uint32_t freq = frequencies[idx]; uint32_t freq1 = frequencies[idx0]; @@ -1528,8 +1528,8 @@ cell_draw_marker_info(int x0, int y0) for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - int xpos = 1 + (j%2)*146 + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*8 - y0; + int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; setForegroundColor(config.trace_color[t]); if (t == uistat.current_trace) @@ -1550,8 +1550,8 @@ cell_draw_marker_info(int x0, int y0) } // draw marker frequency - int xpos = 185 + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*8 - y0; + int xpos = (WIDTH/2+40) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; setForegroundColor(DEFAULT_FG_COLOR); if (uistat.lever_mode == LM_MARKER) @@ -1572,7 +1572,7 @@ cell_draw_marker_info(int x0, int y0) if (electrical_delay != 0) { // draw electrical delay int xpos = 21 + CELLOFFSETX - x0; - int ypos = 1 + ((j+1)/2)*8 - y0; + int ypos = 1 + ((j+1)/2)*(FONT_GET_HEIGHT+1) - y0; float light_speed_ps = 299792458e-12; //(m/ps) plot_printf(buf, sizeof buf, "Edelay %Fs %Fm", electrical_delay * 1e-12, @@ -1663,7 +1663,7 @@ draw_battery_status(void) { if (vbat<=0) return; - uint8_t string_buf[25]; + uint8_t string_buf[16]; // Set battery color setForegroundColor(vbat < BATTERY_WARNING_LEVEL ? DEFAULT_LOW_BAT_COLOR : DEFAULT_NORMAL_BAT_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); @@ -1697,7 +1697,8 @@ request_to_redraw_grid(void) void redraw_frame(void) { - ili9341_fill(0, 0, 320, 240, DEFAULT_BG_COLOR); + setBackgroundColor(DEFAULT_BG_COLOR); + clearScreen(); draw_frequencies(); draw_cal_status(); } diff --git a/ui.c b/ui.c index d5c2d83..a1765e2 100644 --- a/ui.c +++ b/ui.c @@ -1271,7 +1271,7 @@ draw_numeric_area_frame(void) ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, DEFAULT_MENU_COLOR); setForegroundColor(DEFAULT_MENU_TEXT_COLOR); setBackgroundColor(DEFAULT_MENU_COLOR); - ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-FONT_GET_HEIGHT-(NUM_INPUT_HEIGHT-FONT_GET_HEIGHT)/2); + ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); //ili9341_drawfont(KP_KEYPAD, 300, 216); } @@ -1297,8 +1297,8 @@ draw_numeric_input(const char *buf) if (ui_mode == UI_NUMERIC && uistat.digit == 8-i) { fg = DEFAULT_SPEC_INPUT_COLOR; focused = TRUE; - if (uistat.digit_mode) - bg = DEFAULT_MENU_COLOR; +// if (uistat.digit_mode) +// bg = DEFAULT_MENU_COLOR; } setForegroundColor(fg); setBackgroundColor(bg); @@ -1307,12 +1307,12 @@ draw_numeric_input(const char *buf) else if (focused) // c not number, but focused ili9341_drawfont(0, x, 240-NUM_INPUT_HEIGHT+4); else // erase - ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, 20, 24, bg); + ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_HEIGHT, NUM_FONT_GET_WIDTH+2+8, bg); 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, 24, DEFAULT_MENU_COLOR); + ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, DEFAULT_MENU_COLOR); } static int @@ -1607,7 +1607,7 @@ ui_mode_numeric(int _keypad_mode) keypad_mode = _keypad_mode; ui_mode = UI_NUMERIC; area_width = AREA_WIDTH_NORMAL; - area_height = 240-32;//AREA_HEIGHT_NORMAL - 32; + area_height = 240-NUM_INPUT_HEIGHT;//AREA_HEIGHT_NORMAL - 32; draw_numeric_area_frame(); fetch_numeric_target(); @@ -1629,7 +1629,7 @@ ui_mode_keypad(int _keypad_mode) keypads_last_index = i; ui_mode = UI_KEYPAD; - area_width = AREA_WIDTH_NORMAL - 60; + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; area_height = HEIGHT - 32; draw_menu(); draw_keypad(); @@ -1740,7 +1740,7 @@ ui_process_normal(void) if (status & EVT_BUTTON_SINGLE_CLICK) { ui_mode_menu(); } else { - switch (uistat.lever_mode) { + switch (uistat.lever_mode) { case LM_MARKER: lever_move_marker(status); break; case LM_SEARCH: lever_search_marker(status); break; case LM_CENTER: @@ -2051,7 +2051,6 @@ ui_process_lever(void) } } - static void drag_marker(int t, int m) { From 95b3f6f7d0fca8b6c15506227db70f60fcbe500d Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 27 Feb 2020 21:21:54 +0300 Subject: [PATCH 21/65] Disable ChibiOS option CH_CFG_USE_MUTEXES_RECURSIVE All calls chMtxLock - chMtxUnlock not recursive --- chconf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chconf.h b/chconf.h index 09a6139..5e5ce40 100644 --- a/chconf.h +++ b/chconf.h @@ -193,7 +193,7 @@ * @note The default is @p FALSE. * @note Requires @p CH_CFG_USE_MUTEXES. */ -#define CH_CFG_USE_MUTEXES_RECURSIVE TRUE +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE /** * @brief Conditional Variables APIs. From cb587d05a45e889e86cbd54d0128f725effc0543 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 27 Feb 2020 22:11:32 +0300 Subject: [PATCH 22/65] Makefile: Remove compile #include $(CHIBIOS)/test/rt/test.mk #include $(CHIBIOS)/os/various/shell/shell.mk Shell not used, test not used --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 73ebbd9..bd17844 100644 --- a/Makefile +++ b/Makefile @@ -100,9 +100,9 @@ include $(CHIBIOS)/os/hal/osal/rt/osal.mk include $(CHIBIOS)/os/rt/rt.mk include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk # Other files (optional). -include $(CHIBIOS)/test/rt/test.mk +#include $(CHIBIOS)/test/rt/test.mk include $(CHIBIOS)/os/hal/lib/streams/streams.mk -include $(CHIBIOS)/os/various/shell/shell.mk +#include $(CHIBIOS)/os/various/shell/shell.mk # Define linker script file here #LDSCRIPT= $(STARTUPLD)/STM32F072xB.ld From 0116c529ea6d0a72e2451a561cd0feb41f37ae5e Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 28 Feb 2020 00:50:12 +0300 Subject: [PATCH 23/65] Restore sweep stack size as 640 --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 0ebbd40..66e43ed 100644 --- a/main.c +++ b/main.c @@ -82,9 +82,9 @@ int16_t vbat = 0; // // Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show: -// Stack maximum usage = 480 bytes, free stack = 32+64 bytes +// Stack maximum usage = 576 bytes, free stack = 64 bytes // -static THD_WORKING_AREA(waThread1, 512+64); +static THD_WORKING_AREA(waThread1, 640); static THD_FUNCTION(Thread1, arg) { (void)arg; From a164a5765ab00c402ec64747eeb841b954b24f83 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 28 Feb 2020 18:52:25 +0300 Subject: [PATCH 24/65] Disable HAL_USE_RTC usage (need for cmd_time) Add ENABLE_TIME_COMMAND for enable cmd_time if need Fix incorrect data on run cmd_scan cmd_data if Tansform enabled on NanoVNA (remove transform_domain() from sweep, add in front of plot_into_index in sweep thread) Remove pause/run in reload (not need, command run vs CMD_WAIT_MUTEX flag) --- halconf.h | 2 +- main.c | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/halconf.h b/halconf.h index 9a44c8b..38341a0 100644 --- a/halconf.h +++ b/halconf.h @@ -118,7 +118,7 @@ * @brief Enables the RTC subsystem. */ #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) -#define HAL_USE_RTC TRUE +#define HAL_USE_RTC FALSE #endif /** diff --git a/main.c b/main.c index 66e43ed..a6105ce 100644 --- a/main.c +++ b/main.c @@ -56,6 +56,7 @@ static char shell_line[VNA_SHELL_MAX_LENGTH]; //#define ENABLED_DUMP //#define ENABLE_THREADS_COMMAND +//#define ENABLE_TIME_COMMAND static void apply_error_term_at(int i); static void apply_edelay_at(int i); @@ -63,7 +64,8 @@ static void cal_interpolate(int s); void update_frequencies(void); void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); -bool sweep(bool break_on_operation); +static bool sweep(bool break_on_operation); +static void transform_domain(void); static MUTEX_DECL(mutex); @@ -75,7 +77,7 @@ int32_t frequency_offset = 5000; uint32_t frequency = 10000000; int8_t drive_strength = DRIVE_STRENGTH_AUTO; int8_t sweep_enabled = TRUE; -int8_t sweep_once = FALSE; +volatile int8_t sweep_once = FALSE; int8_t cal_auto_interpolate = TRUE; uint16_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; @@ -116,6 +118,8 @@ static THD_FUNCTION(Thread1, arg) // 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; @@ -134,13 +138,13 @@ static THD_FUNCTION(Thread1, arg) } } -void +static inline void pause_sweep(void) { sweep_enabled = FALSE; } -void +static inline void resume_sweep(void) { sweep_enabled = TRUE; @@ -468,6 +472,10 @@ VNA_SHELL_FUNCTION(cmd_power) set_frequency(frequency); } +#ifdef ENABLE_TIME_COMMAND +#if HAL_USE_RTC == FALSE +#error "Error cmd_time require ENABLE_TIME_COMMAND = TRUE in halconf.h" +#endif VNA_SHELL_FUNCTION(cmd_time) { RTCDateTime timespec; @@ -476,7 +484,7 @@ VNA_SHELL_FUNCTION(cmd_time) rtcGetTime(&RTCD1, ×pec); shell_printf("%d/%d/%d %d\r\n", timespec.year+1980, timespec.month, timespec.day, timespec.millisecond); } - +#endif VNA_SHELL_FUNCTION(cmd_dac) { @@ -786,8 +794,6 @@ bool sweep(bool break_on_operation) } // blink LED while scanning palSetPad(GPIOC, GPIOC_LED); - if ((domain_mode & DOMAIN_MODE) == DOMAIN_TIME) - transform_domain(); return true; } @@ -1467,13 +1473,11 @@ VNA_SHELL_FUNCTION(cmd_recall) if (id < 0 || id >= SAVEAREA_MAX) goto usage; - pause_sweep(); if (caldata_recall(id) == 0) { // success update_frequencies(); redraw_request |= REDRAW_CAL_STATUS; } - resume_sweep(); return; usage: @@ -1985,7 +1989,9 @@ static const VNAShellCommand commands[] = {"reset" , cmd_reset , 0}, {"freq" , cmd_freq , CMD_WAIT_MUTEX}, {"offset" , cmd_offset , 0}, +#ifdef ENABLE_TIME_COMMAND {"time" , cmd_time , 0}, +#endif {"dac" , cmd_dac , 0}, {"saveconfig" , cmd_saveconfig , 0}, {"clearconfig" , cmd_clearconfig , 0}, From cc3370c962e618118a6a6ded5694c5d9dcd45617 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 28 Feb 2020 18:57:18 +0300 Subject: [PATCH 25/65] si5351.c Remove unused function from header Set static calls for functions (less size) Set static constants (less size) --- si5351.c | 35 +++++++++++++++++++---------------- si5351.h | 12 ------------ 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/si5351.c b/si5351.c index 8c548a3..56ba597 100644 --- a/si5351.c +++ b/si5351.c @@ -69,15 +69,17 @@ si5351_init(void) } } +static const uint8_t disable_output[] = { + SI5351_REG_16_CLK0_CONTROL, + SI5351_CLK_POWERDOWN, + SI5351_CLK_POWERDOWN, + SI5351_CLK_POWERDOWN +}; + void si5351_disable_output(void) { - uint8_t reg[4]; si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff); - reg[0] = SI5351_REG_16_CLK0_CONTROL; - reg[1] = SI5351_CLK_POWERDOWN; - reg[2] = SI5351_CLK_POWERDOWN; - reg[3] = SI5351_CLK_POWERDOWN; - si5351_bulk_write(reg, 4); + si5351_bulk_write(disable_output, sizeof(disable_output)); } void si5351_enable_output(void) @@ -85,19 +87,19 @@ void si5351_enable_output(void) si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0x00); } -void si5351_reset_pll(void) +static void si5351_reset_pll(void) { //si5351_write(SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); si5351_write(SI5351_REG_177_PLL_RESET, 0xAC); } -void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ +static void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ uint8_t mult, uint32_t num, uint32_t denom) { /* Get the appropriate starting point for the PLL registers */ - const uint8_t pllreg_base[] = { + static const uint8_t pllreg_base[] = { SI5351_REG_26_PLL_A, SI5351_REG_34_PLL_B }; @@ -147,9 +149,9 @@ void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ si5351_bulk_write(reg, 9); } -void +static void si5351_setupMultisynth(uint8_t output, - uint8_t pllSource, + uint8_t pllSource, uint32_t div, // 4,6,8, 8+ ~ 900 uint32_t num, uint32_t denom, @@ -157,12 +159,12 @@ si5351_setupMultisynth(uint8_t output, uint8_t drive_strength) { /* Get the appropriate starting point for the PLL registers */ - const uint8_t msreg_base[] = { + static const uint8_t msreg_base[] = { SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2, }; - const uint8_t clkctrl[] = { + static const uint8_t clkctrl[] = { SI5351_REG_16_CLK0_CONTROL, SI5351_REG_17_CLK1_CONTROL, SI5351_REG_18_CLK2_CONTROL @@ -226,7 +228,7 @@ si5351_setupMultisynth(uint8_t output, #define PLL_N 32 #define PLLFREQ (XTALFREQ * PLL_N) -void +static void si5351_set_frequency_fixedpll(int channel, int pll, uint32_t pllfreq, uint32_t freq, int rdiv, uint8_t drive_strength, int mul) { @@ -255,7 +257,7 @@ si5351_set_frequency_fixedpll(int channel, int pll, uint32_t pllfreq, uint32_t f si5351_setupMultisynth(channel, pll, div, num, denom, rdiv, drive_strength); } -void +static void si5351_set_frequency_fixeddiv(int channel, int pll, uint32_t freq, int div, uint8_t drive_strength, int mul) { @@ -291,6 +293,7 @@ si5351_set_frequency_fixeddiv(int channel, int pll, uint32_t freq, int div, * 100~150MHz fractional PLL 600-900MHz, fixed divider 6 * 150~200MHz fractional PLL 600-900MHz, fixed divider 4 */ +#if 0 void si5351_set_frequency(int channel, int freq, uint8_t drive_strength) { @@ -303,7 +306,7 @@ si5351_set_frequency(int channel, int freq, uint8_t drive_strength) si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength, 1); } } - +#endif int current_band = -1; diff --git a/si5351.h b/si5351.h index 6606454..0a10c96 100644 --- a/si5351.h +++ b/si5351.h @@ -74,16 +74,4 @@ void si5351_init(void); -void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ - uint8_t mult, - uint32_t num, - uint32_t denom); -void si5351_setupMultisynth(uint8_t output, - uint8_t pllSource, - uint32_t div, - uint32_t num, - uint32_t denom, - uint32_t rdiv, - uint8_t drive_strength); - void si5351_set_frequency(int channel, int freq, uint8_t drive_strength); From ccb369351658dfc6ed70320f759952c28750e04c Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 28 Feb 2020 23:15:38 +0300 Subject: [PATCH 26/65] Huge reduce flash usage (about 5k), remove cal_data and _frequencies properties from data section Use void loadDefaultProps() for load default properties (default loaded also on error load from flash) Move some constants to nanovna.h --- flash.c | 19 +++++++---- main.c | 99 +++++++++++++++++++++++++++++-------------------------- nanovna.h | 18 ++++++++-- ui.c | 11 +++---- 4 files changed, 86 insertions(+), 61 deletions(-) diff --git a/flash.c b/flash.c index 12f2182..6d368e4 100644 --- a/flash.c +++ b/flash.c @@ -122,12 +122,15 @@ config_recall(void) #define SAVEAREA_MAX 5 -const uint32_t saveareas[] = - { 0x08018800, 0x0801a000, 0x0801b800, 0x0801d000, 0x0801e800 }; +const uint32_t saveareas[SAVEAREA_MAX] = { + SAVE_CONFIG_0_ADDR, + SAVE_CONFIG_1_ADDR, + SAVE_CONFIG_2_ADDR, + SAVE_CONFIG_3_ADDR, + SAVE_CONFIG_4_ADDR }; int16_t lastsaveid = 0; - int caldata_save(int id) { @@ -172,15 +175,15 @@ caldata_recall(int id) void *dst = ¤t_props; if (id < 0 || id >= SAVEAREA_MAX) - return -1; + goto load_default; // point to saved area on the flash memory src = (properties_t*)saveareas[id]; if (src->magic != CONFIG_MAGIC) - return -1; + goto load_default; if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) - return -1; + goto load_default; /* active configuration points to save data on flash memory */ active_props = src; @@ -188,8 +191,10 @@ caldata_recall(int id) /* duplicated saved data onto sram to be able to modify marker/trace */ memcpy(dst, src, sizeof(properties_t)); - return 0; +load_default: + loadDefaultProps(); + return -1; } const properties_t * diff --git a/main.c b/main.c index a6105ce..9b58d78 100644 --- a/main.c +++ b/main.c @@ -725,29 +725,44 @@ 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 - .default_loadcal = 0, .harmonic_freq_threshold = 300000000 }; -properties_t current_props = { - .magic = CONFIG_MAGIC, - ._frequency0 = 50000, // start = 50kHz - ._frequency1 = 900000000, // end = 900MHz - ._sweep_points = POINTS_COUNT, - ._trace = {/*enable, type, channel, reserved, scale, refpos*/ - { 1, TRC_LOGMAG, 0, 0, 10.0, NGRIDY-1 }, - { 1, TRC_LOGMAG, 1, 0, 10.0, NGRIDY-1 }, - { 1, TRC_SMITH, 0, 0, 1.0, 0 }, - { 1, TRC_PHASE, 1, 0, 90.0, NGRIDY/2 } - }, - ._markers = { - { 1, 30, 0 }, { 0, 40, 0 }, { 0, 60, 0 }, { 0, 80, 0 } - }, - ._velocity_factor = 0.7, - ._marker_smith_format = MS_RLC -}; +properties_t current_props; properties_t *active_props = ¤t_props; +// NanoVNA Default settings +static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, reserved, scale, refpos + { 1, TRC_LOGMAG, 0, 0, 10.0, NGRIDY-1 }, + { 1, TRC_LOGMAG, 1, 0, 10.0, NGRIDY-1 }, + { 1, TRC_SMITH, 0, 0, 1.0, 0 }, + { 1, TRC_PHASE, 1, 0, 90.0, NGRIDY/2 } +}; + +static const marker_t def_markers[MARKERS_MAX] = { + { 1, 30, 0 }, { 0, 40, 0 }, { 0, 60, 0 }, { 0, 80, 0 } +}; + +// Load propeties default settings +void loadDefaultProps(void){ + current_props.magic = CONFIG_MAGIC; + current_props._frequency0 = 50000; // start = 50kHz + current_props._frequency1 = 900000000; // end = 900MHz + current_props._sweep_points = POINTS_COUNT; + current_props._cal_status = 0; +//This data not loaded by default +//current_props._frequencies[POINTS_COUNT]; +//current_props._cal_data[5][POINTS_COUNT][2]; +//============================================= + current_props._electrical_delay = 0.0; + memcpy(current_props._trace, def_trace, sizeof(def_trace)); + memcpy(current_props._markers, def_markers, sizeof(def_markers)); + current_props._velocity_factor = 0.7; + current_props._active_marker = 0; + current_props._domain_mode = 0; + current_props._marker_smith_format = MS_RLC; +} + void ensure_edit_config(void) { @@ -768,20 +783,19 @@ bool sweep(bool break_on_operation) int i; // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); - for (i = 0; i < sweep_points; i++) { - int delay = set_frequency(frequencies[i]); - tlv320aic3204_select(0); // CH0:REFLECT - wait_dsp(delay); - - /* calculate reflection coefficient */ - (*sample_func)(measured[0][i]); - - tlv320aic3204_select(1); // CH1:TRANSMISSION - wait_dsp(DELAY_CHANNEL_CHANGE); - - /* calculate transmission coefficient */ - (*sample_func)(measured[1][i]); - + for (i = 0; i < sweep_points; i++) { // 8365 + int delay = set_frequency(frequencies[i]); // 1560 + tlv320aic3204_select(0); // 60 CH0:REFLECT + + wait_dsp(delay); // 3270 + // calculate reflection coefficient + (*sample_func)(measured[0][i]); // 60 + + tlv320aic3204_select(1); // 60 CH1:TRANSMISSION + wait_dsp(DELAY_CHANNEL_CHANGE); // 2700 + // calculate transmission coefficient + (*sample_func)(measured[1][i]); // 60 + // ======== 170 =========== if (cal_status & CALSTAT_APPLY) apply_error_term_at(i); @@ -928,9 +942,6 @@ freq_mode_centerspan(void) } } -#define START_MIN 50000 -#define STOP_MAX 2700000000U - void set_sweep_frequency(int type, uint32_t freq) { @@ -1472,14 +1483,12 @@ VNA_SHELL_FUNCTION(cmd_recall) int id = my_atoi(argv[0]); if (id < 0 || id >= SAVEAREA_MAX) goto usage; - - if (caldata_recall(id) == 0) { - // success - update_frequencies(); - redraw_request |= REDRAW_CAL_STATUS; - } + // Check for success + if (caldata_recall(id) == -1) + shell_printf("Err, default load\r\n"); + update_frequencies(); + redraw_request |= REDRAW_CAL_STATUS; return; - usage: shell_printf("recall {id}\r\n"); } @@ -2203,6 +2212,8 @@ int main(void) /* restore config */ config_recall(); +/* restore frequencies and calibration 0 slot properties from flash memory */ + caldata_recall(0); dac1cfg1.init = config.dac_value; /* @@ -2214,10 +2225,6 @@ int main(void) /* initial frequencies */ update_frequencies(); -/* restore frequencies and calibration properties from flash memory */ - if (config.default_loadcal >= 0) - caldata_recall(config.default_loadcal); - /* * I2S Initialize */ diff --git a/nanovna.h b/nanovna.h index e256269..99e7354 100644 --- a/nanovna.h +++ b/nanovna.h @@ -25,6 +25,8 @@ /* * main.c */ +#define START_MIN 50000 +#define STOP_MAX 2700000000U #define POINTS_COUNT 101 extern float measured[2][POINTS_COUNT][2]; @@ -82,9 +84,21 @@ uint32_t get_sweep_frequency(int type); double my_atof(const char *p); void toggle_sweep(void); +void loadDefaultProps(void); extern int8_t sweep_enabled; +/* + * flash.c + */ +#define SAVEAREA_MAX 5 + +#define SAVE_CONFIG_0_ADDR 0x08018800 +#define SAVE_CONFIG_1_ADDR 0x0801a000 +#define SAVE_CONFIG_2_ADDR 0x0801b800 +#define SAVE_CONFIG_3_ADDR 0x0801d000 +#define SAVE_CONFIG_4_ADDR 0x0801e800 + /* * ui.c */ @@ -222,8 +236,8 @@ typedef struct { uint16_t menu_normal_color; uint16_t menu_active_color; uint16_t trace_color[TRACES_MAX]; - int16_t touch_cal[4]; - int8_t default_loadcal; + int16_t touch_cal[4]; + int8_t reserved_1; uint32_t harmonic_freq_threshold; uint8_t _reserved[24]; diff --git a/ui.c b/ui.c index a1765e2..24c59a6 100644 --- a/ui.c +++ b/ui.c @@ -490,12 +490,11 @@ static void menu_recall_cb(int item, uint8_t data) { (void)item; - if (caldata_recall(data) == 0) { - menu_move_back(); - ui_mode_normal(); - update_grid(); - draw_cal_status(); - } + caldata_recall(data); + menu_move_back(); + ui_mode_normal(); + update_grid(); + draw_cal_status(); } static void From 153585ff1f7c5a0743347167666592b401077457 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 28 Feb 2020 23:52:01 +0300 Subject: [PATCH 27/65] Move more address constants to nanovna.h --- flash.c | 16 +++++++--------- nanovna.h | 16 ++++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/flash.c b/flash.c index 6d368e4..9888cb5 100644 --- a/flash.c +++ b/flash.c @@ -78,7 +78,7 @@ checksum(const void *start, size_t len) #define FLASH_PAGESIZE 0x800 -const uint32_t save_config_area = 0x08018000; +const uint32_t save_config_area = SAVE_CONFIG_ADDR; int config_save(void) @@ -120,14 +120,12 @@ config_recall(void) return 0; } -#define SAVEAREA_MAX 5 - const uint32_t saveareas[SAVEAREA_MAX] = { - SAVE_CONFIG_0_ADDR, - SAVE_CONFIG_1_ADDR, - SAVE_CONFIG_2_ADDR, - SAVE_CONFIG_3_ADDR, - SAVE_CONFIG_4_ADDR }; + SAVE_PROP_CONFIG_0_ADDR, + SAVE_PROP_CONFIG_1_ADDR, + SAVE_PROP_CONFIG_2_ADDR, + SAVE_PROP_CONFIG_3_ADDR, + SAVE_PROP_CONFIG_4_ADDR }; int16_t lastsaveid = 0; @@ -212,7 +210,7 @@ caldata_ref(int id) return src; } -const uint32_t save_config_prop_area_size = 0x8000; +const uint32_t save_config_prop_area_size = SAVE_CONFIG_AREA_SIZE; void clear_all_config_prop_data(void) diff --git a/nanovna.h b/nanovna.h index 99e7354..f9e31ae 100644 --- a/nanovna.h +++ b/nanovna.h @@ -92,12 +92,16 @@ extern int8_t sweep_enabled; * flash.c */ #define SAVEAREA_MAX 5 - -#define SAVE_CONFIG_0_ADDR 0x08018800 -#define SAVE_CONFIG_1_ADDR 0x0801a000 -#define SAVE_CONFIG_2_ADDR 0x0801b800 -#define SAVE_CONFIG_3_ADDR 0x0801d000 -#define SAVE_CONFIG_4_ADDR 0x0801e800 +// Begin addr 0x08018000 +#define SAVE_CONFIG_AREA_SIZE 0x00008000 +// config save area +#define SAVE_CONFIG_ADDR 0x08018000 +// properties_t save area +#define SAVE_PROP_CONFIG_0_ADDR 0x08018800 +#define SAVE_PROP_CONFIG_1_ADDR 0x0801a000 +#define SAVE_PROP_CONFIG_2_ADDR 0x0801b800 +#define SAVE_PROP_CONFIG_3_ADDR 0x0801d000 +#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 /* * ui.c From 7f5948c4b848bc816453492fb07e08051fdffe39 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 1 Mar 2020 08:18:12 +0900 Subject: [PATCH 28/65] chore: add scope name onto struct and enum --- nanovna.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nanovna.h b/nanovna.h index f0a903d..e491578 100644 --- a/nanovna.h +++ b/nanovna.h @@ -71,7 +71,7 @@ extern float measured[2][POINTS_COUNT][2]; void cal_collect(int type); void cal_done(void); -enum { +enum stimulus { ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW }; @@ -90,7 +90,7 @@ extern int8_t sweep_enabled; extern void ui_init(void); extern void ui_process(void); -enum { OP_NONE = 0, OP_LEVER, OP_TOUCH, OP_FREQCHANGE }; +enum opreq { OP_NONE = 0, OP_LEVER, OP_TOUCH, OP_FREQCHANGE }; extern uint8_t operation_requested; /* @@ -187,7 +187,7 @@ extern const uint16_t numfont16x22[]; #define TRACES_MAX 4 -enum { +enum trace_type { TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF }; // Mask for define rectangular plot @@ -203,7 +203,7 @@ enum { // Electrical Delay // Phase -typedef struct { +typedef struct trace { uint8_t enabled; uint8_t type; uint8_t channel; @@ -212,7 +212,7 @@ typedef struct { float refpos; } trace_t; -typedef struct { +typedef struct config { int32_t magic; uint16_t dac_value; uint16_t grid_color; @@ -248,7 +248,7 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]); #define MARKERS_MAX 4 -typedef struct { +typedef struct marker { int8_t enabled; int16_t index; uint32_t frequency; @@ -342,7 +342,7 @@ void show_logo(void); */ #define SAVEAREA_MAX 5 -typedef struct { +typedef struct properties { uint32_t magic; uint32_t _frequency0; uint32_t _frequency1; @@ -409,16 +409,16 @@ void clear_all_config_prop_data(void); */ // lever_mode -enum { +enum lever_mode { LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN }; // marker smith value format -enum { +enum marker_smithvalue { MS_LIN, MS_LOG, MS_REIM, MS_RX, MS_RLC }; -typedef struct { +typedef struct uistat { int8_t digit; /* 0~5 */ int8_t digit_mode; int8_t current_trace; /* 0..3 */ From 18c5ca9157c2db7f568009890ff42a3d8360ef96 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 1 Mar 2020 08:50:46 +0900 Subject: [PATCH 29/65] feat: add lever operation of electrical delay --- main.c | 1 + nanovna.h | 2 +- plot.c | 4 ++++ ui.c | 31 +++++++++++++++++++++++++++---- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index c34d85c..e5ca07e 100644 --- a/main.c +++ b/main.c @@ -1667,6 +1667,7 @@ void set_electrical_delay(float picoseconds) electrical_delay = picoseconds; force_set_markmap(); } + redraw_request |= REDRAW_MARKER; } float get_electrical_delay(void) diff --git a/nanovna.h b/nanovna.h index e491578..1c481be 100644 --- a/nanovna.h +++ b/nanovna.h @@ -410,7 +410,7 @@ void clear_all_config_prop_data(void); // lever_mode enum lever_mode { - LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN + LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN, LM_EDELAY }; // marker smith value format diff --git a/plot.c b/plot.c index 3c48dd4..a8b5f62 100644 --- a/plot.c +++ b/plot.c @@ -1599,6 +1599,10 @@ cell_draw_marker_info(int m, int n, int w, int h) xpos -= m * CELLWIDTH -CELLOFFSETX; ypos -= n * CELLHEIGHT; + if (uistat.lever_mode == LM_EDELAY) + cell_drawstring(w, h, S_SARROW, xpos, ypos); + xpos += 5; + float light_speed_ps = 299792458e-12; //(m/ps) chsnprintf(buf, sizeof buf, "Edelay %Fs %Fm", electrical_delay * 1e-12, electrical_delay * light_speed_ps * velocity_factor); diff --git a/ui.c b/ui.c index bd00964..ec302c7 100644 --- a/ui.c +++ b/ui.c @@ -1756,6 +1756,23 @@ lever_move(int status, int mode) } } +#define STEPRATIO 0.2 + +static void +lever_edelay(int status) +{ + float value = get_electrical_delay(); + float ratio = STEPRATIO; + if (value < 0) + ratio = -ratio; + if (status & EVT_UP) { + value = (1 - ratio) * value; + } else if (status & EVT_DOWN) { + value = (1 + ratio) * value; + } + set_electrical_delay(value); +} + static void ui_process_normal(void) { @@ -1774,7 +1791,10 @@ ui_process_normal(void) if (FREQ_IS_STARTSTOP()) lever_move(status, ST_STOP); else - lever_zoom_span(status); + lever_zoom_span(status); + break; + case LM_EDELAY: + lever_edelay(status); break; } } @@ -2148,15 +2168,18 @@ touch_lever_mode_select(void) touch_position(&touch_x, &touch_y); if (touch_y > HEIGHT) { if (touch_x < 160) { - select_lever_mode(LM_CENTER); + select_lever_mode(LM_CENTER); } else { - select_lever_mode(LM_SPAN); + select_lever_mode(LM_SPAN); } return TRUE; } if (touch_y < 15) { - select_lever_mode(LM_MARKER); + if (touch_x < 160 && get_electrical_delay() != 0.0) { + select_lever_mode(LM_EDELAY); + } else + select_lever_mode(LM_MARKER); return TRUE; } From b77e1d66802e0b7f9d95e567b11906493435c163 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 5 Mar 2020 22:36:44 +0300 Subject: [PATCH 30/65] Big work around si5351 generator Improve sweep speed about 60% Stop generation on pause sweep Remove all hack for si5351 Reduce code size Fix integer overflow on big freq values Additional Change I2C Others: move marker_tracking variable to ui config move some definition to correct place reduce tlv320aic3204 code size Speedup marker move from lever (BUTTON_REPEAT_TICKS = 625) Need test stability --- main.c | 75 ++++++---- nanovna.h | 56 ++++---- plot.c | 1 - si5351.c | 353 ++++++++++++++++++++++++------------------------ si5351.h | 19 ++- tlv320aic3204.c | 157 ++++++++++----------- ui.c | 80 +++++------ 7 files changed, 371 insertions(+), 370 deletions(-) diff --git a/main.c b/main.c index bb5580b..4f35b24 100644 --- a/main.c +++ b/main.c @@ -69,10 +69,6 @@ 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) - int32_t frequency_offset = 5000; uint32_t frequency = 10000000; int8_t drive_strength = DRIVE_STRENGTH_AUTO; @@ -101,6 +97,7 @@ static THD_FUNCTION(Thread1, arg) sweep_once = FALSE; chMtxUnlock(&mutex); } else { + si5351_disable_output(); __WFI(); } @@ -123,7 +120,7 @@ static THD_FUNCTION(Thread1, arg) plot_into_index(measured); redraw_request |= REDRAW_CELLS; - if (marker_tracking) { + if (uistat.marker_tracking) { int i = marker_search(); if (i != -1 && active_marker != -1) { markers[active_marker].index = i; @@ -316,7 +313,7 @@ const int8_t gain_table[] = { 95 // 2400MHz ~ }; -#define DELAY_GAIN_CHANGE 10 +#define DELAY_GAIN_CHANGE 2 static int adjust_gain(int newfreq) @@ -474,7 +471,7 @@ VNA_SHELL_FUNCTION(cmd_power) #ifdef ENABLE_TIME_COMMAND #if HAL_USE_RTC == FALSE -#error "Error cmd_time require ENABLE_TIME_COMMAND = TRUE in halconf.h" +#error "Error cmd_time require define HAL_USE_RTC = TRUE in halconf.h" #endif VNA_SHELL_FUNCTION(cmd_time) { @@ -745,7 +742,8 @@ static const marker_t def_markers[MARKERS_MAX] = { // Load propeties default settings void loadDefaultProps(void){ - current_props.magic = CONFIG_MAGIC; +//Magic add on caldata_save +//current_props.magic = CONFIG_MAGIC; current_props._frequency0 = 50000; // start = 50kHz current_props._frequency1 = 900000000; // end = 900MHz current_props._sweep_points = POINTS_COUNT; @@ -761,6 +759,8 @@ void loadDefaultProps(void){ current_props._active_marker = 0; current_props._domain_mode = 0; current_props._marker_smith_format = MS_RLC; +//Checksum add on caldata_save +//current_props.checksum = 0; } void @@ -775,7 +775,7 @@ ensure_edit_config(void) cal_status = 0; } -#define DELAY_CHANNEL_CHANGE 3 +#define DELAY_CHANNEL_CHANGE 2 // main loop for measurement bool sweep(bool break_on_operation) @@ -783,11 +783,17 @@ bool sweep(bool break_on_operation) int i; // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); + systime_t time = chVTGetSystemTimeX(); + systime_t sweep_t = 0; + si5351_enable_output(); + // On CW set freq once, and run for (i = 0; i < sweep_points; i++) { // 8365 + sweep_t-= chVTGetSystemTimeX(); int delay = set_frequency(frequencies[i]); // 1560 + sweep_t+= chVTGetSystemTimeX(); tlv320aic3204_select(0); // 60 CH0:REFLECT - wait_dsp(delay); // 3270 + wait_dsp(delay+(i==0 ? 1 :0)); // 3270 // calculate reflection coefficient (*sample_func)(measured[0][i]); // 60 @@ -803,9 +809,11 @@ bool sweep(bool break_on_operation) apply_edelay_at(i); // back to toplevel to handle ui operation - if (operation_requested && break_on_operation) + if (operation_requested && break_on_operation){ return false; + } } + {char string_buf[18];plot_printf(string_buf, sizeof string_buf, "T:%06d:%06d", chVTGetSystemTimeX() - time, sweep_t);ili9341_drawstringV(string_buf, 1, 90);} // blink LED while scanning palSetPad(GPIOC, GPIOC_LED); return true; @@ -912,7 +920,7 @@ update_frequencies(void) } set_frequencies(start, stop, sweep_points); - operation_requested = OP_FREQCHANGE; +// operation_requested|= OP_FREQCHANGE; update_marker_index(); @@ -1430,6 +1438,7 @@ VNA_SHELL_FUNCTION(cmd_cal) shell_printf("\r\n"); return; } + redraw_request|=REDRAW_CAL_STATUS; // 0 1 2 3 4 5 6 7 8 9 10 static const char cmd_cal_list[] = "load|open|short|thru|isoln|done|on|off|reset|data|in"; switch (getStringIndex(argv[0], cmd_cal_list)){ @@ -1439,9 +1448,9 @@ VNA_SHELL_FUNCTION(cmd_cal) case 3:cal_collect(CAL_THRU ); return; case 4:cal_collect(CAL_ISOLN); return; case 5:cal_done(); return; - case 6:cal_status|= CALSTAT_APPLY;redraw_request|=REDRAW_CAL_STATUS; return; - case 7:cal_status&=~CALSTAT_APPLY;redraw_request|=REDRAW_CAL_STATUS; return; - case 8:cal_status = 0; redraw_request|=REDRAW_CAL_STATUS; return; + case 6:cal_status|= CALSTAT_APPLY;return; + case 7:cal_status&=~CALSTAT_APPLY;return; + case 8:cal_status = 0; return; case 9: shell_printf("%f %f\r\n", cal_data[CAL_LOAD ][0][0], cal_data[CAL_LOAD ][0][1]); shell_printf("%f %f\r\n", cal_data[CAL_OPEN ][0][0], cal_data[CAL_OPEN ][0][1]); @@ -1451,11 +1460,9 @@ VNA_SHELL_FUNCTION(cmd_cal) return; case 10: cal_interpolate((argc > 1) ? my_atoi(argv[1]) : 0); - redraw_request|=REDRAW_CAL_STATUS; return; default:break; } - shell_printf("usage: cal [%s]\r\n", cmd_cal_list); } @@ -1687,14 +1694,13 @@ VNA_SHELL_FUNCTION(cmd_marker) } return; } + redraw_request |= REDRAW_MARKER; if (strcmp(argv[0], "off") == 0) { active_marker = -1; for (t = 0; t < MARKERS_MAX; t++) markers[t].enabled = FALSE; - redraw_request |= REDRAW_MARKER; return; } - t = my_atoi(argv[0])-1; if (t < 0 || t >= MARKERS_MAX) goto usage; @@ -1703,13 +1709,12 @@ VNA_SHELL_FUNCTION(cmd_marker) active_marker = t; // select active marker markers[t].enabled = TRUE; - redraw_request |= REDRAW_MARKER; return; } static const char cmd_marker_list[] = "on|off"; switch (getStringIndex(argv[1], cmd_marker_list)){ - case 0: markers[t].enabled = TRUE; active_marker = t; redraw_request |= REDRAW_MARKER; return; - case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = -1; redraw_request|=REDRAW_MARKER; return; + case 0: markers[t].enabled = TRUE; active_marker = t; return; + case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = -1; return; default: // select active marker and move to index markers[t].enabled = TRUE; @@ -1717,7 +1722,6 @@ VNA_SHELL_FUNCTION(cmd_marker) markers[t].index = index; markers[t].frequency = frequencies[index]; active_marker = t; - redraw_request |= REDRAW_MARKER; return; } usage: @@ -1923,8 +1927,8 @@ VNA_SHELL_FUNCTION(cmd_stat) //shell_printf("interval cycle: %d\r\n", stat.interval_cycles); //shell_printf("busy cycle: %d\r\n", stat.busy_cycles); //shell_printf("load: %d\r\n", stat.busy_cycles * 100 / stat.interval_cycles); - extern int awd_count; - shell_printf("awd: %d\r\n", awd_count); +// extern int awd_count; +// shell_printf("awd: %d\r\n", awd_count); } @@ -2160,10 +2164,25 @@ THD_FUNCTION(myshellThread, p) { } #endif +// I2C clock bus setting: depend from STM32_I2C1SW in mcuconf.h +// STM32_I2C1SW = STM32_I2C1SW_HSI (HSI=8MHz) +// STM32_I2C1SW = STM32_I2C1SW_SYSCLK (SYSCLK = 48MHz) static const I2CConfig i2ccfg = { - 0x00300506, //voodoo magic 400kHz @ HSI 8MHz - 0, - 0 + // TIMINGR register initialization. (use I2C timing configuration tool for STM32F3xx and STM32F0xx microcontrollers (AN4235)) + // 400kHz @ SYSCLK 48MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) +// STM32_TIMINGR_PRESC(5U) | +// STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) | +// STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), +// 400kHz @ HSI 8MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) + STM32_TIMINGR_PRESC(0U) | + STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(1U) | + STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), +// Old values voodoo magic 400kHz @ HSI 8MHz +// STM32_TIMINGR_PRESC(0U) | +// STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(0U) | +// STM32_TIMINGR_SCLH(5U) | STM32_TIMINGR_SCLL(6U), + 0, // CR1 register initialization. + 0 // CR2 register initialization. }; static DACConfig dac1cfg1 = { diff --git a/nanovna.h b/nanovna.h index 524b2aa..ba87162 100644 --- a/nanovna.h +++ b/nanovna.h @@ -88,30 +88,6 @@ void loadDefaultProps(void); extern int8_t sweep_enabled; -/* - * flash.c - */ -#define SAVEAREA_MAX 5 -// Begin addr 0x08018000 -#define SAVE_CONFIG_AREA_SIZE 0x00008000 -// config save area -#define SAVE_CONFIG_ADDR 0x08018000 -// properties_t save area -#define SAVE_PROP_CONFIG_0_ADDR 0x08018800 -#define SAVE_PROP_CONFIG_1_ADDR 0x0801a000 -#define SAVE_PROP_CONFIG_2_ADDR 0x0801b800 -#define SAVE_PROP_CONFIG_3_ADDR 0x0801d000 -#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 - -/* - * ui.c - */ -extern void ui_init(void); -extern void ui_process(void); - -enum opreq { OP_NONE = 0, OP_LEVER, OP_TOUCH, OP_FREQCHANGE }; -extern uint8_t operation_requested; - /* * dsp.c */ @@ -134,9 +110,6 @@ void calculate_gamma(float *gamma); void fetch_amplitude(float *gamma); void fetch_amplitude_ref(float *gamma); -int si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength); - - /* * tlv320aic3204.c */ @@ -250,6 +223,10 @@ typedef struct config { extern config_t config; +#define DRIVE_STRENGTH_AUTO (-1) +#define FREQ_HARMONICS (config.harmonic_freq_threshold) +#define IS_HARMONIC_MODE(f) ((f) > FREQ_HARMONICS) + //extern trace_t trace[TRACES_MAX]; void set_trace_type(int t, int type); @@ -366,6 +343,16 @@ void show_logo(void); * flash.c */ #define SAVEAREA_MAX 5 +// Begin addr 0x08018000 +#define SAVE_CONFIG_AREA_SIZE 0x00008000 +// config save area +#define SAVE_CONFIG_ADDR 0x08018000 +// properties_t save area +#define SAVE_PROP_CONFIG_0_ADDR 0x08018800 +#define SAVE_PROP_CONFIG_1_ADDR 0x0801a000 +#define SAVE_PROP_CONFIG_2_ADDR 0x0801b800 +#define SAVE_PROP_CONFIG_3_ADDR 0x0801d000 +#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 typedef struct properties { uint32_t magic; @@ -432,6 +419,15 @@ void clear_all_config_prop_data(void); /* * ui.c */ +extern void ui_init(void); +extern void ui_process(void); + +// Irq operation process set +#define OP_NONE 0x00 +#define OP_LEVER 0x01 +#define OP_TOUCH 0x02 +//#define OP_FREQCHANGE 0x04 +extern volatile uint8_t operation_requested; // lever_mode enum lever_mode { @@ -448,13 +444,13 @@ typedef struct uistat { int8_t digit_mode; int8_t current_trace; /* 0..3 */ uint32_t value; // for editing at numeric input area - uint32_t previous_value; +// uint32_t previous_value; uint8_t lever_mode; - bool marker_delta; + uint8_t marker_delta; + uint8_t marker_tracking; } uistat_t; extern uistat_t uistat; - void ui_init(void); void ui_show(void); void ui_hide(void); diff --git a/plot.c b/plot.c index 70f5e31..d1762f0 100644 --- a/plot.c +++ b/plot.c @@ -1056,7 +1056,6 @@ static int greater(int x, int y) { return x > y; } static int lesser(int x, int y) { return x < y; } static int (*compare)(int x, int y) = lesser; -int8_t marker_tracking = false; int marker_search(void) diff --git a/si5351.c b/si5351.c index 56ba597..ace6af4 100644 --- a/si5351.c +++ b/si5351.c @@ -21,17 +21,18 @@ #include "nanovna.h" #include "si5351.h" +#define XTALFREQ 26000000L +// MCLK (processor clock, audio codec) frequency clock +#define CLK2_FREQUENCY 8000000L + +// Fixed PLL mode multiplier +#define PLL_N 32 + +// #define SI5351_I2C_ADDR (0x60<<1) -static void -si5351_write(uint8_t reg, uint8_t dat) -{ - int addr = SI5351_I2C_ADDR>>1; - uint8_t buf[] = { reg, dat }; - i2cAcquireBus(&I2CD1); - (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000); - i2cReleaseBus(&I2CD1); -} +static uint8_t current_band = 0; +static uint32_t current_freq = 0; static void si5351_bulk_write(const uint8_t *buf, int len) @@ -41,6 +42,22 @@ si5351_bulk_write(const uint8_t *buf, int len) (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000); i2cReleaseBus(&I2CD1); } +#if 0 +static void 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); + i2cReleaseBus(&I2CD1); +} +#endif + +static inline void +si5351_write(uint8_t reg, uint8_t dat) +{ + uint8_t buf[] = { reg, dat }; + si5351_bulk_write(buf, 2); +} // register addr, length, data, ... const uint8_t si5351_configs[] = { @@ -48,13 +65,14 @@ const uint8_t si5351_configs[] = { 4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, 2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF, // setup PLL (26MHz * 32 = 832MHz, 32/2-2=14) - 9, SI5351_REG_26_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, +// 9, SI5351_REG_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, +// 9, SI5351_REG_PLL_B, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, // RESET PLL - 2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B, + 2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B | 0x0C, // // setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50) - 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0, - 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE, - 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0, +// 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0, +// 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE, +// 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0, 0 // sentinel }; @@ -71,26 +89,46 @@ si5351_init(void) static const uint8_t disable_output[] = { SI5351_REG_16_CLK0_CONTROL, - SI5351_CLK_POWERDOWN, - SI5351_CLK_POWERDOWN, - SI5351_CLK_POWERDOWN + SI5351_CLK_POWERDOWN, // CLK 0 + SI5351_CLK_POWERDOWN, // CLK 1 + SI5351_CLK_POWERDOWN // CLK 2 +}; + +/* Get the appropriate starting point for the PLL registers */ +static const uint8_t msreg_base[] = { + SI5351_REG_42_MULTISYNTH0, + SI5351_REG_50_MULTISYNTH1, + SI5351_REG_58_MULTISYNTH2, +}; +static const uint8_t clkctrl[] = { + SI5351_REG_16_CLK0_CONTROL, + SI5351_REG_17_CLK1_CONTROL, + SI5351_REG_18_CLK2_CONTROL }; +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(200); + si5351_write(SI5351_REG_177_PLL_RESET, mask | 0x0C); +// chThdSleepMicroseconds(250); +} + void si5351_disable_output(void) { +// si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, (SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN)); si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff); si5351_bulk_write(disable_output, sizeof(disable_output)); } void si5351_enable_output(void) { + si5351_reset_pll( SI5351_PLL_RESET_A | SI5351_PLL_RESET_B ); +// si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN)); si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0x00); -} - -static void si5351_reset_pll(void) -{ - //si5351_write(SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); - si5351_write(SI5351_REG_177_PLL_RESET, 0xAC); + current_freq = 0; + current_band = 0; } static void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ @@ -98,11 +136,6 @@ static void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ uint32_t num, uint32_t denom) { - /* Get the appropriate starting point for the PLL registers */ - static const uint8_t pllreg_base[] = { - SI5351_REG_26_PLL_A, - SI5351_REG_34_PLL_B - }; uint32_t P1; uint32_t P2; uint32_t P3; @@ -134,10 +167,17 @@ static void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ P2 = 128 * num - denom * ((128 * num) / denom); P3 = denom; } - - /* The datasheet is a nightmare of typos and inconsistencies here! */ +// Pll MSN(A|B) registers Datasheet +// MSN_P3[15:8] +// MSN_P3[ 7:0] +// Reserved | MSN_P1[17:16] +// MSN_P1[15:8] +// MSN_P1[ 7:0] +// MSN_P3[19:16] | MSN_P2[19:16] +// MSN_P2[15:8] +// MSN_P2[ 7:0] uint8_t reg[9]; - reg[0] = pllreg_base[pll]; + reg[0] = pll;//reg_base[pll]; reg[1] = (P3 & 0x0000FF00) >> 8; reg[2] = (P3 & 0x000000FF); reg[3] = (P1 & 0x00030000) >> 16; @@ -149,8 +189,9 @@ static void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ si5351_bulk_write(reg, 9); } + static void -si5351_setupMultisynth(uint8_t output, +si5351_setupMultisynth(uint8_t channel, uint8_t pllSource, uint32_t div, // 4,6,8, 8+ ~ 900 uint32_t num, @@ -158,17 +199,6 @@ si5351_setupMultisynth(uint8_t output, uint32_t rdiv, // SI5351_R_DIV_1~128 uint8_t drive_strength) { - /* Get the appropriate starting point for the PLL registers */ - static const uint8_t msreg_base[] = { - SI5351_REG_42_MULTISYNTH0, - SI5351_REG_50_MULTISYNTH1, - SI5351_REG_58_MULTISYNTH2, - }; - static const uint8_t clkctrl[] = { - SI5351_REG_16_CLK0_CONTROL, - SI5351_REG_17_CLK1_CONTROL, - SI5351_REG_18_CLK2_CONTROL - }; uint8_t dat; uint32_t P1; @@ -204,7 +234,7 @@ si5351_setupMultisynth(uint8_t output, /* Set the MSx config registers */ uint8_t reg[9]; - reg[0] = msreg_base[output]; + reg[0] = msreg_base[channel]; reg[1] = (P3 & 0x0000FF00) >> 8; reg[2] = (P3 & 0x000000FF); reg[3] = ((P1 & 0x00030000) >> 16) | div4 | rdiv; @@ -217,86 +247,80 @@ si5351_setupMultisynth(uint8_t output, /* Configure the clk control and enable the output */ dat = drive_strength | SI5351_CLK_INPUT_MULTISYNTH_N; - if (pllSource == SI5351_PLL_B) + if (pllSource == SI5351_REG_PLL_B) dat |= SI5351_CLK_PLL_SELECT_B; if (num == 0) dat |= SI5351_CLK_INTEGER_MODE; - si5351_write(clkctrl[output], dat); + si5351_write(clkctrl[channel], dat); } -#define XTALFREQ 26000000L -#define PLL_N 32 -#define PLLFREQ (XTALFREQ * PLL_N) - static void -si5351_set_frequency_fixedpll(int channel, int pll, uint32_t pllfreq, uint32_t freq, - int rdiv, uint8_t drive_strength, int mul) +si5351_set_frequency_fixedpll(uint8_t channel, uint32_t pllSource, uint64_t pllfreq, uint32_t freq, uint32_t rdiv, uint8_t drive_strength) { - int denom = freq; - int div = (pllfreq * mul) / denom; // range: 8 ~ 1800 - int num = (pllfreq * mul) - denom * div; + uint32_t denom = freq; + uint32_t div = pllfreq / denom; // range: 8 ~ 1800 + uint32_t num = pllfreq % denom; // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 - int max_denominator = (1 << 20) - 1; + uint32_t max_denominator = (1 << 20) - 1; if (denom > max_denominator) { - int p0 = 0, q0 = 1, p1 = 1, q1 = 0; + uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0; while (denom != 0) { - int a = num / denom; - int q2 = q0 + a*q1; + uint32_t a = num / denom; + uint32_t b = num % denom; + uint32_t q2 = q0 + a*q1; if (q2 > max_denominator) break; - int p2 = p0 + a*p1; - p0 = p1; q0 = q1; p1 = p2; q1 = q2; - int new_denom = num - a * denom; - num = denom; denom = new_denom; + uint32_t p2 = p0 + a*p1; + p0 = p1; + q0 = q1; + p1 = p2; + q1 = q2; + num = denom; denom = b; } num = p1; denom = q1; } + si5351_setupMultisynth(channel, pllSource, div, num, denom, rdiv, drive_strength); +} - si5351_setupMultisynth(channel, pll, div, num, denom, rdiv, drive_strength); +void si5351_setupPLL_freq(uint32_t pll, uint32_t freq, uint32_t div, uint32_t mul){ + uint32_t denom = XTALFREQ * mul; + uint64_t pllfreq = (uint64_t)freq * div; + uint32_t multi = pllfreq / denom; + uint32_t num = pllfreq % denom; + + // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 + uint32_t max_denominator = (1 << 20) - 1; + if (denom > max_denominator) { + uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0; + while (denom != 0) { + uint32_t a = num / denom; + uint32_t b = num % denom; + uint32_t q2 = q0 + a*q1; + if (q2 > max_denominator) + break; + uint32_t p2 = p0 + a*p1; + p0 = p1; q0 = q1; p1 = p2; q1 = q2; + num = denom; denom = b; + } + num = p1; + denom = q1; + } + si5351_setupPLL(pll, multi, num, denom); } +#if 0 static void -si5351_set_frequency_fixeddiv(int channel, int pll, uint32_t freq, int div, - uint8_t drive_strength, int mul) +si5351_set_frequency_fixeddiv(uint8_t channel, uint32_t pll, uint32_t freq, uint32_t div, + uint8_t drive_strength, uint32_t mul) { - int denom = XTALFREQ * mul; - int64_t pllfreq = (int64_t)freq * div; - int multi = pllfreq / denom; - int num = pllfreq - denom * multi; - - // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 - int max_denominator = (1 << 20) - 1; - if (denom > max_denominator) { - int p0 = 0, q0 = 1, p1 = 1, q1 = 0; - while (denom != 0) { - int a = num / denom; - int q2 = q0 + a*q1; - if (q2 > max_denominator) - break; - int p2 = p0 + a*p1; - p0 = p1; q0 = q1; p1 = p2; q1 = q2; - int new_denom = num - a * denom; - num = denom; denom = new_denom; - } - num = p1; - denom = q1; - } - - si5351_setupPLL(pll, multi, num, denom); - si5351_setupMultisynth(channel, pll, div, 0, 1, SI5351_R_DIV_1, drive_strength); + si5351_setupPLL_freq(pll, freq, div, mul); + si5351_setupMultisynth(channel, pll, div, 0, 1, SI5351_R_DIV_1, drive_strength); } -/* - * 1~100MHz fixed PLL 900MHz, fractional divider - * 100~150MHz fractional PLL 600-900MHz, fixed divider 6 - * 150~200MHz fractional PLL 600-900MHz, fixed divider 4 - */ -#if 0 void -si5351_set_frequency(int channel, int freq, uint8_t drive_strength) -{ +si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength){ if (freq <= 100000000) { si5351_setupPLL(SI5351_PLL_B, 32, 0, 1); si5351_set_frequency_fixedpll(channel, SI5351_PLL_B, PLLFREQ, freq, SI5351_R_DIV_1, drive_strength, 1); @@ -308,11 +332,8 @@ si5351_set_frequency(int channel, int freq, uint8_t drive_strength) } #endif -int current_band = -1; - -#define DELAY_NORMAL 3 -#define DELAY_BANDCHANGE 1 -#define DELAY_LOWBAND 1 +#define DELAY_NORMAL 2 +#define DELAY_BANDCHANGE 2 /* * configure output as follows: @@ -320,105 +341,89 @@ int current_band = -1; * CLK1: frequency * CLK2: fixed 8MHz */ -#define CLK2_FREQUENCY 8000000L + int si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength) { - int band; + uint8_t band; int delay = DELAY_NORMAL; + if (freq == current_freq) + return delay; uint32_t ofreq = freq + offset; uint32_t mul = 1, omul = 1; uint32_t rdiv = SI5351_R_DIV_1; - if (freq >= config.harmonic_freq_threshold * 7U) { + uint32_t fdiv; + current_freq = freq; + if (freq >= FREQ_HARMONICS * 7U) { mul = 9; omul = 11; - } else if (freq >= config.harmonic_freq_threshold * 5U) { + } else if (freq >= FREQ_HARMONICS * 5U) { mul = 7; omul = 9; - } else if (freq >= config.harmonic_freq_threshold * 3U) { + } else if (freq >= FREQ_HARMONICS * 3U) { mul = 5; omul = 7; - } else if (freq >= config.harmonic_freq_threshold) { + } else if (freq >= FREQ_HARMONICS) { mul = 3; omul = 5; } - if ((freq / mul) < 100000000U) { - band = 0; - } else if ((freq / mul) < 150000000U) { - band = 1; - } else { - band = 2; - } - if (freq <= 500000U) { + else if (freq <= 500000U) { rdiv = SI5351_R_DIV_64; + freq *= 64; + ofreq *= 64; } else if (freq <= 4000000U) { rdiv = SI5351_R_DIV_8; + freq *= 8; + ofreq *= 8; + } + /* + * Band 0 + * 1~100MHz fixed PLL = XTALFREQ * PLL_N, fractional divider + * Band 1 + * 100~150MHz fractional PLL = 600- 900MHz, fixed divider 6 + * Band 2 + * 150~300MHz fractional PLL = 600-1200MHz, fixed divider 4 + */ + if ((freq / mul) < 100000000U) { + band = 1; + } else if ((freq / mul) < 150000000U) { + band = 2; + fdiv = 6; + } else { + band = 3; + fdiv = 4; } - -#if 1 - if (current_band != band) - si5351_disable_output(); -#endif - switch (band) { - case 0: - // fractional divider mode. only PLL A is used. - if (current_band == 1 || current_band == 2) - si5351_setupPLL(SI5351_PLL_A, 32, 0, 1); - // Set PLL twice on changing from band 2 - if (current_band == 2) - si5351_setupPLL(SI5351_PLL_A, 32, 0, 1); - - if (rdiv == SI5351_R_DIV_8) { - freq *= 8; - ofreq *= 8; - } else if (rdiv == SI5351_R_DIV_64) { - freq *= 64; - ofreq *= 64; - } - - si5351_set_frequency_fixedpll(0, SI5351_PLL_A, PLLFREQ, ofreq, - rdiv, drive_strength, omul); - si5351_set_frequency_fixedpll(1, SI5351_PLL_A, PLLFREQ, freq, - rdiv, drive_strength, mul); - //if (current_band != 0) - si5351_set_frequency_fixedpll(2, SI5351_PLL_A, PLLFREQ, CLK2_FREQUENCY, - SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA, 1); - break; - case 1: - // Set PLL twice on changing from band 2 - if (current_band == 2) { - si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 6, drive_strength, omul); - si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength, mul); + // Setup CH0 and CH1 constant PLL freq at band change, and set CH2 freq = CLK2_FREQUENCY + if (current_band != 1){ + si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1); + si5351_setupPLL(SI5351_REG_PLL_B, PLL_N, 0, 1); + si5351_set_frequency_fixedpll(2, SI5351_REG_PLL_B, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA); } - - // div by 6 mode. both PLL A and B are dedicated for CLK0, CLK1 - si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 6, drive_strength, omul); - si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength, mul); - si5351_set_frequency_fixedpll(2, SI5351_PLL_B, freq / mul * 6, CLK2_FREQUENCY, - SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA, 1); + // Calculate and set CH0 and CH1 divider + si5351_set_frequency_fixedpll(0, SI5351_REG_PLL_A, XTALFREQ * PLL_N * omul, ofreq, rdiv, drive_strength); + si5351_set_frequency_fixedpll(1, SI5351_REG_PLL_A, XTALFREQ * PLL_N * mul, freq, rdiv, drive_strength); break; - case 2: - // div by 4 mode. both PLL A and B are dedicated for CLK0, CLK1 - si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 4, drive_strength, omul); - si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 4, drive_strength, mul); - si5351_set_frequency_fixedpll(2, SI5351_PLL_B, freq / mul * 4, CLK2_FREQUENCY, - SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA, 1); + case 3: + // Setup CH0 and CH1 constant fdiv divider at change + if (current_band != band){ + si5351_setupMultisynth(0, SI5351_REG_PLL_A, fdiv, 0, 1, SI5351_R_DIV_1, drive_strength); + si5351_setupMultisynth(1, SI5351_REG_PLL_B, fdiv, 0, 1, SI5351_R_DIV_1, drive_strength); + } + // 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 + // Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv + si5351_set_frequency_fixedpll(2, SI5351_REG_PLL_B, (freq/mul)*fdiv, CLK2_FREQUENCY, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA); break; } if (current_band != band) { - si5351_reset_pll(); -#if 1 - si5351_enable_output(); -#endif - delay += DELAY_BANDCHANGE; + si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B); + current_band = band; + delay+=DELAY_BANDCHANGE; } - if (band == 0) - delay += DELAY_LOWBAND; - - current_band = band; return delay; } diff --git a/si5351.h b/si5351.h index 0a10c96..4572dc8 100644 --- a/si5351.h +++ b/si5351.h @@ -17,8 +17,8 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -#define SI5351_PLL_A 0 -#define SI5351_PLL_B 1 +//#define SI5351_PLL_A 0 +//#define SI5351_PLL_B 1 #define SI5351_MULTISYNTH_DIV_4 4 #define SI5351_MULTISYNTH_DIV_6 6 @@ -33,12 +33,16 @@ #define SI5351_R_DIV_128 (7<<4) #define SI5351_DIVBY4 (3<<2) -#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 +#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 +#define SI5351_CLK0_EN (1<<0) +#define SI5351_CLK1_EN (1<<2) +#define SI5351_CLK2_EN (1<<3) + #define SI5351_REG_16_CLK0_CONTROL 16 #define SI5351_REG_17_CLK1_CONTROL 17 #define SI5351_REG_18_CLK2_CONTROL 18 -#define SI5351_REG_26_PLL_A 26 -#define SI5351_REG_34_PLL_B 34 +#define SI5351_REG_PLL_A 26 +#define SI5351_REG_PLL_B 34 #define SI5351_REG_42_MULTISYNTH0 42 #define SI5351_REG_50_MULTISYNTH1 50 #define SI5351_REG_58_MULTISYNTH2 58 @@ -74,4 +78,7 @@ void si5351_init(void); -void si5351_set_frequency(int channel, int freq, uint8_t drive_strength); +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); diff --git a/tlv320aic3204.c b/tlv320aic3204.c index cb86ad5..c1b57b5 100644 --- a/tlv320aic3204.c +++ b/tlv320aic3204.c @@ -25,74 +25,78 @@ #define wait_ms(ms) chThdSleepMilliseconds(ms) -static const uint8_t conf_data_pll[] = { - // len, ( reg, data ), - 2, 0x00, 0x00, /* Initialize to Page 0 */ - 2, 0x01, 0x01, /* Initialize the device through software reset */ - 2, 0x04, 0x43, /* PLL Clock High, MCLK, PLL */ +static const uint8_t conf_data[] = { +// reg, data, +// PLL clock config + 0x00, 0x00, /* Initialize to Page 0 */ + 0x01, 0x01, /* Initialize the device through software reset */ + 0x04, 0x43, /* PLL Clock High, MCLK, PLL */ #ifdef REFCLK_8000KHZ /* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */ - 2, 0x05, 0x91, /* Power up PLL, P=1,R=1 */ - 2, 0x06, 0x0a, /* J=10 */ - 2, 0x07, 29, /* D=7520 = (29<<8) + 96 */ - 2, 0x08, 96, + 0x05, 0x91, /* Power up PLL, P=1,R=1 */ + 0x06, 0x0a, /* J=10 */ + 0x07, 29, /* D=7520 = (29<<8) + 96 */ + 0x08, 96, #endif - 0 // sentinel -}; +// Clock config, default fs=48kHz + 0x0b, 0x82, /* Power up the NDAC divider with value 2 */ + 0x0c, 0x87, /* Power up the MDAC divider with value 7 */ + 0x0d, 0x00, /* Program the OSR of DAC to 128 */ + 0x0e, 0x80, + 0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */ + //0x3c, 25, /* Set the DAC Mode to PRB_P25 */ + 0x1b, 0x0c, /* Set the BCLK,WCLK as output */ + 0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */ + 0x25, 0xee, /* DAC power up */ -// default fs=48kHz -static const uint8_t conf_data_clk[] = { - 2, 0x0b, 0x82, /* Power up the NDAC divider with value 2 */ - 2, 0x0c, 0x87, /* Power up the MDAC divider with value 7 */ - 2, 0x0d, 0x00, /* Program the OSR of DAC to 128 */ - 2, 0x0e, 0x80, - 2, 0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */ - //2, 0x3c, 25, /* Set the DAC Mode to PRB_P25 */ - 2, 0x1b, 0x0c, /* Set the BCLK,WCLK as output */ - 2, 0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */ - 2, 0x25, 0xee, /* DAC power up */ + 0x12, 0x82, /* Power up the NADC divider with value 2 */ + 0x13, 0x87, /* Power up the MADC divider with value 7 */ + 0x14, 0x80, /* Program the OSR of ADC to 128 */ + 0x3d, 0x01, /* Select ADC PRB_R1 */ +// Data routing + 0x00, 0x01, /* Select Page 1 */ + 0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/ + 0x02, 0x01, /* Enable Master Analog Power Control */ + 0x7b, 0x01, /* Set the REF charging time to 40ms */ + 0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */ + 0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */ - 2, 0x12, 0x82, /* Power up the NADC divider with value 2 */ - 2, 0x13, 0x87, /* Power up the MADC divider with value 7 */ - 2, 0x14, 0x80, /* Program the OSR of ADC to 128 */ - 2, 0x3d, 0x01, /* Select ADC PRB_R1 */ - 0 // sentinel + 0x3d, 0x00, /* Select ADC PTM_R4 */ + 0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */ + 0x7b, 0x01, /* Set the REF charging time to 40ms */ + 0x34, 0x10, /* Route IN2L to LEFT_P with 10K */ + 0x36, 0x10, /* Route IN2R to LEFT_N with 10K */ +//0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */ +//0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */ +//0x3b, 0x00, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */ +//0x3c, 0x00, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */ }; -static const uint8_t conf_data_routing[] = { - 2, 0x00, 0x01, /* Select Page 1 */ - 2, 0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/ - 2, 0x02, 0x01, /* Enable Master Analog Power Control */ - 2, 0x7b, 0x01, /* Set the REF charging time to 40ms */ - 2, 0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */ - 2, 0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */ +static const uint8_t conf_data_unmute[] = { +// reg, data, + 0x00, 0x00, /* Select Page 0 */ + 0x51, 0xc0, /* Power up Left and Right ADC Channels */ + 0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */ +}; - 2, 0x3d, 0x00, /* Select ADC PTM_R4 */ - 2, 0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */ - 2, 0x7b, 0x01, /* Set the REF charging time to 40ms */ - 2, 0x34, 0x10, /* Route IN2L to LEFT_P with 10K */ - 2, 0x36, 0x10, /* Route IN2R to LEFT_N with 10K */ - 2, 0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */ - 2, 0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */ - 2, 0x3b, 0, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */ - 2, 0x3c, 0, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */ - 0 // sentinel +static const uint8_t conf_data_ch3_select[] = { +// reg, data, + 0x00, 0x01, /* Select Page 1 */ + 0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */ + 0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */ }; -const uint8_t conf_data_unmute[] = { - 2, 0x00, 0x00, /* Select Page 0 */ - 2, 0x51, 0xc0, /* Power up Left and Right ADC Channels */ - 2, 0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */ - 0 // sentinel +static const uint8_t conf_data_ch1_select[] = { +// reg, data, + 0x00, 0x01, /* Select Page 1 */ + 0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */ + 0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */ }; -static void +static inline void tlv320aic3204_bulk_write(const uint8_t *buf, int len) { - int addr = AIC3204_ADDR; - i2cAcquireBus(&I2CD1); - (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000); - i2cReleaseBus(&I2CD1); + (void)i2cMasterTransmitTimeout(&I2CD1, AIC3204_ADDR, buf, len, NULL, 0, 1000); } #if 0 @@ -109,49 +113,32 @@ tlv320aic3204_read(uint8_t d0) #endif static void -tlv320aic3204_config(const uint8_t *data) +tlv320aic3204_config(const uint8_t *data, int len) { - const uint8_t *p = data; - while (*p) { - uint8_t len = *p++; - tlv320aic3204_bulk_write(p, len); - p += len; - } + i2cAcquireBus(&I2CD1); + for (;len--;data+=2) + tlv320aic3204_bulk_write(data, 2); + i2cReleaseBus(&I2CD1); } void tlv320aic3204_init(void) { - tlv320aic3204_config(conf_data_pll); - tlv320aic3204_config(conf_data_clk); - tlv320aic3204_config(conf_data_routing); + tlv320aic3204_config(conf_data, sizeof(conf_data)/2); wait_ms(40); - tlv320aic3204_config(conf_data_unmute); + tlv320aic3204_config(conf_data_unmute, sizeof(conf_data_unmute)/2); } void tlv320aic3204_select(int channel) { - const uint8_t ch3[] = { - 2, 0x00, 0x01, /* Select Page 1 */ - 2, 0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */ - 2, 0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */ - 0 // sentinel - }; - const uint8_t ch1[] = { - 2, 0x00, 0x01, /* Select Page 1 */ - 2, 0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */ - 2, 0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */ - 0 // sentinel - }; - tlv320aic3204_config(channel ? ch1 : ch3); + tlv320aic3204_config(channel ? conf_data_ch1_select : conf_data_ch3_select, sizeof(conf_data_ch3_select)/2); } void tlv320aic3204_set_gain(int lgain, int rgain) { - uint8_t data[] = { - 2, 0x00, 0x01, /* Select Page 1 */ - 2, 0x3b, lgain, /* Unmute Left MICPGA, set gain */ - 2, 0x3c, rgain, /* Unmute Right MICPGA, set gain */ - 0 // sentinel - }; - tlv320aic3204_config(data); + uint8_t data[] = { + 0x00, 0x01, /* Select Page 1 */ + 0x3b, lgain, /* Unmute Left MICPGA, set gain */ + 0x3c, rgain, /* Unmute Right MICPGA, set gain */ + }; + tlv320aic3204_config(data, sizeof(data)/2); } diff --git a/ui.c b/ui.c index 681c8bb..562d0dd 100644 --- a/ui.c +++ b/ui.c @@ -25,12 +25,12 @@ //#include #include - uistat_t uistat = { digit: 6, current_trace: 0, lever_mode: LM_MARKER, marker_delta: FALSE, + marker_tracking : FALSE, }; #define NO_EVENT 0 @@ -41,9 +41,9 @@ uistat_t uistat = { #define EVT_DOWN 0x20 #define EVT_REPEAT 0x40 -#define BUTTON_DOWN_LONG_TICKS 5000 /* 1sec */ -#define BUTTON_DOUBLE_TICKS 5000 /* 500ms */ -#define BUTTON_REPEAT_TICKS 1000 /* 100ms */ +#define BUTTON_DOWN_LONG_TICKS 5000 /* 1sec */ +#define BUTTON_DOUBLE_TICKS 2500 /* 500ms */ +#define BUTTON_REPEAT_TICKS 625 /* 125ms */ #define BUTTON_DEBOUNCE_TICKS 200 /* lever switch assignment */ @@ -59,7 +59,7 @@ static uint32_t last_button_down_ticks; static uint32_t last_button_repeat_ticks; static int8_t inhibit_until_release = FALSE; -uint8_t operation_requested = OP_NONE; +volatile uint8_t operation_requested = OP_NONE; int8_t previous_marker = -1; @@ -71,8 +71,14 @@ enum { KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_SCALE, KM_REFPOS, KM_EDELAY, KM_VELOCITY_FACTOR, KM_SCALEDELAY }; +#define NUMINPUT_LEN 10 + static uint8_t ui_mode = UI_NORMAL; static uint8_t keypad_mode; +static uint8_t keypads_last_index; +static char kp_buf[NUMINPUT_LEN+1]; +static int8_t kp_index = 0; +static uint8_t menu_current_level = 0; static int8_t selection = 0; // Set structure align as WORD (save flash memory) @@ -98,18 +104,13 @@ static int16_t last_touch_y; //int16_t touch_cal[4] = { 1000, 1000, 10*16, 12*16 }; //int16_t touch_cal[4] = { 620, 600, 130, 180 }; -int awd_count; +//int awd_count; //int touch_x, touch_y; -#define NUMINPUT_LEN 10 - #define KP_CONTINUE 0 #define KP_DONE 1 #define KP_CANCEL 2 -static char kp_buf[NUMINPUT_LEN+1]; -static int8_t kp_index = 0; - static void ui_mode_normal(void); static void ui_mode_menu(void); static void ui_mode_numeric(int _keypad_mode); @@ -130,33 +131,29 @@ static int btn_check(void) int status = 0; uint32_t ticks = chVTGetSystemTime(); if (changed & (1<= BUTTON_DEBOUNCE_TICKS) { - if (cur_button & (1<= last_button_down_ticks + BUTTON_DEBOUNCE_TICKS) { + // button released + status |= EVT_BUTTON_SINGLE_CLICK; + if (inhibit_until_release) { + status = 0; + inhibit_until_release = FALSE; } - last_button_down_ticks = ticks; } } - if (changed & (1<= last_button_down_ticks + BUTTON_DEBOUNCE_TICKS)) { status |= EVT_UP; } - last_button_down_ticks = ticks; } if (changed & (1<= last_button_down_ticks + BUTTON_DEBOUNCE_TICKS)) { status |= EVT_DOWN; } - last_button_down_ticks = ticks; } + last_button_down_ticks = ticks; last_button = cur_button; return status; @@ -169,15 +166,14 @@ static int btn_wait_release(void) int changed = last_button ^ cur_button; uint32_t ticks = chVTGetSystemTime(); int status = 0; - if (!inhibit_until_release) { if ((cur_button & (1<= BUTTON_DOWN_LONG_TICKS) { + && ticks >= last_button_down_ticks + BUTTON_DOWN_LONG_TICKS) { inhibit_until_release = TRUE; return EVT_BUTTON_DOWN_LONG; } if ((changed & (1<= BUTTON_DOWN_LONG_TICKS - && ticks - last_button_repeat_ticks >= BUTTON_REPEAT_TICKS) { - if (cur_button & (1<= last_button_down_ticks + BUTTON_DOWN_LONG_TICKS + && ticks >= last_button_repeat_ticks + BUTTON_REPEAT_TICKS) { + if (cur_button & (1< Date: Sat, 7 Mar 2020 14:54:51 +0300 Subject: [PATCH 31/65] si5351.c and si5351.h Cleanup and optimize code Add comments, fix definitions Fix rounding errors Fix band 1 stability mcuconf.h Set I2C bus clock to SYSCLK (more fast) Apply 400kHz bus I2C clock timings for 8MHz and 48Mhz clock main.c Remove and reset some variables Add separate sweep for calibration (allow calibrate if sweep paused) Increase main thread stack (need for run calibrate, possibly need execute some commands in sweep threads for reduce stack usage) --- Makefile | 4 +- main.c | 152 +++++++++------------ mcuconf.h | 3 +- nanovna.h | 8 +- si5351.c | 384 ++++++++++++++++++++++++++---------------------------- si5351.h | 49 +++---- ui.c | 4 +- 7 files changed, 276 insertions(+), 328 deletions(-) diff --git a/Makefile b/Makefile index bd17844..fc18d97 100644 --- a/Makefile +++ b/Makefile @@ -64,13 +64,13 @@ endif # Stack size to be allocated to the Cortex-M process stack. This stack is # the stack used by the main() thread. ifeq ($(USE_PROCESS_STACKSIZE),) - USE_PROCESS_STACKSIZE = 0x200 + USE_PROCESS_STACKSIZE = 0x300 endif # Stack size to the allocated to the Cortex-M main/exceptions stack. This # stack is used for processing interrupts and exceptions. ifeq ($(USE_EXCEPTIONS_STACKSIZE),) - USE_EXCEPTIONS_STACKSIZE = 0x200 + USE_EXCEPTIONS_STACKSIZE = 0x100 endif # diff --git a/main.c b/main.c index 4f35b24..02ef10d 100644 --- a/main.c +++ b/main.c @@ -69,19 +69,17 @@ static void transform_domain(void); static MUTEX_DECL(mutex); -int32_t frequency_offset = 5000; -uint32_t frequency = 10000000; -int8_t drive_strength = DRIVE_STRENGTH_AUTO; -int8_t sweep_enabled = TRUE; -volatile int8_t sweep_once = FALSE; -int8_t cal_auto_interpolate = TRUE; -uint16_t redraw_request = 0; // contains REDRAW_XXX flags +// Obsolete enable/disable calibration interpolation (always on) +#define cal_auto_interpolate TRUE + +static int32_t frequency_offset = 5000; +static uint32_t frequency = 10000000; +static int8_t drive_strength = DRIVE_STRENGTH_AUTO; +volatile int8_t sweep_mode = SWEEP_MODE_ENABLED; + +volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; -// -// Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show: -// Stack maximum usage = 576 bytes, free stack = 64 bytes -// static THD_WORKING_AREA(waThread1, 640); static THD_FUNCTION(Thread1, arg) { @@ -90,11 +88,10 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; - if (sweep_enabled || sweep_once) { + if (sweep_mode&(SWEEP_MODE_ENABLED|SWEEP_MODE_RUN_ONCE)) { chMtxLock(&mutex); - // Sweep require 8367 system tick completed = sweep(true); - sweep_once = FALSE; + sweep_mode&=~SWEEP_MODE_RUN_ONCE; chMtxUnlock(&mutex); } else { si5351_disable_output(); @@ -102,10 +99,8 @@ static THD_FUNCTION(Thread1, arg) } chMtxLock(&mutex); - // Ui and render require 800 system tick ui_process(); - - if (sweep_enabled) { + if (sweep_mode&SWEEP_MODE_ENABLED) { if (vbat != -1) { adc_stop(ADC1); vbat = adc_vbat_read(ADC1); @@ -135,23 +130,10 @@ static THD_FUNCTION(Thread1, arg) } } -static inline void -pause_sweep(void) -{ - sweep_enabled = FALSE; -} - -static inline void -resume_sweep(void) -{ - sweep_enabled = TRUE; -} - -void -toggle_sweep(void) -{ - sweep_enabled = !sweep_enabled; -} +static inline void run_once_sweep(void) {sweep_mode|=SWEEP_MODE_RUN_ONCE;} +static inline void pause_sweep(void) {sweep_mode&=~SWEEP_MODE_ENABLED;} +static inline void resume_sweep(void){sweep_mode|= SWEEP_MODE_ENABLED;} +void toggle_sweep(void){sweep_mode^= SWEEP_MODE_ENABLED;} static float bessel0(float x) { @@ -316,16 +298,15 @@ const int8_t gain_table[] = { #define DELAY_GAIN_CHANGE 2 static int -adjust_gain(int newfreq) +adjust_gain(uint32_t newfreq) { - int delay = 0; int new_order = newfreq / FREQ_HARMONICS; int old_order = frequency / FREQ_HARMONICS; if (new_order != old_order) { tlv320aic3204_set_gain(gain_table[new_order], gain_table[new_order]); - delay += DELAY_GAIN_CHANGE; + return DELAY_GAIN_CHANGE; } - return delay; + return 0; } int set_frequency(uint32_t freq) @@ -778,27 +759,23 @@ ensure_edit_config(void) #define DELAY_CHANNEL_CHANGE 2 // main loop for measurement -bool sweep(bool break_on_operation) +static bool sweep(bool break_on_operation) { - int i; + int i, delay; // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); - systime_t time = chVTGetSystemTimeX(); - systime_t sweep_t = 0; si5351_enable_output(); - // On CW set freq once, and run - for (i = 0; i < sweep_points; i++) { // 8365 - sweep_t-= chVTGetSystemTimeX(); - int delay = set_frequency(frequencies[i]); // 1560 - sweep_t+= chVTGetSystemTimeX(); + wait_dsp(1); // Wait for get optimal timings + for (i = 0; i < sweep_points; i++) { // 5300 + delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT - wait_dsp(delay+(i==0 ? 1 :0)); // 3270 + wait_dsp(delay); // 1900 // calculate reflection coefficient (*sample_func)(measured[0][i]); // 60 tlv320aic3204_select(1); // 60 CH1:TRANSMISSION - wait_dsp(DELAY_CHANNEL_CHANGE); // 2700 + wait_dsp(DELAY_CHANNEL_CHANGE); // 1800 // calculate transmission coefficient (*sample_func)(measured[1][i]); // 60 // ======== 170 =========== @@ -813,7 +790,6 @@ bool sweep(bool break_on_operation) return false; } } - {char string_buf[18];plot_printf(string_buf, sizeof string_buf, "T:%06d:%06d", chVTGetSystemTimeX() - time, sweep_t);ili9341_drawstringV(string_buf, 1, 90);} // blink LED while scanning palSetPad(GPIOC, GPIOC_LED); return true; @@ -849,11 +825,11 @@ VNA_SHELL_FUNCTION(cmd_scan) if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) cal_interpolate(lastsaveid); - sweep_once = TRUE; + run_once_sweep(); chMtxUnlock(&mutex); // wait finishing sweep - while (sweep_once) + while (sweep_mode&SWEEP_MODE_RUN_ONCE) chThdSleepMilliseconds(10); } @@ -1294,36 +1270,21 @@ 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; } - redraw_request |= REDRAW_CAL_STATUS; + // Made sweep operation for collect calibration data + sweep(false); + // Copy calibration data + memcpy(cal_data[dst], measured[src], sizeof measured[0]); + redraw_request|= REDRAW_CAL_STATUS; } void @@ -2165,24 +2126,27 @@ THD_FUNCTION(myshellThread, p) { #endif // I2C clock bus setting: depend from STM32_I2C1SW in mcuconf.h -// STM32_I2C1SW = STM32_I2C1SW_HSI (HSI=8MHz) -// STM32_I2C1SW = STM32_I2C1SW_SYSCLK (SYSCLK = 48MHz) static const I2CConfig i2ccfg = { - // TIMINGR register initialization. (use I2C timing configuration tool for STM32F3xx and STM32F0xx microcontrollers (AN4235)) - // 400kHz @ SYSCLK 48MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) -// STM32_TIMINGR_PRESC(5U) | -// STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) | -// STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), -// 400kHz @ HSI 8MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) + .timingr = // TIMINGR register initialization. (use I2C timing configuration tool for STM32F3xx and STM32F0xx microcontrollers (AN4235)) +#if STM32_I2C1SW == STM32_I2C1SW_HSI + // STM32_I2C1SW == STM32_I2C1SW_HSI (HSI=8MHz) + // 400kHz @ HSI 8MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) STM32_TIMINGR_PRESC(0U) | STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(1U) | STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), -// Old values voodoo magic 400kHz @ HSI 8MHz -// STM32_TIMINGR_PRESC(0U) | -// STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(0U) | -// STM32_TIMINGR_SCLH(5U) | STM32_TIMINGR_SCLL(6U), - 0, // CR1 register initialization. - 0 // CR2 register initialization. + // Old values voodoo magic 400kHz @ HSI 8MHz + //0x00300506, +#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK + // STM32_I2C1SW == STM32_I2C1SW_SYSCLK (SYSCLK = 48MHz) + // 400kHz @ SYSCLK 48MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) + STM32_TIMINGR_PRESC(5U) | + STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) | + STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), +#else +#error "Need Define STM32_I2C1SW and set correct TIMINGR settings" +#endif + .cr1 = 0, // CR1 register initialization. + .cr2 = 0 // CR2 register initialization. }; static DACConfig dac1cfg1 = { diff --git a/mcuconf.h b/mcuconf.h index 3db6404..9021c85 100644 --- a/mcuconf.h +++ b/mcuconf.h @@ -58,7 +58,8 @@ #define STM32_ADCSW STM32_ADCSW_HSI14 #define STM32_USBSW STM32_USBSW_HSI48 #define STM32_CECSW STM32_CECSW_HSI -#define STM32_I2C1SW STM32_I2C1SW_HSI +//#define STM32_I2C1SW STM32_I2C1SW_HSI +#define STM32_I2C1SW STM32_I2C1SW_SYSCLK #define STM32_USART1SW STM32_USART1SW_PCLK #define STM32_RTCSEL STM32_RTCSEL_LSI diff --git a/nanovna.h b/nanovna.h index ba87162..72753d1 100644 --- a/nanovna.h +++ b/nanovna.h @@ -86,7 +86,9 @@ double my_atof(const char *p); void toggle_sweep(void); void loadDefaultProps(void); -extern int8_t sweep_enabled; +#define SWEEP_MODE_ENABLED 0x01 +#define SWEEP_MODE_RUN_ONCE 0x02 +extern volatile int8_t sweep_mode; /* * dsp.c @@ -279,12 +281,12 @@ int marker_search(void); int marker_search_left(int from); int marker_search_right(int from); -extern uint16_t redraw_request; - +// _request flag for update screen #define REDRAW_CELLS (1<<0) #define REDRAW_FREQUENCY (1<<1) #define REDRAW_CAL_STATUS (1<<2) #define REDRAW_MARKER (1<<3) +extern volatile uint8_t redraw_request; extern int16_t vbat; diff --git a/si5351.c b/si5351.c index ace6af4..a08bfbe 100644 --- a/si5351.c +++ b/si5351.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com + * Modified by DiSlord dislordlive@gmail.com * All rights reserved. * * This is free software; you can redistribute it and/or modify @@ -21,15 +22,19 @@ #include "nanovna.h" #include "si5351.h" -#define XTALFREQ 26000000L -// MCLK (processor clock, audio codec) frequency clock -#define CLK2_FREQUENCY 8000000L +// Enable cache for SI5351 CLKX_CONTROL register, little speedup exchange +#define USE_CLK_CONTROL_CACHE TRUE -// Fixed PLL mode multiplier +// XTAL frequency on si5351 +#define XTALFREQ 26000000U +// MCLK (processor clock if set, audio codec) frequency clock +#define CLK2_FREQUENCY 8000000U + +// Fixed PLL mode multiplier (used in band 1) #define PLL_N 32 -// -#define SI5351_I2C_ADDR (0x60<<1) +// 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; @@ -37,18 +42,17 @@ static uint32_t current_freq = 0; static void si5351_bulk_write(const uint8_t *buf, int len) { - int addr = SI5351_I2C_ADDR>>1; i2cAcquireBus(&I2CD1); - (void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000); + (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) { - int addr = SI5351_I2C_ADDR>>1; - i2cAcquireBus(&I2CD1); - msg_t mr = i2cMasterTransmitTimeout(&I2CD1, addr, ®, 1, buf, len, 1000); - i2cReleaseBus(&I2CD1); + int addr = SI5351_I2C_ADDR>>1; + i2cAcquireBus(&I2CD1); + msg_t mr = i2cMasterTransmitTimeout(&I2CD1, addr, ®, 1, buf, len, 1000); + i2cReleaseBus(&I2CD1); } #endif @@ -64,15 +68,18 @@ const uint8_t si5351_configs[] = { 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff, 4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, 2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF, +// All of this init code run late on sweep +#if 0 // setup PLL (26MHz * 32 = 832MHz, 32/2-2=14) -// 9, SI5351_REG_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, -// 9, SI5351_REG_PLL_B, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, + 9, SI5351_REG_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, + 9, SI5351_REG_PLL_B, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, // RESET PLL 2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B | 0x0C, // // setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50) -// 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0, -// 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE, -// 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0, + 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0, + 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE, + 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0, +#endif 0 // sentinel }; @@ -106,217 +113,185 @@ static const uint8_t clkctrl[] = { SI5351_REG_18_CLK2_CONTROL }; +// Reset PLL need then band changes 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(200); si5351_write(SI5351_REG_177_PLL_RESET, mask | 0x0C); -// chThdSleepMicroseconds(250); } void si5351_disable_output(void) { -// si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, (SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN)); - si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff); + si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xFF); si5351_bulk_write(disable_output, sizeof(disable_output)); } void si5351_enable_output(void) { - si5351_reset_pll( SI5351_PLL_RESET_A | SI5351_PLL_RESET_B ); -// si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN)); - si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0x00); + si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN)); +//si5351_reset_pll(SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); current_freq = 0; current_band = 0; } -static void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */ - uint8_t mult, - uint32_t num, - uint32_t denom) +// Set PLL freq = XTALFREQ * (mult + num/denom) +static void si5351_setupPLL(uint8_t pllSource, /* SI5351_REG_PLL_A or SI5351_REG_PLL_B */ + uint32_t mult, + uint32_t num, + uint32_t denom) { - uint32_t P1; - uint32_t P2; - uint32_t P3; - /* Feedback Multisynth Divider Equation * where: a = mult, b = num and c = denom * P1 register is an 18-bit value using following formula: - * P1[17:0] = 128 * mult + floor(128*(num/denom)) - 512 + * P1[17:0] = 128 * mult + int((128*num)/denom) - 512 * P2 register is a 20-bit value using the following formula: - * P2[19:0] = 128 * num - denom * floor(128*(num/denom)) + * P2[19:0] = (128 * num) % denom * P3 register is a 20-bit value using the following formula: * P3[19:0] = denom */ - /* Set the main PLL config registers */ - if (num == 0) - { - /* Integer mode */ - P1 = 128 * mult - 512; - P2 = 0; - P3 = 1; - } - else - { - /* Fractional mode */ - //P1 = (uint32_t)(128 * mult + floor(128 * ((float)num/(float)denom)) - 512); - P1 = 128 * mult + ((128 * num) / denom) - 512; - //P2 = (uint32_t)(128 * num - denom * floor(128 * ((float)num/(float)denom))); - P2 = 128 * num - denom * ((128 * num) / denom); + mult<<=7; + num<<=7; + uint32_t P1 = mult - 512; // Integer mode + uint32_t P2 = 0; + uint32_t P3 = 1; + if (num){ // Fractional mode + P1+= num / denom; + P2 = num % denom; P3 = denom; } -// Pll MSN(A|B) registers Datasheet -// MSN_P3[15:8] -// MSN_P3[ 7:0] -// Reserved | MSN_P1[17:16] -// MSN_P1[15:8] -// MSN_P1[ 7:0] -// MSN_P3[19:16] | MSN_P2[19:16] -// MSN_P2[15:8] -// MSN_P2[ 7:0] + // Pll MSN(A|B) registers Datasheet uint8_t reg[9]; - reg[0] = pll;//reg_base[pll]; - reg[1] = (P3 & 0x0000FF00) >> 8; - reg[2] = (P3 & 0x000000FF); - reg[3] = (P1 & 0x00030000) >> 16; - reg[4] = (P1 & 0x0000FF00) >> 8; - reg[5] = (P1 & 0x000000FF); - reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16); - reg[7] = (P2 & 0x0000FF00) >> 8; - reg[8] = (P2 & 0x000000FF); + reg[0]= pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B + reg[1]=( P3 & 0x0FF00)>> 8; // MSN_P3[15: 8] + reg[2]=( P3 & 0x000FF); // MSN_P3[ 7: 0] + reg[3]=( P1 & 0x30000)>>16; // MSN_P1[17:16] + reg[4]=( P1 & 0x0FF00)>> 8; // MSN_P1[15: 8] + reg[5]=( P1 & 0x000FF); // MSN_P1[ 7: 0] + reg[6]=((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSN_P3[19:16] | MSN_P2[19:16] + reg[7]=( P2 & 0x0FF00)>> 8; // MSN_P2[15: 8] + reg[8]=( P2 & 0x000FF); // MSN_P2[ 7: 0] si5351_bulk_write(reg, 9); } - +// Set Multisynth divider = (div + num/denom) * rdiv static void -si5351_setupMultisynth(uint8_t channel, - uint8_t pllSource, - uint32_t div, // 4,6,8, 8+ ~ 900 - uint32_t num, - uint32_t denom, - uint32_t rdiv, // SI5351_R_DIV_1~128 - uint8_t drive_strength) +si5351_setupMultisynth(uint8_t channel, + uint32_t div, // 4,6,8, 8+ ~ 900 + uint32_t num, + uint32_t denom, + uint32_t rdiv, // SI5351_R_DIV_1~128 + uint8_t chctrl) // SI5351_REG_16_CLKX_CONTROL settings { - uint8_t dat; - - uint32_t P1; - uint32_t P2; - uint32_t P3; - uint32_t div4 = 0; - /* Output Multisynth Divider Equations * where: a = div, b = num and c = denom * P1 register is an 18-bit value using following formula: - * P1[17:0] = 128 * a + floor(128*(b/c)) - 512 + * P1[17:0] = 128 * a + int((128*b)/c) - 512 * P2 register is a 20-bit value using the following formula: - * P2[19:0] = 128 * b - c * floor(128*(b/c)) + * P2[19:0] = (128 * b) % c * P3 register is a 20-bit value using the following formula: - * P3[19:0] = c + * P3[19:0] = c */ /* Set the main PLL config registers */ - if (div == 4) { - div4 = SI5351_DIVBY4; - P1 = P2 = 0; - P3 = 1; - } else if (num == 0) { - /* Integer mode */ - P1 = 128 * div - 512; - P2 = 0; - P3 = 1; - } else { - /* Fractional mode */ - P1 = 128 * div + ((128 * num) / denom) - 512; - P2 = 128 * num - denom * ((128 * num) / denom); - P3 = denom; + uint32_t P1 = 0; + uint32_t P2 = 0; + uint32_t P3 = 1; + if (div == 4) + rdiv|= SI5351_DIVBY4; + else { + num<<=7; + div<<=7; + P1 = div - 512; // Integer mode + if (num){ // Fractional mode + P1+= num / denom; + P2 = num % denom; + P3 = denom; + } } - /* Set the MSx config registers */ uint8_t reg[9]; - reg[0] = msreg_base[channel]; - reg[1] = (P3 & 0x0000FF00) >> 8; - reg[2] = (P3 & 0x000000FF); - reg[3] = ((P1 & 0x00030000) >> 16) | div4 | rdiv; - reg[4] = (P1 & 0x0000FF00) >> 8; - reg[5] = (P1 & 0x000000FF); - reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16); - reg[7] = (P2 & 0x0000FF00) >> 8; - reg[8] = (P2 & 0x000000FF); + reg[0]= msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2 + reg[1]=( P3 & 0x0FF00)>>8; // MSx_P3[15: 8] + reg[2]=( P3 & 0x000FF); // MSx_P3[ 7: 0] + reg[3]=((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16] + reg[4]=( P1 & 0x0FF00)>> 8; // MSx_P1[15: 8] + reg[5]=( P1 & 0x000FF); // MSx_P1[ 7: 0] + reg[6]=((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16] + reg[7]=( P2 & 0x0FF00)>>8; // MSx_P2[15: 8] + reg[8]=( P2 & 0x000FF); // MSx_P2[ 7: 0] si5351_bulk_write(reg, 9); /* Configure the clk control and enable the output */ - dat = drive_strength | SI5351_CLK_INPUT_MULTISYNTH_N; - if (pllSource == SI5351_REG_PLL_B) - dat |= SI5351_CLK_PLL_SELECT_B; + uint8_t dat = chctrl | SI5351_CLK_INPUT_MULTISYNTH_N; if (num == 0) dat |= SI5351_CLK_INTEGER_MODE; - si5351_write(clkctrl[channel], dat); -} -static void -si5351_set_frequency_fixedpll(uint8_t channel, uint32_t pllSource, uint64_t pllfreq, uint32_t freq, uint32_t rdiv, uint8_t drive_strength) -{ - uint32_t denom = freq; - uint32_t div = pllfreq / denom; // range: 8 ~ 1800 - uint32_t num = pllfreq % denom; - - // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 - uint32_t max_denominator = (1 << 20) - 1; - if (denom > max_denominator) { - uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0; - while (denom != 0) { - uint32_t a = num / denom; - uint32_t b = num % denom; - uint32_t q2 = q0 + a*q1; - if (q2 > max_denominator) - break; - uint32_t p2 = p0 + a*p1; - p0 = p1; - q0 = q1; - p1 = p2; - q1 = q2; - num = denom; denom = b; - } - num = p1; - denom = q1; - } - si5351_setupMultisynth(channel, pllSource, div, num, denom, rdiv, drive_strength); +#if USE_CLK_CONTROL_CACHE == TRUE + // Use cache for this reg, not update if not change + static uint8_t clk_cache[3]; + if (clk_cache[channel]!=dat){ + si5351_write(clkctrl[channel], dat); + clk_cache[channel]=dat; + } +#else + si5351_write(clkctrl[channel], dat); +#endif } -void si5351_setupPLL_freq(uint32_t pll, uint32_t freq, uint32_t div, uint32_t mul){ - uint32_t denom = XTALFREQ * mul; - uint64_t pllfreq = (uint64_t)freq * div; - uint32_t multi = pllfreq / denom; - uint32_t num = pllfreq % denom; - +// Find better approximate values for n/d +#define MAX_DENOMINATOR ((1 << 20) - 1) +static inline void fractionalSolve(uint32_t *n, uint32_t *d){ // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 - uint32_t max_denominator = (1 << 20) - 1; - if (denom > max_denominator) { + uint32_t denom = *d; + if (denom > MAX_DENOMINATOR) { + uint32_t num = *n; uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0; while (denom != 0) { - uint32_t a = num / denom; - uint32_t b = num % denom; - uint32_t q2 = q0 + a*q1; - if (q2 > max_denominator) + uint32_t a = num / denom; + uint32_t b = num % denom; + uint32_t q2 = q0 + a*q1; + if (q2 > MAX_DENOMINATOR) break; uint32_t p2 = p0 + a*p1; p0 = p1; q0 = q1; p1 = p2; q1 = q2; num = denom; denom = b; } - num = p1; - denom = q1; + *n = p1; + *d = q1; } - si5351_setupPLL(pll, multi, num, denom); +} + +// Setup Multisynth divider for get correct output freq if fixed PLL = pllfreq +static void +si5351_set_frequency_fixedpll(uint8_t channel, uint64_t pllfreq, uint32_t freq, uint32_t rdiv, uint8_t chctrl) +{ + uint32_t denom = freq; + uint32_t div = pllfreq / denom; // range: 8 ~ 1800 + uint32_t num = pllfreq % denom; + fractionalSolve(&num, &denom); + si5351_setupMultisynth(channel, div, num, denom, rdiv, chctrl); +} + +// Setup PLL freq if Multisynth divider fixed = div (need get output = freq/mul) +static void +si5351_setupPLL_freq(uint32_t pllSource, uint32_t freq, uint32_t div, uint32_t mul){ + uint32_t denom = XTALFREQ * mul; + uint64_t pllfreq = (uint64_t)freq * div; + uint32_t multi = pllfreq / denom; + uint32_t num = pllfreq % denom; + fractionalSolve(&num, &denom); + si5351_setupPLL(pllSource, multi, num, denom); } #if 0 static void si5351_set_frequency_fixeddiv(uint8_t channel, uint32_t pll, uint32_t freq, uint32_t div, - uint8_t drive_strength, uint32_t mul) + uint8_t chctrl, uint32_t mul) { si5351_setupPLL_freq(pll, freq, div, mul); - si5351_setupMultisynth(channel, pll, div, 0, 1, SI5351_R_DIV_1, drive_strength); + si5351_setupMultisynth(channel, div, 0, 1, SI5351_R_DIV_1, chctrl); } void @@ -332,91 +307,106 @@ si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength){ } #endif +/* + * Frequency generation divide on 3 band + * Band 1 + * 1~100MHz fixed PLL = XTALFREQ * PLL_N, fractional divider + * Band 2 + * 100~150MHz fractional PLL = 600- 900MHz, fixed divider 'fdiv = 6' + * Band 3 + * 150~300MHz fractional PLL = 600-1200MHz, fixed divider 'fdiv = 4' + * + * For FREQ_HARMONICS = 300MHz - band range is: + * +-----------------------------------------------------------------------------------------------------------------------+ + * | Band 1 | Band 2 | Band 3 | Band 2 | Band 3 | + * +-----------------------------------------------------------------------------------------------------------------------+ + * | x1 : x1 | x1 : x1 | x1 : x1 | x3 : x5 | x3 : x5 | x5-x7 | x7-x9 | x9-x11 | + * | 50kHz - 100MHz | 100 - 150MHz | 150 - 300MHz | 300-450MHz | 450-900MHz | 900-1500MHz | 1500-2100MHz | 2100-2700MHz | + * +-----------------------------------------------------------------------------------------------------------------------+ + * | f = 50kHz-100MHz | f=100-150 | f=150-300 | f=150-300 | f=214-300 | f=233-300 | + * | of = 50kHz-100MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 | + * +-----------------------------------------------------------------------------------------------------------------------+ + */ +static inline uint8_t si5351_getBand(uint32_t freq){ + if (freq < 100000000U) return 1; + if (freq < 150000000U) return 2; + 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 2 /* + * Maximum supported frequency = FREQ_HARMONICS * 9U * configure output as follows: * CLK0: frequency + offset * CLK1: frequency * 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, int offset, uint8_t drive_strength){ uint8_t band; int delay = DELAY_NORMAL; if (freq == current_freq) - return delay; + 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; if (freq >= FREQ_HARMONICS * 7U) { - mul = 9; + mul = 9; omul = 11; } else if (freq >= FREQ_HARMONICS * 5U) { - mul = 7; + mul = 7; omul = 9; } else if (freq >= FREQ_HARMONICS * 3U) { - mul = 5; + mul = 5; omul = 7; } else if (freq >= FREQ_HARMONICS) { - mul = 3; + mul = 3; omul = 5; } else if (freq <= 500000U) { rdiv = SI5351_R_DIV_64; - freq *= 64; - ofreq *= 64; + freq<<= 6; + ofreq<<= 6; } else if (freq <= 4000000U) { rdiv = SI5351_R_DIV_8; - freq *= 8; - ofreq *= 8; - } - /* - * Band 0 - * 1~100MHz fixed PLL = XTALFREQ * PLL_N, fractional divider - * Band 1 - * 100~150MHz fractional PLL = 600- 900MHz, fixed divider 6 - * Band 2 - * 150~300MHz fractional PLL = 600-1200MHz, fixed divider 4 - */ - if ((freq / mul) < 100000000U) { - band = 1; - } else if ((freq / mul) < 150000000U) { - band = 2; - fdiv = 6; - } else { - band = 3; - fdiv = 4; + freq<<= 3; + ofreq<<= 3; } + + band = si5351_getBand(freq/mul); switch (band) { case 1: - // Setup CH0 and CH1 constant PLL freq at band change, and set CH2 freq = CLK2_FREQUENCY + // Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq = CLK2_FREQUENCY if (current_band != 1){ si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1); - si5351_setupPLL(SI5351_REG_PLL_B, PLL_N, 0, 1); - si5351_set_frequency_fixedpll(2, SI5351_REG_PLL_B, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA); + si5351_set_frequency_fixedpll(2, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA|SI5351_CLK_PLL_SELECT_A); } // Calculate and set CH0 and CH1 divider - si5351_set_frequency_fixedpll(0, SI5351_REG_PLL_A, XTALFREQ * PLL_N * omul, ofreq, rdiv, drive_strength); - si5351_set_frequency_fixedpll(1, SI5351_REG_PLL_A, XTALFREQ * PLL_N * mul, freq, rdiv, drive_strength); + 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: - case 3: + case 2:// fdiv = 6 + case 3:// fdiv = 4; + fdiv = (band == 2) ? 6 : 4; // Setup CH0 and CH1 constant fdiv divider at change if (current_band != band){ - si5351_setupMultisynth(0, SI5351_REG_PLL_A, fdiv, 0, 1, SI5351_R_DIV_1, drive_strength); - si5351_setupMultisynth(1, SI5351_REG_PLL_B, fdiv, 0, 1, SI5351_R_DIV_1, drive_strength); + 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); } // 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 // Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv - si5351_set_frequency_fixedpll(2, SI5351_REG_PLL_B, (freq/mul)*fdiv, CLK2_FREQUENCY, SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA); + 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; } diff --git a/si5351.h b/si5351.h index 4572dc8..6b5bdf5 100644 --- a/si5351.h +++ b/si5351.h @@ -17,53 +17,47 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -//#define SI5351_PLL_A 0 -//#define SI5351_PLL_B 1 - -#define SI5351_MULTISYNTH_DIV_4 4 -#define SI5351_MULTISYNTH_DIV_6 6 -#define SI5351_MULTISYNTH_DIV_8 8 -#define SI5351_R_DIV_1 (0<<4) -#define SI5351_R_DIV_2 (1<<4) -#define SI5351_R_DIV_4 (2<<4) -#define SI5351_R_DIV_8 (3<<4) -#define SI5351_R_DIV_16 (4<<4) -#define SI5351_R_DIV_32 (5<<4) -#define SI5351_R_DIV_64 (6<<4) -#define SI5351_R_DIV_128 (7<<4) -#define SI5351_DIVBY4 (3<<2) #define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 #define SI5351_CLK0_EN (1<<0) -#define SI5351_CLK1_EN (1<<2) -#define SI5351_CLK2_EN (1<<3) +#define SI5351_CLK1_EN (1<<1) +#define SI5351_CLK2_EN (1<<2) +// Reg 16-18 CLKX_CONTROL #define SI5351_REG_16_CLK0_CONTROL 16 #define SI5351_REG_17_CLK1_CONTROL 17 #define SI5351_REG_18_CLK2_CONTROL 18 -#define SI5351_REG_PLL_A 26 -#define SI5351_REG_PLL_B 34 -#define SI5351_REG_42_MULTISYNTH0 42 -#define SI5351_REG_50_MULTISYNTH1 50 -#define SI5351_REG_58_MULTISYNTH2 58 - #define SI5351_CLK_POWERDOWN (1<<7) #define SI5351_CLK_INTEGER_MODE (1<<6) +#define SI5351_CLK_PLL_SELECT_A (0<<5) #define SI5351_CLK_PLL_SELECT_B (1<<5) #define SI5351_CLK_INVERT (1<<4) - #define SI5351_CLK_INPUT_MASK (3<<2) #define SI5351_CLK_INPUT_XTAL (0<<2) #define SI5351_CLK_INPUT_CLKIN (1<<2) #define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) #define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) - #define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) #define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) #define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) #define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) #define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) +#define SI5351_REG_PLL_A 26 +#define SI5351_REG_PLL_B 34 + +#define SI5351_REG_42_MULTISYNTH0 42 +#define SI5351_REG_50_MULTISYNTH1 50 +#define SI5351_REG_58_MULTISYNTH2 58 +#define SI5351_DIVBY4 (3<<2) +#define SI5351_R_DIV_1 (0<<4) +#define SI5351_R_DIV_2 (1<<4) +#define SI5351_R_DIV_4 (2<<4) +#define SI5351_R_DIV_8 (3<<4) +#define SI5351_R_DIV_16 (4<<4) +#define SI5351_R_DIV_32 (5<<4) +#define SI5351_R_DIV_64 (6<<4) +#define SI5351_R_DIV_128 (7<<4) #define SI5351_REG_177_PLL_RESET 177 #define SI5351_PLL_RESET_B (1<<7) @@ -74,11 +68,8 @@ #define SI5351_CRYSTAL_LOAD_8PF (2<<6) #define SI5351_CRYSTAL_LOAD_10PF (3<<6) -#define SI5351_CRYSTAL_FREQ_25MHZ 25000000 - 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); +//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); diff --git a/ui.c b/ui.c index 562d0dd..b73ef29 100644 --- a/ui.c +++ b/ui.c @@ -1358,7 +1358,7 @@ menu_item_modify_attribute(const menuitem_t *menu, int item, *fg = config.menu_normal_color; } } else if (menu == menu_stimulus) { - if (item == 5 /* PAUSE */ && !sweep_enabled) { + if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_MODE_ENABLED)) { *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } @@ -2131,7 +2131,7 @@ touch_lever_mode_select(void) select_lever_mode(touch_x < FREQUENCIES_XPOS2 ? LM_CENTER : LM_SPAN); return TRUE; } - if (touch_y < 15) { + if (touch_y < 25) { if (touch_x < FREQUENCIES_XPOS2 && get_electrical_delay() != 0.0) { select_lever_mode(LM_EDELAY); } else From 12d53738bcaabb032af4673de513a2f2eb214154 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 7 Mar 2020 17:19:43 +0300 Subject: [PATCH 32/65] Revert some changes: Start/stop generation feature (unstable on segment scan from CPU) Calibration on paused sweep (need more stack, need find better solution) Variable use optimization --- Makefile | 4 +-- main.c | 100 +++++++++++++++++++++++++++++++++--------------------- nanovna.h | 8 +---- si5351.c | 19 ++++++----- ui.c | 2 +- 5 files changed, 77 insertions(+), 56 deletions(-) diff --git a/Makefile b/Makefile index fc18d97..bd17844 100644 --- a/Makefile +++ b/Makefile @@ -64,13 +64,13 @@ endif # Stack size to be allocated to the Cortex-M process stack. This stack is # the stack used by the main() thread. ifeq ($(USE_PROCESS_STACKSIZE),) - USE_PROCESS_STACKSIZE = 0x300 + USE_PROCESS_STACKSIZE = 0x200 endif # Stack size to the allocated to the Cortex-M main/exceptions stack. This # stack is used for processing interrupts and exceptions. ifeq ($(USE_EXCEPTIONS_STACKSIZE),) - USE_EXCEPTIONS_STACKSIZE = 0x100 + USE_EXCEPTIONS_STACKSIZE = 0x200 endif # diff --git a/main.c b/main.c index 02ef10d..bb1a4bb 100644 --- a/main.c +++ b/main.c @@ -69,14 +69,17 @@ static void transform_domain(void); static MUTEX_DECL(mutex); -// Obsolete enable/disable calibration interpolation (always on) -#define cal_auto_interpolate TRUE +#define DRIVE_STRENGTH_AUTO (-1) +#define FREQ_HARMONICS (config.harmonic_freq_threshold) +#define IS_HARMONIC_MODE(f) ((f) > FREQ_HARMONICS) +// 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; -volatile int8_t sweep_mode = SWEEP_MODE_ENABLED; - +int8_t sweep_enabled = TRUE; +volatile int8_t sweep_once = FALSE; volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; @@ -88,19 +91,19 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; - if (sweep_mode&(SWEEP_MODE_ENABLED|SWEEP_MODE_RUN_ONCE)) { + if (sweep_enabled || sweep_once) { chMtxLock(&mutex); completed = sweep(true); - sweep_mode&=~SWEEP_MODE_RUN_ONCE; + sweep_once = FALSE; chMtxUnlock(&mutex); } else { - si5351_disable_output(); __WFI(); } chMtxLock(&mutex); ui_process(); - if (sweep_mode&SWEEP_MODE_ENABLED) { + + if (sweep_enabled) { if (vbat != -1) { adc_stop(ADC1); vbat = adc_vbat_read(ADC1); @@ -130,10 +133,23 @@ static THD_FUNCTION(Thread1, arg) } } -static inline void run_once_sweep(void) {sweep_mode|=SWEEP_MODE_RUN_ONCE;} -static inline void pause_sweep(void) {sweep_mode&=~SWEEP_MODE_ENABLED;} -static inline void resume_sweep(void){sweep_mode|= SWEEP_MODE_ENABLED;} -void toggle_sweep(void){sweep_mode^= SWEEP_MODE_ENABLED;} +static inline void +pause_sweep(void) +{ + sweep_enabled = FALSE; +} + +static inline void +resume_sweep(void) +{ + sweep_enabled = TRUE; +} + +void +toggle_sweep(void) +{ + sweep_enabled = !sweep_enabled; +} static float bessel0(float x) { @@ -723,8 +739,7 @@ static const marker_t def_markers[MARKERS_MAX] = { // Load propeties default settings void loadDefaultProps(void){ -//Magic add on caldata_save -//current_props.magic = CONFIG_MAGIC; + current_props.magic = CONFIG_MAGIC; current_props._frequency0 = 50000; // start = 50kHz current_props._frequency1 = 900000000; // end = 900MHz current_props._sweep_points = POINTS_COUNT; @@ -740,8 +755,6 @@ void loadDefaultProps(void){ current_props._active_marker = 0; current_props._domain_mode = 0; current_props._marker_smith_format = MS_RLC; -//Checksum add on caldata_save -//current_props.checksum = 0; } void @@ -759,23 +772,20 @@ ensure_edit_config(void) #define DELAY_CHANNEL_CHANGE 2 // main loop for measurement -static bool sweep(bool break_on_operation) +bool sweep(bool break_on_operation) { int i, delay; // blink LED while scanning palClearPad(GPIOC, GPIOC_LED); - si5351_enable_output(); - wait_dsp(1); // Wait for get optimal timings for (i = 0; i < sweep_points; i++) { // 5300 delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT - wait_dsp(delay); // 1900 // calculate reflection coefficient (*sample_func)(measured[0][i]); // 60 tlv320aic3204_select(1); // 60 CH1:TRANSMISSION - wait_dsp(DELAY_CHANNEL_CHANGE); // 1800 + wait_dsp(DELAY_CHANNEL_CHANGE); // 1700 // calculate transmission coefficient (*sample_func)(measured[1][i]); // 60 // ======== 170 =========== @@ -786,9 +796,8 @@ static bool sweep(bool break_on_operation) apply_edelay_at(i); // back to toplevel to handle ui operation - if (operation_requested && break_on_operation){ + if (operation_requested && break_on_operation) return false; - } } // blink LED while scanning palSetPad(GPIOC, GPIOC_LED); @@ -825,11 +834,11 @@ VNA_SHELL_FUNCTION(cmd_scan) if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) cal_interpolate(lastsaveid); - run_once_sweep(); + sweep_once = TRUE; chMtxUnlock(&mutex); // wait finishing sweep - while (sweep_mode&SWEEP_MODE_RUN_ONCE) + while (sweep_once) chThdSleepMilliseconds(10); } @@ -1270,21 +1279,36 @@ void cal_collect(int type) { ensure_edit_config(); - int dst, src; + switch (type) { - 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; + 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; } - // Made sweep operation for collect calibration data - sweep(false); - // Copy calibration data - memcpy(cal_data[dst], measured[src], sizeof measured[0]); - redraw_request|= REDRAW_CAL_STATUS; + redraw_request |= REDRAW_CAL_STATUS; } void diff --git a/nanovna.h b/nanovna.h index 72753d1..b79d4c8 100644 --- a/nanovna.h +++ b/nanovna.h @@ -86,9 +86,7 @@ double my_atof(const char *p); void toggle_sweep(void); void loadDefaultProps(void); -#define SWEEP_MODE_ENABLED 0x01 -#define SWEEP_MODE_RUN_ONCE 0x02 -extern volatile int8_t sweep_mode; +extern int8_t sweep_enabled; /* * dsp.c @@ -225,10 +223,6 @@ typedef struct config { extern config_t config; -#define DRIVE_STRENGTH_AUTO (-1) -#define FREQ_HARMONICS (config.harmonic_freq_threshold) -#define IS_HARMONIC_MODE(f) ((f) > FREQ_HARMONICS) - //extern trace_t trace[TRACES_MAX]; void set_trace_type(int t, int type); diff --git a/si5351.c b/si5351.c index a08bfbe..6a8ad49 100644 --- a/si5351.c +++ b/si5351.c @@ -78,8 +78,8 @@ const uint8_t si5351_configs[] = { // setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50) 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0, 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE, - 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0, #endif + 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN), 0 // sentinel }; @@ -118,7 +118,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(200); + chThdSleepMicroseconds(400); si5351_write(SI5351_REG_177_PLL_RESET, mask | 0x0C); } @@ -126,6 +126,7 @@ void si5351_disable_output(void) { si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xFF); si5351_bulk_write(disable_output, sizeof(disable_output)); + current_band = 0; } void si5351_enable_output(void) @@ -338,7 +339,8 @@ static inline uint8_t si5351_getBand(uint32_t freq){ // 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 2 +#define DELAY_BANDCHANGE_1 3 +#define DELAY_BANDCHANGE_2 3 /* * Maximum supported frequency = FREQ_HARMONICS * 9U @@ -358,16 +360,16 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng uint32_t rdiv = SI5351_R_DIV_1; uint32_t fdiv; current_freq = freq; - if (freq >= FREQ_HARMONICS * 7U) { + if (freq >= config.harmonic_freq_threshold * 7U) { mul = 9; omul = 11; - } else if (freq >= FREQ_HARMONICS * 5U) { + } else if (freq >= config.harmonic_freq_threshold * 5U) { mul = 7; omul = 9; - } else if (freq >= FREQ_HARMONICS * 3U) { + } else if (freq >= config.harmonic_freq_threshold * 3U) { mul = 5; omul = 7; - } else if (freq >= FREQ_HARMONICS) { + } else if (freq >= config.harmonic_freq_threshold) { mul = 3; omul = 5; } @@ -388,6 +390,7 @@ 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; } // 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); @@ -401,6 +404,7 @@ 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; } // Calculate and set CH0 and CH1 PLL freq si5351_setupPLL_freq(SI5351_REG_PLL_A, ofreq, fdiv, omul);// set PLLA freq = (ofreq/omul)*fdiv @@ -413,7 +417,6 @@ si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_streng if (current_band != band) { si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B); current_band = band; - delay+=DELAY_BANDCHANGE; } return delay; } diff --git a/ui.c b/ui.c index b73ef29..eaffa8d 100644 --- a/ui.c +++ b/ui.c @@ -1358,7 +1358,7 @@ menu_item_modify_attribute(const menuitem_t *menu, int item, *fg = config.menu_normal_color; } } else if (menu == menu_stimulus) { - if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_MODE_ENABLED)) { + if (item == 5 /* PAUSE */ && !sweep_enabled) { *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } From e896f328033319059e69289bdcd58e0dc349cfb5 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 7 Mar 2020 20:57:43 +0300 Subject: [PATCH 33/65] Replace function wait_dsp(delay) by definition: DSP_START(delay) //================================================ // Place some code thats need execute while delay //================================================ DSP_WAIT_READY Fix Band table description Add power stabilization delay on sweep start --- main.c | 38 +++++++++++++++++++++++--------------- si5351.c | 11 ++++++----- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/main.c b/main.c index bb1a4bb..8dc8c17 100644 --- a/main.c +++ b/main.c @@ -423,9 +423,9 @@ static int getStringIndex(char *v, const char *list){ } // Set new substring ptr while (1){ - // End of string, not found - if (*list == 0 ) return -1; - if (*list++ == '|') break; + // End of string, not found + if (*list == 0 ) return -1; + if (*list++ == '|') break; } i++; } @@ -553,15 +553,6 @@ volatile int16_t wait_count = 0; float measured[2][POINTS_COUNT][2]; -static void -wait_dsp(int count) -{ - wait_count = count; - //reset_dsp_accumerator(); - while (wait_count) - __WFI(); -} - #ifdef ENABLED_DUMP static void duplicate_buffer_to_dump(int16_t *p) @@ -739,7 +730,8 @@ static const marker_t def_markers[MARKERS_MAX] = { // Load propeties default settings void loadDefaultProps(void){ - current_props.magic = CONFIG_MAGIC; +//Magic add on caldata_save +//current_props.magic = CONFIG_MAGIC; current_props._frequency0 = 50000; // start = 50kHz current_props._frequency1 = 900000000; // end = 900MHz current_props._sweep_points = POINTS_COUNT; @@ -755,6 +747,8 @@ void loadDefaultProps(void){ current_props._active_marker = 0; current_props._domain_mode = 0; current_props._marker_smith_format = MS_RLC; +//Checksum add on caldata_save +//current_props.checksum = 0; } void @@ -769,6 +763,9 @@ ensure_edit_config(void) cal_status = 0; } +#define DSP_START(delay) wait_count = delay; +#define DSP_WAIT_READY while (wait_count) __WFI(); + #define DELAY_CHANNEL_CHANGE 2 // main loop for measurement @@ -777,15 +774,26 @@ 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; for (i = 0; i < sweep_points; i++) { // 5300 delay = set_frequency(frequencies[i]); // 700 tlv320aic3204_select(0); // 60 CH0:REFLECT - wait_dsp(delay); // 1900 + DSP_START(delay); // 1900 + //================================================ + // Place some code thats need execute while delay + //================================================ + DSP_WAIT_READY; // calculate reflection coefficient (*sample_func)(measured[0][i]); // 60 tlv320aic3204_select(1); // 60 CH1:TRANSMISSION - wait_dsp(DELAY_CHANNEL_CHANGE); // 1700 + DSP_START(DELAY_CHANNEL_CHANGE); // 1700 + //================================================ + // Place some code thats need execute while delay + //================================================ + DSP_WAIT_READY; // calculate transmission coefficient (*sample_func)(measured[1][i]); // 60 // ======== 170 =========== diff --git a/si5351.c b/si5351.c index 6a8ad49..92eeb8a 100644 --- a/si5351.c +++ b/si5351.c @@ -321,11 +321,12 @@ si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength){ * +-----------------------------------------------------------------------------------------------------------------------+ * | Band 1 | Band 2 | Band 3 | Band 2 | Band 3 | * +-----------------------------------------------------------------------------------------------------------------------+ - * | x1 : x1 | x1 : x1 | x1 : x1 | x3 : x5 | x3 : x5 | x5-x7 | x7-x9 | x9-x11 | + * | Direct mode x1 : x1 | x3 : x5 | x5-x7 | x7-x9 | x9-x11 | + * +-----------------------------------------------------------------------------------------------------------------------+ * | 50kHz - 100MHz | 100 - 150MHz | 150 - 300MHz | 300-450MHz | 450-900MHz | 900-1500MHz | 1500-2100MHz | 2100-2700MHz | * +-----------------------------------------------------------------------------------------------------------------------+ - * | f = 50kHz-100MHz | f=100-150 | f=150-300 | f=150-300 | f=214-300 | f=233-300 | - * | of = 50kHz-100MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 | + * | f = 50kHz-300MHz | f=100-150 | f=150-300 | f=150-300 | f=214-300 | f=233-300 | + * | of = 50kHz-300MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 | * +-----------------------------------------------------------------------------------------------------------------------+ */ static inline uint8_t si5351_getBand(uint32_t freq){ @@ -339,8 +340,8 @@ static inline uint8_t si5351_getBand(uint32_t freq){ // 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 3 -#define DELAY_BANDCHANGE_2 3 +#define DELAY_BANDCHANGE_1 2 +#define DELAY_BANDCHANGE_2 2 /* * Maximum supported frequency = FREQ_HARMONICS * 9U From bb7127fdd019159f1d53c738a9f3ddef072828af Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 7 Mar 2020 22:21:02 +0300 Subject: [PATCH 34/65] Remove variable, use speep_mode flag --- main.c | 20 ++++++++++---------- nanovna.h | 4 +++- ui.c | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/main.c b/main.c index 8dc8c17..008f30e 100644 --- a/main.c +++ b/main.c @@ -78,8 +78,8 @@ static MUTEX_DECL(mutex); static int32_t frequency_offset = 5000; static uint32_t frequency = 10000000; static int8_t drive_strength = DRIVE_STRENGTH_AUTO; -int8_t sweep_enabled = TRUE; -volatile int8_t sweep_once = FALSE; +int8_t sweep_mode = SWEEP_ENABLE; + volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; @@ -91,10 +91,10 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; - if (sweep_enabled || sweep_once) { + if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) { chMtxLock(&mutex); completed = sweep(true); - sweep_once = FALSE; + sweep_mode&=~SWEEP_ONCE; chMtxUnlock(&mutex); } else { __WFI(); @@ -103,7 +103,7 @@ static THD_FUNCTION(Thread1, arg) chMtxLock(&mutex); ui_process(); - if (sweep_enabled) { + if (sweep_mode&SWEEP_ENABLE) { if (vbat != -1) { adc_stop(ADC1); vbat = adc_vbat_read(ADC1); @@ -136,19 +136,19 @@ static THD_FUNCTION(Thread1, arg) static inline void pause_sweep(void) { - sweep_enabled = FALSE; + sweep_mode&=~SWEEP_ENABLE; } static inline void resume_sweep(void) { - sweep_enabled = TRUE; + sweep_mode|=SWEEP_ENABLE; } void toggle_sweep(void) { - sweep_enabled = !sweep_enabled; + sweep_mode^=SWEEP_ENABLE; } static float @@ -842,11 +842,11 @@ VNA_SHELL_FUNCTION(cmd_scan) if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) cal_interpolate(lastsaveid); - sweep_once = TRUE; + sweep_mode|= SWEEP_ONCE; chMtxUnlock(&mutex); // wait finishing sweep - while (sweep_once) + while (sweep_mode&SWEEP_ONCE) chThdSleepMilliseconds(10); } diff --git a/nanovna.h b/nanovna.h index b79d4c8..f2b9721 100644 --- a/nanovna.h +++ b/nanovna.h @@ -86,7 +86,9 @@ double my_atof(const char *p); void toggle_sweep(void); void loadDefaultProps(void); -extern int8_t sweep_enabled; +#define SWEEP_ENABLE 0x01 +#define SWEEP_ONCE 0x02 +extern int8_t sweep_mode; /* * dsp.c diff --git a/ui.c b/ui.c index eaffa8d..93cc96d 100644 --- a/ui.c +++ b/ui.c @@ -1358,7 +1358,7 @@ menu_item_modify_attribute(const menuitem_t *menu, int item, *fg = config.menu_normal_color; } } else if (menu == menu_stimulus) { - if (item == 5 /* PAUSE */ && !sweep_enabled) { + if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_ENABLE)) { *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } From fc6e090595e35299db5acf309bee39f58dc1b6cd Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 7 Mar 2020 23:37:39 +0300 Subject: [PATCH 35/65] Add vbat_offset to config Implement vbat_offset command (if defined ENABLE_VBAT_OFFSET_COMMAND) Reduce code size --- adc.c | 121 +++++++++++++++++++++++++++--------------------------- main.c | 31 ++++++++------ nanovna.h | 18 ++++---- plot.c | 9 ++-- ui.c | 20 ++++----- 5 files changed, 103 insertions(+), 96 deletions(-) diff --git a/adc.c b/adc.c index 1da498d..2486210 100644 --- a/adc.c +++ b/adc.c @@ -28,80 +28,79 @@ #define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */ #define ADC_CFGR1_RES_12BIT (0U << 3U) +#define VNA_ADC ADC1 + void adc_init(void) { rccEnableADC1(FALSE); /* Ensure flag states */ - ADC1->IER = 0; + VNA_ADC->IER = 0; /* Calibration procedure.*/ ADC->CCR = 0; - if (ADC1->CR & ADC_CR_ADEN) { - ADC1->CR |= ~ADC_CR_ADDIS; /* Disable ADC */ + if (VNA_ADC->CR & ADC_CR_ADEN) { + VNA_ADC->CR |= ~ADC_CR_ADDIS; /* Disable ADC */ } - while (ADC1->CR & ADC_CR_ADEN) + while (VNA_ADC->CR & ADC_CR_ADEN) ; - ADC1->CFGR1 &= ~ADC_CFGR1_DMAEN; - ADC1->CR |= ADC_CR_ADCAL; - while (ADC1->CR & ADC_CR_ADCAL) + VNA_ADC->CFGR1 &= ~ADC_CFGR1_DMAEN; + VNA_ADC->CR |= ADC_CR_ADCAL; + while (VNA_ADC->CR & ADC_CR_ADCAL) ; - if (ADC1->ISR & ADC_ISR_ADRDY) { - ADC1->ISR |= ADC_ISR_ADRDY; /* clear ADRDY */ + if (VNA_ADC->ISR & ADC_ISR_ADRDY) { + VNA_ADC->ISR |= ADC_ISR_ADRDY; /* clear ADRDY */ } /* Enable ADC */ - ADC1->CR |= ADC_CR_ADEN; - while (!(ADC1->ISR & ADC_ISR_ADRDY)) + VNA_ADC->CR |= ADC_CR_ADEN; + while (!(VNA_ADC->ISR & ADC_ISR_ADRDY)) ; } -uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel) +uint16_t adc_single_read(uint32_t chsel) { /* ADC setup */ - adc->ISR = adc->ISR; - adc->IER = 0; - adc->TR = ADC_TR(0, 0); - adc->SMPR = ADC_SMPR_SMP_239P5; - adc->CFGR1 = ADC_CFGR1_RES_12BIT; - adc->CHSELR = chsel; + VNA_ADC->ISR = VNA_ADC->ISR; + VNA_ADC->IER = 0; + VNA_ADC->TR = ADC_TR(0, 0); + VNA_ADC->SMPR = ADC_SMPR_SMP_239P5; + VNA_ADC->CFGR1 = ADC_CFGR1_RES_12BIT; + VNA_ADC->CHSELR = chsel; /* ADC conversion start.*/ - adc->CR |= ADC_CR_ADSTART; + VNA_ADC->CR |= ADC_CR_ADSTART; - while (adc->CR & ADC_CR_ADSTART) + while (VNA_ADC->CR & ADC_CR_ADSTART) ; - return adc->DR; + return VNA_ADC->DR; } -int16_t adc_vbat_read(ADC_TypeDef *adc) +int16_t adc_vbat_read(void) { #define ADC_FULL_SCALE 3300 -#define VBAT_DIODE_VF 500 #define VREFINT_CAL (*((uint16_t*)0x1FFFF7BA)) - float vbat = 0; - float vrefint = 0; - - ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN; - // VREFINT == ADC_IN17 - vrefint = adc_single_read(adc, ADC_CHSELR_CHSEL17); - // VBAT == ADC_IN18 - // VBATEN enables resiter devider circuit. It consume vbat power. - vbat = adc_single_read(adc, ADC_CHSELR_CHSEL18); - ADC->CCR &= ~(ADC_CCR_VREFEN | ADC_CCR_VBATEN); - - uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * vbat * 2 / (vrefint * ((1<<12)-1))); - if (vbat_raw < 100) { - // maybe D2 is not installed - return -1; - } - - return vbat_raw + VBAT_DIODE_VF; - + 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); + // VBAT == ADC_IN18 + // VBATEN enables resiter devider circuit. It consume vbat power. + 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))); + if (vbat_raw < 100) { + // maybe D2 is not installed + return -1; + } + return vbat_raw + config.vbat_offset; } -void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel) +void adc_start_analog_watchdogd(uint32_t chsel) { uint32_t cfgr1; @@ -111,38 +110,38 @@ void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel) /* ADC setup, if it is defined a callback for the analog watch dog then it is enabled.*/ - adc->ISR = adc->ISR; - adc->IER = ADC_IER_AWDIE; - adc->TR = ADC_TR(0, TOUCH_THRESHOLD); - adc->SMPR = ADC_SMPR_SMP_1P5; - adc->CHSELR = chsel; + VNA_ADC->ISR = VNA_ADC->ISR; + VNA_ADC->IER = ADC_IER_AWDIE; + VNA_ADC->TR = ADC_TR(0, TOUCH_THRESHOLD); + VNA_ADC->SMPR = ADC_SMPR_SMP_1P5; + VNA_ADC->CHSELR = chsel; /* ADC configuration and start.*/ - adc->CFGR1 = cfgr1; + VNA_ADC->CFGR1 = cfgr1; /* ADC conversion start.*/ - adc->CR |= ADC_CR_ADSTART; + VNA_ADC->CR |= ADC_CR_ADSTART; } -void adc_stop(ADC_TypeDef *adc) +void adc_stop(void) { - if (adc->CR & ADC_CR_ADEN) { - if (adc->CR & ADC_CR_ADSTART) { - adc->CR |= ADC_CR_ADSTP; - while (adc->CR & ADC_CR_ADSTP) + if (VNA_ADC->CR & ADC_CR_ADEN) { + if (VNA_ADC->CR & ADC_CR_ADSTART) { + VNA_ADC->CR |= ADC_CR_ADSTP; + while (VNA_ADC->CR & ADC_CR_ADSTP) ; } - /* adc->CR |= ADC_CR_ADDIS; - while (adc->CR & ADC_CR_ADDIS) + /* VNA_ADC->CR |= ADC_CR_ADDIS; + while (VNA_ADC->CR & ADC_CR_ADDIS) ;*/ } } -void adc_interrupt(ADC_TypeDef *adc) +void adc_interrupt(void) { - uint32_t isr = adc->ISR; - adc->ISR = isr; + uint32_t isr = VNA_ADC->ISR; + VNA_ADC->ISR = isr; if (isr & ADC_ISR_OVR) { /* ADC overflow condition, this could happen only if the DMA is unable @@ -159,7 +158,7 @@ OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) { OSAL_IRQ_PROLOGUE(); - adc_interrupt(ADC1); + adc_interrupt(); OSAL_IRQ_EPILOGUE(); } diff --git a/main.c b/main.c index 008f30e..bb13344 100644 --- a/main.c +++ b/main.c @@ -57,6 +57,7 @@ static char shell_line[VNA_SHELL_MAX_LENGTH]; //#define ENABLED_DUMP //#define ENABLE_THREADS_COMMAND //#define ENABLE_TIME_COMMAND +#define ENABLE_VBAT_OFFSET_COMMAND static void apply_error_term_at(int i); static void apply_edelay_at(int i); @@ -79,9 +80,7 @@ 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 -int16_t vbat = 0; static THD_WORKING_AREA(waThread1, 640); static THD_FUNCTION(Thread1, arg) @@ -104,19 +103,12 @@ static THD_FUNCTION(Thread1, arg) ui_process(); if (sweep_mode&SWEEP_ENABLE) { - if (vbat != -1) { - adc_stop(ADC1); - vbat = adc_vbat_read(ADC1); - touch_start_watchdog(); - draw_battery_status(); - } - // 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_request |= REDRAW_CELLS|REDRAW_BATTERY; if (uistat.marker_tracking) { int i = marker_search(); @@ -710,7 +702,8 @@ 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 - .harmonic_freq_threshold = 300000000 + .harmonic_freq_threshold = 300000000, + .vbat_offset = 500 }; properties_t current_props; @@ -1942,9 +1935,20 @@ VNA_SHELL_FUNCTION(cmd_vbat) { (void)argc; (void)argv; - shell_printf("%d mV\r\n", vbat); + shell_printf("%d mV\r\n", adc_vbat_read()); } +#ifdef ENABLE_VBAT_OFFSET_COMMAND +VNA_SHELL_FUNCTION(cmd_vbat_offset) +{ + if (argc != 1) { + shell_printf("%d\r\n", config.vbat_offset); + return; + } + config.vbat_offset = (int16_t)my_atoi(argv[0]); +} +#endif + #ifdef ENABLE_THREADS_COMMAND #if CH_CFG_USE_REGISTRY == FALSE #error "Threads Requite enabled CH_CFG_USE_REGISTRY in chconf.h" @@ -2028,6 +2032,9 @@ static const VNAShellCommand commands[] = {"edelay" , cmd_edelay , 0}, {"capture" , cmd_capture , CMD_WAIT_MUTEX}, {"vbat" , cmd_vbat , 0}, +#ifdef ENABLE_VBAT_OFFSET_COMMAND + {"vbat_offset" , cmd_vbat_offset , 0}, +#endif {"transform" , cmd_transform , 0}, {"threshold" , cmd_threshold , 0}, {"help" , cmd_help , 0}, diff --git a/nanovna.h b/nanovna.h index f2b9721..58e4e4c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -218,8 +218,8 @@ typedef struct config { int16_t touch_cal[4]; int8_t reserved_1; uint32_t harmonic_freq_threshold; - - uint8_t _reserved[24]; + uint16_t vbat_offset; + uint8_t _reserved[22]; uint32_t checksum; } config_t; @@ -234,7 +234,6 @@ void set_trace_refpos(int t, float refpos); float get_trace_scale(int t); float get_trace_refpos(int t); const char *get_trace_typename(int t); -void draw_battery_status(void); void set_electrical_delay(float picoseconds); float get_electrical_delay(void); @@ -282,10 +281,9 @@ int marker_search_right(int from); #define REDRAW_FREQUENCY (1<<1) #define REDRAW_CAL_STATUS (1<<2) #define REDRAW_MARKER (1<<3) +#define REDRAW_BATTERY (1<<4) extern volatile uint8_t redraw_request; -extern int16_t vbat; - /* * ili9341.c */ @@ -468,11 +466,11 @@ void enter_dfu(void); */ void adc_init(void); -uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel); -void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel); -void adc_stop(ADC_TypeDef *adc); -void adc_interrupt(ADC_TypeDef *adc); -int16_t adc_vbat_read(ADC_TypeDef *adc); +uint16_t adc_single_read(uint32_t chsel); +void adc_start_analog_watchdogd(uint32_t chsel); +void adc_stop(void); +void adc_interrupt(void); +int16_t adc_vbat_read(void); /* * misclinous diff --git a/plot.c b/plot.c index d1762f0..5d712a6 100644 --- a/plot.c +++ b/plot.c @@ -6,6 +6,7 @@ #include "nanovna.h" static void cell_draw_marker_info(int x0, int y0); +static void draw_battery_status(void); int16_t grid_offset; int16_t grid_width; @@ -1388,6 +1389,8 @@ draw_all(bool flush) draw_frequencies(); if (redraw_request & REDRAW_CAL_STATUS) draw_cal_status(); + if (redraw_request & REDRAW_BATTERY) + draw_battery_status(); redraw_request = 0; } @@ -1661,10 +1664,10 @@ draw_cal_status(void) #define BATTERY_BOTTOM_LEVEL 3100 #define BATTERY_WARNING_LEVEL 3300 -void -draw_battery_status(void) +static void draw_battery_status(void) { - if (vbat<=0) + int16_t vbat = adc_vbat_read(); + if (vbat <= 0) return; uint8_t string_buf[16]; // Set battery color diff --git a/ui.c b/ui.c index 93cc96d..a3ac007 100644 --- a/ui.c +++ b/ui.c @@ -212,7 +212,7 @@ touch_measure_y(void) palSetPad(GPIOA, 6); chThdSleepMilliseconds(2); - v = adc_single_read(ADC1, ADC_CHSELR_CHSEL7); + v = adc_single_read(ADC_CHSELR_CHSEL7); //chThdSleepMilliseconds(2); //v += adc_single_read(ADC1, ADC_CHSELR_CHSEL7); return v; @@ -232,7 +232,7 @@ touch_measure_x(void) palClearPad(GPIOA, 7); chThdSleepMilliseconds(2); - v = adc_single_read(ADC1, ADC_CHSELR_CHSEL6); + v = adc_single_read(ADC_CHSELR_CHSEL6); //chThdSleepMilliseconds(2); //v += adc_single_read(ADC1, ADC_CHSELR_CHSEL6); return v; @@ -255,14 +255,14 @@ void touch_start_watchdog(void) { touch_prepare_sense(); - adc_start_analog_watchdogd(ADC1, ADC_CHSELR_CHSEL7); + adc_start_analog_watchdogd(ADC_CHSELR_CHSEL7); } static int touch_status(void) { touch_prepare_sense(); - return adc_single_read(ADC1, ADC_CHSELR_CHSEL7) > TOUCH_THRESHOLD; + return adc_single_read(ADC_CHSELR_CHSEL7) > TOUCH_THRESHOLD; } static int @@ -302,7 +302,7 @@ touch_cal_exec(void) { int x1, x2, y1, y2; - adc_stop(ADC1); + adc_stop(); setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); clearScreen(); @@ -338,7 +338,7 @@ touch_draw_test(void) int x0, y0; int x1, y1; - adc_stop(ADC1); + adc_stop(); setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); @@ -372,7 +372,7 @@ void show_version(void) { int x = 5, y = 5; - adc_stop(ADC1); + adc_stop(); setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); @@ -404,7 +404,7 @@ show_version(void) void enter_dfu(void) { - adc_stop(ADC1); + adc_stop(); int x = 5, y = 5; setForegroundColor(DEFAULT_FG_COLOR); @@ -2003,7 +2003,7 @@ static void ui_process_keypad(void) { int status; - adc_stop(ADC1); + adc_stop(); kp_index = 0; while (TRUE) { @@ -2145,7 +2145,7 @@ static void ui_process_touch(void) { // awd_count++; - adc_stop(ADC1); + adc_stop(); int status = touch_check(); if (status == EVT_TOUCH_PRESSED || status == EVT_TOUCH_DOWN) { From 45f04420cbacc1420deaecdd3cd300b85a1208d3 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 8 Mar 2020 08:32:38 +0300 Subject: [PATCH 36/65] Implement info command, move info_about[] to main.c Command enabled by default: ENABLE_INFO_COMMAND This feature not increase flash size --- main.c | 32 ++++++++++++++++++++++++++++++-- nanovna.h | 1 + ui.c | 23 +++++++---------------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/main.c b/main.c index bb13344..2593545 100644 --- a/main.c +++ b/main.c @@ -58,6 +58,7 @@ static char shell_line[VNA_SHELL_MAX_LENGTH]; //#define ENABLE_THREADS_COMMAND //#define ENABLE_TIME_COMMAND #define ENABLE_VBAT_OFFSET_COMMAND +#define ENABLE_INFO_COMMAND static void apply_error_term_at(int i); static void apply_edelay_at(int i); @@ -82,6 +83,21 @@ static int8_t drive_strength = DRIVE_STRENGTH_AUTO; int8_t sweep_mode = SWEEP_ENABLE; volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags +// Version text, displayed in Config->Version menu, also send by info command +const char *info_about[]={ + BOARD_NAME, + "2016-2020 Copyright @edy555", + "Licensed under GPL. See: https://github.com/ttrftech/NanoVNA", + "Version: " VERSION, + "Build Time: " __DATE__ " - " __TIME__, + "Kernel: " CH_KERNEL_VERSION, + "Compiler: " PORT_COMPILER_NAME, + "Architecture: " PORT_ARCHITECTURE_NAME " Core Variant: " PORT_CORE_VARIANT_NAME, + "Port Info: " PORT_INFO, + "Platform: " PLATFORM_NAME, + 0 // sentinel +}; + static THD_WORKING_AREA(waThread1, 640); static THD_FUNCTION(Thread1, arg) { @@ -1949,6 +1965,17 @@ VNA_SHELL_FUNCTION(cmd_vbat_offset) } #endif +#ifdef ENABLE_INFO_COMMAND +VNA_SHELL_FUNCTION(cmd_info) +{ + (void)argc; + (void)argv; + int i=0; + while (info_about[i]) + shell_printf("%s\r\n", info_about[i++]); +} +#endif + #ifdef ENABLE_THREADS_COMMAND #if CH_CFG_USE_REGISTRY == FALSE #error "Threads Requite enabled CH_CFG_USE_REGISTRY in chconf.h" @@ -1970,8 +1997,6 @@ VNA_SHELL_FUNCTION(cmd_threads) { #else uint32_t stklimit = 0U; #endif - - shell_printf("%08x|%08x|%08x|%08x|%4u|%4u|%9s|%12s"VNA_SHELL_NEWLINE_STR, stklimit, (uint32_t)tp->ctx.sp, max_stack_use, (uint32_t)tp, (uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state], @@ -2038,6 +2063,9 @@ static const VNAShellCommand commands[] = {"transform" , cmd_transform , 0}, {"threshold" , cmd_threshold , 0}, {"help" , cmd_help , 0}, +#ifdef ENABLE_INFO_COMMAND + {"info" , cmd_info , 0}, +#endif #ifdef ENABLE_THREADS_COMMAND {"threads" , cmd_threads , 0}, #endif diff --git a/nanovna.h b/nanovna.h index 58e4e4c..d5d14cc 100644 --- a/nanovna.h +++ b/nanovna.h @@ -89,6 +89,7 @@ void loadDefaultProps(void); #define SWEEP_ENABLE 0x01 #define SWEEP_ONCE 0x02 extern int8_t sweep_mode; +extern const char *info_about[]; /* * dsp.c diff --git a/ui.c b/ui.c index a3ac007..a2267da 100644 --- a/ui.c +++ b/ui.c @@ -367,30 +367,21 @@ touch_position(int *x, int *y) *y = (last_touch_y - config.touch_cal[1]) * 16 / config.touch_cal[3]; } - void show_version(void) { - int x = 5, y = 5; + int x = 5, y = 5, i = 0; adc_stop(); setForegroundColor(DEFAULT_FG_COLOR); setBackgroundColor(DEFAULT_BG_COLOR); clearScreen(); - ili9341_drawstring_size(BOARD_NAME, x, y, 4); - y += 25; - - ili9341_drawstring("2016-2020 Copyright @edy555", x, y += 10); - ili9341_drawstring("Licensed under GPL. See: https://github.com/ttrftech/NanoVNA", x, y += 10); - ili9341_drawstring("Version: " VERSION, x, y += 10); - ili9341_drawstring("Build Time: " __DATE__ " - " __TIME__, x, y += 10); - y += 5; - ili9341_drawstring("Kernel: " CH_KERNEL_VERSION, x, y += 10); - ili9341_drawstring("Compiler: " PORT_COMPILER_NAME, x, y += 10); - ili9341_drawstring("Architecture: " PORT_ARCHITECTURE_NAME " Core Variant: " PORT_CORE_VARIANT_NAME, x, y += 10); - ili9341_drawstring("Port Info: " PORT_INFO, x, y += 10); - ili9341_drawstring("Platform: " PLATFORM_NAME, x, y += 10); - + uint16_t shift = 0b0000010000111110; + ili9341_drawstring_size(info_about[i++], x , y, 4); + while (info_about[i]){ + do {shift>>=1; y+=5;} while (shift&1); + ili9341_drawstring(info_about[i++], x, y+=5); + } while (true) { if (touch_check() == EVT_TOUCH_PRESSED) break; From 6befd57bc11f4433bc43614c70453a127cf785f3 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 8 Mar 2020 19:37:26 +0900 Subject: [PATCH 37/65] fix: segv in sample command --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 2593545..c6c5a96 100644 --- a/main.c +++ b/main.c @@ -699,7 +699,7 @@ VNA_SHELL_FUNCTION(cmd_sample) if (argc!=1) goto usage; // 0 1 2 static const char cmd_sample_list[] = "gamma|ampl|ref"; - switch (getStringIndex(argv[1], cmd_sample_list)){ + switch (getStringIndex(argv[0], cmd_sample_list)){ case 0:sample_func = calculate_gamma; return; case 1:sample_func = fetch_amplitude; return; case 2:sample_func = fetch_amplitude_ref; return; From ba5bf9c1adf789b5a2bbdcdfbe5e0cfe40477454 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 8 Mar 2020 19:55:57 +0900 Subject: [PATCH 38/65] fix: board definition --- NANOVNA_STM32_F072/board.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index 7ab4c29..c64cf75 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -17,10 +17,6 @@ #ifndef _BOARD_H_ #define _BOARD_H_ -/* - * Setup for the Strawberry Linux STbee - */ - /* * Board identifier. */ @@ -130,8 +126,8 @@ PIN_MODE_ALTERNATE(GPIOA_MCO) | \ PIN_MODE_INPUT(9U) | \ PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \ - PIN_MODE_INPUT(GPIOA_USB_DM) | \ - PIN_MODE_INPUT(GPIOA_USB_DP) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_DM) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_DP) | \ PIN_MODE_ALTERNATE(GPIOA_JTMS) | \ PIN_MODE_ALTERNATE(GPIOA_JTCK) | \ PIN_MODE_OUTPUT(GPIOA_LCD_RESET)) @@ -161,7 +157,7 @@ PIN_OSPEED_2M(7) | \ PIN_OSPEED_100M(GPIOA_MCO) | \ PIN_OSPEED_100M(9) | \ - PIN_OSPEED_100M(10) | \ + PIN_OSPEED_100M(GPIOA_USB_DISC) | \ PIN_OSPEED_100M(GPIOA_USB_DM) | \ PIN_OSPEED_100M(GPIOA_USB_DP) | \ PIN_OSPEED_100M(GPIOA_JTMS) | \ @@ -177,7 +173,7 @@ PIN_PUPDR_FLOATING(7) | \ PIN_PUPDR_PULLUP(GPIOA_MCO) | \ PIN_PUPDR_PULLUP(9) | \ - PIN_PUPDR_PULLUP(GPIOA_USB_DISC) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_DISC) | \ PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \ PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \ PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \ From 608482a9706de2cb414f8edd76a20ab95b4dcb2b Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 8 Mar 2020 19:56:37 +0900 Subject: [PATCH 39/65] env: add debug conf for vscode --- .vscode/launch.json | 31 +++++++++++++++++++++++++++++++ .vscode/tasks.json | 12 ++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e9a90c4 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,31 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "OpenOCD-Debug", + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "executable": "build/ch.elf", + "configFiles": [ + "interface/stlink.cfg", + "target/stm32f0x.cfg" + ], + "cwd": "${workspaceRoot}", + "svdFile": "STM32F0x2.svd", + "device": "stm32f0x", + "preLaunchTask": "build", + }, + { + "name": "STLink-Debug", + "type": "cortex-debug", + "request": "launch", + "servertype": "stutil", + "executable": "build/ch.elf", + "cwd": "${workspaceRoot}", + "svdFile": "STM32F0x2.svd", + "device": "stm32f0x", + "preLaunchTask": "build", + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index dc6b6f8..d5aad65 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,19 +2,19 @@ "version": "2.0.0", "tasks": [ { - "label": "make", + "label": "build", "type": "shell", "command": "make", - "group": "build" + "group": { + "kind": "build", + "isDefault": true + } }, { "label": "flash", "type": "shell", "command": "make dfu flash", - "group": { - "kind": "build", - "isDefault": true - } + "group": "build" } ] } \ No newline at end of file From c40d78d80fcba820a9260cfe16b83349537f9a34 Mon Sep 17 00:00:00 2001 From: TT Date: Sun, 8 Mar 2020 20:03:54 +0900 Subject: [PATCH 40/65] env: clean Makefile --- Makefile | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index bd17844..bec51b8 100644 --- a/Makefile +++ b/Makefile @@ -118,12 +118,9 @@ CSRC = $(STARTUPSRC) \ $(PLATFORMSRC) \ $(BOARDSRC) \ $(STREAMSSRC) \ - $(SHELLSRC) \ usbcfg.c \ main.c si5351.c tlv320aic3204.c dsp.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c flash.c adc.c -# $(TESTSRC) \ - # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. CPPSRC = @@ -153,8 +150,7 @@ ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM) INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ $(HALINC) $(PLATFORMINC) $(BOARDINC) \ - $(STREAMSINC) $(SHELLINC) -# $(TESTINC) + $(STREAMSINC) # # Project, sources and paths @@ -176,7 +172,7 @@ CPPC = $(TRGT)g++ LD = $(TRGT)gcc #LD = $(TRGT)g++ CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp +AS = $(TRGT)gcc -x assembler-with-cpp -ggdb AR = $(TRGT)ar OD = $(TRGT)objdump SZ = $(TRGT)size @@ -231,7 +227,4 @@ flash: build/ch.bin dfu: -@printf "reset dfu\r" >/dev/cu.usbmodem401 -TAGS: Makefile - @etags *.[ch] NANOVNA_STM32_F072/*.[ch] $(shell find ChibiOS/os/hal/ports/STM32/STM32F0xx ChibiOS/os -name \*.\[ch\] -print) - @ls -l TAGS From 77b5d0bcc87ade5d4e76bf108880cfb82c10f841 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 8 Mar 2020 22:48:36 +0300 Subject: [PATCH 41/65] 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 c6c5a96..5bc5603 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 5d712a6..498aa88 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 92eeb8a..9b3511b 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 42/65] 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 6e9f607..2f5f97e 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 9b3511b..a43a313 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 43/65] 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 2f5f97e..6e9f607 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 44/65] 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 498aa88..9fa1c07 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 45/65] 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 9fa1c07..9996d91 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 46/65] Fix typo --- plot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plot.c b/plot.c index 9996d91..2475a87 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 47/65] 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 2475a87..8aaef85 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 48/65] 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 8aaef85..4e14ca7 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 49/65] 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 5bc5603..4ec00cc 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 d5d14cc..a618cb5 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 4e14ca7..0ee0c42 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 50/65] 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 a618cb5..4a2063c 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 0ee0c42..39d0e9b 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 a2267da..268ec51 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 51/65] 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 4a2063c..826a0f2 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 39d0e9b..8d3b1ca 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 52/65] Little cleanup --- plot.c | 11 +++++++---- ui.c | 1 - 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/plot.c b/plot.c index 8d3b1ca..0975bb4 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 268ec51..ab8ef6c 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 53/65] 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 a43a313..96c82a2 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 54/65] 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 5e5ce40..fd54b74 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 4ec00cc..f0cf527 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 ab8ef6c..e3c8515 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 55/65] 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 f0cf527..243f2ab 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 e3c8515..8d82c35 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 56/65] 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 3c7568b..a66fc9a 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 243f2ab..e903394 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 826a0f2..0fbab6d 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 0975bb4..1ebf2b2 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 96c82a2..7cd37da 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 57/65] 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 0c367b7..dbaa32f 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 e903394..3748579 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 0fbab6d..5fddc78 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 1ebf2b2..fd2f8cf 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 7cd37da..fefffb0 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 6b5bdf5..42a7d99 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 58/65] 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 2486210..53ede93 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 59/65] 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 3748579..1335bfc 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 60/65] 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 1335bfc..9939473 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 61/65] 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 5fddc78..281fa26 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 62/65] 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 9939473..6a92268 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 fd2f8cf..a510b5b 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 8d82c35..ae25126 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 63/65] 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 6a92268..069abb2 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 fefffb0..1d589b3 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 64/65] 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 069abb2..69245fd 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 1d589b3..aee7ba8 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; From 0d407577f8c42517bdf1572d6ce5a9120037af2d Mon Sep 17 00:00:00 2001 From: TT Date: Sat, 21 Mar 2020 08:03:09 +0900 Subject: [PATCH 65/65] style: uniform code style and untabify --- .clang-format | 156 ++ .vscode/settings.json | 3 +- Font5x7.c | 4884 ++++++++++++++++++++--------------------- chprintf.c | 103 +- flash.c | 9 +- ili9341.c | 216 +- main.c | 517 +++-- mcuconf.h | 2 +- nanovna.h | 54 +- numfont20x22.c | 1013 +++++---- plot.c | 386 ++-- si5351.c | 160 +- si5351.h | 82 +- tlv320aic3204.c | 2 +- ui.c | 159 +- 15 files changed, 4019 insertions(+), 3727 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..59ea9b2 --- /dev/null +++ b/.clang-format @@ -0,0 +1,156 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseTab: Never +... + diff --git a/.vscode/settings.json b/.vscode/settings.json index 691a8f6..ee6833d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "C_Cpp.errorSquiggles": "Disabled" + "C_Cpp.errorSquiggles": "Disabled", + "cpplint.filters": ["-build/include_subdir", "-build/include_order", "-readability/casting", "-whitespace/comments"] } \ No newline at end of file diff --git a/Font5x7.c b/Font5x7.c index 87b9127..26a0a87 100644 --- a/Font5x7.c +++ b/Font5x7.c @@ -1,2442 +1,2442 @@ -/* - * Font size 5x7 pixels - * most font glyph have width 5 pixels - */ - -#include - -/* - * Check 1 byte of char bitmap data for get width - */ - -#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) -#define FONT_GET_WIDTH(ch) (8-x5x7_bits[ch*7]&7) -#define FONT_MAX_WIDTH 7 -#define FONT_GET_HEIGHT 7 - -#define CHAR5x7_WIDTH_1px 0x07 -#define CHAR5x7_WIDTH_2px 0x06 -#define CHAR5x7_WIDTH_3px 0x05 -#define CHAR5x7_WIDTH_4px 0x04 -#define CHAR5x7_WIDTH_5px 0x03 -#define CHAR5x7_WIDTH_6px 0x02 -#define CHAR5x7_WIDTH_7px 0x01 -#define CHAR5x7_WIDTH_8px 0x00 - -/* Font character bitmap data. */ -const uint8_t x5x7_bits[127*7] = -{ - - /* Character (0x00): - width=5 - +--------+ - |**** | - |**** | - |**** | - |**** | - |**** | - |**** | - | | - +--------+ */ - 0b11110000|CHAR5x7_WIDTH_5px, - 0b11110000, - 0b11110000, - 0b11110000, - 0b11110000, - 0b11110000, - 0b00000000, - - /* Character (0x01): - width=5 - +--------+ - | | - | * | - | *** | - |***** | - | *** | - | * | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b01110000, - 0b11111000, - 0b01110000, - 0b00100000, - 0b00000000, - - /* Character (0x02): - width=5 - +--------+ - | * * | - |* * * | - | * * | - |* * * | - | * * | - |* * * | - | * * | - +--------+ */ - 0b01010000|CHAR5x7_WIDTH_5px, - 0b10101000, - 0b01010000, - 0b10101000, - 0b01010000, - 0b10101000, - 0b01010000, - - /* Character (0x03): - width=5 - +--------+ - |* * | - |*** | - |* * | - |* * | - | *** | - | * | - | * | - +--------+ */ - 0b10100000|CHAR5x7_WIDTH_5px, - 0b11100000, - 0b10100000, - 0b10100000, - 0b01110000, - 0b00100000, - 0b00100000, - - /* Character (0x04): - width=6 - +--------+ - | | - | * | - | * | - | * * | - | * * | - |* * | - |***** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b00100000, - 0b01010000, - 0b01010000, - 0b10001000, - 0b11111000, - - /* Character (0x05): - width=5 - +--------+ - |** | - |* | - |** | - | ** | - | * * | - | ** | - | * * | - +--------+ */ - 0b11000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b11000000, - 0b01100000, - 0b01010000, - 0b01100000, - 0b01010000, - - /* Character (0x06): - width=5 - +--------+ - |* | - |* | - |** | - | ** | - | * | - | ** | - | * | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b11000000, - 0b00110000, - 0b00100000, - 0b00110000, - 0b00100000, - - /* Character (0x07): - width=5 - +--------+ - | * | - | * * | - | * | - | | - | | - | | - | | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b01010000, - 0b00100000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x08): - width=5 - +--------+ - | | - | * | - | *** | - | * | - | | - | *** | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b01110000, - 0b00100000, - 0b00000000, - 0b01110000, - 0b00000000, - - /* Character (0x09): - width=5 - +--------+ - |* * | - |** * | - |* ** | - |* * | - | * | - | * | - | ** | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b11010000, - 0b10110000, - 0b10010000, - 0b00100000, - 0b00100000, - 0b00110000, - - /* Character (0x0a): - width=5 - +--------+ - |* * | - |* * | - |* * | - | * | - | *** | - | * | - | * | - +--------+ */ - 0b10100000|CHAR5x7_WIDTH_5px, - 0b10100000, - 0b10100000, - 0b01000000, - 0b01110000, - 0b00100000, - 0b00100000, - - /* Character (0x0b): - width=5 - +--------+ - | * | - | * | - | * | - |*** | - | | - | | - | | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b00100000, - 0b11100000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x0c): - width=5 - +--------+ - | | - | | - | | - |*** | - | * | - | * | - | * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b11100000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x0d): - width=5 - +--------+ - | | - | | - | | - | *** | - | * | - | * | - | * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b00111000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x0e): - width=5 - +--------+ - | * | - | * | - | * | - | *** | - | | - | | - | | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b00100000, - 0b00111000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x0f): - width=5 - +--------+ - | * | - | * | - | * | - |***** | - | * | - | * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b00100000, - 0b11111000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x10): - width=5 - +--------+ - | | - |***** | - | | - | | - | | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b11111000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x11): - width=5 - +--------+ - | | - | | - |***** | - | | - | | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b11111000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x12): - width=5 - +--------+ - | | - | | - | | - |***** | - | | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b11111000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x13): - width=5 - +--------+ - | | - | | - | | - | | - |***** | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b00000000, - 0b11111000, - 0b00000000, - 0b00000000, - - /* Character (0x14): - width=5 - +--------+ - | | - | | - | | - | | - | | - |***** | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b11111000, - 0b00000000, - - /* Character (0x15): - width=5 - +--------+ - | * | - | * | - | * | - | *** | - | * | - | * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b00100000, - 0b00111000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x16): - width=5 - +--------+ - | ** | - | *** | - | *** | - | *** | - | *** | - | *** | - | ** | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b00100000, - 0b11100000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x17): - width=6 - +--------+ - | | - |** | - |**** | - |****** | - |**** | - |** | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b11000000, - 0b11110000, - 0b00011100, - 0b11110000, - 0b11000000, - 0b00000000, - - /* Character (0x18): - width=5 - +--------+ - |* | - |** | - |*** | - |**** | - |*** | - |** | - |* | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_4px, - 0b11000000, - 0b11100000, - 0b11110000, - 0b11100000, - 0b11000000, - 0b10000000, - - /* Character (0x19): - width=7 - +--------+ - | | - | ** ** | - |* ** * | - |* * * | - |* ** * | - | ** ** | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_7px, - 0b01101100, - 0b10110010, - 0b10010010, - 0b10011010, - 0b01101100, - 0b00000000, - - /* Character (0x1a): - width=6 - +--------+ - | | - | * | - | * | - |***** | - | * | - | * | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b01000000, - 0b11111000, - 0b01000000, - 0b00100000, - 0b00000000, - - /* Character (0x1b): - width=6 - +--------+ - | | - | * | - | * | - |***** | - | * | - | * | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b00010000, - 0b11111000, - 0b00010000, - 0b00100000, - 0b00000000, - - /* Character (0x1c): - width=6 - +--------+ - | | - |***** | - | * * | - | * * | - | * * | - | * * | - |* ** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b11111000, - 0b01010000, - 0b01010000, - 0b01010000, - 0b01010000, - 0b10011000, - - /* Character (0x1d): - width=6 - +--------+ - | | - | | - |* * | - |* * | - |** ** | - |* * * | - |* | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00000000, - 0b10001000, - 0b10001000, - 0b11011000, - 0b10101000, - 0b10000000, - - /* Character (0x1e): - width=6 - +--------+ - | | - | *** | - |* * | - |* * | - |* * | - | * * | - |** ** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b01110000, - 0b10001000, - 0b10001000, - 0b10001000, - 0b01010000, - 0b11011000, - - /* Character (0x1f): - width=5 - +--------+ - | ** | - |* * | - |* * | - | ** | - | | - | | - | | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b01100000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x20): ' ' - width=3 - +--------+ - | | - | | - | | - | | - | | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_4px, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x21): '!' - width=3 - +--------+ - | * | - | * | - | * | - | * | - | * | - | | - | * | - +--------+ */ - 0b01000000|CHAR5x7_WIDTH_3px, - 0b01000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b00000000, - 0b01000000, - - /* Character (0x22): '"' - width=5 - +--------+ - | * * | - | * * | - | * * | - | | - | | - | | - | | - +--------+ */ - 0b01010000, - 0b01010000, - 0b01010000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x23): '#' - width=5 - +--------+ - | * * | - | * * | - |***** | - | * * | - |***** | - | * * | - | * * | - +--------+ */ - 0b01010000|CHAR5x7_WIDTH_6px, - 0b01010000, - 0b11111000, - 0b01010000, - 0b11111000, - 0b01010000, - 0b01010000, - - /* Character (0x24): '$' - width=5 - +--------+ - | * | - | **** | - |* * | - | *** | - | * * | - |**** | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_6px, - 0b01111000, - 0b10100000, - 0b01110000, - 0b00101000, - 0b11110000, - 0b00100000, - - /* Character (0x25): '%' - width=6 - +--------+ - |** | - |** * | - | * | - | * | - | * | - |* ** | - | ** | - +--------+ */ - 0b11000000|CHAR5x7_WIDTH_6px, - 0b11001000, - 0b00010000, - 0b00100000, - 0b01000000, - 0b10011000, - 0b00011000, - - /* Character (0x26): '&' - width=5 - +--------+ - | | - | * | - | * * | - | ** | - |* * * | - |* * | - | ** * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b01010000, - 0b01100000, - 0b10101000, - 0b10010000, - 0b01101000, - - /* Character (0x27): ''' - width=4 - +--------+ - | ** | - | * | - |* | - | | - | | - | | - | | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b10000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x28): '(' - width=4 - +--------+ - | * | - | * | - |* | - |* | - |* | - | * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b01000000, - 0b00100000, - - /* Character (0x29): ')' - width=5 - +--------+ - |* | - | * | - | * | - | * | - | * | - | * | - |* | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b01000000, - 0b10000000, - - /* Character (0x2a): '*' - width=6 - +--------+ - | | - | * | - |* * * | - | *** | - |* * * | - | * | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b10101000, - 0b01110000, - 0b10101000, - 0b00100000, - 0b00000000, - - /* Character (0x2b): '+' - width=6 - +--------+ - | | - | * | - | * | - |***** | - | * | - | * | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b00100000, - 0b11111000, - 0b00100000, - 0b00100000, - 0b00000000, - - /* Character (0x2c): ',' - width=4 - +--------+ - | | - | | - | | - | | - |** | - | * | - |* | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_3px, - 0b00000000, - 0b00000000, - 0b00000000, - 0b11000000, - 0b01000000, - 0b10000000, - - /* Character (0x2d): '-' - width=5 - +--------+ - | | - | | - | | - |**** | - | | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b11110000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x2e): '.' - width=3 - +--------+ - | | - | | - | | - | | - | | - |** | - |** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_3px, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b11000000, - 0b11000000, - - /* Character (0x2f): '/' - width=4 - +--------+ - | * | - | * | - | * | - | * | - | * | - |* | - |* | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_4px, - 0b00100000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b10000000, - 0b10000000, - - /* Character (0x30): '0' - width=5 - +--------+ - | ** | - |* * | - |* ** | - |** * | - |* * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10110000, - 0b11010000, - 0b10010000, - 0b10010000, - 0b01100000, - - /* Character (0x31): '1' - width=5 - +--------+ - | * | - | ** | - | * | - | * | - | * | - | * | - | *** | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b01100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b01110000, - - /* Character (0x32): '2' - width=5 - +--------+ - | ** | - |* * | - | * | - | * | - | * | - |* | - |**** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b00010000, - 0b00100000, - 0b01000000, - 0b10000000, - 0b11110000, - - /* Character (0x33): '3' - width=5 - +--------+ - | ** | - |* * | - | * | - | ** | - | * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b00010000, - 0b01100000, - 0b00010000, - 0b10010000, - 0b01100000, - - /* Character (0x34): '4' - width=5 - +--------+ - |* * | - |* * | - |* * | - |* * | - |**** | - | * | - | * | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b11110000, - 0b00010000, - 0b00010000, - - /* Character (0x35): '5' - width=5 - +--------+ - |**** | - |* | - |*** | - | * | - | * | - |* * | - | ** | - +--------+ */ - 0b11110000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b11100000, - 0b00010000, - 0b00010000, - 0b10010000, - 0b01100000, - - /* Character (0x36): '6' - width=5 - +--------+ - | ** | - |* * | - |* | - |*** | - |* * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10000000, - 0b11100000, - 0b10010000, - 0b10010000, - 0b01100000, - - /* Character (0x37): '7' - width=5 - +--------+ - |**** | - | * | - | * | - | * | - | * | - | * | - | * | - +--------+ */ - 0b11110000|CHAR5x7_WIDTH_5px, - 0b00010000, - 0b00100000, - 0b00100000, - 0b01000000, - 0b01000000, - 0b01000000, - - /* Character (0x38): '8' - width=5 - +--------+ - | ** | - |* * | - |* * | - | ** | - |* * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b01100000, - 0b10010000, - 0b10010000, - 0b01100000, - - /* Character (0x39): '9' - width=5 - +--------+ - | ** | - |* * | - |* * | - | *** | - | * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b01110000, - 0b00010000, - 0b10010000, - 0b01100000, - - /* Character (0x3a): ':' - width=3 - +--------+ - | | - |** | - |** | - | | - |** | - |** | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_4px, - 0b11000000, - 0b11000000, - 0b00000000, - 0b11000000, - 0b11000000, - 0b00000000, - - /* Character (0x3b): ';' - width=4 - +--------+ - | | - | ** | - | ** | - | | - | ** | - | * | - |* | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_4px, - 0b01100000, - 0b01100000, - 0b00000000, - 0b01100000, - 0b01000000, - 0b10000000, - - /* Character (0x3c): '<' - width=5 - +--------+ - | | - | * | - | * | - |* | - | * | - | * | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00100000, - 0b01000000, - 0b10000000, - 0b01000000, - 0b00100000, - 0b00000000, - - /* Character (0x3d): '=' - width=5 - +--------+ - | | - | | - |**** | - | | - |**** | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b11110000, - 0b00000000, - 0b11110000, - 0b00000000, - 0b00000000, - - /* Character (0x3e): '>' - width=5 - +--------+ - | | - |* | - | * | - | * | - | * | - |* | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b01000000, - 0b00100000, - 0b01000000, - 0b10000000, - 0b00000000, - - /* Character (0x3f): '?' - width=5 - +--------+ - | ** | - |* * | - | * | - | * | - | * | - | | - | * | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b00010000, - 0b00100000, - 0b01000000, - 0b00000000, - 0b01000000, - - /* Character (0x40): '@' - width=5 - +--------+ - | ** | - |* * | - |* ** | - |* ** | - |* | - |* | - | *** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10110000, - 0b10110000, - 0b10000000, - 0b10000000, - 0b01110000, - - /* Character (0x41): 'A' - width=5 - +--------+ - | ** | - |* * | - |* * | - |* * | - |**** | - |* * | - |* * | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b11110000, - 0b10010000, - 0b10010000, - - /* Character (0x42): 'B' - width=5 - +--------+ - |*** | - |* * | - |* * | - |*** | - |* * | - |* * | - |*** | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b11100000, - 0b10010000, - 0b10010000, - 0b11100000, - - /* Character (0x43): 'C' - width=5 - +--------+ - | ** | - |* * | - |* | - |* | - |* | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b10010000, - 0b01100000, - - /* Character (0x44): 'D' - width=5 - +--------+ - |*** | - |* * | - |* * | - |* * | - |* * | - |* * | - |*** | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b11100000, - - /* Character (0x45): 'E' - width=5 - +--------+ - |**** | - |* | - |* | - |*** | - |* | - |* | - |**** | - +--------+ */ - 0b11110000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b10000000, - 0b11100000, - 0b10000000, - 0b10000000, - 0b11110000, - - /* Character (0x46): 'F' - width=5 - +--------+ - |**** | - |* | - |* | - |*** | - |* | - |* | - |* | - +--------+ */ - 0b11110000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b10000000, - 0b11100000, - 0b10000000, - 0b10000000, - 0b10000000, - - /* Character (0x47): 'G' - width=5 - +--------+ - | ** | - |* * | - |* | - |* ** | - |* * | - |* * | - | *** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10000000, - 0b10110000, - 0b10010000, - 0b10010000, - 0b01110000, - - /* Character (0x48): 'H' - width=5 - +--------+ - |* * | - |* * | - |* * | - |**** | - |* * | - |* * | - |* * | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b11110000, - 0b10010000, - 0b10010000, - 0b10010000, - - /* Character (0x49): 'I' - width=4 - +--------+ - |*** | - | * | - | * | - | * | - | * | - | * | - |*** | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b11100000, - - /* Character (0x4a): 'J' - width=5 - +--------+ - | *** | - | * | - | * | - | * | - | * | - |* * | - | ** | - +--------+ */ - 0b01110000|CHAR5x7_WIDTH_5px, - 0b00010000, - 0b00010000, - 0b00010000, - 0b00010000, - 0b10010000, - 0b01100000, - - /* Character (0x4b): 'K' - width=5 - +--------+ - |* * | - |* * | - |* * | - |** | - |* * | - |* * | - |* * | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b11100000, - 0b10010000, - 0b10010000, - 0b10010000, - - /* Character (0x4c): 'L' - width=5 - +--------+ - |* | - |* | - |* | - |* | - |* | - |* | - |**** | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b11110000, - - /* Character (0x4d): 'M' - width=6 - +--------+ - |* * | - |** ** | - |* * * | - |* * * | - |* * | - |* * | - |* * | - +--------+ */ - 0b10001000|CHAR5x7_WIDTH_6px, - 0b11011000, - 0b10101000, - 0b10101000, - 0b10001000, - 0b10001000, - 0b10001000, - - /* Character (0x4e): 'N' - width=5 - +--------+ - |* * | - |* * | - |** * | - |* ** | - |* * | - |* * | - |* * | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b11010000, - 0b10110000, - 0b10010000, - 0b10010000, - 0b10010000, - - /* Character (0x4f): 'O' - width=5 - +--------+ - | ** | - |* * | - |* * | - |* * | - |* * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b01100000, - - /* Character (0x50): 'P' - width=5 - +--------+ - |*** | - |* * | - |* * | - |*** | - |* | - |* | - |* | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b11100000, - 0b10000000, - 0b10000000, - 0b10000000, - - /* Character (0x51): 'Q' - width=5 - +--------+ - | ** | - |* * | - |* * | - |* * | - |* * | - |* * | - | * * | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10100000, - 0b01010000, - - /* Character (0x52): 'R' - width=5 - +--------+ - |*** | - |* * | - |* * | - |*** | - |* * | - |* * | - |* * | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b11100000, - 0b10010000, - 0b10010000, - 0b10010000, - - /* Character (0x53): 'S' - width=5 - +--------+ - | ** | - |* * | - |* | - | ** | - | * | - |* * | - | ** | - +--------+ */ - 0b01100000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10000000, - 0b01100000, - 0b00010000, - 0b10010000, - 0b01100000, - - /* Character (0x54): 'T' - width=6 - +--------+ - |***** | - | * | - | * | - | * | - | * | - | * | - | * | - +--------+ */ - 0b11111000|CHAR5x7_WIDTH_6px, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x55): 'U' - width=5 - +--------+ - |* * | - |* * | - |* * | - |* * | - |* * | - |* * | - | *** | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b01110000, - - /* Character (0x56): 'V' - width=5 - +--------+ - |* * | - |* * | - |* * | - |* * | - |* * | - | ** | - | ** | - +--------+ */ - 0b10010000|CHAR5x7_WIDTH_5px, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b01100000, - 0b01100000, - - /* Character (0x57): 'W' - width=6 - +--------+ - |* * | - |* * | - |* * | - |* * * | - |* * * | - |* * * | - | * * | - +--------+ */ - 0b10001000|CHAR5x7_WIDTH_6px, - 0b10001000, - 0b10001000, - 0b10101000, - 0b10101000, - 0b10101000, - 0b01010000, - - /* Character (0x58): 'X' - width=6 - +--------+ - |* * | - |* * | - | * * | - | * | - | * * | - |* * | - |* * | - +--------+ */ - 0b10001000|CHAR5x7_WIDTH_6px, - 0b10001000, - 0b01010000, - 0b00100000, - 0b01010000, - 0b10001000, - 0b10001000, - - /* Character (0x59): 'Y' - width=6 - +--------+ - |* * | - |* * | - |* * | - | * * | - | * | - | * | - | * | - +--------+ */ - 0b10001000|CHAR5x7_WIDTH_6px, - 0b10001000, - 0b10001000, - 0b01010000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x5a): 'Z' - width=5 - +--------+ - |**** | - | * | - | * | - | * | - |* | - |* | - |**** | - +--------+ */ - 0b11110000|CHAR5x7_WIDTH_5px, - 0b00010000, - 0b00100000, - 0b01000000, - 0b10000000, - 0b10000000, - 0b11110000, - - /* Character (0x5b): '[' - width=4 - +--------+ - |*** | - |* | - |* | - |* | - |* | - |* | - |*** | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_4px, - 0b10000000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b11100000, - - /* Character (0x5c): '\' - width=4 - +--------+ - |* | - |* | - | * | - | * | - | * | - | * | - | * | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_4px, - 0b10000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b00100000, - 0b00100000, - - /* Character (0x5d): ']' - width=4 - +--------+ - |*** | - | * | - | * | - | * | - | * | - | * | - |*** | - +--------+ */ - 0b11100000|CHAR5x7_WIDTH_4px, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b11100000, - - /* Character (0x5e): '^' - width=4 - +--------+ - | * | - |* * | - | | - | | - | | - | | - | | - +--------+ */ - 0b01000000|CHAR5x7_WIDTH_4px, - 0b10100000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x5f): '_' - width=5 - +--------+ - | | - | | - | | - | | - | | - | | - |***** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b11111000, - - /* Character (0x60): '`' - width=4 - +--------+ - |** | - | * | - | * | - | | - | | - | | - | | - +--------+ */ - 0b11000000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b00100000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - - /* Character (0x61): 'a' - width=5 - +--------+ - | | - | | - | *** | - |* * | - |* * | - |* ** | - | * * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01110000, - 0b10010000, - 0b10010000, - 0b10110000, - 0b01010000, - - /* Character (0x62): 'b' - width=5 - +--------+ - |* | - |* | - |* * | - |** * | - |* * | - |* * | - |*** | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b10100000, - 0b11010000, - 0b10010000, - 0b10010000, - 0b11100000, - - /* Character (0x63): 'c' - width=5 - +--------+ - | | - | | - | *** | - |* | - |* | - |* | - | *** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01110000, - 0b10000000, - 0b10000000, - 0b10000000, - 0b01110000, - - /* Character (0x64): 'd' - width=5 - +--------+ - | * | - | * | - | * * | - |* ** | - |* * | - |* * | - | *** | - +--------+ */ - 0b00010000|CHAR5x7_WIDTH_5px, - 0b00010000, - 0b01010000, - 0b10110000, - 0b10010000, - 0b10010000, - 0b01110000, - - /* Character (0x65): 'e' - width=5 - +--------+ - | | - | | - | ** | - |* * | - |**** | - |* | - | *** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01100000, - 0b10010000, - 0b11110000, - 0b10000000, - 0b01110000, - - /* Character (0x66): 'f' - width=5 - +--------+ - | * | - | * * | - | * | - |*** | - | * | - | * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_5px, - 0b01010000, - 0b01000000, - 0b11100000, - 0b01000000, - 0b01000000, - 0b01000000, - - /* Character (0x67): 'g' - width=5 - +--------+ - | | - | | - | *** | - |* * | - | *** | - | * | - | ** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01110000, - 0b10010000, - 0b01110000, - 0b00010000, - 0b01100000, - - /* Character (0x68): 'h' - width=5 - +--------+ - |* | - |* | - |* * | - |** * | - |* * | - |* * | - |* * | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b10100000, - 0b11010000, - 0b10010000, - 0b10010000, - 0b10010000, - - /* Character (0x69): 'i' - width=4 - +--------+ - | * | - | | - |** | - | * | - | * | - | * | - |*** | - +--------+ */ - 0b01000000|CHAR5x7_WIDTH_4px, - 0b00000000, - 0b11000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b11100000, - - /* Character (0x6a): - width=4 - +--------+ - | * | - | | - | * | - | * | - | * | - |* * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_4px, - 0b00000000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b10100000, - 0b01000000, - - /* Character (0x6b): 'k' - width=5 - +--------+ - |* | - |* | - |* * | - |* * | - |** | - |* * | - |* * | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_5px, - 0b10000000, - 0b10010000, - 0b10100000, - 0b11000000, - 0b10100000, - 0b10010000, - - /* Character (0x6c): 'l' - width=4 - +--------+ - |** | - | * | - | * | - | * | - | * | - | * | - |*** | - +--------+ */ - 0b11000000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b11100000, - - /* Character (0x6d): 'm' - width=6 - +--------+ - | | - | | - |**** | - |* * * | - |* * * | - |* * * | - |* * * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00000000, - 0b11110000, - 0b10101000, - 0b10101000, - 0b10101000, - 0b10101000, - - /* Character (0x6e): 'n' - width=5 - +--------+ - | | - | | - |* * | - |** * | - |* * | - |* * | - |* * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b10100000, - 0b11010000, - 0b10010000, - 0b10010000, - 0b10010000, - - /* Character (0x6f): 'o' - width=5 - +--------+ - | | - | | - | ** | - |* * | - |* * | - |* * | - | ** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01100000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b01100000, - - /* Character (0x70): 'p' - width=5 - +--------+ - | | - | | - |*** | - |* * | - |* * | - |*** | - |* | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b11100000, - 0b10010000, - 0b10010000, - 0b11100000, - 0b10000000, - - /* Character (0x71): 'q' - width=5 - +--------+ - | | - | | - | *** | - |* * | - |* * | - | *** | - | * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01110000, - 0b10010000, - 0b10010000, - 0b01110000, - 0b00010000, - - /* Character (0x72): 'r' - width=5 - +--------+ - | | - | | - |* * | - |** * | - |* | - |* | - |* | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b10100000, - 0b11010000, - 0b10000000, - 0b10000000, - 0b10000000, - - /* Character (0x73): 's' - width=5 - +--------+ - | | - | | - | *** | - |* | - | ** | - | * | - |*** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01110000, - 0b10000000, - 0b01100000, - 0b00010000, - 0b11100000, - - /* Character (0x74): 't' - width=5 - +--------+ - | * | - | * | - |*** | - | * | - | * | - | * | - | ** | - +--------+ */ - 0b01000000|CHAR5x7_WIDTH_5px, - 0b01000000, - 0b11100000, - 0b01000000, - 0b01000000, - 0b01000000, - 0b00110000, - - /* Character (0x75): 'u' - width=5 - +--------+ - | | - | | - |* * | - |* * | - |* * | - |* ** | - | * * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b10110000, - 0b01010000, - - /* Character (0x76): 'v' - width=5 - +--------+ - | | - | | - |* * | - |* * | - |* * | - | ** | - | ** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b10010000, - 0b10010000, - 0b10010000, - 0b01100000, - 0b01100000, - - /* Character (0x77): 'w' - width=6 - +--------+ - | | - | | - |* * | - |* * | - |* * * | - |* * * | - | * * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_6px, - 0b00000000, - 0b10001000, - 0b10001000, - 0b10101000, - 0b10101000, - 0b01010000, - - /* Character (0x78): 'x' - width=5 - +--------+ - | | - | | - |* * | - |* * | - | ** | - |* * | - |* * | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b10010000, - 0b10010000, - 0b01100000, - 0b10010000, - 0b10010000, - - /* Character (0x79): 'y' - width=5 - +--------+ - | | - | | - |* * | - |* * | - | *** | - | * | - |*** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b10010000, - 0b10010000, - 0b01110000, - 0b00010000, - 0b11100000, - - /* Character (0x7a): 'z' - width=5 - +--------+ - | | - | | - |**** | - | * | - | * | - |* | - |**** | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b11110000, - 0b00100000, - 0b01000000, - 0b10000000, - 0b11110000, - - /* Character (0x7b): '{' - width=5 - +--------+ - | * | - | * | - | * | - |* | - | * | - | * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b01000000, - 0b10000000, - 0b01000000, - 0b01000000, - 0b00100000, - - /* Character (0x7c): '|' - width=5 - +--------+ - | * | - | * | - | * | - | * | - | * | - | * | - | * | - +--------+ */ - 0b00100000|CHAR5x7_WIDTH_4px, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - 0b00100000, - - /* Character (0x7d): '}' - width=5 - +--------+ - |* | - | * | - | * | - | * | - | * | - | * | - |* | - +--------+ */ - 0b10000000|CHAR5x7_WIDTH_4px, - 0b01000000, - 0b01000000, - 0b00100000, - 0b01000000, - 0b01000000, - 0b10000000, - - /* Character (0x7e): '~' - width=5 - +--------+ - | | - | | - | * * | - |* * | - | | - | | - | | - +--------+ */ - 0b00000000|CHAR5x7_WIDTH_5px, - 0b00000000, - 0b01010000, - 0b10100000, - 0b00000000, - 0b00000000, - 0b00000000, -}; +/* + * Font size 5x7 pixels + * most font glyph have width 5 pixels + */ + +#include + +/* + * Check 1 byte of char bitmap data for get width + */ + +#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) +#define FONT_GET_WIDTH(ch) (8-x5x7_bits[ch*7]&7) +#define FONT_MAX_WIDTH 7 +#define FONT_GET_HEIGHT 7 + +#define CHAR5x7_WIDTH_1px 0x07 +#define CHAR5x7_WIDTH_2px 0x06 +#define CHAR5x7_WIDTH_3px 0x05 +#define CHAR5x7_WIDTH_4px 0x04 +#define CHAR5x7_WIDTH_5px 0x03 +#define CHAR5x7_WIDTH_6px 0x02 +#define CHAR5x7_WIDTH_7px 0x01 +#define CHAR5x7_WIDTH_8px 0x00 + +/* Font character bitmap data. */ +const uint8_t x5x7_bits[127*7] = +{ + + /* Character (0x00): + width=5 + +--------+ + |**** | + |**** | + |**** | + |**** | + |**** | + |**** | + | | + +--------+ */ + 0b11110000|CHAR5x7_WIDTH_5px, + 0b11110000, + 0b11110000, + 0b11110000, + 0b11110000, + 0b11110000, + 0b00000000, + + /* Character (0x01): + width=5 + +--------+ + | | + | * | + | *** | + |***** | + | *** | + | * | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b01110000, + 0b11111000, + 0b01110000, + 0b00100000, + 0b00000000, + + /* Character (0x02): + width=5 + +--------+ + | * * | + |* * * | + | * * | + |* * * | + | * * | + |* * * | + | * * | + +--------+ */ + 0b01010000|CHAR5x7_WIDTH_5px, + 0b10101000, + 0b01010000, + 0b10101000, + 0b01010000, + 0b10101000, + 0b01010000, + + /* Character (0x03): + width=5 + +--------+ + |* * | + |*** | + |* * | + |* * | + | *** | + | * | + | * | + +--------+ */ + 0b10100000|CHAR5x7_WIDTH_5px, + 0b11100000, + 0b10100000, + 0b10100000, + 0b01110000, + 0b00100000, + 0b00100000, + + /* Character (0x04): + width=6 + +--------+ + | | + | * | + | * | + | * * | + | * * | + |* * | + |***** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b00100000, + 0b01010000, + 0b01010000, + 0b10001000, + 0b11111000, + + /* Character (0x05): + width=5 + +--------+ + |** | + |* | + |** | + | ** | + | * * | + | ** | + | * * | + +--------+ */ + 0b11000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b11000000, + 0b01100000, + 0b01010000, + 0b01100000, + 0b01010000, + + /* Character (0x06): + width=5 + +--------+ + |* | + |* | + |** | + | ** | + | * | + | ** | + | * | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b11000000, + 0b00110000, + 0b00100000, + 0b00110000, + 0b00100000, + + /* Character (0x07): + width=5 + +--------+ + | * | + | * * | + | * | + | | + | | + | | + | | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b01010000, + 0b00100000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x08): + width=5 + +--------+ + | | + | * | + | *** | + | * | + | | + | *** | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b01110000, + 0b00100000, + 0b00000000, + 0b01110000, + 0b00000000, + + /* Character (0x09): + width=5 + +--------+ + |* * | + |** * | + |* ** | + |* * | + | * | + | * | + | ** | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b11010000, + 0b10110000, + 0b10010000, + 0b00100000, + 0b00100000, + 0b00110000, + + /* Character (0x0a): + width=5 + +--------+ + |* * | + |* * | + |* * | + | * | + | *** | + | * | + | * | + +--------+ */ + 0b10100000|CHAR5x7_WIDTH_5px, + 0b10100000, + 0b10100000, + 0b01000000, + 0b01110000, + 0b00100000, + 0b00100000, + + /* Character (0x0b): + width=5 + +--------+ + | * | + | * | + | * | + |*** | + | | + | | + | | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b00100000, + 0b11100000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x0c): + width=5 + +--------+ + | | + | | + | | + |*** | + | * | + | * | + | * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b11100000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x0d): + width=5 + +--------+ + | | + | | + | | + | *** | + | * | + | * | + | * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b00111000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x0e): + width=5 + +--------+ + | * | + | * | + | * | + | *** | + | | + | | + | | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b00100000, + 0b00111000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x0f): + width=5 + +--------+ + | * | + | * | + | * | + |***** | + | * | + | * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b00100000, + 0b11111000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x10): + width=5 + +--------+ + | | + |***** | + | | + | | + | | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b11111000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x11): + width=5 + +--------+ + | | + | | + |***** | + | | + | | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b11111000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x12): + width=5 + +--------+ + | | + | | + | | + |***** | + | | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b11111000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x13): + width=5 + +--------+ + | | + | | + | | + | | + |***** | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b00000000, + 0b11111000, + 0b00000000, + 0b00000000, + + /* Character (0x14): + width=5 + +--------+ + | | + | | + | | + | | + | | + |***** | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b11111000, + 0b00000000, + + /* Character (0x15): + width=5 + +--------+ + | * | + | * | + | * | + | *** | + | * | + | * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b00100000, + 0b00111000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x16): + width=5 + +--------+ + | ** | + | *** | + | *** | + | *** | + | *** | + | *** | + | ** | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b00100000, + 0b11100000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x17): + width=6 + +--------+ + | | + |** | + |**** | + |****** | + |**** | + |** | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b11000000, + 0b11110000, + 0b00011100, + 0b11110000, + 0b11000000, + 0b00000000, + + /* Character (0x18): + width=5 + +--------+ + |* | + |** | + |*** | + |**** | + |*** | + |** | + |* | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_4px, + 0b11000000, + 0b11100000, + 0b11110000, + 0b11100000, + 0b11000000, + 0b10000000, + + /* Character (0x19): + width=7 + +--------+ + | | + | ** ** | + |* ** * | + |* * * | + |* ** * | + | ** ** | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_7px, + 0b01101100, + 0b10110010, + 0b10010010, + 0b10011010, + 0b01101100, + 0b00000000, + + /* Character (0x1a): + width=6 + +--------+ + | | + | * | + | * | + |***** | + | * | + | * | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b01000000, + 0b11111000, + 0b01000000, + 0b00100000, + 0b00000000, + + /* Character (0x1b): + width=6 + +--------+ + | | + | * | + | * | + |***** | + | * | + | * | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b00010000, + 0b11111000, + 0b00010000, + 0b00100000, + 0b00000000, + + /* Character (0x1c): + width=6 + +--------+ + | | + |***** | + | * * | + | * * | + | * * | + | * * | + |* ** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b11111000, + 0b01010000, + 0b01010000, + 0b01010000, + 0b01010000, + 0b10011000, + + /* Character (0x1d): + width=6 + +--------+ + | | + | | + |* * | + |* * | + |** ** | + |* * * | + |* | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00000000, + 0b10001000, + 0b10001000, + 0b11011000, + 0b10101000, + 0b10000000, + + /* Character (0x1e): + width=6 + +--------+ + | | + | *** | + |* * | + |* * | + |* * | + | * * | + |** ** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b01110000, + 0b10001000, + 0b10001000, + 0b10001000, + 0b01010000, + 0b11011000, + + /* Character (0x1f): + width=5 + +--------+ + | ** | + |* * | + |* * | + | ** | + | | + | | + | | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b01100000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x20): ' ' + width=3 + +--------+ + | | + | | + | | + | | + | | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_4px, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x21): '!' + width=3 + +--------+ + | * | + | * | + | * | + | * | + | * | + | | + | * | + +--------+ */ + 0b01000000|CHAR5x7_WIDTH_3px, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b00000000, + 0b01000000, + + /* Character (0x22): '"' + width=5 + +--------+ + | * * | + | * * | + | * * | + | | + | | + | | + | | + +--------+ */ + 0b01010000, + 0b01010000, + 0b01010000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x23): '#' + width=5 + +--------+ + | * * | + | * * | + |***** | + | * * | + |***** | + | * * | + | * * | + +--------+ */ + 0b01010000|CHAR5x7_WIDTH_6px, + 0b01010000, + 0b11111000, + 0b01010000, + 0b11111000, + 0b01010000, + 0b01010000, + + /* Character (0x24): '$' + width=5 + +--------+ + | * | + | **** | + |* * | + | *** | + | * * | + |**** | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_6px, + 0b01111000, + 0b10100000, + 0b01110000, + 0b00101000, + 0b11110000, + 0b00100000, + + /* Character (0x25): '%' + width=6 + +--------+ + |** | + |** * | + | * | + | * | + | * | + |* ** | + | ** | + +--------+ */ + 0b11000000|CHAR5x7_WIDTH_6px, + 0b11001000, + 0b00010000, + 0b00100000, + 0b01000000, + 0b10011000, + 0b00011000, + + /* Character (0x26): '&' + width=5 + +--------+ + | | + | * | + | * * | + | ** | + |* * * | + |* * | + | ** * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b01010000, + 0b01100000, + 0b10101000, + 0b10010000, + 0b01101000, + + /* Character (0x27): ''' + width=4 + +--------+ + | ** | + | * | + |* | + | | + | | + | | + | | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b10000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x28): '(' + width=4 + +--------+ + | * | + | * | + |* | + |* | + |* | + | * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b01000000, + 0b00100000, + + /* Character (0x29): ')' + width=5 + +--------+ + |* | + | * | + | * | + | * | + | * | + | * | + |* | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b01000000, + 0b10000000, + + /* Character (0x2a): '*' + width=6 + +--------+ + | | + | * | + |* * * | + | *** | + |* * * | + | * | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b10101000, + 0b01110000, + 0b10101000, + 0b00100000, + 0b00000000, + + /* Character (0x2b): '+' + width=6 + +--------+ + | | + | * | + | * | + |***** | + | * | + | * | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b00100000, + 0b11111000, + 0b00100000, + 0b00100000, + 0b00000000, + + /* Character (0x2c): ',' + width=4 + +--------+ + | | + | | + | | + | | + |** | + | * | + |* | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_3px, + 0b00000000, + 0b00000000, + 0b00000000, + 0b11000000, + 0b01000000, + 0b10000000, + + /* Character (0x2d): '-' + width=5 + +--------+ + | | + | | + | | + |**** | + | | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b11110000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x2e): '.' + width=3 + +--------+ + | | + | | + | | + | | + | | + |** | + |** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_3px, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b11000000, + 0b11000000, + + /* Character (0x2f): '/' + width=4 + +--------+ + | * | + | * | + | * | + | * | + | * | + |* | + |* | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_4px, + 0b00100000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b10000000, + 0b10000000, + + /* Character (0x30): '0' + width=5 + +--------+ + | ** | + |* * | + |* ** | + |** * | + |* * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10110000, + 0b11010000, + 0b10010000, + 0b10010000, + 0b01100000, + + /* Character (0x31): '1' + width=5 + +--------+ + | * | + | ** | + | * | + | * | + | * | + | * | + | *** | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b01100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b01110000, + + /* Character (0x32): '2' + width=5 + +--------+ + | ** | + |* * | + | * | + | * | + | * | + |* | + |**** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b00010000, + 0b00100000, + 0b01000000, + 0b10000000, + 0b11110000, + + /* Character (0x33): '3' + width=5 + +--------+ + | ** | + |* * | + | * | + | ** | + | * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b00010000, + 0b01100000, + 0b00010000, + 0b10010000, + 0b01100000, + + /* Character (0x34): '4' + width=5 + +--------+ + |* * | + |* * | + |* * | + |* * | + |**** | + | * | + | * | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b11110000, + 0b00010000, + 0b00010000, + + /* Character (0x35): '5' + width=5 + +--------+ + |**** | + |* | + |*** | + | * | + | * | + |* * | + | ** | + +--------+ */ + 0b11110000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b11100000, + 0b00010000, + 0b00010000, + 0b10010000, + 0b01100000, + + /* Character (0x36): '6' + width=5 + +--------+ + | ** | + |* * | + |* | + |*** | + |* * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10000000, + 0b11100000, + 0b10010000, + 0b10010000, + 0b01100000, + + /* Character (0x37): '7' + width=5 + +--------+ + |**** | + | * | + | * | + | * | + | * | + | * | + | * | + +--------+ */ + 0b11110000|CHAR5x7_WIDTH_5px, + 0b00010000, + 0b00100000, + 0b00100000, + 0b01000000, + 0b01000000, + 0b01000000, + + /* Character (0x38): '8' + width=5 + +--------+ + | ** | + |* * | + |* * | + | ** | + |* * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b01100000, + 0b10010000, + 0b10010000, + 0b01100000, + + /* Character (0x39): '9' + width=5 + +--------+ + | ** | + |* * | + |* * | + | *** | + | * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b01110000, + 0b00010000, + 0b10010000, + 0b01100000, + + /* Character (0x3a): ':' + width=3 + +--------+ + | | + |** | + |** | + | | + |** | + |** | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_4px, + 0b11000000, + 0b11000000, + 0b00000000, + 0b11000000, + 0b11000000, + 0b00000000, + + /* Character (0x3b): ';' + width=4 + +--------+ + | | + | ** | + | ** | + | | + | ** | + | * | + |* | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_4px, + 0b01100000, + 0b01100000, + 0b00000000, + 0b01100000, + 0b01000000, + 0b10000000, + + /* Character (0x3c): '<' + width=5 + +--------+ + | | + | * | + | * | + |* | + | * | + | * | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00100000, + 0b01000000, + 0b10000000, + 0b01000000, + 0b00100000, + 0b00000000, + + /* Character (0x3d): '=' + width=5 + +--------+ + | | + | | + |**** | + | | + |**** | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b11110000, + 0b00000000, + 0b11110000, + 0b00000000, + 0b00000000, + + /* Character (0x3e): '>' + width=5 + +--------+ + | | + |* | + | * | + | * | + | * | + |* | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b01000000, + 0b00100000, + 0b01000000, + 0b10000000, + 0b00000000, + + /* Character (0x3f): '?' + width=5 + +--------+ + | ** | + |* * | + | * | + | * | + | * | + | | + | * | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b00010000, + 0b00100000, + 0b01000000, + 0b00000000, + 0b01000000, + + /* Character (0x40): '@' + width=5 + +--------+ + | ** | + |* * | + |* ** | + |* ** | + |* | + |* | + | *** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10110000, + 0b10110000, + 0b10000000, + 0b10000000, + 0b01110000, + + /* Character (0x41): 'A' + width=5 + +--------+ + | ** | + |* * | + |* * | + |* * | + |**** | + |* * | + |* * | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b11110000, + 0b10010000, + 0b10010000, + + /* Character (0x42): 'B' + width=5 + +--------+ + |*** | + |* * | + |* * | + |*** | + |* * | + |* * | + |*** | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b11100000, + 0b10010000, + 0b10010000, + 0b11100000, + + /* Character (0x43): 'C' + width=5 + +--------+ + | ** | + |* * | + |* | + |* | + |* | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10010000, + 0b01100000, + + /* Character (0x44): 'D' + width=5 + +--------+ + |*** | + |* * | + |* * | + |* * | + |* * | + |* * | + |*** | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b11100000, + + /* Character (0x45): 'E' + width=5 + +--------+ + |**** | + |* | + |* | + |*** | + |* | + |* | + |**** | + +--------+ */ + 0b11110000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b10000000, + 0b11100000, + 0b10000000, + 0b10000000, + 0b11110000, + + /* Character (0x46): 'F' + width=5 + +--------+ + |**** | + |* | + |* | + |*** | + |* | + |* | + |* | + +--------+ */ + 0b11110000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b10000000, + 0b11100000, + 0b10000000, + 0b10000000, + 0b10000000, + + /* Character (0x47): 'G' + width=5 + +--------+ + | ** | + |* * | + |* | + |* ** | + |* * | + |* * | + | *** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10000000, + 0b10110000, + 0b10010000, + 0b10010000, + 0b01110000, + + /* Character (0x48): 'H' + width=5 + +--------+ + |* * | + |* * | + |* * | + |**** | + |* * | + |* * | + |* * | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b11110000, + 0b10010000, + 0b10010000, + 0b10010000, + + /* Character (0x49): 'I' + width=4 + +--------+ + |*** | + | * | + | * | + | * | + | * | + | * | + |*** | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b11100000, + + /* Character (0x4a): 'J' + width=5 + +--------+ + | *** | + | * | + | * | + | * | + | * | + |* * | + | ** | + +--------+ */ + 0b01110000|CHAR5x7_WIDTH_5px, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b10010000, + 0b01100000, + + /* Character (0x4b): 'K' + width=5 + +--------+ + |* * | + |* * | + |* * | + |** | + |* * | + |* * | + |* * | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b11100000, + 0b10010000, + 0b10010000, + 0b10010000, + + /* Character (0x4c): 'L' + width=5 + +--------+ + |* | + |* | + |* | + |* | + |* | + |* | + |**** | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b11110000, + + /* Character (0x4d): 'M' + width=6 + +--------+ + |* * | + |** ** | + |* * * | + |* * * | + |* * | + |* * | + |* * | + +--------+ */ + 0b10001000|CHAR5x7_WIDTH_6px, + 0b11011000, + 0b10101000, + 0b10101000, + 0b10001000, + 0b10001000, + 0b10001000, + + /* Character (0x4e): 'N' + width=5 + +--------+ + |* * | + |* * | + |** * | + |* ** | + |* * | + |* * | + |* * | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b11010000, + 0b10110000, + 0b10010000, + 0b10010000, + 0b10010000, + + /* Character (0x4f): 'O' + width=5 + +--------+ + | ** | + |* * | + |* * | + |* * | + |* * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b01100000, + + /* Character (0x50): 'P' + width=5 + +--------+ + |*** | + |* * | + |* * | + |*** | + |* | + |* | + |* | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b11100000, + 0b10000000, + 0b10000000, + 0b10000000, + + /* Character (0x51): 'Q' + width=5 + +--------+ + | ** | + |* * | + |* * | + |* * | + |* * | + |* * | + | * * | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10100000, + 0b01010000, + + /* Character (0x52): 'R' + width=5 + +--------+ + |*** | + |* * | + |* * | + |*** | + |* * | + |* * | + |* * | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b11100000, + 0b10010000, + 0b10010000, + 0b10010000, + + /* Character (0x53): 'S' + width=5 + +--------+ + | ** | + |* * | + |* | + | ** | + | * | + |* * | + | ** | + +--------+ */ + 0b01100000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10000000, + 0b01100000, + 0b00010000, + 0b10010000, + 0b01100000, + + /* Character (0x54): 'T' + width=6 + +--------+ + |***** | + | * | + | * | + | * | + | * | + | * | + | * | + +--------+ */ + 0b11111000|CHAR5x7_WIDTH_6px, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x55): 'U' + width=5 + +--------+ + |* * | + |* * | + |* * | + |* * | + |* * | + |* * | + | *** | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b01110000, + + /* Character (0x56): 'V' + width=5 + +--------+ + |* * | + |* * | + |* * | + |* * | + |* * | + | ** | + | ** | + +--------+ */ + 0b10010000|CHAR5x7_WIDTH_5px, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b01100000, + 0b01100000, + + /* Character (0x57): 'W' + width=6 + +--------+ + |* * | + |* * | + |* * | + |* * * | + |* * * | + |* * * | + | * * | + +--------+ */ + 0b10001000|CHAR5x7_WIDTH_6px, + 0b10001000, + 0b10001000, + 0b10101000, + 0b10101000, + 0b10101000, + 0b01010000, + + /* Character (0x58): 'X' + width=6 + +--------+ + |* * | + |* * | + | * * | + | * | + | * * | + |* * | + |* * | + +--------+ */ + 0b10001000|CHAR5x7_WIDTH_6px, + 0b10001000, + 0b01010000, + 0b00100000, + 0b01010000, + 0b10001000, + 0b10001000, + + /* Character (0x59): 'Y' + width=6 + +--------+ + |* * | + |* * | + |* * | + | * * | + | * | + | * | + | * | + +--------+ */ + 0b10001000|CHAR5x7_WIDTH_6px, + 0b10001000, + 0b10001000, + 0b01010000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x5a): 'Z' + width=5 + +--------+ + |**** | + | * | + | * | + | * | + |* | + |* | + |**** | + +--------+ */ + 0b11110000|CHAR5x7_WIDTH_5px, + 0b00010000, + 0b00100000, + 0b01000000, + 0b10000000, + 0b10000000, + 0b11110000, + + /* Character (0x5b): '[' + width=4 + +--------+ + |*** | + |* | + |* | + |* | + |* | + |* | + |*** | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_4px, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b11100000, + + /* Character (0x5c): '\' + width=4 + +--------+ + |* | + |* | + | * | + | * | + | * | + | * | + | * | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_4px, + 0b10000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b00100000, + 0b00100000, + + /* Character (0x5d): ']' + width=4 + +--------+ + |*** | + | * | + | * | + | * | + | * | + | * | + |*** | + +--------+ */ + 0b11100000|CHAR5x7_WIDTH_4px, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b11100000, + + /* Character (0x5e): '^' + width=4 + +--------+ + | * | + |* * | + | | + | | + | | + | | + | | + +--------+ */ + 0b01000000|CHAR5x7_WIDTH_4px, + 0b10100000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x5f): '_' + width=5 + +--------+ + | | + | | + | | + | | + | | + | | + |***** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b11111000, + + /* Character (0x60): '`' + width=4 + +--------+ + |** | + | * | + | * | + | | + | | + | | + | | + +--------+ */ + 0b11000000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b00100000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + + /* Character (0x61): 'a' + width=5 + +--------+ + | | + | | + | *** | + |* * | + |* * | + |* ** | + | * * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01110000, + 0b10010000, + 0b10010000, + 0b10110000, + 0b01010000, + + /* Character (0x62): 'b' + width=5 + +--------+ + |* | + |* | + |* * | + |** * | + |* * | + |* * | + |*** | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b10100000, + 0b11010000, + 0b10010000, + 0b10010000, + 0b11100000, + + /* Character (0x63): 'c' + width=5 + +--------+ + | | + | | + | *** | + |* | + |* | + |* | + | *** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01110000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b01110000, + + /* Character (0x64): 'd' + width=5 + +--------+ + | * | + | * | + | * * | + |* ** | + |* * | + |* * | + | *** | + +--------+ */ + 0b00010000|CHAR5x7_WIDTH_5px, + 0b00010000, + 0b01010000, + 0b10110000, + 0b10010000, + 0b10010000, + 0b01110000, + + /* Character (0x65): 'e' + width=5 + +--------+ + | | + | | + | ** | + |* * | + |**** | + |* | + | *** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01100000, + 0b10010000, + 0b11110000, + 0b10000000, + 0b01110000, + + /* Character (0x66): 'f' + width=5 + +--------+ + | * | + | * * | + | * | + |*** | + | * | + | * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_5px, + 0b01010000, + 0b01000000, + 0b11100000, + 0b01000000, + 0b01000000, + 0b01000000, + + /* Character (0x67): 'g' + width=5 + +--------+ + | | + | | + | *** | + |* * | + | *** | + | * | + | ** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01110000, + 0b10010000, + 0b01110000, + 0b00010000, + 0b01100000, + + /* Character (0x68): 'h' + width=5 + +--------+ + |* | + |* | + |* * | + |** * | + |* * | + |* * | + |* * | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b10100000, + 0b11010000, + 0b10010000, + 0b10010000, + 0b10010000, + + /* Character (0x69): 'i' + width=4 + +--------+ + | * | + | | + |** | + | * | + | * | + | * | + |*** | + +--------+ */ + 0b01000000|CHAR5x7_WIDTH_4px, + 0b00000000, + 0b11000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b11100000, + + /* Character (0x6a): + width=4 + +--------+ + | * | + | | + | * | + | * | + | * | + |* * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_4px, + 0b00000000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b10100000, + 0b01000000, + + /* Character (0x6b): 'k' + width=5 + +--------+ + |* | + |* | + |* * | + |* * | + |** | + |* * | + |* * | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_5px, + 0b10000000, + 0b10010000, + 0b10100000, + 0b11000000, + 0b10100000, + 0b10010000, + + /* Character (0x6c): 'l' + width=4 + +--------+ + |** | + | * | + | * | + | * | + | * | + | * | + |*** | + +--------+ */ + 0b11000000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b11100000, + + /* Character (0x6d): 'm' + width=6 + +--------+ + | | + | | + |**** | + |* * * | + |* * * | + |* * * | + |* * * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00000000, + 0b11110000, + 0b10101000, + 0b10101000, + 0b10101000, + 0b10101000, + + /* Character (0x6e): 'n' + width=5 + +--------+ + | | + | | + |* * | + |** * | + |* * | + |* * | + |* * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b10100000, + 0b11010000, + 0b10010000, + 0b10010000, + 0b10010000, + + /* Character (0x6f): 'o' + width=5 + +--------+ + | | + | | + | ** | + |* * | + |* * | + |* * | + | ** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01100000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b01100000, + + /* Character (0x70): 'p' + width=5 + +--------+ + | | + | | + |*** | + |* * | + |* * | + |*** | + |* | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b11100000, + 0b10010000, + 0b10010000, + 0b11100000, + 0b10000000, + + /* Character (0x71): 'q' + width=5 + +--------+ + | | + | | + | *** | + |* * | + |* * | + | *** | + | * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01110000, + 0b10010000, + 0b10010000, + 0b01110000, + 0b00010000, + + /* Character (0x72): 'r' + width=5 + +--------+ + | | + | | + |* * | + |** * | + |* | + |* | + |* | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b10100000, + 0b11010000, + 0b10000000, + 0b10000000, + 0b10000000, + + /* Character (0x73): 's' + width=5 + +--------+ + | | + | | + | *** | + |* | + | ** | + | * | + |*** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01110000, + 0b10000000, + 0b01100000, + 0b00010000, + 0b11100000, + + /* Character (0x74): 't' + width=5 + +--------+ + | * | + | * | + |*** | + | * | + | * | + | * | + | ** | + +--------+ */ + 0b01000000|CHAR5x7_WIDTH_5px, + 0b01000000, + 0b11100000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b00110000, + + /* Character (0x75): 'u' + width=5 + +--------+ + | | + | | + |* * | + |* * | + |* * | + |* ** | + | * * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b10110000, + 0b01010000, + + /* Character (0x76): 'v' + width=5 + +--------+ + | | + | | + |* * | + |* * | + |* * | + | ** | + | ** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b10010000, + 0b10010000, + 0b10010000, + 0b01100000, + 0b01100000, + + /* Character (0x77): 'w' + width=6 + +--------+ + | | + | | + |* * | + |* * | + |* * * | + |* * * | + | * * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_6px, + 0b00000000, + 0b10001000, + 0b10001000, + 0b10101000, + 0b10101000, + 0b01010000, + + /* Character (0x78): 'x' + width=5 + +--------+ + | | + | | + |* * | + |* * | + | ** | + |* * | + |* * | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b10010000, + 0b10010000, + 0b01100000, + 0b10010000, + 0b10010000, + + /* Character (0x79): 'y' + width=5 + +--------+ + | | + | | + |* * | + |* * | + | *** | + | * | + |*** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b10010000, + 0b10010000, + 0b01110000, + 0b00010000, + 0b11100000, + + /* Character (0x7a): 'z' + width=5 + +--------+ + | | + | | + |**** | + | * | + | * | + |* | + |**** | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b11110000, + 0b00100000, + 0b01000000, + 0b10000000, + 0b11110000, + + /* Character (0x7b): '{' + width=5 + +--------+ + | * | + | * | + | * | + |* | + | * | + | * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b01000000, + 0b10000000, + 0b01000000, + 0b01000000, + 0b00100000, + + /* Character (0x7c): '|' + width=5 + +--------+ + | * | + | * | + | * | + | * | + | * | + | * | + | * | + +--------+ */ + 0b00100000|CHAR5x7_WIDTH_4px, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + 0b00100000, + + /* Character (0x7d): '}' + width=5 + +--------+ + |* | + | * | + | * | + | * | + | * | + | * | + |* | + +--------+ */ + 0b10000000|CHAR5x7_WIDTH_4px, + 0b01000000, + 0b01000000, + 0b00100000, + 0b01000000, + 0b01000000, + 0b10000000, + + /* Character (0x7e): '~' + width=5 + +--------+ + | | + | | + | * * | + |* * | + | | + | | + | | + +--------+ */ + 0b00000000|CHAR5x7_WIDTH_5px, + 0b00000000, + 0b01010000, + 0b10100000, + 0b00000000, + 0b00000000, + 0b00000000, +}; diff --git a/chprintf.c b/chprintf.c index 7906dc9..fbfd1cd 100644 --- a/chprintf.c +++ b/chprintf.c @@ -49,17 +49,17 @@ static const uint32_t pow10[FLOAT_PRECISION+1] = { }; // 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}; +static 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}; +static char smallPrefix[] = {'m', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0}; #pragma pack(pop) static char *long_to_string_with_divisor(char *p, uint32_t num, - uint32_t radix, - uint32_t precision) { + uint32_t radix, + uint32_t precision) { char *q = p + MAX_FILLER; char *b = q; // convert to string from end buffer to begin @@ -78,12 +78,14 @@ static char *long_to_string_with_divisor(char *p, // default prescision = 13 // g.mmm kkk hhh -#define MAX_FREQ_PRESCISION 13 -#define FREQ_PSET 1 -#define FREQ_NO_SPACE 2 -#define FREQ_PREFIX_SPACE 4 - -static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ +#define MAX_FREQ_PRESCISION 13 +#define FREQ_PSET 1 +#define FREQ_NO_SPACE 2 +#define FREQ_PREFIX_SPACE 4 + +static char * +ulong_freq(char *p, uint32_t freq, uint32_t precision) +{ uint8_t flag = FREQ_PSET; if (precision == 0) flag|=FREQ_PREFIX_SPACE; @@ -94,7 +96,7 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ // Prefix counter uint32_t s = 0; // Set format (every 3 digits add ' ' up to GHz) - uint32_t format=0b00100100100; + uint32_t format = 0b00100100100; do { #if 0 uint8_t c = freq % 10; @@ -104,21 +106,27 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ // c = freq % 10 // freq = freq / 10; uint32_t c = freq; - freq>>=1; - freq+=freq>>1; - freq+=freq>>4; - freq+=freq>>8; - freq+=freq>>16; // freq = 858993459*freq/1073741824 = freq * 0,799999999813735485076904296875 - freq>>=3; // freq/=8; freq = freq * 0,09999999997671693563461303710938 - c-= freq*10; // freq*10 = (freq*4+freq)*2 = ((freq<<2)+freq)<<1 - while (c>=10) {freq++;c-=10;} + freq >>= 1; + freq += freq >> 1; + freq += freq >> 4; + freq += freq >> 8; + freq += freq >> 16; // freq = 858993459*freq/1073741824 = freq * + // 0,799999999813735485076904296875 + freq >>= 3; // freq/=8; freq = freq * 0,09999999997671693563461303710938 + c -= freq * 10; // freq*10 = (freq*4+freq)*2 = ((freq<<2)+freq)<<1 + while (c >= 10) { + freq++; + c -= 10; + } #endif *--q = c + '0'; - if (freq==0) - break; + if (freq == 0) break; // Add spaces, calculate prefix - if (format&1) {*--q = ' '; s++;} - format>>=1; + if (format & 1) { + *--q = ' '; + s++; + } + format >>= 1; } while (1); s = bigPrefix[s]; @@ -126,26 +134,25 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ uint32_t i = (b - q); // Limit string size, max size is - precision if (precision && i > precision) { - i = precision; - flag|=FREQ_NO_SPACE; + i = precision; + flag |= FREQ_NO_SPACE; } // copy string // Replace first ' ' by '.', remove ' ' if size too big - do{ + do { char c = *q++; // replace first ' ' on '.' if (c == ' ') { - if (flag&FREQ_PSET){ + if (flag & FREQ_PSET) { c = '.'; - flag&=~FREQ_PSET; - } - else if (flag&FREQ_NO_SPACE) + flag &= ~FREQ_PSET; + } else if (flag & FREQ_NO_SPACE) c = *q++; } *p++ = c; - }while (--i); + } while (--i); // Put pref (amd space before it if need) - if (flag&FREQ_PREFIX_SPACE && s!=' ') + if (flag & FREQ_PREFIX_SPACE && s != ' ') *p++ = ' '; *p++ = s; return p; @@ -153,7 +160,7 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){ #if CHPRINTF_USE_FLOAT static char *ftoa(char *p, float num, uint32_t precision) { - // Check precision limit + // Check precision limit if (precision > FLOAT_PRECISION) precision = FLOAT_PRECISION; uint32_t multi = pow10[precision]; @@ -163,7 +170,7 @@ static char *ftoa(char *p, float num, uint32_t precision) { // Fix rounding error if get if (k>=multi){k-=multi;l++;} p = long_to_string_with_divisor(p, l, 10, 0); - if (precision){ + if (precision) { *p++ = '.'; p=long_to_string_with_divisor(p, k, 10, precision); #ifndef CHPRINTF_FORCE_TRAILING_ZEROS @@ -227,23 +234,23 @@ static char *ftoaS(char *p, float num, uint32_t precision) { * * @api */ -#define IS_LONG 1 -#define LEFT_ALIGN 2 -#define POSITIVE 4 -#define NEGATIVE 8 -#define PAD_ZERO 16 -#define PLUS_SPACE 32 -#define DEFAULT_PRESCISION 64 +#define IS_LONG 1 +#define LEFT_ALIGN 2 +#define POSITIVE 4 +#define NEGATIVE 8 +#define PAD_ZERO 16 +#define PLUS_SPACE 32 +#define DEFAULT_PRESCISION 64 int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { char *p, *s, c, filler=' '; int precision, width; int n = 0; - uint32_t state; + uint32_t state; union { - uint32_t u; - int32_t l; - float f; + uint32_t u; + int32_t l; + float f; }value; #if CHPRINTF_USE_FLOAT char tmpbuf[2*MAX_FILLER + 1]; @@ -321,8 +328,8 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { if (*fmt) c = *fmt++; } - else if((c >= 'A') && (c <= 'Z')) - state|=IS_LONG; + else if ((c >= 'A') && (c <= 'Z')) + state|=IS_LONG; */ // Parse type switch (c) { @@ -377,7 +384,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { *p++ = '+'; #ifdef CHPRINTF_USE_SPACE_FLAG else if (state & PLUS_SPACE) - *p++ = ' '; + *p++ = ' '; #endif if (value.f == INFINITY){ *p++ = 0x19; diff --git a/flash.c b/flash.c index 9888cb5..a66315d 100644 --- a/flash.c +++ b/flash.c @@ -96,7 +96,7 @@ config_save(void) flash_erase_page((uint32_t)dst); /* write to flahs */ - while(count-- > 0) { + while (count-- > 0) { flash_program_half_word((uint32_t)dst, *src++); dst++; } @@ -141,7 +141,8 @@ caldata_save(int id) dst = (uint16_t*)saveareas[id]; current_props.magic = CONFIG_MAGIC; - current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum); + current_props.checksum = checksum( + ¤t_props, sizeof current_props - sizeof current_props.checksum); flash_unlock(); @@ -154,7 +155,7 @@ caldata_save(int id) } /* write to flahs */ - while(count-- > 0) { + while (count-- > 0) { flash_program_half_word((uint32_t)dst, *src++); dst++; } @@ -191,7 +192,7 @@ caldata_recall(int id) memcpy(dst, src, sizeof(properties_t)); return 0; load_default: - loadDefaultProps(); + load_default_properties(); return -1; } diff --git a/ili9341.c b/ili9341.c index a66fc9a..f1e4674 100644 --- a/ili9341.c +++ b/ili9341.c @@ -23,8 +23,8 @@ uint16_t spi_buffer[SPI_BUFFER_SIZE]; // Default foreground & background colors -uint16_t foreground_color=0; -uint16_t background_color=0; +uint16_t foreground_color = 0; +uint16_t background_color = 0; // Display width and height definition #define ILI9341_WIDTH 320 @@ -129,7 +129,8 @@ uint16_t background_color=0; #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_180 (ILI9341_MADCTL_MX | ILI9341_MADCTL_MY \ + | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR) // // Pin macros @@ -179,14 +180,17 @@ uint16_t background_color=0; #define SPI_READ_DATA SPI1->DR #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 void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { +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 void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) +{ (void)spip; (void)flags; } @@ -199,13 +203,15 @@ static uint32_t rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL) | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; -static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { +static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) +{ (void)spip; (void)flags; } -static void dmaStreamFlush(uint32_t len){ - while (len){ +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); @@ -251,11 +257,13 @@ static void __attribute__ ((noinline)) send_command(uint8_t cmd, uint8_t len, co DC_CMD; SPI_WRITE_8BIT(cmd); // Need wait transfer complete and set data bit - while (SPI_IS_BUSY); + while (SPI_IS_BUSY) + ; // Send command data (if need) DC_DATA; while (len-- > 0) { - while (SPI_TX_IS_NOT_EMPTY); + while (SPI_TX_IS_NOT_EMPTY) + ; SPI_WRITE_8BIT(*data++); } //CS_HIGH; @@ -345,31 +353,33 @@ 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)); + 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); + 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) }; + // 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); + 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); + while (len-- > 0) { + while (SPI_TX_IS_NOT_EMPTY) + ; SPI_WRITE_16BIT(*buf++); } } @@ -378,18 +388,18 @@ static uint8_t ssp_sendrecvdata(void) { // Start RX clock (by sending data) SPI_WRITE_8BIT(0); - while(SPI_RX_IS_EMPTY && SPI_IS_BUSY) + 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); + // 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); @@ -399,11 +409,11 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) // 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); + // 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; } @@ -415,10 +425,10 @@ 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); + 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); @@ -426,18 +436,20 @@ void ili9341_fill(int x, int y, int w, int h, int color) 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); +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){ + while (len-- > 0) { uint16_t color = palette[*buf++]; - while (SPI_TX_IS_NOT_EMPTY); + while (SPI_TX_IS_NOT_EMPTY) + ; SPI_WRITE_16BIT(color); } } @@ -445,15 +457,16 @@ void ili9341_bulk_8bit(int x, int y, int w, int h, uint16_t *palette){ // 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); + 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); + dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC); dmaStreamFlush(w * h); } @@ -462,25 +475,25 @@ void ili9341_bulk(int x, int y, int w, int h) 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; + 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); + 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; + 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); + 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); @@ -498,39 +511,53 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) r = rgbbuf[0]; g = rgbbuf[1]; b = rgbbuf[2]; - *out++ = RGB565(r,g,b); - rgbbuf+=3; + *out++ = RGB565(r, g, b); + rgbbuf += 3; } } #endif -void clearScreen(void){ +void ili9341_clear_screen(void) +{ 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_set_foreground(uint16_t fg) +{ + foreground_color = fg; +} -void ili9341_setRotation(uint8_t r) { -// static const uint8_t rotation_const[]={DISPLAY_ROTATION_0, DISPLAY_ROTATION_90, DISPLAY_ROTATION_180, DISPLAY_ROTATION_270}; +void ili9341_set_background(uint16_t bg) +{ + background_color = bg; +} + +void ili9341_set_rotation(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); } -void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap){ +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++) { + 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; - } + 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){ +static 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++) { + 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; @@ -552,36 +579,38 @@ void ili9341_drawstring(const char *str, int x, int y) 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; + x += w; } } -void ili9341_drawstringV(const char *str, int x, int y){ - ili9341_setRotation(DISPLAY_ROTATION_270); +void ili9341_drawstringV(const char *str, int x, int y) +{ + ili9341_set_rotation(DISPLAY_ROTATION_270); ili9341_drawstring(str, ILI9341_HEIGHT-y, x); - ili9341_setRotation(DISPLAY_ROTATION_0); + ili9341_set_rotation(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 dy ? dx : -dy) / 2; - while (1){ + while (1) { ili9341_pixel(x0, y0, DEFAULT_FG_COLOR); if (x0 == x1 && y0 == y1) break; diff --git a/main.c b/main.c index 69245fd..fff210d 100644 --- a/main.c +++ b/main.c @@ -26,16 +26,15 @@ #include "fft.h" #include -//#include #include -//#include #include /* * Shell settings */ -// If need run shell as thread (use more amount of memory fore stack), after enable this need reduce spi_buffer size, by default shell run in main thread -//#define VNA_SHELL_THREAD +// If need run shell as thread (use more amount of memory fore stack), after +// enable this need reduce spi_buffer size, by default shell run in main thread +// #define VNA_SHELL_THREAD static BaseSequentialStream *shell_stream = (BaseSequentialStream *)&SDU1; @@ -47,13 +46,15 @@ static BaseSequentialStream *shell_stream = (BaseSequentialStream *)&SDU1; #define VNA_SHELL_MAX_ARGUMENTS 4 // Shell max command line size #define VNA_SHELL_MAX_LENGTH 48 + // Shell command functions prototypes -typedef void (*vna_shellcmd_t)(int argc, char *argv[]); -#define VNA_SHELL_FUNCTION(command_name) static void command_name(int argc, char *argv[]) +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, args, nargs, and function ptr static char shell_line[VNA_SHELL_MAX_LENGTH]; -static char *shell_args[VNA_SHELL_MAX_ARGUMENTS + 1]; +static char *shell_args[VNA_SHELL_MAX_ARGUMENTS + 1]; static uint16_t shell_nargs; static volatile vna_shellcmd_t shell_function = 0; @@ -117,21 +118,21 @@ static THD_FUNCTION(Thread1, arg) __WFI(); } // Run Shell command in sweep thread - if (shell_function){ - shell_function(shell_nargs-1, &shell_args[1]); + if (shell_function) { + shell_function(shell_nargs - 1, &shell_args[1]); shell_function = 0; osalThreadSleepMilliseconds(10); continue; } // Process UI inputs ui_process(); - // 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(); + // 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; + redraw_request |= REDRAW_CELLS | REDRAW_BATTERY; if (uistat.marker_tracking) { int i = marker_search(); @@ -142,30 +143,32 @@ static THD_FUNCTION(Thread1, arg) } } // plot trace and other indications as raster - draw_all(completed); // flush markmap only if scan completed to prevent remaining traces + draw_all(completed); // flush markmap only if scan completed to prevent + // remaining traces } } static inline void pause_sweep(void) { - sweep_mode&=~SWEEP_ENABLE; + sweep_mode &= ~SWEEP_ENABLE; } static inline void resume_sweep(void) { - sweep_mode|=SWEEP_ENABLE; + sweep_mode |= SWEEP_ENABLE; } void toggle_sweep(void) { - sweep_mode^=SWEEP_ENABLE; + sweep_mode ^= SWEEP_ENABLE; } static float -bessel0(float x) { +bessel0(float x) +{ const float eps = 0.0001; float ret = 0; @@ -181,7 +184,8 @@ bessel0(float x) { } static float -kaiser_window(float k, float n, float beta) { +kaiser_window(float k, float n, float beta) +{ if (beta == 0.0) return 1.0; float r = (2 * k) / (n - 1) - 1; return bessel0(beta * sqrt(1 - r * r)) / bessel0(beta); @@ -197,70 +201,70 @@ transform_domain(void) uint8_t window_size = POINTS_COUNT, offset = 0; uint8_t is_lowpass = FALSE; switch (domain_mode & TD_FUNC) { - case TD_FUNC_BANDPASS: - offset = 0; - window_size = POINTS_COUNT; - break; - case TD_FUNC_LOWPASS_IMPULSE: - case TD_FUNC_LOWPASS_STEP: - is_lowpass = TRUE; - offset = POINTS_COUNT; - window_size = POINTS_COUNT*2; - break; + case TD_FUNC_BANDPASS: + offset = 0; + window_size = POINTS_COUNT; + break; + case TD_FUNC_LOWPASS_IMPULSE: + case TD_FUNC_LOWPASS_STEP: + is_lowpass = TRUE; + offset = POINTS_COUNT; + window_size = POINTS_COUNT * 2; + break; } float beta = 0.0; switch (domain_mode & TD_WINDOW) { - case TD_WINDOW_MINIMUM: - beta = 0.0; // this is rectangular - break; - case TD_WINDOW_NORMAL: - beta = 6.0; - break; - case TD_WINDOW_MAXIMUM: - beta = 13; - break; + case TD_WINDOW_MINIMUM: + beta = 0.0; // this is rectangular + break; + case TD_WINDOW_NORMAL: + beta = 6.0; + break; + case TD_WINDOW_MAXIMUM: + beta = 13; + break; } - for (int ch = 0; ch < 2; ch++) { - memcpy(tmp, measured[ch], sizeof(measured[0])); - for (int i = 0; i < POINTS_COUNT; i++) { - float w = kaiser_window(i+offset, window_size, beta); - tmp[i*2+0] *= w; - tmp[i*2+1] *= w; - } - for (int i = POINTS_COUNT; i < FFT_SIZE; i++) { - tmp[i*2+0] = 0.0; - tmp[i*2+1] = 0.0; - } - if (is_lowpass) { - for (int i = 1; i < POINTS_COUNT; i++) { - tmp[(FFT_SIZE-i)*2+0] = tmp[i*2+0]; - tmp[(FFT_SIZE-i)*2+1] = -tmp[i*2+1]; - } + memcpy(tmp, measured[ch], sizeof(measured[0])); + for (int i = 0; i < POINTS_COUNT; i++) { + float w = kaiser_window(i + offset, window_size, beta); + tmp[i * 2 + 0] *= w; + tmp[i * 2 + 1] *= w; + } + for (int i = POINTS_COUNT; i < FFT_SIZE; i++) { + tmp[i * 2 + 0] = 0.0; + tmp[i * 2 + 1] = 0.0; + } + if (is_lowpass) { + for (int i = 1; i < POINTS_COUNT; i++) { + tmp[(FFT_SIZE - i) * 2 + 0] = tmp[i * 2 + 0]; + tmp[(FFT_SIZE - i) * 2 + 1] = -tmp[i * 2 + 1]; } + } - fft256_inverse((float(*)[2])tmp); - memcpy(measured[ch], tmp, sizeof(measured[0])); - for (int i = 0; i < POINTS_COUNT; i++) { - measured[ch][i][0] /= (float)FFT_SIZE; - if (is_lowpass) { - measured[ch][i][1] = 0.0; - } else { - measured[ch][i][1] /= (float)FFT_SIZE; - } + fft256_inverse((float(*)[2])tmp); + memcpy(measured[ch], tmp, sizeof(measured[0])); + for (int i = 0; i < POINTS_COUNT; i++) { + measured[ch][i][0] /= (float)FFT_SIZE; + if (is_lowpass) { + measured[ch][i][1] = 0.0; + } else { + measured[ch][i][1] /= (float)FFT_SIZE; } - if ( (domain_mode & TD_FUNC) == TD_FUNC_LOWPASS_STEP ) { - for (int i = 1; i < POINTS_COUNT; i++) { - measured[ch][i][0] += measured[ch][i-1][0]; - } + } + if ((domain_mode & TD_FUNC) == TD_FUNC_LOWPASS_STEP) { + for (int i = 1; i < POINTS_COUNT; i++) { + measured[ch][i][0] += measured[ch][i - 1][0]; } + } } } // Shell commands output -static int shell_printf(const char *fmt, ...) { +static int shell_printf(const char *fmt, ...) +{ va_list ap; int formatted_bytes; va_start(ap, fmt); @@ -330,7 +334,7 @@ static int adjust_gain(uint32_t newfreq) { int new_order = newfreq / FREQ_HARMONICS; - int old_order = si5351_getFrequency() / FREQ_HARMONICS; + int old_order = si5351_get_frequency() / FREQ_HARMONICS; if (new_order != old_order) { tlv320aic3204_set_gain(gain_table[new_order], gain_table[new_order]); return DELAY_GAIN_CHANGE; @@ -345,7 +349,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, ds); + delay += si5351_set_frequency(freq, ds); return delay; } @@ -354,7 +358,8 @@ int set_frequency(uint32_t freq) // Rewrite universal standart str to value functions to more compact // // Convert string to int32 -static int32_t my_atoi(const char *p){ +static int32_t my_atoi(const char *p) +{ int32_t value = 0; uint32_t c; bool neg = false; @@ -371,7 +376,8 @@ static int32_t my_atoi(const char *p){ // 0o - for oct radix // 0b - for bin radix // default dec radix -uint32_t my_atoui(const char *p) { +uint32_t my_atoui(const char *p) +{ uint32_t value = 0, radix = 10, c; if (*p == '+') p++; if (*p == '0') { @@ -435,13 +441,15 @@ my_atof(const char *p) // Example need search parameter "center" in "start|stop|center|span|cw" getStringIndex return 2 // If not found return -1 // Used for easy parse command arguments -static int getStringIndex(char *v, const char *list){ +static int get_str_index(char *v, const char *list) +{ int i = 0; - while(1){ + while (1) { char *p = v; - while (1){ - char c = *list; if (c == '|') c = 0; - if (c == *p++){ + while (1) { + char c = *list; + if (c == '|') c = 0; + if (c == *p++) { // Found, return index if (c == 0) return i; list++; // Compare next symbol @@ -450,9 +458,9 @@ static int getStringIndex(char *v, const char *list){ break; // Not equal, break } // Set new substring ptr - while (1){ + while (1) { // End of string, not found - if (*list == 0 ) return -1; + if (*list == 0) return -1; if (*list++ == '|') break; } i++; @@ -684,11 +692,11 @@ VNA_SHELL_FUNCTION(cmd_capture) #error "Low size of spi_buffer for cmd_capture" #endif // read 2 row pixel time (read buffer limit by 2/3 + 1 from spi_buffer size) - for (y=0; y < 240; y+=2){ + for (y = 0; y < 240; y += 2) { // use uint16_t spi_buffer[2048] (defined in ili9341) for read buffer uint8_t *buf = (uint8_t *)spi_buffer; - ili9341_read_memory(0, y, 320, 2, 2*320, spi_buffer); - for (i = 0; i < 4*320; i++) { + ili9341_read_memory(0, y, 320, 2, 2 * 320, spi_buffer); + for (i = 0; i < 4 * 320; i++) { streamPut(shell_stream, *buf++); } } @@ -715,14 +723,21 @@ static void (*sample_func)(float *gamma) = calculate_gamma; VNA_SHELL_FUNCTION(cmd_sample) { - if (argc!=1) goto usage; + if (argc != 1) goto usage; // 0 1 2 static const char cmd_sample_list[] = "gamma|ampl|ref"; - switch (getStringIndex(argv[0], cmd_sample_list)){ - case 0:sample_func = calculate_gamma; return; - case 1:sample_func = fetch_amplitude; return; - case 2:sample_func = fetch_amplitude_ref; return; - default:break; + switch (get_str_index(argv[0], cmd_sample_list)) { + case 0: + sample_func = calculate_gamma; + return; + case 1: + sample_func = fetch_amplitude; + return; + case 2: + sample_func = fetch_amplitude_ref; + return; + default: + break; } usage: shell_printf("usage: sample {%s}\r\n", cmd_sample_list); @@ -758,7 +773,8 @@ static const marker_t def_markers[MARKERS_MAX] = { }; // Load propeties default settings -void loadDefaultProps(void){ +void load_default_properties(void) +{ //Magic add on caldata_save //current_props.magic = CONFIG_MAGIC; current_props._frequency0 = 50000; // start = 50kHz @@ -808,7 +824,7 @@ bool sweep(bool break_on_operation) 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)?1:0)); // 1900 + DSP_START(delay + ((i == 0) ? 1 : 0)); // 1900 //================================================ // Place some code thats need execute while delay //================================================ @@ -870,17 +886,15 @@ VNA_SHELL_FUNCTION(cmd_scan) pause_sweep(); sweep(false); // Output data after if set (faster data recive) - if (argc == 4){ + 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"); + 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"); + } } } } @@ -905,7 +919,7 @@ update_marker_index(void) } else { for (i = 0; i < sweep_points-1; i++) { if (frequencies[i] <= f && f < frequencies[i+1]) { - markers[m].index = f < (frequencies[i]/2 + frequencies[i+1]/2) ? i : i+1; + markers[m].index = f < (frequencies[i] / 2 + frequencies[i + 1] / 2) ? i : i + 1; break; } } @@ -927,7 +941,7 @@ set_frequencies(uint32_t start, uint32_t stop, uint16_t points) df+=error; if (df >=step) { f++; - df-=step; + df -= step; } } // disable at out of sweep range @@ -943,10 +957,10 @@ update_frequencies(void) stop = get_sweep_frequency(ST_STOP); set_frequencies(start, stop, sweep_points); -// operation_requested|= OP_FREQCHANGE; - + // operation_requested|= OP_FREQCHANGE; + update_marker_index(); - + // set grid layout update_grid(); } @@ -957,67 +971,65 @@ set_sweep_frequency(int type, uint32_t freq) int cal_applied = cal_status & CALSTAT_APPLY; // Check frequency for out of bounds (minimum SPAN can be any value) - if (type!=ST_SPAN && freq < START_MIN) + if (type != ST_SPAN && freq < START_MIN) freq = START_MIN; if (freq > STOP_MAX) freq = STOP_MAX; ensure_edit_config(); switch (type) { - case ST_START: - config.freq_mode&=~FREQ_MODE_CENTER_SPAN; - if (frequency0 != freq) { - frequency0 = freq; - // if start > stop then make start = stop - if (frequency1 < freq) - frequency1 = freq; - } - break; - case ST_STOP: - config.freq_mode&=~FREQ_MODE_CENTER_SPAN; - if (frequency1 != freq) { - frequency1 = freq; - // if start > stop then make start = stop - if (frequency0 > freq) + case ST_START: + config.freq_mode &= ~FREQ_MODE_CENTER_SPAN; + if (frequency0 != freq) { frequency0 = freq; - } - break; - case ST_CENTER: - config.freq_mode|=FREQ_MODE_CENTER_SPAN; - uint32_t center = frequency0/2 + frequency1/2; - if (center != freq) { - uint32_t span = frequency1 - frequency0; - if (freq < START_MIN + span/2) { - span = (freq - START_MIN) * 2; + // if start > stop then make start = stop + if (frequency1 < freq) frequency1 = freq; } - if (freq > STOP_MAX - span/2) { - span = (STOP_MAX - freq) * 2; + break; + case ST_STOP: + config.freq_mode &= ~FREQ_MODE_CENTER_SPAN; + if (frequency1 != freq) { + frequency1 = freq; + // if start > stop then make start = stop + if (frequency0 > freq) frequency0 = freq; } - frequency0 = freq - span/2; - frequency1 = freq + span/2; - } - break; - case ST_SPAN: - 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; + break; + case ST_CENTER: + config.freq_mode |= FREQ_MODE_CENTER_SPAN; + uint32_t center = frequency0 / 2 + frequency1 / 2; + if (center != freq) { + 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; + } + break; + case ST_SPAN: + 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; + } + if (center > STOP_MAX - freq / 2) { + center = STOP_MAX - freq / 2; + } + frequency0 = center - freq / 2; + frequency1 = center + freq / 2; } - if (center > STOP_MAX - freq/2) { - center = STOP_MAX - freq/2; + break; + case ST_CW: + config.freq_mode |= FREQ_MODE_CENTER_SPAN; + if (frequency0 != freq || frequency1 != freq) { + frequency0 = freq; + frequency1 = freq; } - frequency0 = center - freq/2; - frequency1 = center + freq/2; - } - break; - case ST_CW: - config.freq_mode|=FREQ_MODE_CENTER_SPAN; - if (frequency0 != freq || frequency1 != freq) { - frequency0 = freq; - frequency1 = freq; - } - break; + break; } update_frequencies(); if (cal_auto_interpolate && cal_applied) @@ -1028,7 +1040,11 @@ uint32_t get_sweep_frequency(int type) { // Obsolete, ensure correct start/stop, start always must be < stop - if (frequency0>frequency1) {uint32_t t=frequency0; frequency0=frequency1; frequency1=t;} + if (frequency0 > frequency1) { + uint32_t t = frequency0; + frequency0 = frequency1; + frequency1 = t; + } switch (type) { case ST_START: return frequency0; case ST_STOP: return frequency1; @@ -1049,16 +1065,16 @@ VNA_SHELL_FUNCTION(cmd_sweep) } uint32_t value0 = 0; uint32_t value1 = 0; - if (argc >=1) value0 = my_atoui(argv[0]); - if (argc >=2) value1 = my_atoui(argv[1]); -#if MAX_FREQ_TYPE!=5 + if (argc >= 1) value0 = my_atoui(argv[0]); + if (argc >= 2) value1 = my_atoui(argv[1]); +#if MAX_FREQ_TYPE != 5 #error "Sweep mode possibly changed, check cmd_sweep function" #endif // Parse sweep {start|stop|center|span|cw} {freq(Hz)} // get enum ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW static const char sweep_cmd[] = "start|stop|center|span|cw"; if (argc == 2 && value0 == 0) { - int type = getStringIndex(argv[0], sweep_cmd); + int type = get_str_index(argv[0], sweep_cmd); if (type == -1) goto usage; set_sweep_frequency(type, value1); @@ -1367,7 +1383,7 @@ cal_interpolate(int s) // found f between freqs at j and j+1 float k1 = (float)(f - src->_frequencies[j]) / (src->_frequencies[j+1] - src->_frequencies[j]); - + // avoid glitch between freqs in different harmonics mode if (IS_HARMONIC_MODE(src->_frequencies[j]) != IS_HARMONIC_MODE(src->_frequencies[j+1])) { // assume f[j] < f[j+1] @@ -1385,7 +1401,7 @@ cal_interpolate(int s) if (j == src->_sweep_points-1) break; } - + // upper than end freq of src range for (; i < sweep_points; i++) { // fill cal_data at tail of src @@ -1415,27 +1431,46 @@ VNA_SHELL_FUNCTION(cmd_cal) redraw_request|=REDRAW_CAL_STATUS; // 0 1 2 3 4 5 6 7 8 9 10 static const char cmd_cal_list[] = "load|open|short|thru|isoln|done|on|off|reset|data|in"; - switch (getStringIndex(argv[0], cmd_cal_list)){ - case 0:cal_collect(CAL_LOAD ); return; - case 1:cal_collect(CAL_OPEN ); return; - case 2:cal_collect(CAL_SHORT); return; - case 3:cal_collect(CAL_THRU ); return; - case 4:cal_collect(CAL_ISOLN); return; - case 5:cal_done(); return; - case 6:cal_status|= CALSTAT_APPLY;return; - case 7:cal_status&=~CALSTAT_APPLY;return; - case 8:cal_status = 0; return; - case 9: - shell_printf("%f %f\r\n", cal_data[CAL_LOAD ][0][0], cal_data[CAL_LOAD ][0][1]); - shell_printf("%f %f\r\n", cal_data[CAL_OPEN ][0][0], cal_data[CAL_OPEN ][0][1]); + switch (get_str_index(argv[0], cmd_cal_list)) { + case 0: + cal_collect(CAL_LOAD); + return; + case 1: + cal_collect(CAL_OPEN); + return; + case 2: + cal_collect(CAL_SHORT); + return; + case 3: + cal_collect(CAL_THRU); + return; + case 4: + cal_collect(CAL_ISOLN); + return; + case 5: + cal_done(); + return; + case 6: + cal_status |= CALSTAT_APPLY; + return; + case 7: + cal_status &= ~CALSTAT_APPLY; + return; + case 8: + cal_status = 0; + return; + case 9: + shell_printf("%f %f\r\n", cal_data[CAL_LOAD][0][0], cal_data[CAL_LOAD][0][1]); + shell_printf("%f %f\r\n", cal_data[CAL_OPEN][0][0], cal_data[CAL_OPEN][0][1]); shell_printf("%f %f\r\n", cal_data[CAL_SHORT][0][0], cal_data[CAL_SHORT][0][1]); - shell_printf("%f %f\r\n", cal_data[CAL_THRU ][0][0], cal_data[CAL_THRU ][0][1]); + shell_printf("%f %f\r\n", cal_data[CAL_THRU][0][0], cal_data[CAL_THRU][0][1]); shell_printf("%f %f\r\n", cal_data[CAL_ISOLN][0][0], cal_data[CAL_ISOLN][0][1]); return; case 10: cal_interpolate((argc > 1) ? my_atoi(argv[1]) : 0); return; - default:break; + default: + break; } shell_printf("usage: cal [%s]\r\n", cmd_cal_list); } @@ -1517,7 +1552,7 @@ void set_trace_type(int t, int type) // Set default trace scale trace[t].scale = trace_info[type].scale_unit; force = TRUE; - } + } if (force) { plot_into_index(measured); force_set_markmap(); @@ -1572,7 +1607,7 @@ VNA_SHELL_FUNCTION(cmd_trace) } } return; - } + } if (strcmp(argv[0], "all") == 0 && argc > 1 && strcmp(argv[1], "off") == 0) { @@ -1590,20 +1625,20 @@ VNA_SHELL_FUNCTION(cmd_trace) shell_printf("%d %s %s\r\n", t, type, channel); return; } -#if MAX_TRACE_TYPE!=12 +#if MAX_TRACE_TYPE != 12 #error "Trace type enum possibly changed, check cmd_trace function" #endif // enum TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF static const char cmd_type_list[] = "logmag|phase|delay|smith|polar|linear|swr|real|imag|r|x|off"; - int type = getStringIndex(argv[1], cmd_type_list); - if (type >= 0){ + int type = get_str_index(argv[1], cmd_type_list); + if (type >= 0) { set_trace_type(t, type); goto check_ch_num; } // 0 1 static const char cmd_scale_ref_list[] = "scale|refpos"; - if (argc >= 3){ - switch (getStringIndex(argv[1], cmd_scale_ref_list)){ + if (argc >= 3) { + switch (get_str_index(argv[1], cmd_scale_ref_list)) { case 0: //trace[t].scale = my_atof(argv[2]); set_trace_scale(t, my_atof(argv[2])); @@ -1686,7 +1721,7 @@ VNA_SHELL_FUNCTION(cmd_marker) return; } static const char cmd_marker_list[] = "on|off"; - switch (getStringIndex(argv[1], cmd_marker_list)){ + switch (get_str_index(argv[1], cmd_marker_list)) { case 0: markers[t].enabled = TRUE; active_marker = t; return; case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = -1; return; default: @@ -1726,7 +1761,7 @@ VNA_SHELL_FUNCTION(cmd_touchtest) (void)argv; do { touch_draw_test(); - } while(argc); + } while (argc); } VNA_SHELL_FUNCTION(cmd_frequencies) @@ -1771,16 +1806,33 @@ VNA_SHELL_FUNCTION(cmd_transform) // 0 1 2 3 4 5 6 7 static const char cmd_transform_list[] = "on|off|impulse|step|bandpass|minimum|normal|maximum"; for (i = 0; i < argc; i++) { - switch (getStringIndex(argv[i], cmd_transform_list)){ - case 0:set_domain_mode(DOMAIN_TIME);return; - case 1:set_domain_mode(DOMAIN_FREQ);return; - case 2:set_timedomain_func(TD_FUNC_LOWPASS_IMPULSE);return; - case 3:set_timedomain_func(TD_FUNC_LOWPASS_STEP);return; - case 4:set_timedomain_func(TD_FUNC_BANDPASS);return; - case 5:set_timedomain_window(TD_WINDOW_MINIMUM);return; - case 6:set_timedomain_window(TD_WINDOW_NORMAL);return; - case 7:set_timedomain_window(TD_WINDOW_MAXIMUM);return; - default: goto usage; + switch (get_str_index(argv[i], cmd_transform_list)) { + case 0: + set_domain_mode(DOMAIN_TIME); + return; + case 1: + set_domain_mode(DOMAIN_FREQ); + return; + case 2: + set_timedomain_func(TD_FUNC_LOWPASS_IMPULSE); + return; + case 3: + set_timedomain_func(TD_FUNC_LOWPASS_STEP); + return; + case 4: + set_timedomain_func(TD_FUNC_BANDPASS); + return; + case 5: + set_timedomain_window(TD_WINDOW_MINIMUM); + return; + case 6: + set_timedomain_window(TD_WINDOW_NORMAL); + return; + case 7: + set_timedomain_window(TD_WINDOW_MAXIMUM); + return; + default: + goto usage; } } return; @@ -1941,7 +1993,7 @@ VNA_SHELL_FUNCTION(cmd_info) { (void)argc; (void)argv; - int i=0; + int i = 0; while (info_about[i]) shell_printf("%s\r\n", info_about[i++]); } @@ -1956,7 +2008,7 @@ VNA_SHELL_FUNCTION(cmd_color) shell_printf("usage: color {id} {rgb24}\r\n"); for (i=-3; i < TRACES_MAX; i++) { #if 0 - switch(i){ + 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; @@ -1981,7 +2033,7 @@ VNA_SHELL_FUNCTION(cmd_color) return; color = RGBHEX(my_atoui(argv[1])); #if 0 - switch(i){ + 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; @@ -2000,7 +2052,8 @@ VNA_SHELL_FUNCTION(cmd_color) #if CH_CFG_USE_REGISTRY == FALSE #error "Threads Requite enabled CH_CFG_USE_REGISTRY in chconf.h" #endif -VNA_SHELL_FUNCTION(cmd_threads) { +VNA_SHELL_FUNCTION(cmd_threads) +{ static const char *states[] = {CH_STATE_NAMES}; thread_t *tp; (void)argc; @@ -2116,18 +2169,19 @@ VNA_SHELL_FUNCTION(cmd_help) // // Read command line from shell_stream // -static int VNAShell_readLine(char *line, int max_size){ +static int VNAShell_readLine(char *line, int max_size) +{ // Read line from input stream uint8_t c; char *ptr = line; - while (1){ + while (1) { // Return 0 only if stream not active if (streamRead(shell_stream, &c, 1) == 0) return 0; // Backspace or Delete if (c == 8 || c == 0x7f) { if (ptr != line) { - static const char backspace[] = {0x08,0x20,0x08,0x00}; + static const char backspace[] = {0x08, 0x20, 0x08, 0x00}; shell_printf(backspace); ptr--; } @@ -2154,52 +2208,54 @@ static int VNAShell_readLine(char *line, int max_size){ // // Parse and run command line // -static void VNAShell_executeLine(char *line){ +static void VNAShell_executeLine(char *line) +{ // Parse and execute line char *lp = line, *ep; shell_nargs = 0; - while (*lp!=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"); + 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 - shell_args[shell_nargs++]=lp; + shell_args[shell_nargs++] = lp; // Stop, end of input string - if ((lp = ep) == NULL) - break; + if ((lp = ep) == NULL) break; // Argument limits check if (shell_nargs > VNA_SHELL_MAX_ARGUMENTS) { - shell_printf("too many arguments, max "define_to_STR(VNA_SHELL_MAX_ARGUMENTS)""VNA_SHELL_NEWLINE_STR); + 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 (shell_nargs == 0) - return; + if (shell_nargs == 0) return; // Execute line const VNAShellCommand *scp; - for (scp = commands; scp->sc_name!=NULL;scp++) { + for (scp = commands; scp->sc_name != NULL; scp++) { if (strcmp(scp->sc_name, shell_args[0]) == 0) { - if (scp->flags&CMD_WAIT_MUTEX){ - shell_function= scp->sc_function; + if (scp->flags & CMD_WAIT_MUTEX) { + shell_function = scp->sc_function; // Wait execute command in sweep thread - do{ + do { osalThreadSleepMilliseconds(100); - } while(shell_function); + } while (shell_function); + } else { + scp->sc_function(shell_nargs - 1, &shell_args[1]); } - else - scp->sc_function(shell_nargs-1, &shell_args[1]); return; } } - shell_printf("%s?"VNA_SHELL_NEWLINE_STR, shell_args[0]); + shell_printf("%s?" VNA_SHELL_NEWLINE_STR, shell_args[0]); } #ifdef VNA_SHELL_THREAD static THD_WORKING_AREA(waThread2, /* cmd_* max stack size + alpha */442); -THD_FUNCTION(myshellThread, p) { +THD_FUNCTION(myshellThread, p) +{ (void)p; chRegSetThreadName("shell"); shell_printf(VNA_SHELL_NEWLINE_STR"NanoVNA Shell"VNA_SHELL_NEWLINE_STR); @@ -2341,20 +2397,21 @@ int main(void) /* The prototype shows it is a naked function - in effect this is just an assembly function. */ -void HardFault_Handler( void ); +void HardFault_Handler(void); -void hard_fault_handler_c(uint32_t *sp) __attribute__( ( naked ) );; +void hard_fault_handler_c(uint32_t *sp) __attribute__((naked)); void HardFault_Handler(void) { - uint32_t* sp; + uint32_t *sp; //__asm volatile ("mrs %0, msp \n\t": "=r" (sp) ); - __asm volatile ("mrs %0, psp \n\t": "=r" (sp) ); + __asm volatile("mrs %0, psp \n\t" : "=r"(sp)); hard_fault_handler_c(sp); } -void hard_fault_handler_c(uint32_t* sp) +void hard_fault_handler_c(uint32_t *sp) { (void)sp; - while (true) {} + while (true) { + } } diff --git a/mcuconf.h b/mcuconf.h index 9021c85..a1da287 100644 --- a/mcuconf.h +++ b/mcuconf.h @@ -96,7 +96,7 @@ #define STM32_EXT_EXTI17_IRQ_PRIORITY 3 #define STM32_EXT_EXTI21_22_IRQ_PRIORITY 3 -#define STM32_DISABLE_EXTI2122_HANDLER TRUE +#define STM32_DISABLE_EXTI2122_HANDLER TRUE /* * GPT driver system settings. diff --git a/nanovna.h b/nanovna.h index 281fa26..d553f38 100644 --- a/nanovna.h +++ b/nanovna.h @@ -93,7 +93,7 @@ uint32_t get_sweep_frequency(int type); double my_atof(const char *p); void toggle_sweep(void); -void loadDefaultProps(void); +void load_default_properties(void); #define SWEEP_ENABLE 0x01 #define SWEEP_ONCE 0x02 @@ -169,15 +169,15 @@ extern int16_t area_height; // font extern const uint8_t x5x7_bits []; -#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) -#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7)) -#define FONT_MAX_WIDTH 7 -#define FONT_GET_HEIGHT 7 +#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) +#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7)) +#define FONT_MAX_WIDTH 7 +#define FONT_GET_HEIGHT 7 extern const uint16_t numfont16x22[]; -#define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*22]) -#define NUM_FONT_GET_WIDTH 16 -#define NUM_FONT_GET_HEIGHT 22 +#define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*22]) +#define NUM_FONT_GET_WIDTH 16 +#define NUM_FONT_GET_HEIGHT 22 #define S_DELTA "\004" #define S_DEGREE "\037" @@ -306,21 +306,21 @@ extern volatile uint8_t redraw_request; #define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) ) // Define size of screen buffer in pixels (one pixel 16bit size) -#define SPI_BUFFER_SIZE 2048 - -#define DEFAULT_FG_COLOR RGB565(255,255,255) -#define DEFAULT_BG_COLOR RGB565( 0, 0, 0) -#define DEFAULT_GRID_COLOR RGB565(128,128,128) -#define DEFAULT_MENU_COLOR RGB565(255,255,255) -#define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0) -#define DEFAULT_MENU_ACTIVE_COLOR RGB565(180,255,180) -#define DEFAULT_TRACE_1_COLOR RGB565(255,255, 0) -#define DEFAULT_TRACE_2_COLOR RGB565( 0,255,255) -#define DEFAULT_TRACE_3_COLOR RGB565( 0,255, 0) -#define DEFAULT_TRACE_4_COLOR RGB565(255, 0,255) -#define DEFAULT_NORMAL_BAT_COLOR RGB565( 31,227, 0) -#define DEFAULT_LOW_BAT_COLOR RGB565(255, 0, 0) -#define DEFAULT_SPEC_INPUT_COLOR RGB565(128,255,128); +#define SPI_BUFFER_SIZE 2048 + +#define DEFAULT_FG_COLOR RGB565(255,255,255) +#define DEFAULT_BG_COLOR RGB565( 0, 0, 0) +#define DEFAULT_GRID_COLOR RGB565(128,128,128) +#define DEFAULT_MENU_COLOR RGB565(255,255,255) +#define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0) +#define DEFAULT_MENU_ACTIVE_COLOR RGB565(180,255,180) +#define DEFAULT_TRACE_1_COLOR RGB565(255,255, 0) +#define DEFAULT_TRACE_2_COLOR RGB565( 0,255,255) +#define DEFAULT_TRACE_3_COLOR RGB565( 0,255, 0) +#define DEFAULT_TRACE_4_COLOR RGB565(255, 0,255) +#define DEFAULT_NORMAL_BAT_COLOR RGB565( 31,227, 0) +#define DEFAULT_LOW_BAT_COLOR RGB565(255, 0, 0) +#define DEFAULT_SPEC_INPUT_COLOR RGB565(128,255,128); extern uint16_t foreground_color; extern uint16_t background_color; @@ -328,15 +328,13 @@ extern uint16_t background_color; extern uint16_t spi_buffer[SPI_BUFFER_SIZE]; void ili9341_init(void); -//void ili9341_setRotation(uint8_t r); void ili9341_test(int mode); void ili9341_bulk(int x, int y, int w, int h); void ili9341_fill(int x, int y, int w, int h, int color); -void setForegroundColor(uint16_t fg); -void setBackgroundColor(uint16_t fg); -void clearScreen(void); +void ili9341_set_foreground(uint16_t fg); +void ili9341_set_background(uint16_t fg); +void ili9341_clear_screen(void); void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap); -void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap); void ili9341_drawchar(uint8_t ch, int x, int y); void ili9341_drawstring(const char *str, int x, int y); void ili9341_drawstringV(const char *str, int x, int y); diff --git a/numfont20x22.c b/numfont20x22.c index 34ce947..85498ec 100644 --- a/numfont20x22.c +++ b/numfont20x22.c @@ -24,533 +24,532 @@ const uint16_t numfont16x22[] = { - 0b0000111111110000, - 0b0011111111111100, - 0b0111111111111110, - 0b0111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111110, - 0b0111111111111110, - 0b0011111111111100, - 0b0000111111110000, + 0b0000111111110000, + 0b0011111111111100, + 0b0111111111111110, + 0b0111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111110, + 0b0111111111111110, + 0b0011111111111100, + 0b0000111111110000, - 0b0000000011110000, - 0b0000000111110000, - 0b0000001111110000, - 0b0000011111110000, - 0b0000111111110000, - 0b0000111111110000, - 0b0000111011110000, - 0b0000110011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000000011110000, - 0b0000001111111100, - 0b0000001111111100, - 0b0000001111111100, + 0b0000000011110000, + 0b0000000111110000, + 0b0000001111110000, + 0b0000011111110000, + 0b0000111111110000, + 0b0000111111110000, + 0b0000111011110000, + 0b0000110011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000000011110000, + 0b0000001111111100, + 0b0000001111111100, + 0b0000001111111100, - 0b0000111111110000, - 0b0011111111111100, - 0b0111111111111110, - 0b0111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000001111, - 0b0000000000011111, - 0b0000000000111111, - 0b0000000001111110, - 0b0000000011111100, - 0b0000000111111000, - 0b0000001111110000, - 0b0000011111100000, - 0b0000111111000000, - 0b0001111110000000, - 0b0011111100000000, - 0b0111111000000000, - 0b1111110000000000, - 0b1111111111111111, - 0b1111111111111111, - 0b1111111111111111, + 0b0000111111110000, + 0b0011111111111100, + 0b0111111111111110, + 0b0111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000001111, + 0b0000000000011111, + 0b0000000000111111, + 0b0000000001111110, + 0b0000000011111100, + 0b0000000111111000, + 0b0000001111110000, + 0b0000011111100000, + 0b0000111111000000, + 0b0001111110000000, + 0b0011111100000000, + 0b0111111000000000, + 0b1111110000000000, + 0b1111111111111111, + 0b1111111111111111, + 0b1111111111111111, - 0b0000111111110000, - 0b0011111111111100, - 0b0111111111111110, - 0b0111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000001111, - 0b0000000000011110, - 0b0000000000111110, - 0b0000000111111100, - 0b0000000111111000, - 0b0000000111111100, - 0b0000000001111110, - 0b0000000000011111, - 0b0000000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111110, - 0b0111111111111110, - 0b0011111111111100, - 0b0000111111110000, + 0b0000111111110000, + 0b0011111111111100, + 0b0111111111111110, + 0b0111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000001111, + 0b0000000000011110, + 0b0000000000111110, + 0b0000000111111100, + 0b0000000111111000, + 0b0000000111111100, + 0b0000000001111110, + 0b0000000000011111, + 0b0000000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111110, + 0b0111111111111110, + 0b0011111111111100, + 0b0000111111110000, - 0b0000000111111000, - 0b0000000111111000, - 0b0000001111111000, - 0b0000001111111000, - 0b0000011111111000, - 0b0000011111111000, - 0b0000111111111000, - 0b0000111101111000, - 0b0001111101111000, - 0b0001111001111000, - 0b0011111001111000, - 0b0011110001111000, - 0b0111110001111000, - 0b0111100001111000, - 0b1111100001111000, - 0b1111111111111111, - 0b1111111111111111, - 0b1111111111111111, - 0b0000000001111000, - 0b0000000001111000, - 0b0000000001111000, - 0b0000000001111000, + 0b0000000111111000, + 0b0000000111111000, + 0b0000001111111000, + 0b0000001111111000, + 0b0000011111111000, + 0b0000011111111000, + 0b0000111111111000, + 0b0000111101111000, + 0b0001111101111000, + 0b0001111001111000, + 0b0011111001111000, + 0b0011110001111000, + 0b0111110001111000, + 0b0111100001111000, + 0b1111100001111000, + 0b1111111111111111, + 0b1111111111111111, + 0b1111111111111111, + 0b0000000001111000, + 0b0000000001111000, + 0b0000000001111000, + 0b0000000001111000, - 0b1111111111111111, - 0b1111111111111111, - 0b1111111111111111, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111011111110000, - 0b1111111111111100, - 0b1111111111111110, - 0b1111110000111110, - 0b1111100000011111, - 0b0000000000001111, - 0b0000000000001111, - 0b0000000000001111, - 0b0000000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111110, - 0b0111111111111110, - 0b0011111111111100, - 0b0000111111110000, + 0b1111111111111111, + 0b1111111111111111, + 0b1111111111111111, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111011111110000, + 0b1111111111111100, + 0b1111111111111110, + 0b1111110000111110, + 0b1111100000011111, + 0b0000000000001111, + 0b0000000000001111, + 0b0000000000001111, + 0b0000000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111110, + 0b0111111111111110, + 0b0011111111111100, + 0b0000111111110000, - 0b0000111111110000, - 0b0011111111111100, - 0b0111111111111110, - 0b0111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000000000, - 0b1111000000000000, - 0b1111011111110000, - 0b1111111111111100, - 0b1111111111111110, - 0b1111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111110, - 0b0111111111111110, - 0b0011111111111100, - 0b0000111111110000, + 0b0000111111110000, + 0b0011111111111100, + 0b0111111111111110, + 0b0111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000000000, + 0b1111000000000000, + 0b1111011111110000, + 0b1111111111111100, + 0b1111111111111110, + 0b1111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111110, + 0b0111111111111110, + 0b0011111111111100, + 0b0000111111110000, - 0b1111111111111111, - 0b1111111111111111, - 0b1111111111111111, - 0b0000000000011111, - 0b0000000000111110, - 0b0000000001111100, - 0b0000000011111000, - 0b0000000111110000, - 0b0000000111100000, - 0b0000001111100000, - 0b0000001111000000, - 0b0000011111000000, - 0b0000011110000000, - 0b0000011110000000, - 0b0000111110000000, - 0b0000111100000000, - 0b0000111100000000, - 0b0000111100000000, - 0b0000111100000000, - 0b0000111100000000, - 0b0000111100000000, - 0b0000111100000000, + 0b1111111111111111, + 0b1111111111111111, + 0b1111111111111111, + 0b0000000000011111, + 0b0000000000111110, + 0b0000000001111100, + 0b0000000011111000, + 0b0000000111110000, + 0b0000000111100000, + 0b0000001111100000, + 0b0000001111000000, + 0b0000011111000000, + 0b0000011110000000, + 0b0000011110000000, + 0b0000111110000000, + 0b0000111100000000, + 0b0000111100000000, + 0b0000111100000000, + 0b0000111100000000, + 0b0000111100000000, + 0b0000111100000000, + 0b0000111100000000, - 0b0000011111100000, - 0b0001111111111000, - 0b0011111111111100, - 0b0111110000111110, - 0b0111100000011110, - 0b0111100000011110, - 0b0111100000011110, - 0b0011110000111100, - 0b0001111111111000, - 0b0000111111110000, - 0b0011111111111100, - 0b0111110000111110, - 0b0111100000011110, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111110, - 0b0111111111111110, - 0b0011111111111100, - 0b0000111111110000, + 0b0000011111100000, + 0b0001111111111000, + 0b0011111111111100, + 0b0111110000111110, + 0b0111100000011110, + 0b0111100000011110, + 0b0111100000011110, + 0b0011110000111100, + 0b0001111111111000, + 0b0000111111110000, + 0b0011111111111100, + 0b0111110000111110, + 0b0111100000011110, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111110, + 0b0111111111111110, + 0b0011111111111100, + 0b0000111111110000, - 0b0000111111110000, - 0b0011111111111100, - 0b0111111111111110, - 0b0111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111111, - 0b0111111111111111, - 0b0011111111111111, - 0b0000111111111111, - 0b0000000000001111, - 0b0000000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111110, - 0b0111111111111110, - 0b0011111111111100, - 0b0000111111110000, + 0b0000111111110000, + 0b0011111111111100, + 0b0111111111111110, + 0b0111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111111, + 0b0111111111111111, + 0b0011111111111111, + 0b0000111111111111, + 0b0000000000001111, + 0b0000000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111110, + 0b0111111111111110, + 0b0011111111111100, + 0b0000111111110000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001110000000, - 0b0000011111000000, - 0b0000011111000000, - 0b0000001110000000, - 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001110000000, + 0b0000011111000000, + 0b0000011111000000, + 0b0000001110000000, + 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0011111111111100, - 0b0011111111111100, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0011111111111100, + 0b0011111111111100, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, - 0b0000000000000011, - 0b0000000000000111, - 0b0000000000001111, - 0b0000000000011111, - 0b0000000000111111, - 0b0000000001111111, - 0b0000000000001111, - 0b0000000000001111, - 0b0000000000001111, - 0b0110000011001111, - 0b1111000111101111, - 0b0111101111001111, - 0b0011111110001111, - 0b0001111100001111, - 0b0001111100001111, - 0b0011111110001111, - 0b0111101111001111, - 0b1111000111101111, - 0b0110000011001111, - 0b0000000000001111, - 0b0000000000001111, - 0b0000000000001111, + 0b0000000000000011, + 0b0000000000000111, + 0b0000000000001111, + 0b0000000000011111, + 0b0000000000111111, + 0b0000000001111111, + 0b0000000000001111, + 0b0000000000001111, + 0b0000000000001111, + 0b0110000011001111, + 0b1111000111101111, + 0b0111101111001111, + 0b0011111110001111, + 0b0001111100001111, + 0b0001111100001111, + 0b0011111110001111, + 0b0111101111001111, + 0b1111000111101111, + 0b0110000011001111, + 0b0000000000001111, + 0b0000000000001111, + 0b0000000000001111, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000111110, - 0b1111000001111100, - 0b1111000011111000, - 0b1111000111110000, - 0b1111001111100000, - 0b1111011111000000, - 0b1111111110000000, - 0b1111111100000000, - 0b1111111100000000, - 0b1111111110000000, - 0b1111011111000000, - 0b1111001111100000, - 0b1111000111110000, - 0b1111000011111000, - 0b1111000001111100, - 0b1111000000111110, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000111110, + 0b1111000001111100, + 0b1111000011111000, + 0b1111000111110000, + 0b1111001111100000, + 0b1111011111000000, + 0b1111111110000000, + 0b1111111100000000, + 0b1111111100000000, + 0b1111111110000000, + 0b1111011111000000, + 0b1111001111100000, + 0b1111000111110000, + 0b1111000011111000, + 0b1111000001111100, + 0b1111000000111110, - 0b1111000000001111, - 0b1111000000001111, - 0b1111100000011111, - 0b1111100000011111, - 0b1111110000111111, - 0b1111110000111111, - 0b1111111001111111, - 0b1111111001111111, - 0b1111111111111111, - 0b1111111111111111, - 0b1111111111111111, - 0b1111111111111111, - 0b1111011111101111, - 0b1111011111101111, - 0b1111001111001111, - 0b1111001111001111, - 0b1111000110001111, - 0b1111000110001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111100000011111, + 0b1111100000011111, + 0b1111110000111111, + 0b1111110000111111, + 0b1111111001111111, + 0b1111111001111111, + 0b1111111111111111, + 0b1111111111111111, + 0b1111111111111111, + 0b1111111111111111, + 0b1111011111101111, + 0b1111011111101111, + 0b1111001111001111, + 0b1111001111001111, + 0b1111000110001111, + 0b1111000110001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, - 0b0000111111110000, - 0b0011111111111100, - 0b0111111111111110, - 0b0111110000111110, - 0b1111100000011111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000111111, - 0b1111000000111111, - 0b1111000000111111, - 0b1111000000000111, - 0b1111000000001111, - 0b1111100000011111, - 0b0111110000111111, - 0b0111111111111111, - 0b0011111111110111, - 0b0000111111100111, + 0b0000111111110000, + 0b0011111111111100, + 0b0111111111111110, + 0b0111110000111110, + 0b1111100000011111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000111111, + 0b1111000000111111, + 0b1111000000111111, + 0b1111000000000111, + 0b1111000000001111, + 0b1111100000011111, + 0b0111110000111111, + 0b0111111111111111, + 0b0011111111110111, + 0b0000111111100111, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000001000000, - 0b0000000011000000, - 0b0000000111000000, - 0b0000001111000000, - 0b0000011111000000, - 0b0000111111111111, - 0b0001111111111111, - 0b0011111111111111, - 0b0111111111111111, - 0b1111111111111111, - 0b0111111111111111, - 0b0011111111111111, - 0b0001111111111111, - 0b0000111111111111, - 0b0000011111000000, - 0b0000001111000000, - 0b0000000111000000, - 0b0000000011000000, - 0b0000000001000000, - 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000001000000, + 0b0000000011000000, + 0b0000000111000000, + 0b0000001111000000, + 0b0000011111000000, + 0b0000111111111111, + 0b0001111111111111, + 0b0011111111111111, + 0b0111111111111111, + 0b1111111111111111, + 0b0111111111111111, + 0b0011111111111111, + 0b0001111111111111, + 0b0000111111111111, + 0b0000011111000000, + 0b0000001111000000, + 0b0000000111000000, + 0b0000000011000000, + 0b0000000001000000, + 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0001111000111100, - 0b0011111101111110, - 0b0111001111100110, - 0b0110000111000011, - 0b1110000111000011, - 0b1100000110000011, - 0b1100000110000011, - 0b1100000110000011, - 0b1100000110000011, - 0b1100001110000111, - 0b1100001110000110, - 0b0110011111001110, - 0b0111111011111100, - 0b0011110001111000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0001111000111100, + 0b0011111101111110, + 0b0111001111100110, + 0b0110000111000011, + 0b1110000111000011, + 0b1100000110000011, + 0b1100000110000011, + 0b1100000110000011, + 0b1100000110000011, + 0b1100001110000111, + 0b1100001110000110, + 0b0110011111001110, + 0b0111111011111100, + 0b0011110001111000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000011101111100, - 0b0000011101111110, - 0b0000001101100110, - 0b0000001101100110, - 0b0000001101100110, - 0b0000001101100110, - 0b0000001101100110, - 0b0011101101111100, - 0b0111111101111110, - 0b1110011101100111, - 0b1100001101100011, - 0b1100001101100011, - 0b1100001101100011, - 0b1100001101100011, - 0b1100001101100011, - 0b1100001101100011, - 0b1110011101100111, - 0b0111111101111110, - 0b0011101101111100, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000011101111100, + 0b0000011101111110, + 0b0000001101100110, + 0b0000001101100110, + 0b0000001101100110, + 0b0000001101100110, + 0b0000001101100110, + 0b0011101101111100, + 0b0111111101111110, + 0b1110011101100111, + 0b1100001101100011, + 0b1100001101100011, + 0b1100001101100011, + 0b1100001101100011, + 0b1100001101100011, + 0b1100001101100011, + 0b1110011101100111, + 0b0111111101111110, + 0b0011101101111100, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0011111111111000, - 0b0011111111111000, - 0b0011111111111000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0011111111111000, - 0b0011111111111000, - 0b0011111111111000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0011111111111000, + 0b0011111111111000, + 0b0011111111111000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0011111111111000, + 0b0011111111111000, + 0b0011111111111000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, - 0b0000000000000000, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0000000000000000, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0000000000000000, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0000000000000000, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0111101111011110, - 0b0000000000000000, - 0b0000000000000000, + 0b0000000000000000, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0000000000000000, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0000000000000000, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0000000000000000, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0111101111011110, + 0b0000000000000000, + 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b1111000111110000, - 0b1111011111111100, - 0b1111111111111110, - 0b1111111000111110, - 0b1111110000011111, - 0b1111100000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, - 0b1111000000001111, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b1111000111110000, + 0b1111011111111100, + 0b1111111111111110, + 0b1111111000111110, + 0b1111110000011111, + 0b1111100000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, + 0b1111000000001111, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b1111001111110000, - 0b1111011111111100, - 0b1111111111111110, - 0b1111111000011111, - 0b1111110000001111, - 0b1111100000000111, - 0b1111100000000111, - 0b1111100000000111, - 0b1111110000001111, - 0b1111111000011111, - 0b1111111111111110, - 0b1111011111111100, - 0b1111001111110000, - 0b1111000000000000, - 0b1111000000000000, - 0b1111000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b1111001111110000, + 0b1111011111111100, + 0b1111111111111110, + 0b1111111000011111, + 0b1111110000001111, + 0b1111100000000111, + 0b1111100000000111, + 0b1111100000000111, + 0b1111110000001111, + 0b1111111000011111, + 0b1111111111111110, + 0b1111011111111100, + 0b1111001111110000, + 0b1111000000000000, + 0b1111000000000000, + 0b1111000000000000, }; - diff --git a/plot.c b/plot.c index a510b5b..01b1e85 100644 --- a/plot.c +++ b/plot.c @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com + * All rights reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include #include #include "ch.h" @@ -15,8 +35,8 @@ int16_t area_width = AREA_WIDTH_NORMAL; int16_t area_height = AREA_HEIGHT_NORMAL; // Cell render use spi buffer -typedef uint16_t pixel; -pixel *cell_buffer = (pixel *)spi_buffer; +typedef uint16_t pixel_t; +pixel_t *cell_buffer = (pixel_t *)spi_buffer; // Cell size // Depends from spi_buffer size, CELLWIDTH*CELLHEIGHT*sizeof(pixel) <= sizeof(spi_buffer) #define CELLWIDTH (64) @@ -51,12 +71,13 @@ static index_t trace_index[TRACES_MAX][POINTS_COUNT]; #define CELL_X(i) (int)(((i)>>16)) #define CELL_Y(i) (int)(((i)&0xFFFF)) -//#define floatToInt(v) ((int)(v)) -static int -floatToInt(float v){ - if (v < 0) return v-0.5; - if (v > 0) return v+0.5; - return 0; +//#define float2int(v) ((int)(v)) +static int +float2int(float v) +{ + if (v < 0) return v - 0.5; + if (v > 0) return v + 0.5; + return 0; } void update_grid(void) @@ -65,7 +86,7 @@ void update_grid(void) uint32_t fstart = get_sweep_frequency(ST_START); uint32_t fspan = get_sweep_frequency(ST_SPAN); uint32_t grid; - + while (gdigit > 100) { grid = 5 * gdigit; if (fspan / grid >= 4) @@ -112,8 +133,7 @@ polar_grid(int x, int y) if (d == 0) return 1; // vertical and horizontal axis - if (x == 0 || y == 0) - return 1; + if (x == 0 || y == 0) return 1; d = circle_inout(x, y, P_RADIUS / 5); if (d == 0) return 1; @@ -124,8 +144,7 @@ polar_grid(int x, int y) if (d > 0) return 0; // cross sloping lines - if (x == y || x == -y) - return 1; + if (x == y || x == -y) return 1; d = circle_inout(x, y, P_RADIUS * 3 / 5); if (d == 0) return 1; @@ -148,52 +167,42 @@ smith_grid(int x, int y) // offset to center x -= P_CENTER_X; y -= P_CENTER_Y; - + // outer circle d = circle_inout(x, y, P_RADIUS); - if (d < 0) - return 0; - if (d == 0) - return 1; - + if (d < 0) return 0; + if (d == 0) return 1; + // horizontal axis - if (y == 0) - return 1; + if (y == 0) return 1; // shift circle center to right origin x -= P_RADIUS; // Constant Reactance Circle: 2j : R/2 = P_RADIUS/2 - if (circle_inout(x, y+P_RADIUS/2, P_RADIUS/2) == 0) - return 1; - if (circle_inout(x, y-P_RADIUS/2, P_RADIUS/2) == 0) - return 1; + if (circle_inout(x, y + P_RADIUS / 2, P_RADIUS / 2) == 0) return 1; + if (circle_inout(x, y - P_RADIUS / 2, P_RADIUS / 2) == 0) return 1; // Constant Resistance Circle: 3 : R/4 = P_RADIUS/4 - d = circle_inout(x+P_RADIUS/4, y, P_RADIUS/4); + d = circle_inout(x + P_RADIUS / 4, y, P_RADIUS / 4); if (d > 0) return 0; if (d == 0) return 1; // Constant Reactance Circle: 1j : R = P_RADIUS - if (circle_inout(x, y+P_RADIUS, P_RADIUS) == 0) - return 1; - if (circle_inout(x, y-P_RADIUS, P_RADIUS) == 0) - return 1; + if (circle_inout(x, y + P_RADIUS, P_RADIUS) == 0) return 1; + if (circle_inout(x, y - P_RADIUS, P_RADIUS) == 0) return 1; // Constant Resistance Circle: 1 : R/2 - d = circle_inout(x+P_RADIUS/2, y, P_RADIUS/2); + d = circle_inout(x + P_RADIUS / 2, y, P_RADIUS / 2); if (d > 0) return 0; if (d == 0) return 1; // Constant Reactance Circle: 1/2j : R*2 - if (circle_inout(x, y+P_RADIUS*2, P_RADIUS*2) == 0) - return 1; - if (circle_inout(x, y-P_RADIUS*2, P_RADIUS*2) == 0) - return 1; + if (circle_inout(x, y + P_RADIUS * 2, P_RADIUS * 2) == 0) return 1; + if (circle_inout(x, y - P_RADIUS * 2, P_RADIUS * 2) == 0) return 1; // Constant Resistance Circle: 1/3 : R*3/4 - if (circle_inout(x+P_RADIUS*3/4, y, P_RADIUS*3/4) == 0) - return 1; + if (circle_inout(x + P_RADIUS * 3 / 4, y, P_RADIUS * 3 / 4) == 0) return 1; return 0; } @@ -206,7 +215,7 @@ smith_grid2(int x, int y, float scale) // offset to center x -= P_CENTER_X; y -= P_CENTER_Y; - + // outer circle d = circle_inout(x, y, P_RADIUS); if (d < 0) @@ -293,7 +302,7 @@ const int cirs[][4] = { { 115/2, 0, 115/2, 1 }, // Constant Resistance Circle: 0 : R { 173/2, 0, 173/2, 1 }, // Constant Resistance Circle: -1/3 : R*3/2 = 173 { 0, 0, 0, 0 } // sentinel -}; +}; static int smith_grid3(int x, int y) @@ -303,7 +312,7 @@ smith_grid3(int x, int y) // offset to center x -= P_CENTER_X; y -= P_CENTER_Y; - + // outer circle d = circle_inout(x, y, P_RADIUS); if (d < 0) @@ -354,9 +363,8 @@ rectangular_grid(int x, int y) static int rectangular_grid_x(int x) { - x-=CELLOFFSETX; - if (x < 0) - return 0; + x -= CELLOFFSETX; + if (x < 0) return 0; if (x == 0 || x == WIDTH) return 1; if ((((x + grid_offset) * 10) % grid_width) < 10) @@ -466,7 +474,8 @@ swr(const float *v) } static float -resitance(const float *v) { +resitance(const float *v) +{ float z0 = 50; float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); float zr = ((1+v[0])*(1-v[0]) - v[1]*v[1]) * d; @@ -474,7 +483,8 @@ resitance(const float *v) { } static float -reactance(const float *v) { +reactance(const float *v) +{ float z0 = 50; float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); float zi = 2*v[1] * d; @@ -485,8 +495,8 @@ static void cartesian_scale(float re, float im, int *xp, int *yp, float scale) { //float scale = 4e-3; - int x = floatToInt(re * P_RADIUS * scale); - int y = floatToInt(im * P_RADIUS * scale); + int x = float2int(re * P_RADIUS * scale); + int y = float2int(im * P_RADIUS * scale); if (x < -P_RADIUS) x = -P_RADIUS; else if (x > P_RADIUS) x = P_RADIUS; if (y < -P_RADIUS) y = -P_RADIUS; @@ -566,7 +576,7 @@ trace_into_index(int t, int i, float array[POINTS_COUNT][2]) if (v < 0) v = 0; if (v > NGRIDY) v = NGRIDY; x = (i * (WIDTH) + (sweep_points-1)/2) / (sweep_points-1) + CELLOFFSETX; - y = floatToInt(v * GRIDY); + y = float2int(v * GRIDY); set_index: return INDEX(x, y); } @@ -594,20 +604,20 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) plot_printf(buf, len, "%.1fdB %.1f" S_DEGREE, v, phase(coeff)); } break; + case MS_REIM: plot_printf(buf, len, "%F%+Fj", coeff[0], coeff[1]); - break; + break; case MS_RX: plot_printf(buf, len, "%F"S_OHM"%+Fj", zr, zi); break; case MS_RLC: - if (zi < 0){// Capacity + if (zi < 0) {// Capacity prefix = 'F'; value = -1 / (2 * VNA_PI * frequency * zi); - } - else { + } else { prefix = 'H'; value = zi / (2 * VNA_PI * frequency); } @@ -698,8 +708,7 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT case TRC_SWR: format = S_DELTA"%.3f"; v = swr(coeff); - if (v!=INFINITY) - v-=swr(coeff_ref); + if (v != INFINITY) v -= swr(coeff_ref); break; case TRC_SMITH: format_smith_value(buf, len, coeff, frequencies[index]); @@ -753,20 +762,23 @@ trace_get_info(int t, char *buf, int len) return 0; } -static float time_of_index(int idx) { - return 1.0 / (float)(frequencies[1] - frequencies[0]) / (float)FFT_SIZE * idx; +static float time_of_index(int idx) +{ + return 1.0 / (float)(frequencies[1] - frequencies[0]) / (float)FFT_SIZE * idx; } -static float distance_of_index(int idx) { - float distance = ((float)idx * (float)SPEED_OF_LIGHT) / ( (float)(frequencies[1] - frequencies[0]) * (float)FFT_SIZE * 2.0); - return distance * velocity_factor; +static float distance_of_index(int idx) +{ + float distance = ((float)idx * (float)SPEED_OF_LIGHT) / + ((float)(frequencies[1] - frequencies[0]) * (float)FFT_SIZE * 2.0); + return distance * velocity_factor; } static inline void mark_map(int x, int y) { if (y >= 0 && y < MAX_MARKMAP_Y && x >= 0 && x < MAX_MARKMAP_X) - markmap[current_mappage][y] |= 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(j=x0; j<=x1; j++) - map[y0]|= 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 (j = x0; j <= x1; j++) + map[y0] |= 1 << j; } } } @@ -832,7 +845,7 @@ static inline void markmap_upperarea(void) { // Hardcoded, Text info from upper area - invalidateRect(0, 0, AREA_WIDTH_NORMAL, 31); + invalidate_rect(0, 0, AREA_WIDTH_NORMAL, 31); } // @@ -841,20 +854,20 @@ markmap_upperarea(void) static inline void cell_drawline(int x0, int y0, int x1, int y1, int c) { - if (x0<0 && x1<0) return; - if (y0<0 && y1<0) return; - if (x0>=CELLWIDTH && x1>=CELLWIDTH )return; - if (y0>=CELLHEIGHT && y1>=CELLHEIGHT)return; + if (x0 < 0 && x1 < 0) return; + if (y0 < 0 && y1 < 0) return; + if (x0 >= CELLWIDTH && x1 >= CELLWIDTH) return; + if (y0 >= CELLHEIGHT && y1 >= CELLHEIGHT) return; // modifed Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm - if (x1 < x0) {SWAP(x0,x1);SWAP(y0,y1);} + if (x1 < x0) { SWAP(x0, x1); SWAP(y0, y1); } int dx = x1 - x0; - int dy = y1 - y0, sy = 1; if (dy < 0) {dy = -dy; sy = -1;} + int dy = y1 - y0, sy = 1; if (dy < 0) { dy = -dy; sy = -1; } int err = (dx > dy ? dx : -dy) / 2; - while (1){ - if (y0>=0 && y0=0 && x0= 0 && y0 < CELLHEIGHT && x0 >= 0 && x0 < CELLWIDTH) + cell_buffer[y0 * CELLWIDTH + x0] |= c; if (x0 == x1 && y0 == y1) return; int e2 = err; @@ -877,12 +890,12 @@ search_index_range_x(int x1, int x2, index_t index[POINTS_COUNT], int *i0, int * while (1) { i = (head + tail) / 2; idx_x = CELL_X(index[i]); - if (idx_x >= x2){ // index after cell + if (idx_x >= x2) { // index after cell if (tail == i) return false; tail = i; } - else if (idx_x < x1){ // index before cell + else if (idx_x < x1) { // index before cell if (head == i) return false; head = i; @@ -892,14 +905,14 @@ search_index_range_x(int x1, int x2, index_t index[POINTS_COUNT], int *i0, int * } j = i; // Search index left from point - do{ + do { j--; - }while (j > 0 && x1 <= CELL_X(index[j])); + } while (j > 0 && x1 <= CELL_X(index[j])); *i0 = j; // Search index right from point - do{ + do { i++; - }while (i < sweep_points-1 && CELL_X(index[i]) < x2); + } while (i < sweep_points-1 && CELL_X(index[i]) < x2); *i1 = i; return TRUE; @@ -922,17 +935,16 @@ static const uint8_t reference_bitmap[]={ static void draw_refpos(int x, int y, int c) { - int y0=y, j; - for (j=0; j= CELLHEIGHT) - continue; - int x0=x; + int y0 = y, j; + for (j = 0; j < REFERENCE_HEIGHT; j++, y0++) { + if (y0 < 0 || y0 >= CELLHEIGHT) continue; + int x0 = x; uint8_t bits = reference_bitmap[j]; - while (bits){ + while (bits) { if (x0 >= 0 && x0 < CELLWIDTH) - cell_buffer[y0*CELLWIDTH+x0] = (bits&0x80) ? c : DEFAULT_BG_COLOR; + cell_buffer[y0 * CELLWIDTH + x0] = (bits & 0x80) ? c : DEFAULT_BG_COLOR; x0++; - bits<<=1; + bits <<= 1; } } } @@ -991,22 +1003,21 @@ static const uint8_t marker_bitmap[]={ static void draw_marker(int x, int y, int c, int ch) { - int y0=y, j; - for (j=0;j= 0 && x0 < CELLWIDTH && y0 >= 0 && y0 < CELLHEIGHT){ - if (bits&0x80) - cell_buffer[y0*CELLWIDTH+x0] = c; + while (bits) { + if (bits & 0x80) force_color = true; + if (x0 >= 0 && x0 < CELLWIDTH && y0 >= 0 && y0 < CELLHEIGHT) { + if (bits & 0x80) + cell_buffer[y0 * CELLWIDTH + x0] = c; else if (force_color) - cell_buffer[y0*CELLWIDTH+x0] = DEFAULT_BG_COLOR; + cell_buffer[y0 * CELLWIDTH + x0] = DEFAULT_BG_COLOR; } x0++; - bits<<=1; + bits <<= 1; } } } @@ -1023,7 +1034,7 @@ markmap_marker(int marker) index_t index = trace_index[t][markers[marker].index]; int x = CELL_X(index) - X_MARKER_OFFSET; int y = CELL_Y(index) - Y_MARKER_OFFSET; - invalidateRect(x, y, x+MARKER_WIDTH-1, y+MARKER_HEIGHT-1); + invalidate_rect(x, y, x+MARKER_WIDTH-1, y+MARKER_HEIGHT-1); } } @@ -1211,14 +1222,14 @@ 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 / (16/sizeof(pixel)); + int count = h*CELLWIDTH / (16/sizeof(pixel_t)); 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); - p[2] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); - p[3] = DEFAULT_BG_COLOR|(DEFAULT_BG_COLOR<<16); - p+=4; + p[0] = DEFAULT_BG_COLOR | (DEFAULT_BG_COLOR << 16); + p[1] = DEFAULT_BG_COLOR | (DEFAULT_BG_COLOR << 16); + p[2] = DEFAULT_BG_COLOR | (DEFAULT_BG_COLOR << 16); + p[3] = DEFAULT_BG_COLOR | (DEFAULT_BG_COLOR << 16); + p += 4; } #endif @@ -1227,41 +1238,40 @@ draw_cell(int m, int n) c = config.grid_color; // Generate grid type list uint32_t trace_type = 0; - for (t = 0; t < TRACES_MAX; t++) - if (trace[t].enabled) - trace_type|=(1<= CELLOFFSETX && x+x0 <= WIDTH+CELLOFFSETX) + if (x + x0 >= CELLOFFSETX && x + x0 <= WIDTH + CELLOFFSETX) cell_buffer[y * CELLWIDTH + x] = c; } } } // Smith greed line (1000 system ticks for all screen calls) - if(trace_type&(1<=0 && x-MARKER_WIDTH=0 && y-MARKER_HEIGHT= 0 && x - MARKER_WIDTH < CELLWIDTH && + y + MARKER_HEIGHT >= 0 && y - MARKER_HEIGHT < CELLHEIGHT) draw_marker(x, y, config.trace_color[t], i); } } @@ -1325,24 +1340,24 @@ draw_cell(int m, int n) for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) continue; - uint32_t trace_type = (1<=0 && x-REFERENCE_WIDTH=0 && y-REFERENCE_HEIGHT= 0 && x - REFERENCE_WIDTH < CELLWIDTH) { + int y = HEIGHT - float2int((get_trace_refpos(t) * GRIDY)) - y0 - REFERENCE_Y_OFFSET; + if (y + REFERENCE_HEIGHT >= 0 && y - REFERENCE_HEIGHT < CELLHEIGHT) draw_refpos(x, y, config.trace_color[t]); } } // Need right clip cell render (25 system ticks for all screen calls) #if 1 - if (w < CELLWIDTH){ - pixel *src = cell_buffer+CELLWIDTH; - pixel *dst = cell_buffer+w; - for (y=h; --y; src+=CELLWIDTH-w) - for(x=w;x--;) - *dst++=*src++; + if (w < CELLWIDTH) { + pixel_t *src = cell_buffer + CELLWIDTH; + pixel_t *dst = cell_buffer + w; + for (y = h; --y; src += CELLWIDTH - w) + for (x = w; x--;) + *dst++ = *src++; } #endif // Draw cell (500 system ticks for all screen calls) @@ -1350,12 +1365,13 @@ draw_cell(int m, int n) } static void -draw_all_cells(bool flush_markmap){ +draw_all_cells(bool flush_markmap) +{ int m, n; // 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<= CELLHEIGHT || x <= -ch_size || x >= CELLWIDTH) -// return ch_size; + ch_size = FONT_GET_WIDTH(ch); + // if (y <= -FONT_GET_HEIGHT || y >= CELLHEIGHT || x <= -ch_size || x >= CELLWIDTH) + // return ch_size; if (x <= -ch_size) return ch_size; - for(c = 0; c < FONT_GET_HEIGHT; c++) { + for (c = 0; c < FONT_GET_HEIGHT; c++) { bits = *char_buf++; if ((y + c) < 0 || (y + c) >= CELLHEIGHT) continue; @@ -1478,7 +1494,7 @@ cell_draw_marker_info(int x0, int y0) int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; - setForegroundColor(config.trace_color[t]); + ili9341_set_foreground(config.trace_color[t]); if (mk == active_marker) cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; @@ -1500,7 +1516,7 @@ cell_draw_marker_info(int x0, int y0) trace_get_value_string_delta(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index, markers[active_marker].index); else trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], markers[mk].index); - setForegroundColor(DEFAULT_FG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); cell_drawstring(buf, xpos, ypos); j++; } @@ -1512,7 +1528,7 @@ cell_draw_marker_info(int x0, int y0) int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; plot_printf(buf, sizeof buf, S_DELTA"%d-%d:", active_marker+1, previous_marker+1); - setForegroundColor(DEFAULT_FG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); cell_drawstring(buf, xpos, ypos); xpos += 27; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { @@ -1532,7 +1548,7 @@ cell_draw_marker_info(int x0, int y0) int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; - setForegroundColor(config.trace_color[t]); + ili9341_set_foreground(config.trace_color[t]); if (t == uistat.current_trace) cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; @@ -1545,7 +1561,7 @@ cell_draw_marker_info(int x0, int y0) xpos += n * 5 + 2; //xpos += 60; trace_get_value_string(t, buf, sizeof buf, measured[trace[t].channel], idx); - setForegroundColor(DEFAULT_FG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); cell_drawstring(buf, xpos, ypos); j++; } @@ -1554,7 +1570,7 @@ cell_draw_marker_info(int x0, int y0) int xpos = (WIDTH/2+40) + CELLOFFSETX - x0; int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; - setForegroundColor(DEFAULT_FG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); if (uistat.lever_mode == LM_MARKER) cell_drawstring(S_SARROW, xpos, ypos); xpos += 5; @@ -1569,7 +1585,7 @@ cell_draw_marker_info(int x0, int y0) } cell_drawstring(buf, xpos, ypos); } - setForegroundColor(DEFAULT_FG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); if (electrical_delay != 0) { // draw electrical delay int xpos = 21 + CELLOFFSETX - x0; @@ -1590,9 +1606,9 @@ void draw_frequencies(void) { char buf1[32]; - char buf2[32];buf2[0]=0; + char buf2[32]; buf2[0] = 0; if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { - if (FREQ_IS_CW()){ + 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)); @@ -1605,8 +1621,8 @@ draw_frequencies(void) plot_printf(buf1, sizeof(buf1), " START 0s"); 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); + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); ili9341_fill(0, FREQUENCIES_YPOS, 320, FONT_GET_HEIGHT, DEFAULT_BG_COLOR); if (uistat.lever_mode == LM_CENTER) buf1[0] = S_SARROW[0]; @@ -1622,8 +1638,8 @@ draw_cal_status(void) int x = 0; int y = 100; char c[3]; - setForegroundColor(DEFAULT_FG_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); ili9341_fill(0, y, OFFSETX, 6*(FONT_GET_HEIGHT+1), DEFAULT_BG_COLOR); if (cal_status & CALSTAT_APPLY) { c[0] = cal_status & CALSTAT_INTERPOLATED ? 'c' : 'C'; @@ -1657,13 +1673,13 @@ static void draw_battery_status(void) return; uint8_t string_buf[16]; // Set battery color - setForegroundColor(vbat < BATTERY_WARNING_LEVEL ? DEFAULT_LOW_BAT_COLOR : DEFAULT_NORMAL_BAT_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); + ili9341_set_foreground(vbat < BATTERY_WARNING_LEVEL ? DEFAULT_LOW_BAT_COLOR : DEFAULT_NORMAL_BAT_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); // plot_printf(string_buf, sizeof string_buf, "V:%d", vbat); // ili9341_drawstringV(string_buf, 1, 60); // Prepare battery bitmap image // Battery top - int x=0; + int x = 0; string_buf[x++] = 0b00111100; string_buf[x++] = 0b00100100; string_buf[x++] = 0b11111111; @@ -1689,8 +1705,8 @@ request_to_redraw_grid(void) void redraw_frame(void) { - setBackgroundColor(DEFAULT_BG_COLOR); - clearScreen(); + ili9341_set_background(DEFAULT_BG_COLOR); + ili9341_clear_screen(); draw_frequencies(); draw_cal_status(); } diff --git a/si5351.c b/si5351.c index aee7ba8..8f7c9c5 100644 --- a/si5351.c +++ b/si5351.c @@ -34,7 +34,7 @@ #define PLL_N 32 // I2C address on bus (only 0x60 for Si5351A in 10-Pin MSOP) -#define SI5351_I2C_ADDR 0x60 +#define SI5351_I2C_ADDR 0x60 static uint8_t current_band = 0; static uint32_t current_freq = 0; @@ -51,9 +51,13 @@ static int32_t current_offset = FREQUENCY_OFFSET; // 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;} +uint32_t si5351_get_frequency(void) +{ + return current_freq; +} -void si5351_set_frequency_offset(int32_t offset) { +void si5351_set_frequency_offset(int32_t offset) +{ current_offset = offset; current_freq = 0; // reset freq, for } @@ -178,34 +182,34 @@ static void si5351_setupPLL(uint8_t pllSource, /* SI5351_REG_PLL_A or SI5351_ /* Feedback Multisynth Divider Equation * where: a = mult, b = num and c = denom * P1 register is an 18-bit value using following formula: - * P1[17:0] = 128 * mult + int((128*num)/denom) - 512 + * P1[17:0] = 128 * mult + int((128*num)/denom) - 512 * P2 register is a 20-bit value using the following formula: - * P2[19:0] = (128 * num) % denom + * P2[19:0] = (128 * num) % denom * P3 register is a 20-bit value using the following formula: - * P3[19:0] = denom + * P3[19:0] = denom */ /* Set the main PLL config registers */ - mult<<=7; - num<<=7; - uint32_t P1 = mult - 512; // Integer mode + mult <<= 7; + num <<= 7; + uint32_t P1 = mult - 512; // Integer mode uint32_t P2 = 0; uint32_t P3 = 1; - if (num){ // Fractional mode + if (num) { // Fractional mode P1+= num / denom; P2 = num % denom; P3 = denom; } // Pll MSN(A|B) registers Datasheet uint8_t reg[9]; - reg[0]= pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B - reg[1]=( P3 & 0x0FF00)>> 8; // MSN_P3[15: 8] - reg[2]=( P3 & 0x000FF); // MSN_P3[ 7: 0] - reg[3]=( P1 & 0x30000)>>16; // MSN_P1[17:16] - reg[4]=( P1 & 0x0FF00)>> 8; // MSN_P1[15: 8] - reg[5]=( P1 & 0x000FF); // MSN_P1[ 7: 0] - reg[6]=((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSN_P3[19:16] | MSN_P2[19:16] - reg[7]=( P2 & 0x0FF00)>> 8; // MSN_P2[15: 8] - reg[8]=( P2 & 0x000FF); // MSN_P2[ 7: 0] + reg[0] = pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B + reg[1] = (P3 & 0x0FF00) >> 8; // MSN_P3[15: 8] + reg[2] = (P3 & 0x000FF); // MSN_P3[ 7: 0] + reg[3] = (P1 & 0x30000) >> 16; // MSN_P1[17:16] + reg[4] = (P1 & 0x0FF00) >> 8; // MSN_P1[15: 8] + reg[5] = (P1 & 0x000FF); // MSN_P1[ 7: 0] + reg[6] = ((P3 & 0xF0000) >> 12) | ((P2 & 0xF0000) >> 16); // MSN_P3[19:16] | MSN_P2[19:16] + reg[7] = (P2 & 0x0FF00) >> 8; // MSN_P2[15: 8] + reg[8] = (P2 & 0x000FF); // MSN_P2[ 7: 0] si5351_bulk_write(reg, 9); } @@ -237,7 +241,7 @@ si5351_setupMultisynth(uint8_t channel, num<<=7; div<<=7; P1 = div - 512; // Integer mode - if (num){ // Fractional mode + if (num) { // Fractional mode P1+= num / denom; P2 = num % denom; P3 = denom; @@ -245,15 +249,15 @@ si5351_setupMultisynth(uint8_t channel, } /* Set the MSx config registers */ uint8_t reg[9]; - reg[0]= msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2 - reg[1]=( P3 & 0x0FF00)>>8; // MSx_P3[15: 8] - reg[2]=( P3 & 0x000FF); // MSx_P3[ 7: 0] - reg[3]=((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16] - reg[4]=( P1 & 0x0FF00)>> 8; // MSx_P1[15: 8] - reg[5]=( P1 & 0x000FF); // MSx_P1[ 7: 0] - reg[6]=((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16] - reg[7]=( P2 & 0x0FF00)>>8; // MSx_P2[15: 8] - reg[8]=( P2 & 0x000FF); // MSx_P2[ 7: 0] + reg[0] = msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2 + reg[1] = (P3 & 0x0FF00)>>8; // MSx_P3[15: 8] + reg[2] = (P3 & 0x000FF); // MSx_P3[ 7: 0] + reg[3] = ((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16] + reg[4] = (P1 & 0x0FF00)>> 8; // MSx_P1[15: 8] + reg[5] = (P1 & 0x000FF); // MSx_P1[ 7: 0] + reg[6] = ((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16] + reg[7] = (P2 & 0x0FF00)>>8; // MSx_P2[15: 8] + reg[8] = (P2 & 0x000FF); // MSx_P2[ 7: 0] si5351_bulk_write(reg, 9); /* Configure the clk control and enable the output */ @@ -264,7 +268,7 @@ si5351_setupMultisynth(uint8_t channel, #if USE_CLK_CONTROL_CACHE == TRUE // Use cache for this reg, not update if not change static uint8_t clk_cache[3]; - if (clk_cache[channel]!=dat){ + if (clk_cache[channel]!=dat) { si5351_write(clkctrl[channel], dat); clk_cache[channel]=dat; } @@ -275,7 +279,8 @@ si5351_setupMultisynth(uint8_t channel, // Find better approximate values for n/d #define MAX_DENOMINATOR ((1 << 20) - 1) -static inline void fractionalSolve(uint32_t *n, uint32_t *d){ +static inline void approximate_fraction(uint32_t *n, uint32_t *d) +{ // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 uint32_t denom = *d; if (denom > MAX_DENOMINATOR) { @@ -303,18 +308,19 @@ si5351_set_frequency_fixedpll(uint8_t channel, uint64_t pllfreq, uint32_t freq, uint32_t denom = freq; uint32_t div = pllfreq / denom; // range: 8 ~ 1800 uint32_t num = pllfreq % denom; - fractionalSolve(&num, &denom); + approximate_fraction(&num, &denom); si5351_setupMultisynth(channel, div, num, denom, rdiv, chctrl); } // Setup PLL freq if Multisynth divider fixed = div (need get output = freq/mul) static void -si5351_setupPLL_freq(uint32_t pllSource, uint32_t freq, uint32_t div, uint32_t mul){ +si5351_setupPLL_freq(uint32_t pllSource, uint32_t freq, uint32_t div, uint32_t mul) +{ uint32_t denom = XTALFREQ * mul; uint64_t pllfreq = (uint64_t)freq * div; uint32_t multi = pllfreq / denom; uint32_t num = pllfreq % denom; - fractionalSolve(&num, &denom); + approximate_fraction(&num, &denom); si5351_setupPLL(pllSource, multi, num, denom); } @@ -328,7 +334,8 @@ si5351_set_frequency_fixeddiv(uint8_t channel, uint32_t pll, uint32_t freq, uint } void -si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength){ +si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength) +{ if (freq <= 100000000) { si5351_setupPLL(SI5351_PLL_B, 32, 0, 1); si5351_set_frequency_fixedpll(channel, SI5351_PLL_B, PLLFREQ, freq, SI5351_R_DIV_1, drive_strength, 1); @@ -361,7 +368,9 @@ si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength){ * | of = 50kHz-300MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 | * +-----------------------------------------------------------------------------------------------------------------------+ */ -static inline uint8_t si5351_getBand(uint32_t freq){ +static inline uint8_t +si5351_get_band(uint32_t freq) +{ if (freq < 100000000U) return 1; if (freq < 150000000U) return 2; return 3; @@ -375,7 +384,8 @@ static inline uint8_t si5351_getBand(uint32_t freq){ * CLK2: fixed 8MHz */ int -si5351_set_frequency_with_offset(uint32_t freq, uint8_t drive_strength){ +si5351_set_frequency(uint32_t freq, uint8_t drive_strength) +{ uint8_t band; int delay = DELAY_NORMAL; if (freq == current_freq) @@ -402,8 +412,7 @@ si5351_set_frequency_with_offset(uint32_t freq, uint8_t drive_strength){ } else if (freq >= config.harmonic_freq_threshold) { mul = 3; omul = 5; - } - else if (freq <= 500000U) { + } else if (freq <= 500000U) { rdiv = SI5351_R_DIV_64; freq<<= 6; ofreq<<= 6; @@ -412,38 +421,49 @@ si5351_set_frequency_with_offset(uint32_t freq, uint8_t drive_strength){ freq<<= 3; ofreq<<= 3; } - band = si5351_getBand(freq/mul); + band = si5351_get_band(freq / mul); switch (band) { - case 1: - // Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq = CLK2_FREQUENCY - 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; - } - 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); - break; - case 2:// fdiv = 6 - case 3:// fdiv = 4; - fdiv = (band == 2) ? 6 : 4; - // Setup CH0 and CH1 constant fdiv divider at change - 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; - } - 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 - // Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv - 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; + case 1: + // Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq = + // CLK2_FREQUENCY + 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; + } 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); + break; + case 2: // fdiv = 6 + case 3: // fdiv = 4; + fdiv = (band == 2) ? 6 : 4; + // Setup CH0 and CH1 constant fdiv divider at change + 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; + } 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 + // Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv + 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); diff --git a/si5351.h b/si5351.h index 42a7d99..315ce3c 100644 --- a/si5351.h +++ b/si5351.h @@ -24,56 +24,54 @@ #define SI5351_CLK2_EN (1<<2) // Reg 16-18 CLKX_CONTROL -#define SI5351_REG_16_CLK0_CONTROL 16 -#define SI5351_REG_17_CLK1_CONTROL 17 -#define SI5351_REG_18_CLK2_CONTROL 18 -#define SI5351_CLK_POWERDOWN (1<<7) -#define SI5351_CLK_INTEGER_MODE (1<<6) -#define SI5351_CLK_PLL_SELECT_A (0<<5) -#define SI5351_CLK_PLL_SELECT_B (1<<5) -#define SI5351_CLK_INVERT (1<<4) -#define SI5351_CLK_INPUT_MASK (3<<2) -#define SI5351_CLK_INPUT_XTAL (0<<2) -#define SI5351_CLK_INPUT_CLKIN (1<<2) -#define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) -#define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) -#define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) -#define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) -#define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) -#define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) -#define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) +#define SI5351_REG_16_CLK0_CONTROL 16 +#define SI5351_REG_17_CLK1_CONTROL 17 +#define SI5351_REG_18_CLK2_CONTROL 18 +#define SI5351_CLK_POWERDOWN (1<<7) +#define SI5351_CLK_INTEGER_MODE (1<<6) +#define SI5351_CLK_PLL_SELECT_A (0<<5) +#define SI5351_CLK_PLL_SELECT_B (1<<5) +#define SI5351_CLK_INVERT (1<<4) +#define SI5351_CLK_INPUT_MASK (3<<2) +#define SI5351_CLK_INPUT_XTAL (0<<2) +#define SI5351_CLK_INPUT_CLKIN (1<<2) +#define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) +#define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) +#define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) +#define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) +#define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) +#define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) +#define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) -#define SI5351_REG_PLL_A 26 -#define SI5351_REG_PLL_B 34 +#define SI5351_REG_PLL_A 26 +#define SI5351_REG_PLL_B 34 -#define SI5351_REG_42_MULTISYNTH0 42 -#define SI5351_REG_50_MULTISYNTH1 50 -#define SI5351_REG_58_MULTISYNTH2 58 -#define SI5351_DIVBY4 (3<<2) -#define SI5351_R_DIV_1 (0<<4) -#define SI5351_R_DIV_2 (1<<4) -#define SI5351_R_DIV_4 (2<<4) -#define SI5351_R_DIV_8 (3<<4) -#define SI5351_R_DIV_16 (4<<4) -#define SI5351_R_DIV_32 (5<<4) -#define SI5351_R_DIV_64 (6<<4) -#define SI5351_R_DIV_128 (7<<4) +#define SI5351_REG_42_MULTISYNTH0 42 +#define SI5351_REG_50_MULTISYNTH1 50 +#define SI5351_REG_58_MULTISYNTH2 58 +#define SI5351_DIVBY4 (3<<2) +#define SI5351_R_DIV_1 (0<<4) +#define SI5351_R_DIV_2 (1<<4) +#define SI5351_R_DIV_4 (2<<4) +#define SI5351_R_DIV_8 (3<<4) +#define SI5351_R_DIV_16 (4<<4) +#define SI5351_R_DIV_32 (5<<4) +#define SI5351_R_DIV_64 (6<<4) +#define SI5351_R_DIV_128 (7<<4) -#define SI5351_REG_177_PLL_RESET 177 -#define SI5351_PLL_RESET_B (1<<7) -#define SI5351_PLL_RESET_A (1<<5) +#define SI5351_REG_177_PLL_RESET 177 +#define SI5351_PLL_RESET_B (1<<7) +#define SI5351_PLL_RESET_A (1<<5) #define SI5351_REG_183_CRYSTAL_LOAD 183 -#define SI5351_CRYSTAL_LOAD_6PF (1<<6) -#define SI5351_CRYSTAL_LOAD_8PF (2<<6) -#define SI5351_CRYSTAL_LOAD_10PF (3<<6) +#define SI5351_CRYSTAL_LOAD_6PF (1<<6) +#define SI5351_CRYSTAL_LOAD_8PF (2<<6) +#define SI5351_CRYSTAL_LOAD_10PF (3<<6) 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); 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); - +int si5351_set_frequency(uint32_t freq, uint8_t drive_strength); +uint32_t si5351_get_frequency(void); diff --git a/tlv320aic3204.c b/tlv320aic3204.c index c1b57b5..21fbe84 100644 --- a/tlv320aic3204.c +++ b/tlv320aic3204.c @@ -116,7 +116,7 @@ static void tlv320aic3204_config(const uint8_t *data, int len) { i2cAcquireBus(&I2CD1); - for (;len--;data+=2) + for (; len--; data += 2) tlv320aic3204_bulk_write(data, 2); i2cReleaseBus(&I2CD1); } diff --git a/ui.c b/ui.c index ae25126..391af98 100644 --- a/ui.c +++ b/ui.c @@ -33,23 +33,23 @@ uistat_t uistat = { marker_tracking : FALSE, }; -#define NO_EVENT 0 -#define EVT_BUTTON_SINGLE_CLICK 0x01 -#define EVT_BUTTON_DOUBLE_CLICK 0x02 -#define EVT_BUTTON_DOWN_LONG 0x04 -#define EVT_UP 0x10 -#define EVT_DOWN 0x20 -#define EVT_REPEAT 0x40 - -#define BUTTON_DOWN_LONG_TICKS 5000 /* 1sec */ -#define BUTTON_DOUBLE_TICKS 2500 /* 500ms */ -#define BUTTON_REPEAT_TICKS 625 /* 125ms */ -#define BUTTON_DEBOUNCE_TICKS 200 +#define NO_EVENT 0 +#define EVT_BUTTON_SINGLE_CLICK 0x01 +#define EVT_BUTTON_DOUBLE_CLICK 0x02 +#define EVT_BUTTON_DOWN_LONG 0x04 +#define EVT_UP 0x10 +#define EVT_DOWN 0x20 +#define EVT_REPEAT 0x40 + +#define BUTTON_DOWN_LONG_TICKS 5000 /* 1sec */ +#define BUTTON_DOUBLE_TICKS 2500 /* 500ms */ +#define BUTTON_REPEAT_TICKS 625 /* 125ms */ +#define BUTTON_DEBOUNCE_TICKS 200 /* lever switch assignment */ -#define BIT_UP1 3 -#define BIT_PUSH 2 -#define BIT_DOWN1 1 +#define BIT_UP1 3 +#define BIT_PUSH 2 +#define BIT_DOWN1 1 #define READ_PORT() palReadPort(GPIOA) #define BUTTON_MASK 0b1111 @@ -288,24 +288,28 @@ touch_check(void) } static inline void -touch_wait_release(void) { - while(touch_check()!=EVT_TOUCH_RELEASED); +touch_wait_release(void) +{ + while (touch_check() != EVT_TOUCH_RELEASED) + ; } static inline void -touch_wait_pressed(void) { - while(touch_check()!=EVT_TOUCH_PRESSED); +touch_wait_pressed(void) +{ + while (touch_check() != EVT_TOUCH_PRESSED) + ; } void touch_cal_exec(void) { int x1, x2, y1, y2; - + adc_stop(); - setForegroundColor(DEFAULT_FG_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); - clearScreen(); + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); + ili9341_clear_screen(); ili9341_line(0, 0, 0, 32); ili9341_line(0, 0, 32, 0); ili9341_drawstring("TOUCH UPPER LEFT", 10, 10); @@ -314,7 +318,7 @@ touch_cal_exec(void) x1 = last_touch_x; y1 = last_touch_y; - clearScreen(); + ili9341_clear_screen(); ili9341_line(320-1, 240-1, 320-1, 240-32); ili9341_line(320-1, 240-1, 320-32, 240-1); ili9341_drawstring("TOUCH LOWER RIGHT", 230, 220); @@ -340,9 +344,9 @@ touch_draw_test(void) adc_stop(); - setForegroundColor(DEFAULT_FG_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); - clearScreen(); + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); + ili9341_clear_screen(); ili9341_drawstring("TOUCH TEST: DRAG PANEL", OFFSETX, 233); touch_wait_pressed(); @@ -354,7 +358,7 @@ touch_draw_test(void) x0 = x1; y0 = y1; chThdSleepMilliseconds(50); - } while(touch_check()!=EVT_TOUCH_RELEASED); + } while (touch_check() != EVT_TOUCH_RELEASED); touch_start_watchdog(); } @@ -372,13 +376,13 @@ show_version(void) { int x = 5, y = 5, i = 0; adc_stop(); - setForegroundColor(DEFAULT_FG_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); - clearScreen(); + ili9341_clear_screen(); uint16_t shift = 0b0000010000111110; ili9341_drawstring_size(info_about[i++], x , y, 4); - while (info_about[i]){ + while (info_about[i]) { do {shift>>=1; y+=5;} while (shift&1); ili9341_drawstring(info_about[i++], x, y+=5); } @@ -398,10 +402,10 @@ enter_dfu(void) adc_stop(); int x = 5, y = 5; - setForegroundColor(DEFAULT_FG_COLOR); - setBackgroundColor(DEFAULT_BG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_set_background(DEFAULT_BG_COLOR); // leave a last message - clearScreen(); + ili9341_clear_screen(); ili9341_drawstring("DFU: Device Firmware Update Mode", x, y += 10); ili9341_drawstring("To exit DFU mode, please reset device yourself.", x, y += 10); @@ -606,7 +610,8 @@ menu_transform_cb(int item, uint8_t data) } static void -menu_velocity_cb(int item, uint8_t data){ +menu_velocity_cb(int item, uint8_t data) +{ (void)item; (void)data; if (btn_wait_release() & EVT_BUTTON_DOWN_LONG) { @@ -1233,16 +1238,18 @@ static void draw_keypad(void) { int i = 0; - while (keypads[i].c>=0) { + while (keypads[i].c >= 0) { uint16_t bg = config.menu_normal_color; if (i == selection) bg = config.menu_active_color; - setForegroundColor(DEFAULT_MENU_TEXT_COLOR); - setBackgroundColor(bg); + ili9341_set_foreground(DEFAULT_MENU_TEXT_COLOR); + ili9341_set_background(bg); int x = KP_GET_X(keypads[i].x); int y = KP_GET_Y(keypads[i].y); ili9341_fill(x+2, y+2, KP_WIDTH-4, KP_HEIGHT-4, bg); - ili9341_drawfont(keypads[i].c, x+(KP_WIDTH-NUM_FONT_GET_WIDTH)/2, y+(KP_HEIGHT-NUM_FONT_GET_HEIGHT)/2); + ili9341_drawfont(keypads[i].c, + x + (KP_WIDTH - NUM_FONT_GET_WIDTH) / 2, + y + (KP_HEIGHT - NUM_FONT_GET_HEIGHT) / 2); i++; } } @@ -1251,8 +1258,8 @@ static void draw_numeric_area_frame(void) { ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, config.menu_normal_color); - setForegroundColor(DEFAULT_MENU_TEXT_COLOR); - setBackgroundColor(config.menu_normal_color); + ili9341_set_foreground(DEFAULT_MENU_TEXT_COLOR); + ili9341_set_background(config.menu_normal_color); ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); //ili9341_drawfont(KP_KEYPAD, 300, 216); } @@ -1282,15 +1289,15 @@ draw_numeric_input(const char *buf) // if (uistat.digit_mode) // bg = DEFAULT_MENU_COLOR; } - setForegroundColor(fg); - setBackgroundColor(bg); + ili9341_set_foreground(fg); + ili9341_set_background(bg); if (c >= 0) // c is number ili9341_drawfont(c, x, 240-NUM_INPUT_HEIGHT+4); else if (focused) // c not number, but focused ili9341_drawfont(0, x, 240-NUM_INPUT_HEIGHT+4); else // erase ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_HEIGHT, NUM_FONT_GET_WIDTH+2+8, bg); - + x += xsim&0x8000 ? NUM_FONT_GET_WIDTH+2+8 : NUM_FONT_GET_WIDTH+2; } // erase last @@ -1397,8 +1404,8 @@ draw_menu_buttons(const menuitem_t *menu) ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); menu_item_modify_attribute(menu, i, &fg, &bg); - setForegroundColor(fg); - setBackgroundColor(bg); + ili9341_set_foreground(fg); + ili9341_set_background(bg); if (menu_is_multiline(menu[i].label, &l1, &l2)) { ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+5, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); ili9341_drawstring(l1, 320-MENU_BUTTON_WIDTH+5, y+7); @@ -1431,7 +1438,7 @@ menu_apply_touch(void) for (i = 0; i < 7; i++) { if (menu[i].type == MT_NONE) break; - if (menu[i].type == MT_BLANK) + if (menu[i].type == MT_BLANK) continue; int y = MENU_BUTTON_HEIGHT*i; if (y < touch_y && touch_y < y+MENU_BUTTON_HEIGHT && 320-MENU_BUTTON_WIDTH < touch_x) { @@ -1510,7 +1517,7 @@ fetch_numeric_target(void) uistat.value = get_trace_scale(uistat.current_trace) * 1e12; break; } - + { uint32_t x = uistat.value; int n = 0; @@ -1566,7 +1573,7 @@ draw_numeric_area(void) static void ui_mode_menu(void) { - if (ui_mode == UI_MENU) + if (ui_mode == UI_MENU) return; ui_mode = UI_MENU; @@ -1580,11 +1587,11 @@ ui_mode_menu(void) static void ui_mode_numeric(int _keypad_mode) { - if (ui_mode == UI_NUMERIC) + if (ui_mode == UI_NUMERIC) return; leave_ui_mode(); - + // keypads array keypad_mode = _keypad_mode; ui_mode = UI_NUMERIC; @@ -1599,7 +1606,7 @@ ui_mode_numeric(int _keypad_mode) static void ui_mode_keypad(int _keypad_mode) { - if (ui_mode == UI_KEYPAD) + if (ui_mode == UI_KEYPAD) return; // keypads array @@ -1622,7 +1629,7 @@ ui_mode_keypad(int _keypad_mode) static void ui_mode_normal(void) { - if (ui_mode == UI_NORMAL) + if (ui_mode == UI_NORMAL) return; area_width = AREA_WIDTH_NORMAL; @@ -1678,13 +1685,13 @@ step_round(uint32_t v) uint32_t x = 1; for (x = 1; x*10 < v; x*= 10) ; - + // 1-2-5 step if (x * 2 > v) return x; else if (x * 5 > v) return x * 2; - else + else return x * 5; } @@ -1791,7 +1798,7 @@ menuclose: } static int -keypad_click(int key) +keypad_click(int key) { int c = keypads[key].c; if ((c >= KP_X1 && c <= KP_G) || c == KP_N || c == KP_P) { @@ -1839,9 +1846,9 @@ keypad_click(int key) } return KP_DONE; - } else if (c <= 9 && kp_index < NUMINPUT_LEN) + } else if (c <= 9 && kp_index < NUMINPUT_LEN) { kp_buf[kp_index++] = '0' + c; - else if (c == KP_PERIOD && kp_index < NUMINPUT_LEN) { + } else if (c == KP_PERIOD && kp_index < NUMINPUT_LEN) { // check period in former input int j; for (j = 0; j < kp_index && kp_buf[j] != '.'; j++) @@ -1871,7 +1878,7 @@ keypad_apply_touch(void) touch_position(&touch_x, &touch_y); - while (keypads[i].c>=0) { + while (keypads[i].c >= 0) { int x = KP_GET_X(keypads[i].x); int y = KP_GET_Y(keypads[i].y); if (x < touch_x && touch_x < x+KP_WIDTH && y < touch_y && touch_y < y+KP_HEIGHT) { @@ -1922,11 +1929,11 @@ numeric_apply_touch(void) uistat.value += step; } draw_numeric_area(); - + touch_wait_release(); uistat.digit_mode = FALSE; draw_numeric_area(); - + return; } @@ -2016,7 +2023,7 @@ ui_process_keypad(void) if (status == EVT_BUTTON_SINGLE_CLICK) { if (keypad_click(selection)) /* exit loop on done or cancel */ - break; + break; } if (touch_check() == EVT_TOUCH_PRESSED) { @@ -2040,16 +2047,16 @@ ui_process_lever(void) switch (ui_mode) { case UI_NORMAL: ui_process_normal(); - break; + break; case UI_MENU: ui_process_menu(); - break; + break; case UI_NUMERIC: ui_process_numeric(); - break; + break; case UI_KEYPAD: ui_process_keypad(); - break; + break; } } @@ -2069,7 +2076,7 @@ drag_marker(int t, int m) markers[m].frequency = frequencies[index]; redraw_marker(m); } - } while(touch_check()!=EVT_TOUCH_RELEASED); + } while (touch_check()!= EVT_TOUCH_RELEASED); } static int @@ -2091,9 +2098,9 @@ touch_pickup_marker(void) continue; marker_position(m, t, &x, &y); - x-=touch_x; - y-=touch_y; - if ((x*x+y*y) < 20*20) { + x -= touch_x; + y -= touch_y; + if ((x * x + y * y) < 20 * 20) { if (active_marker != m) { previous_marker = active_marker; active_marker = m; @@ -2102,7 +2109,7 @@ touch_pickup_marker(void) // select trace uistat.current_trace = t; select_lever_mode(LM_MARKER); - + // drag marker until release drag_marker(t, m); return TRUE; @@ -2125,8 +2132,9 @@ touch_lever_mode_select(void) if (touch_y < 25) { if (touch_x < FREQUENCIES_XPOS2 && get_electrical_delay() != 0.0) { select_lever_mode(LM_EDELAY); - } else + } else { select_lever_mode(LM_MARKER); + } return TRUE; } return FALSE; @@ -2178,7 +2186,8 @@ ui_process(void) } /* Triggered when the button is pressed or released. The LED4 is set to ON.*/ -static void extcb1(EXTDriver *extp, expchannel_t channel) { +static void extcb1(EXTDriver *extp, expchannel_t channel) +{ (void)extp; (void)channel; operation_requested|=OP_LEVER; @@ -2243,7 +2252,7 @@ void ui_init() { adc_init(); - + /* * Activates the EXT driver 1. */