mirror of
https://github.com/ttrftech/NanoVNA.git
synced 2025-12-06 03:31:59 +01:00
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
This commit is contained in:
parent
ae38c9794d
commit
e9f65b1426
75
Font5x7.c
75
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,
|
||||
|
|
|
|||
534
chprintf.c
Normal file
534
chprintf.c
Normal file
|
|
@ -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 <math.h>
|
||||
|
||||
// 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:
|
||||
* - <b>x</b> hexadecimal integer.
|
||||
* - <b>X</b> hexadecimal long.
|
||||
* - <b>o</b> octal integer.
|
||||
* - <b>O</b> octal long.
|
||||
* - <b>d</b> decimal signed integer.
|
||||
* - <b>D</b> decimal signed long.
|
||||
* - <b>u</b> decimal unsigned integer.
|
||||
* - <b>U</b> decimal unsigned long.
|
||||
* - <b>c</b> character.
|
||||
* - <b>s</b> 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:
|
||||
* - <b>x</b> hexadecimal integer.
|
||||
* - <b>X</b> hexadecimal long.
|
||||
* - <b>o</b> octal integer.
|
||||
* - <b>O</b> octal long.
|
||||
* - <b>d</b> decimal signed integer.
|
||||
* - <b>D</b> decimal signed long.
|
||||
* - <b>u</b> decimal unsigned integer.
|
||||
* - <b>U</b> decimal unsigned long.
|
||||
* - <b>c</b> character.
|
||||
* - <b>s</b> 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:
|
||||
* - <b>x</b> hexadecimal integer.
|
||||
* - <b>X</b> hexadecimal long.
|
||||
* - <b>o</b> octal integer.
|
||||
* - <b>O</b> octal long.
|
||||
* - <b>d</b> decimal signed integer.
|
||||
* - <b>D</b> decimal signed long.
|
||||
* - <b>u</b> decimal unsigned integer.
|
||||
* - <b>U</b> decimal unsigned long.
|
||||
* - <b>c</b> character.
|
||||
* - <b>s</b> 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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
318
main.c
318
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)
|
||||
set_frequencies(uint32_t start, uint32_t stop, uint16_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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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 (argc >= 1) {
|
||||
int32_t value = atoi(argv[0]);
|
||||
if (value == 0)
|
||||
// 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<sizeof(t_list)/sizeof(type_list); i++){
|
||||
if (strcmp(argv[1], t_list[i].tracename) == 0) {
|
||||
set_trace_type(t, t_list[i].type);
|
||||
goto check_ch_num;
|
||||
}
|
||||
}
|
||||
if (strcmp(argv[1], "scale") == 0 && argc >= 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<sizeof(t_list)/sizeof(type_list); i++){
|
||||
if (strcmp(argv[1], t_list[i].tracename) == 0) {
|
||||
set_trace_type(t, t_list[i].type);
|
||||
goto check_ch_num;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
495
plot.c
495
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_REAL:
|
||||
format = "%.4f";
|
||||
v = coeff[0];
|
||||
break;
|
||||
case TRC_IMAG:
|
||||
format = "%.4fj";
|
||||
v = coeff[1];
|
||||
break;
|
||||
case TRC_R:
|
||||
format = "%.2F"S_OHM;
|
||||
v = gamma2resistance(coeff);
|
||||
break;
|
||||
case TRC_X:
|
||||
format = "%.2F"S_OHM;
|
||||
v = gamma2reactance(coeff);
|
||||
break;
|
||||
case TRC_SMITH:
|
||||
format_smith_value(buf, len, coeff, frequencies[i]);
|
||||
break;
|
||||
case TRC_REAL:
|
||||
chsnprintf(buf, len, "%.2f", coeff[0]);
|
||||
break;
|
||||
case TRC_IMAG:
|
||||
chsnprintf(buf, len, "%.2fj", coeff[1]);
|
||||
break;
|
||||
case TRC_R:
|
||||
gamma2resistance(buf, len, coeff);
|
||||
break;
|
||||
case TRC_X:
|
||||
gamma2reactance(buf, len, coeff);
|
||||
break;
|
||||
//case TRC_ADMIT:
|
||||
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)
|
||||
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;
|
||||
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;
|
||||
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(int w, int h, char *str, int x, int y)
|
||||
{
|
||||
while (*str) {
|
||||
x += cell_drawchar(w, h, *str, x, y, FALSE);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cell_drawstring_invert(int w, int h, char *str, int x, int y, int invert)
|
||||
{
|
||||
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
|
||||
|
|
|
|||
6
ui.c
6
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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue