diff --git a/.cproject b/.cproject index bc1de25..79b304e 100644 --- a/.cproject +++ b/.cproject @@ -3,9 +3,9 @@ - + - + @@ -29,193 +29,193 @@ - + - + - + - - - @@ -267,7 +265,7 @@ - + @@ -275,12 +273,24 @@ + + + + + + + + + + + + diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 11b93a5..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "ChibiOS"] - path = ChibiOS - url = https://github.com/edy555/ChibiOS.git - branch = I2SFULLDUPLEX diff --git a/FatFs/ff.c b/FatFs/ff.c index 580a916..b658786 100644 --- a/FatFs/ff.c +++ b/FatFs/ff.c @@ -22,6 +22,8 @@ #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ +// Use size optimization +#pragma GCC optimize ("Os") /*-------------------------------------------------------------------------- diff --git a/Font10x14.c b/Font10x14.c deleted file mode 100644 index 98145fd..0000000 --- a/Font10x14.c +++ /dev/null @@ -1,1715 +0,0 @@ -/* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@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. - - * Font size 10x14 pixels - * most font glyph have width 10 pixels - */ - -#include -#include "nanovna.h" - -/* - * Check 1 byte of bitmap data for get width - */ - -#define wFONT_START_CHAR 0x17 -#define wFONT_GET_HEIGHT 14 -#define wFONT_STR_HEIGHT 16 -#define wFONT_GET_DATA(ch) ( &x10x14_bits[(ch-wFONT_START_CHAR)*2*wFONT_GET_HEIGHT ]) -#define wFONT_GET_WIDTH(ch) (14-(x10x14_bits[(ch-wFONT_START_CHAR)*2*wFONT_GET_HEIGHT+1]&0x7)) - - -#define CW_06 0x07 -#define CW_07 0x06 -#define CW_08 0x05 -#define CW_09 0x04 -#define CW_10 0x03 -#define CW_11 0x02 -#define CW_12 0x01 -#define CW_13 0x00 - -// Font character bitmap data. -// If use blit8BitWidthBitmap width should be > 8 !!) -// for less 8 width used 9 but next char draw at correct place -const uint8_t x10x14_bits[(127-wFONT_START_CHAR)*wFONT_GET_HEIGHT*2] = -{ -//S_DELTA "\029" // 0x17 - _BMP16(0b0000000000000000|CW_13), // | | - _BMP16(0b0000011000000000), // | ** | - _BMP16(0b0000011000000000), // | ** | - _BMP16(0b0000111100000000), // | **** | - _BMP16(0b0000111100000000), // | **** | - _BMP16(0b0000111100000000), // | **** | - _BMP16(0b0001101110000000), // | ** *** | - _BMP16(0b0001101110000000), // | ** *** | - _BMP16(0b0011000111000000), // | ** *** | - _BMP16(0b0011000111000000), // | ** *** | - _BMP16(0b0110000011100000), // | ** *** | - _BMP16(0b0110000011100000), // | ** *** | - _BMP16(0b0110000011100000), // | ** *** | - _BMP16(0b1111111111110000), // |************ | - -//S_SARROW "\030" // 0x18 - _BMP16(0b0000000000000000|CW_08), // | | - _BMP16(0b1000000000000000), // |* | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b1111110000000000), // |****** | - _BMP16(0b1111111000000000), // |******* | - _BMP16(0b1111110000000000), // |****** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1000000000000000), // |* | - -//S_INFINITY "\031" // 0x19 - _BMP16(0b0000000000000000|CW_13), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011100111000000), // | *** *** | - _BMP16(0b0111111111100000), // | ********** | - _BMP16(0b1110111001110000), // |*** *** *** | - _BMP16(0b1100111000110000), // |** *** ** | - _BMP16(0b1100011000110000), // |** ** ** | - _BMP16(0b1100011100110000), // |** *** ** | - _BMP16(0b1110011101110000), // |*** *** *** | - _BMP16(0b0111111111100000), // | ********** | - _BMP16(0b0011100111000000), // | *** *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -//S_LARROW "\032" // 0x1A - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0001000000000000), // | * | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0111000000000000), // | *** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b0111000000000000), // | *** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0001000000000000), // | * | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -//S_RARROW "\033" // 0x1B - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000100000000000), // | * | - _BMP16(0b0000110000000000), // | ** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000110000000000), // | ** | - _BMP16(0b0000100000000000), // | * | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -//S_PI "\034" // 0x1C - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0111111111100000), // | ********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1011000110000000), // |* ** ** | - _BMP16(0b0011000110000000), // | ** ** | - _BMP16(0b0011000110000000), // | ** ** | - _BMP16(0b0011000110000000), // | ** ** | - _BMP16(0b0011000110000000), // | ** ** | - _BMP16(0b0011000110000000), // | ** ** | - _BMP16(0b1110000111110000), // |*** **** | - _BMP16(0b1110000111100000), // |** *** | - -//S_MICRO "\035" // 0x1D - _BMP16(0b0000000000000000|CW_13), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0111000111000000), // | *** *** | - _BMP16(0b0111000111000000), // | *** *** | - _BMP16(0b0111000111000000), // | *** *** | - _BMP16(0b0111000111000000), // | *** *** | - _BMP16(0b0111000111000000), // | *** *** | - _BMP16(0b0111001111010000), // | *** **** * | - _BMP16(0b0111111011100000), // | ****** *** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - -//S_OHM "\036" // 0x1E - _BMP16(0b0000111100000000|CW_13), // | **** | - _BMP16(0b0011111111000000), // | ******** | - _BMP16(0b0111000011100000), // | *** *** | - _BMP16(0b1110000001110000), // |*** *** | - _BMP16(0b1110000001110000), // |*** *** | - _BMP16(0b1110000001110000), // |*** *** | - _BMP16(0b1110000001110000), // |*** *** | - _BMP16(0b1110000001110000), // |*** *** | - _BMP16(0b1110000001110000), // |*** *** | - _BMP16(0b0111000011100000), // | *** *** | - _BMP16(0b0011100111000000), // | *** *** | - _BMP16(0b1001100110010000), // | ** ** | - _BMP16(0b1111100111110000), // |***** ***** | - _BMP16(0b1111100111110000), // |***** ***** | - -//S_DEGREE "\037" // 0x1F - _BMP16(0b0001110000000000|CW_09), // | *** | - _BMP16(0b0011111000000000), // | ***** | - _BMP16(0b0110001100000000), // | ** ** | - _BMP16(0b0110001100000000), // | ** ** | - _BMP16(0b0110001100000000), // | ** ** | - _BMP16(0b0011111000000000), // | ***** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char ' ', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '!', width = 6 - _BMP16(0b0011000000000000|CW_06), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b0011000000000000), // | ** | - -// Char '"', width = 8 - _BMP16(0b0110011000000000|CW_08), // | ** ** | - _BMP16(0b0110011000000000), // | ** ** | - _BMP16(0b0110011000000000), // | ** ** | - _BMP16(0b0110011000000000), // | ** ** | - _BMP16(0b0100010000000000), // | * * | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '#', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b0011001100000000), // | ** ** | - _BMP16(0b0000000000000000), // | | - -// Char '$', width = 10 - _BMP16(0b0011111000000000|CW_10), // | ***** | - _BMP16(0b0110101100000000), // | ** * ** | - _BMP16(0b1100100100000000), // |** * * | - _BMP16(0b1100100100000000), // |** * * | - _BMP16(0b1110100000000000), // |*** * | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b0011110000000000), // | **** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000101100000000), // | * ** | - _BMP16(0b0000100110000000), // | * ** | - _BMP16(0b1000100110000000), // |* * ** | - _BMP16(0b1000100110000000), // |* * ** | - _BMP16(0b1100101100000000), // |** * ** | - _BMP16(0b0111111000000000), // | ****** | - - // Char '%', width = 13 - _BMP16(0b0111000000010000|CW_13), // | *** * | - _BMP16(0b1000100000110000), // |* * ** | - _BMP16(0b1000100001100000), // |* * ** | - _BMP16(0b1000100011000000), // |* * ** | - _BMP16(0b1000100110000000), // |* * ** | - _BMP16(0b0111001100000000), // | *** ** | - _BMP16(0b0000011000000000), // | ** | - _BMP16(0b0000110011100000), // | ** *** | - _BMP16(0b0001100100010000), // | ** * * | - _BMP16(0b0011000100010000), // | ** * * | - _BMP16(0b0110000100010000), // | ** * * | - _BMP16(0b1100000100010000), // |** * * | - _BMP16(0b1000000011100000), // |* *** | - _BMP16(0b0000000000000000), // | | - -// Char '&', width = 13 - _BMP16(0b0001111000000000|CW_13), // | **** | - _BMP16(0b0011000100000000), // | ** * | - _BMP16(0b0011000100000000), // | ** * | - _BMP16(0b0011000100000000), // | ** * | - _BMP16(0b0011001000000000), // | ** * | - _BMP16(0b0001110011110000), // | *** **** | - _BMP16(0b0001100001100000), // | ** ** | - _BMP16(0b0010110001000000), // | * ** * | - _BMP16(0b0100111010000000), // | * *** * | - _BMP16(0b1100011100000000), // |** *** | - _BMP16(0b1100001100000000), // |** ** | - _BMP16(0b1100001110010000), // |** *** * | - _BMP16(0b1110010111110000), // |*** * ***** | - _BMP16(0b0111100001100000), // | **** ** | - -// Char ''', width = 6 - _BMP16(0b0011100000000000|CW_06), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '(', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0000000000000000), // | | - -// Char ')', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0000000000000000), // | | - -// Char '*', width = 9 - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0001000000000000), // | * | - _BMP16(0b1101011000000000), // |** * ** | - _BMP16(0b1101011000000000), // |** * ** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1101011000000000), // |** * ** | - _BMP16(0b1101011000000000), // |** * ** | - _BMP16(0b0001000000000000), // | * | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '+', width = 9 - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char ',', width = 5 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0111000000000000), // | *** | - _BMP16(0b1110000000000000), // |*** | - -// Char '-', width = 9 - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '.', width = 4 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0110000000000000), // | ** | - -// Char '/', width = 9 - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000100000000), // | * | - _BMP16(0b0000001100000000), // | ** | - _BMP16(0b0000011000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b1000000000000000), // |* | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '0', width = 12 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110011111000000), // |*** ***** | - _BMP16(0b1110110111000000), // |*** ** *** | - _BMP16(0b1110110111000000), // |*** ** *** | - _BMP16(0b1111100111000000), // |***** *** | - _BMP16(0b1111000111000000), // |**** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char '1', width = 8 - _BMP16(0b0011100000000000|CW_08), // | *** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1111111000000000), // |******* | - _BMP16(0b1111111000000000), // |******* | - -// Char '2', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000001111000000), // | **** | - _BMP16(0b0000011110000000), // | **** | - _BMP16(0b0000111100000000), // | **** | - _BMP16(0b0011110000000000), // | **** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - -// Char '3', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000001111000000), // | **** | - _BMP16(0b0001111110000000), // | ****** | - _BMP16(0b0001111110000000), // | ****** | - _BMP16(0b0000001111000000), // | **** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char '4', width = 11 - _BMP16(0b1110001110000000|CW_11), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - -// Char '5', width = 11 - _BMP16(0b1111111111000000|CW_11), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char '6', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110111100000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char '7', width = 11 - _BMP16(0b1111111111000000|CW_11), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000001111000000), // | **** | - _BMP16(0b0000011110000000), // | **** | - _BMP16(0b0000111100000000), // | **** | - _BMP16(0b0001111000000000), // | **** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - -// Char '8', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char '9', width = 12 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011110111000000), // | **** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char ':', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char ';', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0000000000000000), // | | - -// Char '<', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000011000000), // | ** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000000011000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '=', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '>', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0111000000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0111000000000000), // | *** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '?', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - -// Char '@', width = 13 - _BMP16(0b0000111100000000|CW_13), // | **** | - _BMP16(0b0011000011000000), // | ** ** | - _BMP16(0b0100000000100000), // | * * | - _BMP16(0b1000011010010000), // |* ** * * | - _BMP16(0b1000100110010000), // |* * ** * | - _BMP16(0b1001000010010000), // |* * * * | - _BMP16(0b1001000010010000), // |* * * * | - _BMP16(0b1001000010010000), // |* * * * | - _BMP16(0b1001000010010000), // |* * * * | - _BMP16(0b1000100110010000), // |* * ** * | - _BMP16(0b1000011011100000), // |* ** *** | - _BMP16(0b0100000000000000), // | * | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0000111100000000), // | **** | - -// Char 'A', width = 11 - _BMP16(0b0000110000000000|CW_11), // | ** | - _BMP16(0b0001111000000000), // | **** | - _BMP16(0b0011111100000000), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - -// Char 'B', width = 11 - _BMP16(0b1111111100000000|CW_11), // |******** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111100000000), // |******** | - -// Char 'C', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char 'D', width = 11 - _BMP16(0b1111111100000000|CW_11), // |******** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111100000000), // |******** | - -// Char 'E', width = 11 - _BMP16(0b1111111111000000|CW_11), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - -// Char 'F', width = 12 - _BMP16(0b1111111111000000|CW_11), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - -// Char 'G', width = 12 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110011111000000), // |*** ***** | - _BMP16(0b1110011111000000), // |*** ***** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1111011111000000), // |**** ***** | - _BMP16(0b0111111011000000), // | ****** ** | - _BMP16(0b0011110011000000), // | **** ** | - -// Char 'H', width = 11 - _BMP16(0b1110000111000000|CW_11), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - -// Char 'I', width = 8 - _BMP16(0b1111111000000000|CW_08), // |******* | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1111111000000000), // |******* | - -// Char 'J', width = 11 - _BMP16(0b0001111111000000|CW_11), // | ******* | - _BMP16(0b0001111111000000), // | ******* | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1110001110000000), // |*** *** | - _BMP16(0b1111011110000000), // |**** **** | - _BMP16(0b0111111100000000), // | ******* | - _BMP16(0b0011111000000000), // | ***** | - -// Char 'K', width = 12 - _BMP16(0b1110000011100000|CW_12), // |*** *** | - _BMP16(0b1110000111100000), // |*** **** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110011110000000), // |*** **** | - _BMP16(0b1110111100000000), // |*** **** | - _BMP16(0b1111111000000000), // |******* | - _BMP16(0b1111110000000000), // |****** | - _BMP16(0b1111110000000000), // |****** | - _BMP16(0b1111111000000000), // |******* | - _BMP16(0b1110111100000000), // |*** **** | - _BMP16(0b1110011110000000), // |*** **** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111100000), // |*** **** | - _BMP16(0b1110000011100000), // |*** *** | - -// Char 'L', width = 11 - _BMP16(0b1110000000000000|CW_11), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - -// Char 'M', width = 12 - _BMP16(0b1110000011100000|CW_12), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b1111101111100000), // |***** ***** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110010011100000), // |*** * *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - -// Char 'N', width = 11 - _BMP16(0b1110000111000000|CW_11), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111000111000000), // |*** *** | - _BMP16(0b1111100111000000), // |***** *** | - _BMP16(0b1111110111000000), // |****** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110111111000000), // |*** ****** | - _BMP16(0b1110011111000000), // |*** ***** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - -// Char 'O', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char 'P', width = 11 - _BMP16(0b1111111100000000|CW_11), // |******** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - -// Char 'Q', width = 12 - _BMP16(0b0011111110000000|CW_12), // | ******* | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111111100000), // |*** ******* | - _BMP16(0b1110011110000000), // |*** **** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111111100000), // | ********** | - _BMP16(0b0011111011100000), // | ***** *** | - -// Char 'R', width = 12 - _BMP16(0b1111111100000000|CW_11), // |******** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - -// Char 'S', width = 11 - _BMP16(0b0011111100000000|CW_11), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b0111111100000000), // | ******* | - _BMP16(0b0011111110000000), // | ******* | - _BMP16(0b0000001111000000), // | **** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char 'T', width = 12 - _BMP16(0b1111111111100000|CW_12), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1000111000100000), // |* *** * | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - -// Char 'U', width = 11 - _BMP16(0b1110000111000000|CW_11), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char 'V', width = 11 - _BMP16(0b1110000111000000|CW_11), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - _BMP16(0b0001111000000000), // | **** | - _BMP16(0b0000110000000000), // | ** | - -// Char 'W', width = 12 - _BMP16(0b1110000011100000|CW_12), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b0111101111000000), // | **** **** | - _BMP16(0b0011000110000000), // | ** ** | - -// Char 'X', width = 12 - _BMP16(0b1110000011100000|CW_12), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b0111101111000000), // | **** **** | - _BMP16(0b0011111110000000), // | ******* | - _BMP16(0b0001111100000000), // | ***** | - _BMP16(0b0001111100000000), // | ***** | - _BMP16(0b0011111110000000), // | ******* | - _BMP16(0b0111101111000000), // | **** **** | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - -// Char 'Y', width = 12 - _BMP16(0b1110000011100000|CW_12), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b0111101111000000), // | **** **** | - _BMP16(0b0011111110000000), // | ******* | - _BMP16(0b0001111100000000), // | ***** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - -// Char 'Z', width = 12 - _BMP16(0b1111111111100000|CW_12), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b0000000011100000), // | *** | - _BMP16(0b0000000111100000), // | **** | - _BMP16(0b0000001111000000), // | **** | - _BMP16(0b0000011110000000), // | **** | - _BMP16(0b0000111100000000), // | **** | - _BMP16(0b0001111000000000), // | **** | - _BMP16(0b0011110000000000), // | **** | - _BMP16(0b0111100000000000), // | **** | - _BMP16(0b1111000000000000), // |**** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - -// Char '[', width = 6 - _BMP16(0b1111100000000000|CW_06), // |***** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b1111100000000000), // |***** | - -// Char '\', width = 7 - _BMP16(0b0000000000000000|CW_09), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1000000000000000), // |* | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0000110000000000), // | ** | - _BMP16(0b0000011000000000), // | ** | - _BMP16(0b0000001100000000), // | ** | - _BMP16(0b0000000100000000), // | * | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char ']', width = 6 - _BMP16(0b1111100000000000|CW_06), // |***** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b1111100000000000), // |***** | - -// Char '^', width = 10 - _BMP16(0b0000100000000000|CW_10), // | * | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0011011000000000), // | ** ** | - _BMP16(0b0110001100000000), // | ** ** | - _BMP16(0b1100000110000000), // |** ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char '_', width = 12 - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1111111111100000), // |*********** | - -// Char '`', width = 6 - _BMP16(0b0110000000000000|CW_06), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - -// Char 'a', width = 12 - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b0111111101100000), // | ******* ** | - -// Char 'b', width = 11 - _BMP16(0b1110000000000000|CW_11), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110111100000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1101111100000000), // |** ***** | - -// Char 'c', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011111100000000), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char 'd', width = 11 - _BMP16(0b0000000111000000|CW_11), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0011110111000000), // | **** *** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111000111000000), // |**** *** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011111011000000), // | ***** ** | - -// Char 'e', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011111100000000), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111000011000000), // |**** ** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011111110000000), // | ******* | - -// Char 'f', width = 11 - _BMP16(0b0000111111000000|CW_11), // | ****** | - _BMP16(0b0001111111000000), // | ******* | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - -// Char 'g', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011111011000000), // | ***** ** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b1111000111000000), // |**** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011111111000000), // | ******** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b0111111110000000), // | ******** | - -// Char 'h', width = 11 - _BMP16(0b1110000000000000|CW_11), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110111100000000), // |*** **** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - -// Char 'i', width = 8 - _BMP16(0b0011100000000000|CW_08), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1111100000000000), // |***** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1111111000000000), // |******* | - -// Char 'j', width = 10 - _BMP16(0b0000011100000000|CW_09), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0001111100000000), // | ***** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b1110011100000000), // |*** *** | - _BMP16(0b0111111000000000), // | ****** | - -// Char 'k', width = 12 - _BMP16(0b1110000000000000|CW_12), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000111100000), // |*** **** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110011110000000), // |*** **** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1111111100000000), // |******** | - _BMP16(0b1110011110000000), // |*** **** | - _BMP16(0b1110001111000000), // |*** **** | - _BMP16(0b1110000111100000), // |*** **** | - _BMP16(0b1110000011100000), // |*** *** | - -// Char 'l', width = 8 - _BMP16(0b1111100000000000|CW_08), // |***** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b1111111000000000), // |******* | - -// Char 'm', width = 12 - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1101101110000000), // |** ** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - -// Char 'n', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1101111100000000), // |** ***** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - -// Char 'o', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011111100000000), // | ****** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - -// Char 'p', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1101111110000000), // |** ****** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1110000000000000), // |*** | - -// Char 'q', width = 12 - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011111011100000), // | ***** *** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011111111000000), // | ******** | - _BMP16(0b0000000111000000), // | *** | - -// Char 'r', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1101111110000000), // |** ****** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111000111000000), // |**** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1110000000000000), // |*** | - -// Char 's', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0111111110000000), // | ******** | - -// Char 't', width = 11 - _BMP16(0b0001110000000000|CW_11), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b1111111110000000), // |********* | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0001110111000000), // | *** *** | - _BMP16(0b0001111111000000), // | ******* | - _BMP16(0b0000111110000000), // | ***** | - -// Char 'u', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011111011000000), // | ***** ** | - -// Char 'v', width = 12 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111001111000000), // |**** **** | - _BMP16(0b0111111110000000), // | ******** | - _BMP16(0b0011111100000000), // | ****** | - _BMP16(0b0001111000000000), // | **** | - _BMP16(0b0000110000000000), // | ** | - -// Char 'w', width = 12 - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1110111011100000), // |*** *** *** | - _BMP16(0b1111111111100000), // |*********** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0011101110000000), // | *** *** | - -// Char 'x', width = 12 - _BMP16(0b0000000000000000|CW_12), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1110000011100000), // |*** *** | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b0111101111000000), // | **** **** | - _BMP16(0b0011111110000000), // | ******* | - _BMP16(0b0001111100000000), // | ***** | - _BMP16(0b0001111100000000), // | ***** | - _BMP16(0b0011111110000000), // | ******* | - _BMP16(0b0111101111000000), // | **** **** | - _BMP16(0b1111000111100000), // |**** **** | - _BMP16(0b1110000011100000), // |*** *** | - -// Char 'y', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b1111000111000000), // |**** *** | - _BMP16(0b0111111111000000), // | ********* | - _BMP16(0b0001110111000000), // | *** *** | - _BMP16(0b0000000111000000), // | *** | - _BMP16(0b1110000111000000), // |*** *** | - _BMP16(0b0111111110000000), // | ******** | - -// Char 'z', width = 11 - _BMP16(0b0000000000000000|CW_11), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b0000001110000000), // | *** | - _BMP16(0b0000011100000000), // | *** | - _BMP16(0b0000111000000000), // | *** | - _BMP16(0b0001110000000000), // | *** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0111000000000000), // | *** | - _BMP16(0b1111111111000000), // |********** | - _BMP16(0b1111111111000000), // |********** | - -// Char '{', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b1100000000000000), // |** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0110000000000000), // | ** | - _BMP16(0b0011100000000000), // | *** | - _BMP16(0b0000000000000000), // | | - -// Char '|', width = 6 - _BMP16(0b0011000000000000|CW_06), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - -// Char '}', width = 6 - _BMP16(0b0000000000000000|CW_06), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0001100000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b0011000000000000), // | ** | - _BMP16(0b1110000000000000), // |*** | - _BMP16(0b0000000000000000), // | | - -// Char '~', width = 10 - _BMP16(0b0000000000000000|CW_10), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0011100011000000), // | *** ** | - _BMP16(0b0110110110000000), // |** ** ** | - _BMP16(0b1100011100000000), // |** *** | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | - _BMP16(0b0000000000000000), // | | -}; diff --git a/Font7x11b.c b/Font7x11b.c index cfb5c9e..5086f72 100644 --- a/Font7x11b.c +++ b/Font7x11b.c @@ -367,8 +367,8 @@ const uint8_t x7x11b_bits[] = 0b11111110, // |******* | 0b00000000, // | | -// Char "\030" width = 5 - 0b00000000|CW_05, // | | +// Char "\030" width = 6 + 0b00000000|CW_06, // | | 0b10000000, // |* | 0b11000000, // |** | 0b11100000, // |*** | @@ -406,14 +406,14 @@ const uint8_t x7x11b_bits[] = 0b00010000, // | * | 0b00000000, // | | -// Char "\033" width = 7 - 0b00000000|CW_07, // | | +// Char "\033" width = 8 + 0b00000000|CW_08, // | | 0b00000000, // | | 0b00010000, // | * | 0b00011000, // | ** | 0b00001100, // | ** | - 0b01111110, // | ****** | - 0b01111110, // | ****** | + 0b11111110, // |******* | + 0b11111110, // |******* | 0b00001100, // | ** | 0b00011000, // | ** | 0b00010000, // | * | @@ -564,8 +564,8 @@ const uint8_t x7x11b_bits[] = // Char ''' width = 5 0b00000000|CW_05, // | | - 0b01110000, // | *** | - 0b01110000, // | *** | + 0b11100000, // |*** | + 0b11100000, // |*** | 0b01100000, // | ** | 0b11000000, // |** | 0b00000000, // | | diff --git a/Makefile b/Makefile index 009aa00..98fca41 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,6 @@ USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-fun endif # additional options, use math optimisations USE_OPT+= -ffast-math -fsingle-precision-constant - -USE_OPT+= -D__BAND_MODE__ - #USE_OPT+= -D__MS5351__ @@ -101,7 +98,11 @@ endif # # Define project name here -PROJECT = ch +ifeq ($(TARGET),F303) + PROJECT = H4 +else + PROJECT = H +endif # Imported source files and paths #CHIBIOS = ../ChibiOS-RT @@ -154,7 +155,7 @@ CSRC = $(STARTUPSRC) \ FatFs/ff.c \ FatFs/ffunicode.c \ usbcfg.c \ - main.c si5351.c tlv320aic3204.c dsp.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c Font6x10.c Font7x11b.c Font11x14.c data_storage.c hardware.c vna_math.c + main.c si5351.c tlv320aic3204.c dsp.c plot.c ui.c ili9341.c numfont16x22.c Font5x7.c Font6x10.c Font7x11b.c Font11x14.c data_storage.c hardware.c vna_math.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. @@ -249,7 +250,7 @@ endif UDEFS+= -DVNA_AUTO_SELECT_RTC_SOURCE #Enable if install external 32.768kHz clock quartz on PC14 and PC15 pins on STM32 CPU and no VNA_AUTO_SELECT_RTC_SOURCE #UDEFS+= -DVNA_USE_LSE -#UDEFS+= -D__VNA_Z_RENORMALIZATION__ -D__SD_FILE_BROWSER__ -D__VNA_FAST_LINES__ +#UDEFS+= -D__VNA_Z_RENORMALIZATION__ -D__VNA_FAST_LINES__ # Define ASM defines here UADEFS = @@ -270,8 +271,8 @@ ULIBS = -lm RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC include $(RULESPATH)/rules.mk -flash: build/ch.bin - dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin +flash: build/$(PROJECT).bin + dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/$(PROJECT).bin dfu: -@printf "reset dfu\r" >/dev/cu.usbmodem401 diff --git a/NANOVNA_STM32_F072/board.c b/NANOVNA_STM32_F072/board.c index 7871834..dc9254d 100644 --- a/NANOVNA_STM32_F072/board.c +++ b/NANOVNA_STM32_F072/board.c @@ -62,13 +62,38 @@ const PALConfig pal_default_config = { }; #endif +static bool needDFU(void) { + // Magick data in memory before reset + if (*((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) == BOOT_FROM_SYTEM_MEMORY_MAGIC) + return true; + // init PortA (leveler port) and check press + rccEnableAHB(STM32_GPIO_EN_MASK, FALSE); + GPIOA->OTYPER = VAL_GPIOA_OTYPER; +// GPIOA->OSPEEDR = VAL_GPIOA_OSPEEDR; + GPIOA->PUPDR = VAL_GPIOA_PUPDR; + GPIOA->ODR = VAL_GPIOA_ODR; +// GPIOA->AFR[0] = VAL_GPIOA_AFRL; +// GPIOA->AFR[1] = VAL_GPIOA_AFRH; + GPIOA->MODER = VAL_GPIOA_MODER; + if (GPIOA->IDR & (1<IDR & (1<CCR = STM32_ADC_ADC34_CLOCK_MODE; } -#define ADC_AVERAGE_N 3 +#define ADC_AVERAGE_N 4 static void adcStartMeasure(ADC_TypeDef *adc, uint32_t sqr0, uint16_t *samples) { // ADC setup adc->ISR = adc->ISR; // reset interrupts diff --git a/NANOVNA_STM32_F303/board.c b/NANOVNA_STM32_F303/board.c index 2fa77f2..cdb3823 100644 --- a/NANOVNA_STM32_F303/board.c +++ b/NANOVNA_STM32_F303/board.c @@ -62,63 +62,17 @@ const PALConfig pal_default_config = { }; #endif +void boardDFUEnter(void) { + __set_MSP(*((uint32_t *)(STM32F303xC_SYSTEM_MEMORY))); + ((void (*)(void))(*((uint32_t *)(STM32F303xC_SYSTEM_MEMORY + 4))))(); // jump to DFU +} + /* * Early initialization code. * This initialization must be performed just after stack setup and before * any other initialization. */ void __early_init(void) { - // Refer to thess pages for how to start dfu from software - // https://community.st.com/s/question/0D50X00009XkeeWSAR/stm32l476rg-jump-to-bootloader-from-software - // https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/ -#if 0 - if ( *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) == BOOT_FROM_SYTEM_MEMORY_MAGIC ) { - // require irq - // __enable_irq(); - // reset magic bytes - *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) = 0; - #if 1 - // https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/ - // Step: Disable systick timer and reset it to default values - #if 0 - SysTick->CTRL = 0; - SysTick->LOAD = 0; - SysTick->VAL = 0; - #endif - // Step: Disable all interrupts - __disable_irq(); - // Remap system memory to address 0x0000 0000 in address space - typedef void (*pFunction)(void); - pFunction bootloader; - uint32_t msp; - uint32_t foo = SYSCFG->CFGR1; - foo = (foo & ~SYSCFG_CFGR1_MEM_MODE) || SYSCFG_CFGR1_MEM_MODE_0; - SYSCFG->CFGR1 = foo; - //foo = SYSCFG->CFGR1; - __DSB(); - __ISB(); - //__DSB(); - //__ISB(); - #if 1 - bootloader = (void (*)(void)) (*((uint32_t *)(STM32F303xC_SYSTEM_MEMORY+4))); - //msp = *(uint32_t *) STM32F303xC_SYSTEM_MEMORY; - msp = 0x20002250; - #else - bootloader = (void (*)(void)) (*((uint32_t *)(4))); - //msp = *(uint32_t *) 0; - msp = 0x20002250; - #endif - __set_MSP(msp); - bootloader(); - while(1); - #else - __set_MSP(SYSTEM_BOOT_MSP); - ( (void (*)(void)) (*((uint32_t *)(STM32F303xC_SYSTEM_MEMORY+4))) )(); - while(1); - #endif - } -#endif - stm32_clock_init(); } diff --git a/NANOVNA_STM32_F303/board.h b/NANOVNA_STM32_F303/board.h index ffbf16d..5520617 100644 --- a/NANOVNA_STM32_F303/board.h +++ b/NANOVNA_STM32_F303/board.h @@ -38,11 +38,9 @@ */ #define STM32F303xC -#define STM32F303xC_SYSTEM_MEMORY 0x1FFFD800 -#define BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS 0x20009FF0 -#define BOOT_FROM_SYTEM_MEMORY_MAGIC 0xDEADBEEF -//#define SYSTEM_BOOT_MSP *(uint32_t *)0 // 0x20001258 -#define SYSTEM_BOOT_MSP 0x20001258 +#define STM32F303xC_SYSTEM_MEMORY 0x1FFFD800 +#define BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS 0x20009FFC +#define BOOT_FROM_SYTEM_MEMORY_MAGIC 0xDEADBEEF /* * IO pins assignments @@ -52,8 +50,8 @@ #define GPIOA_BUTTON 0 #define GPIOA_LEVER1 1 -#define GPIOA_LEVER2 2 -#define GPIOA_PUSH 3 +#define GPIOA_PUSH 2 +#define GPIOA_LEVER2 3 #define GPIOA_VBUS 4 #define GPIOA_DAC2 5 #define GPIOA_XP 6 @@ -794,6 +792,7 @@ extern "C" { #endif void boardInit(void); + void boardDFUEnter(void); #ifdef __cplusplus } #endif diff --git a/STM32F072xB.ld b/STM32F072xB.ld deleted file mode 100644 index a22fed9..0000000 --- a/STM32F072xB.ld +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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. -*/ - -/* - * STM32F072xB memory setup. - */ -MEMORY -{ - flash0 : org = 0x08000000, len = 96k - flash1 : org = 0x00000000, len = 0 - flash2 : org = 0x00000000, len = 0 - flash3 : org = 0x00000000, len = 0 - flash4 : org = 0x00000000, len = 0 - flash5 : org = 0x00000000, len = 0 - flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x08018000, len = 32k - ram0 : org = 0x20000000, len = 16k - ram1 : org = 0x00000000, len = 0 - ram2 : org = 0x00000000, len = 0 - ram3 : org = 0x00000000, len = 0 - ram4 : org = 0x00000000, len = 0 - ram5 : org = 0x00000000, len = 0 - ram6 : org = 0x00000000, len = 0 - ram7 : org = 0x00000000, len = 0 -} - -/* For each data/text section two region are defined, a virtual region - and a load region (_LMA suffix).*/ - -/* Flash region to be used for exception vectors.*/ -REGION_ALIAS("VECTORS_FLASH", flash0); -REGION_ALIAS("VECTORS_FLASH_LMA", flash0); - -/* Flash region to be used for constructors and destructors.*/ -REGION_ALIAS("XTORS_FLASH", flash0); -REGION_ALIAS("XTORS_FLASH_LMA", flash0); - -/* Flash region to be used for code text.*/ -REGION_ALIAS("TEXT_FLASH", flash0); -REGION_ALIAS("TEXT_FLASH_LMA", flash0); - -/* Flash region to be used for read only data.*/ -REGION_ALIAS("RODATA_FLASH", flash0); -REGION_ALIAS("RODATA_FLASH_LMA", flash0); - -/* Flash region to be used for various.*/ -REGION_ALIAS("VARIOUS_FLASH", flash0); -REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); - -/* Flash region to be used for RAM(n) initialization data.*/ -REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); - -/* Flash region to be saved calibration data */ -REGION_ALIAS("CALDATA_FLASH", flash7); - -/* RAM region to be used for Main stack. This stack accommodates the processing - of all exceptions and interrupts.*/ -REGION_ALIAS("MAIN_STACK_RAM", ram0); - -/* RAM region to be used for the process stack. This is the stack used by - the main() function.*/ -REGION_ALIAS("PROCESS_STACK_RAM", ram0); - -/* RAM region to be used for data segment.*/ -REGION_ALIAS("DATA_RAM", ram0); -REGION_ALIAS("DATA_RAM_LMA", flash0); - -/* RAM region to be used for BSS segment.*/ -REGION_ALIAS("BSS_RAM", ram0); - -/* RAM region to be used for the default heap.*/ -REGION_ALIAS("HEAP_RAM", ram0); - -/* Generic rules inclusion.*/ -INCLUDE rules.ld - -SECTIONS -{ - .calsave (NOLOAD) : ALIGN(4) - { - *(.calsave) - } > CALDATA_FLASH -} diff --git a/STM32F072xB_AA.ld b/STM32F072xB_AA.ld deleted file mode 100644 index 1c2f3df..0000000 --- a/STM32F072xB_AA.ld +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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. -*/ - -/* - * STM32F072xB memory setup. - */ -MEMORY -{ - flash0 : org = 0x08000000, len = 102k - flash1 : org = 0x00000000, len = 0 - flash2 : org = 0x00000000, len = 0 - flash3 : org = 0x00000000, len = 0 - flash4 : org = 0x00000000, len = 0 - flash5 : org = 0x00000000, len = 0 - flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x08019800, len = 26k - ram0 : org = 0x20000000, len = 16k - ram1 : org = 0x00000000, len = 0 - ram2 : org = 0x00000000, len = 0 - ram3 : org = 0x00000000, len = 0 - ram4 : org = 0x00000000, len = 0 - ram5 : org = 0x00000000, len = 0 - ram6 : org = 0x00000000, len = 0 - ram7 : org = 0x00000000, len = 0 -} - -/* For each data/text section two region are defined, a virtual region - and a load region (_LMA suffix).*/ - -/* Flash region to be used for exception vectors.*/ -REGION_ALIAS("VECTORS_FLASH", flash0); -REGION_ALIAS("VECTORS_FLASH_LMA", flash0); - -/* Flash region to be used for constructors and destructors.*/ -REGION_ALIAS("XTORS_FLASH", flash0); -REGION_ALIAS("XTORS_FLASH_LMA", flash0); - -/* Flash region to be used for code text.*/ -REGION_ALIAS("TEXT_FLASH", flash0); -REGION_ALIAS("TEXT_FLASH_LMA", flash0); - -/* Flash region to be used for read only data.*/ -REGION_ALIAS("RODATA_FLASH", flash0); -REGION_ALIAS("RODATA_FLASH_LMA", flash0); - -/* Flash region to be used for various.*/ -REGION_ALIAS("VARIOUS_FLASH", flash0); -REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); - -/* Flash region to be used for RAM(n) initialization data.*/ -REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); - -/* Flash region to be saved calibration data */ -REGION_ALIAS("CALDATA_FLASH", flash7); - -/* RAM region to be used for Main stack. This stack accommodates the processing - of all exceptions and interrupts.*/ -REGION_ALIAS("MAIN_STACK_RAM", ram0); - -/* RAM region to be used for the process stack. This is the stack used by - the main() function.*/ -REGION_ALIAS("PROCESS_STACK_RAM", ram0); - -/* RAM region to be used for data segment.*/ -REGION_ALIAS("DATA_RAM", ram0); -REGION_ALIAS("DATA_RAM_LMA", flash0); - -/* RAM region to be used for BSS segment.*/ -REGION_ALIAS("BSS_RAM", ram0); - -/* RAM region to be used for the default heap.*/ -REGION_ALIAS("HEAP_RAM", ram0); - -/* Generic rules inclusion.*/ -INCLUDE rules.ld - -SECTIONS -{ - .calsave (NOLOAD) : ALIGN(4) - { - *(.calsave) - } > CALDATA_FLASH -} diff --git a/STM32F303xC.ld b/STM32F303xC.ld deleted file mode 100644 index c804623..0000000 --- a/STM32F303xC.ld +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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. -*/ - -/* - * STM32F303xC memory setup. - */ -MEMORY -{ - flash0 : org = 0x08000000, len = 192k - flash1 : org = 0x00000000, len = 0 - flash2 : org = 0x00000000, len = 0 - flash3 : org = 0x00000000, len = 0 - flash4 : org = 0x00000000, len = 0 - flash5 : org = 0x00000000, len = 0 - flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x08030000, len = 64k - ram0 : org = 0x20000000, len = 40k - ram1 : org = 0x00000000, len = 0 - ram2 : org = 0x00000000, len = 0 - ram3 : org = 0x00000000, len = 0 - ram4 : org = 0x10000000, len = 8k - ram5 : org = 0x00000000, len = 0 - ram6 : org = 0x00000000, len = 0 - ram7 : org = 0x00000000, len = 0 -} - -/* For each data/text section two region are defined, a virtual region - and a load region (_LMA suffix).*/ - -/* Flash region to be used for exception vectors.*/ -REGION_ALIAS("VECTORS_FLASH", flash0); -REGION_ALIAS("VECTORS_FLASH_LMA", flash0); - -/* Flash region to be used for constructors and destructors.*/ -REGION_ALIAS("XTORS_FLASH", flash0); -REGION_ALIAS("XTORS_FLASH_LMA", flash0); - -/* Flash region to be used for code text.*/ -REGION_ALIAS("TEXT_FLASH", flash0); -REGION_ALIAS("TEXT_FLASH_LMA", flash0); - -/* Flash region to be used for read only data.*/ -REGION_ALIAS("RODATA_FLASH", flash0); -REGION_ALIAS("RODATA_FLASH_LMA", flash0); - -/* Flash region to be used for various.*/ -REGION_ALIAS("VARIOUS_FLASH", flash0); -REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); - -/* Flash region to be used for RAM(n) initialization data.*/ -REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); - -/* Flash region to be saved calibration data */ -REGION_ALIAS("CALDATA_FLASH", flash7); - -/* RAM region to be used for Main stack. This stack accommodates the processing - of all exceptions and interrupts.*/ -REGION_ALIAS("MAIN_STACK_RAM", ram0); - -/* RAM region to be used for the process stack. This is the stack used by - the main() function.*/ -REGION_ALIAS("PROCESS_STACK_RAM", ram0); - -/* RAM region to be used for data segment.*/ -REGION_ALIAS("DATA_RAM", ram0); -REGION_ALIAS("DATA_RAM_LMA", flash0); - -/* RAM region to be used for BSS segment.*/ -REGION_ALIAS("BSS_RAM", ram0); - -/* RAM region to be used for the default heap.*/ -REGION_ALIAS("HEAP_RAM", ram0); - -/* Generic rules inclusion.*/ -INCLUDE rules.ld - -SECTIONS -{ - .calsave (NOLOAD) : ALIGN(4) - { - *(.calsave) - } > CALDATA_FLASH -} diff --git a/adc.c b/adc.c deleted file mode 100644 index 7f2de1c..0000000 --- a/adc.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com - * Based on 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 "ch.h" -#include "hal.h" -#include "nanovna.h" - -#ifndef VNA_ADC_H -#define VNA_ADC_H - -// Measure vbat every 5 second -#define VBAT_MEASURE_INTERVAL S2ST(5) - -#ifdef NANOVNA_F303 -#include "NANOVNA_STM32_F303/adc.c" -#else -#include "NANOVNA_STM32_F072/adc.c" -#endif -#endif diff --git a/adc_F303.h b/adc_F303.h deleted file mode 100644 index 8fca2ac..0000000 --- a/adc_F303.h +++ /dev/null @@ -1,26 +0,0 @@ - -// F303 related ADC defines - - -#define ADC_SMPR_SMP_247P5 6 /**< @brief 260 cycles conversion time. */ -#define ADC_SMPR_SMP_24P5 3 /**< @brief 37 cycles conversion time. */ - - -#define rccEnableWWDG(lp) rccEnableAPB1(RCC_APB1ENR_WWDGEN, lp) -#define ADC_CHSELR_CHSEL6 ADC_CHANNEL_IN3 -#define ADC_CHSELR_CHSEL7 ADC_CHANNEL_IN4 -#define ADC_SMPR_SMP_239P5 7U -#define ADC_SMPR_SMP_28P5 3U /**< @brief 41 cycles conversion time. */ -#define ADC_CFGR_RES_12BIT (0 << 3) -/* -msg_t adcConvert(ADCDriver *adcp, - const ADCConversionGroup *grpp, - adcsample_t *samples, - size_t depth); -*/ -#define ADC_CR1_AWDEN ((uint32_t)0x00800000) /*!< Analog watchdog enable on regular channels */ -//ADC_Common_TypeDef *adcc; -#define ADC_CHSELR_VREFINT ADC_CHANNEL_IN18 -#define ADC_CHSELR_VBAT ADC_CHANNEL_IN17 - - diff --git a/chprintf.c b/chprintf.c index e11606a..a2c25eb 100644 --- a/chprintf.c +++ b/chprintf.c @@ -35,23 +35,26 @@ // 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 +// for %q format use uint32_t or uint64_t //#define CHPRINTF_FREQUENCY_SIZE_64 +// allow use int64_t values for %D %U %O %X or %ld %lu %lo %lx type //#define CHPRINTF_USE_INT_64 -// Force putting trailing zeros on float value +// Force putting trailing zeros on float value (for %0.f format) #define CHPRINTF_FORCE_TRAILING_ZEROS -#define MAX_FILLER 11 +// Maximum digits for values 11.11 + 1 for float, int64 need 21 digit (use MAX_FILLER * 2 + 1) +#define MAX_FILLER 11 #define FLOAT_PRECISION 9 #define FLOAT_PREFIX_PRECISION 3 -#ifdef CHPRINTF_USE_INT_64 +#ifdef CHPRINTF_FREQUENCY_SIZE_64 typedef uint64_t pfreq_t; #else typedef uint32_t pfreq_t; #endif -#ifdef CHPRINTF_FREQUENCY_SIZE_64 +#ifdef CHPRINTF_USE_INT_64 typedef uint64_t ulongval_t; typedef int64_t longval_t; #else @@ -93,11 +96,11 @@ static char *long_to_string_with_divisor(char *p, return p; } -// default prescision = 13 -// g.mmm kkk hhh +// default frequency prescision = 14 +// gg.mmm kkk hhh #define MAX_FREQ_PRESCISION 14 -#define FREQ_PSET 1 -#define FREQ_PREFIX_SPACE 2 +#define FREQ_PSET 1 +#define FREQ_PREFIX_SPACE 2 static char * ulong_freq(char *p, pfreq_t freq, int precision) @@ -163,7 +166,7 @@ ulong_freq(char *p, pfreq_t freq, int precision) if (!(flag & FREQ_PSET) && precision-- < 0) break; *p++ = c; } while (--i); - // Put pref (amd space before it if need) + // Put pref (and space before it if need) if ((flag & FREQ_PREFIX_SPACE) && s != ' ') *p++ = ' '; *p++ = s; @@ -229,7 +232,7 @@ static char *ftoaS(char *p, float num, int16_t precision) { * @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 general parameters format is: %[flags][width|*][.precision|*][l|L]p. * The following parameter types (p) are supported: * - x hexadecimal int32. * - X hexadecimal int64. @@ -241,7 +244,9 @@ static char *ftoaS(char *p, float num, int16_t precision) { * - U decimal unsigned int64. * - c char. * - s string. - * . + * - f float. + * - F float (use prefix formatting) + * - q uint32 or uint64 frequency formatting (depend from defined or not CHPRINTF_FREQUENCY_SIZE_64). * * @param[in] chp pointer to a @p BaseSequentialStream implementing object * @param[in] fmt formatting string @@ -286,7 +291,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { n++; continue; } - // Parse %[flags][width][.precision][length]type + // Parse %[flags][width|*][.precision|*] p = tmpbuf; s = tmpbuf; state = 0; @@ -298,6 +303,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { // '+' 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.) + // 'j' Then add 'j' before '+' or '-', need for complex values. while (true){ if (*fmt == '-') state|=LEFT_ALIGN; @@ -317,7 +323,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { break; fmt++; } - // Get [width] - The Width field specifies a minimum number of characters to output + // Get [width|*] - The Width field specifies a minimum number of characters to output // if set *, get width as argument while (true) { c = *fmt++; @@ -329,7 +335,8 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { break; width = width * 10 + c; } - // Get [.precision] + // Get [.precision|*] + // if set *, get precision as argument if (c == '.') { while (true) { c = *fmt++; @@ -344,8 +351,8 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { } else state|=DEFAULT_PRESCISION; - //Get [length] -#ifdef CHPRINTF_FREQUENCY_SIZE_64 + // Get type (or skip [l|L] for int64_t) support +#ifdef CHPRINTF_USE_INT_64 if (c == 'l' || c == 'L') { state|=IS_LONG; if (*fmt) @@ -373,7 +380,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { case 'd': case 'I': case 'i': -#ifdef CHPRINTF_FREQUENCY_SIZE_64 +#ifdef CHPRINTF_USE_INT_64 if (state & IS_LONG) value.l = va_arg(ap, int64_t); else @@ -395,11 +402,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { p = long_to_string_with_divisor(p, value.l, 10, 0); break; case 'q': -#ifdef CHPRINTF_FREQUENCY_SIZE_64 - p=ulong_freq(p, va_arg(ap, uint64_t), precision); -#else - p=ulong_freq(p, va_arg(ap, uint32_t), precision); -#endif + p=ulong_freq(p, va_arg(ap, pfreq_t), precision); break; #if CHPRINTF_USE_FLOAT case 'F': @@ -450,7 +453,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { case 'o': c = 8; unsigned_common: -#ifdef CHPRINTF_FREQUENCY_SIZE_64 +#ifdef CHPRINTF_USE_INT_64 if (state & IS_LONG) value.u = va_arg(ap, int64_t); else diff --git a/data_storage.c b/data_storage.c index 0153170..e118892 100644 --- a/data_storage.c +++ b/data_storage.c @@ -30,9 +30,11 @@ uint16_t lastsaveid = 0; // properties CRC check cache (max 8 slots) static uint8_t checksum_ok = 0; -static uint32_t -checksum(const void *start, size_t len) -{ +static uint32_t calibration_slot_area(int id) { + return SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE; +} + +static uint32_t checksum(const void *start, size_t len) { uint32_t *p = (uint32_t*)start; uint32_t value = 0; // align by sizeof(uint32_t) @@ -42,9 +44,7 @@ checksum(const void *start, size_t len) return value; } -int -config_save(void) -{ +int config_save(void) { // Apply magic word and calculate checksum config.magic = CONFIG_MAGIC; config.checksum = checksum(&config, sizeof config - sizeof config.checksum); @@ -54,9 +54,7 @@ config_save(void) return 0; } -int -config_recall(void) -{ +int config_recall(void) { const config_t *src = (const config_t*)SAVE_CONFIG_ADDR; if (src->magic != CONFIG_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) @@ -66,49 +64,44 @@ config_recall(void) return 0; } -int -caldata_save(uint32_t id) -{ +int caldata_save(uint32_t id) { if (id >= SAVEAREA_MAX) return -1; // Apply magic word and calculate checksum - current_props.magic = PROPS_MAGIC; + current_props.magic = PROPERTIES_MAGIC; current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum); // write to flash - uint16_t *dst = (uint16_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); + uint16_t *dst = (uint16_t*)calibration_slot_area(id); flash_program_half_word_buffer(dst, (uint16_t*)¤t_props, sizeof(properties_t)); lastsaveid = id; return 0; } -const properties_t * -get_properties(uint32_t id) -{ +const properties_t * get_properties(uint32_t id) { if (id >= SAVEAREA_MAX) return NULL; // point to saved area on the flash memory - properties_t *src = (properties_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); + properties_t *src = (properties_t*)calibration_slot_area(id); // Check crc cache mask (made it only 1 time) if (checksum_ok&(1<magic != PROPS_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) + if (src->magic != PROPERTIES_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) return NULL; checksum_ok|=1<=1:Enable */ -/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value - defines how many files can be opened simultaneously. */ - - -#endif /* _FFCONFIG */ diff --git a/fft.h b/fft.h deleted file mode 100644 index bfbb73d..0000000 --- a/fft.h +++ /dev/null @@ -1,385 +0,0 @@ -/* - * fft.h is Based on - * Free FFT and convolution (C) - * - * Copyright (c) 2019 Project Nayuki. (MIT License) - * https://www.nayuki.io/page/free-small-fft-in-multiple-languages - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - - -#include -#include - -// Use table increase transform speed from 6500 tick to 2025, increase code size on 700 bytes -// Use compact table, increase code size on 208 bytes, and not decrease speed -// Used only if not defined __VNA_USE_MATH_TABLES__ (use self table for TTF or direct sin/cos calculations) -#define FFT_USE_SIN_COS_TABLE - -// Use sin table and interpolation for sin/sos calculations -#ifdef __VNA_USE_MATH_TABLES__ -// Use 512 table for calculation sin/cos value, also use this table for FFT -#define FAST_MATH_TABLE_SIZE 512 - -// Not use high part of table -#define GET_SIN_TABLE(idx) (((idx) < 256) ? sin_table_512[(idx)] : -sin_table_512[(idx)-256]) - -static const float sin_table_512[FAST_MATH_TABLE_SIZE/2 + 1] = { - /* - * float has about 7.2 digits of precision - for (int i = 0; i < FAST_MATH_TABLE_SIZE; i++) { - printf("% .8f,%c", sin(2 * M_PI * i / FAST_MATH_TABLE_SIZE), i % 8 == 7 ? '\n' : ' '); - } - */ - 0.00000000f, 0.01227154f, 0.02454123f, 0.03680722f, 0.04906767f, 0.06132074f, 0.07356456f, 0.08579731f, - 0.09801714f, 0.11022221f, 0.12241068f, 0.13458071f, 0.14673047f, 0.15885814f, 0.17096189f, 0.18303989f, - 0.19509032f, 0.20711138f, 0.21910124f, 0.23105811f, 0.24298018f, 0.25486566f, 0.26671276f, 0.27851969f, - 0.29028468f, 0.30200595f, 0.31368174f, 0.32531029f, 0.33688985f, 0.34841868f, 0.35989504f, 0.37131719f, - 0.38268343f, 0.39399204f, 0.40524131f, 0.41642956f, 0.42755509f, 0.43861624f, 0.44961133f, 0.46053871f, - 0.47139674f, 0.48218377f, 0.49289819f, 0.50353838f, 0.51410274f, 0.52458968f, 0.53499762f, 0.54532499f, - 0.55557023f, 0.56573181f, 0.57580819f, 0.58579786f, 0.59569930f, 0.60551104f, 0.61523159f, 0.62485949f, - 0.63439328f, 0.64383154f, 0.65317284f, 0.66241578f, 0.67155895f, 0.68060100f, 0.68954054f, 0.69837625f, - 0.70710678f, 0.71573083f, 0.72424708f, 0.73265427f, 0.74095113f, 0.74913639f, 0.75720885f, 0.76516727f, - 0.77301045f, 0.78073723f, 0.78834643f, 0.79583690f, 0.80320753f, 0.81045720f, 0.81758481f, 0.82458930f, - 0.83146961f, 0.83822471f, 0.84485357f, 0.85135519f, 0.85772861f, 0.86397286f, 0.87008699f, 0.87607009f, - 0.88192126f, 0.88763962f, 0.89322430f, 0.89867447f, 0.90398929f, 0.90916798f, 0.91420976f, 0.91911385f, - 0.92387953f, 0.92850608f, 0.93299280f, 0.93733901f, 0.94154407f, 0.94560733f, 0.94952818f, 0.95330604f, - 0.95694034f, 0.96043052f, 0.96377607f, 0.96697647f, 0.97003125f, 0.97293995f, 0.97570213f, 0.97831737f, - 0.98078528f, 0.98310549f, 0.98527764f, 0.98730142f, 0.98917651f, 0.99090264f, 0.99247953f, 0.99390697f, - 0.99518473f, 0.99631261f, 0.99729046f, 0.99811811f, 0.99879546f, 0.99932238f, 0.99969882f, 0.99992470f, - 1.00000000f, 0.99992470f, 0.99969882f, 0.99932238f, 0.99879546f, 0.99811811f, 0.99729046f, 0.99631261f, - 0.99518473f, 0.99390697f, 0.99247953f, 0.99090264f, 0.98917651f, 0.98730142f, 0.98527764f, 0.98310549f, - 0.98078528f, 0.97831737f, 0.97570213f, 0.97293995f, 0.97003125f, 0.96697647f, 0.96377607f, 0.96043052f, - 0.95694034f, 0.95330604f, 0.94952818f, 0.94560733f, 0.94154407f, 0.93733901f, 0.93299280f, 0.92850608f, - 0.92387953f, 0.91911385f, 0.91420976f, 0.90916798f, 0.90398929f, 0.89867447f, 0.89322430f, 0.88763962f, - 0.88192126f, 0.87607009f, 0.87008699f, 0.86397286f, 0.85772861f, 0.85135519f, 0.84485357f, 0.83822471f, - 0.83146961f, 0.82458930f, 0.81758481f, 0.81045720f, 0.80320753f, 0.79583690f, 0.78834643f, 0.78073723f, - 0.77301045f, 0.76516727f, 0.75720885f, 0.74913639f, 0.74095113f, 0.73265427f, 0.72424708f, 0.71573083f, - 0.70710678f, 0.69837625f, 0.68954054f, 0.68060100f, 0.67155895f, 0.66241578f, 0.65317284f, 0.64383154f, - 0.63439328f, 0.62485949f, 0.61523159f, 0.60551104f, 0.59569930f, 0.58579786f, 0.57580819f, 0.56573181f, - 0.55557023f, 0.54532499f, 0.53499762f, 0.52458968f, 0.51410274f, 0.50353838f, 0.49289819f, 0.48218377f, - 0.47139674f, 0.46053871f, 0.44961133f, 0.43861624f, 0.42755509f, 0.41642956f, 0.40524131f, 0.39399204f, - 0.38268343f, 0.37131719f, 0.35989504f, 0.34841868f, 0.33688985f, 0.32531029f, 0.31368174f, 0.30200595f, - 0.29028468f, 0.27851969f, 0.26671276f, 0.25486566f, 0.24298018f, 0.23105811f, 0.21910124f, 0.20711138f, - 0.19509032f, 0.18303989f, 0.17096189f, 0.15885814f, 0.14673047f, 0.13458071f, 0.12241068f, 0.11022221f, - 0.09801714f, 0.08579731f, 0.07356456f, 0.06132074f, 0.04906767f, 0.03680722f, 0.02454123f, 0.01227154f, - 0.00000000f, - /* - -0.01227154f,-0.02454123f,-0.03680722f,-0.04906767f,-0.06132074f,-0.07356456f,-0.08579731f, - -0.09801714f,-0.11022221f,-0.12241068f,-0.13458071f,-0.14673047f,-0.15885814f,-0.17096189f,-0.18303989f, - -0.19509032f,-0.20711138f,-0.21910124f,-0.23105811f,-0.24298018f,-0.25486566f,-0.26671276f,-0.27851969f, - -0.29028468f,-0.30200595f,-0.31368174f,-0.32531029f,-0.33688985f,-0.34841868f,-0.35989504f,-0.37131719f, - -0.38268343f,-0.39399204f,-0.40524131f,-0.41642956f,-0.42755509f,-0.43861624f,-0.44961133f,-0.46053871f, - -0.47139674f,-0.48218377f,-0.49289819f,-0.50353838f,-0.51410274f,-0.52458968f,-0.53499762f,-0.54532499f, - -0.55557023f,-0.56573181f,-0.57580819f,-0.58579786f,-0.59569930f,-0.60551104f,-0.61523159f,-0.62485949f, - -0.63439328f,-0.64383154f,-0.65317284f,-0.66241578f,-0.67155895f,-0.68060100f,-0.68954054f,-0.69837625f, - -0.70710678f,-0.71573083f,-0.72424708f,-0.73265427f,-0.74095113f,-0.74913639f,-0.75720885f,-0.76516727f, - -0.77301045f,-0.78073723f,-0.78834643f,-0.79583690f,-0.80320753f,-0.81045720f,-0.81758481f,-0.82458930f, - -0.83146961f,-0.83822471f,-0.84485357f,-0.85135519f,-0.85772861f,-0.86397286f,-0.87008699f,-0.87607009f, - -0.88192126f,-0.88763962f,-0.89322430f,-0.89867447f,-0.90398929f,-0.90916798f,-0.91420976f,-0.91911385f, - -0.92387953f,-0.92850608f,-0.93299280f,-0.93733901f,-0.94154407f,-0.94560733f,-0.94952818f,-0.95330604f, - -0.95694034f,-0.96043052f,-0.96377607f,-0.96697647f,-0.97003125f,-0.97293995f,-0.97570213f,-0.97831737f, - -0.98078528f,-0.98310549f,-0.98527764f,-0.98730142f,-0.98917651f,-0.99090264f,-0.99247953f,-0.99390697f, - -0.99518473f,-0.99631261f,-0.99729046f,-0.99811811f,-0.99879546f,-0.99932238f,-0.99969882f,-0.99992470f, - -1.00000000f,-0.99992470f,-0.99969882f,-0.99932238f,-0.99879546f,-0.99811811f,-0.99729046f,-0.99631261f, - -0.99518473f,-0.99390697f,-0.99247953f,-0.99090264f,-0.98917651f,-0.98730142f,-0.98527764f,-0.98310549f, - -0.98078528f,-0.97831737f,-0.97570213f,-0.97293995f,-0.97003125f,-0.96697647f,-0.96377607f,-0.96043052f, - -0.95694034f,-0.95330604f,-0.94952818f,-0.94560733f,-0.94154407f,-0.93733901f,-0.93299280f,-0.92850608f, - -0.92387953f,-0.91911385f,-0.91420976f,-0.90916798f,-0.90398929f,-0.89867447f,-0.89322430f,-0.88763962f, - -0.88192126f,-0.87607009f,-0.87008699f,-0.86397286f,-0.85772861f,-0.85135519f,-0.84485357f,-0.83822471f, - -0.83146961f,-0.82458930f,-0.81758481f,-0.81045720f,-0.80320753f,-0.79583690f,-0.78834643f,-0.78073723f, - -0.77301045f,-0.76516727f,-0.75720885f,-0.74913639f,-0.74095113f,-0.73265427f,-0.72424708f,-0.71573083f, - -0.70710678f,-0.69837625f,-0.68954054f,-0.68060100f,-0.67155895f,-0.66241578f,-0.65317284f,-0.64383154f, - -0.63439328f,-0.62485949f,-0.61523159f,-0.60551104f,-0.59569930f,-0.58579786f,-0.57580819f,-0.56573181f, - -0.55557023f,-0.54532499f,-0.53499762f,-0.52458968f,-0.51410274f,-0.50353838f,-0.49289819f,-0.48218377f, - -0.47139674f,-0.46053871f,-0.44961133f,-0.43861624f,-0.42755509f,-0.41642956f,-0.40524131f,-0.39399204f, - -0.38268343f,-0.37131719f,-0.35989504f,-0.34841868f,-0.33688985f,-0.32531029f,-0.31368174f,-0.30200595f, - -0.29028468f,-0.27851969f,-0.26671276f,-0.25486566f,-0.24298018f,-0.23105811f,-0.21910124f,-0.20711138f, - -0.19509032f,-0.18303989f,-0.17096189f,-0.15885814f,-0.14673047f,-0.13458071f,-0.12241068f,-0.11022221f, - -0.09801714f,-0.08579731f,-0.07356456f,-0.06132074f,-0.04906767f,-0.03680722f,-0.02454123f,-0.01227154f, - -0.00000000f*/ -}; -// -#if FFT_SIZE == 256 -#define FFT_SIN(i) sin_table_512[ 2*(i)] -#define FFT_COS(i) ((i) > 64 ?-sin_table_512[2*(i)-128] : sin_table_512[128-2*(i)]) -#elif FFT_SIZE == 512 -#define FFT_SIN(i) sin_table_512[ (i)] -#define FFT_COS(i) ((i) > 128 ?-sin_table_512[ (i)-128] : sin_table_512[128- (i)]) -#else -#error "Need use bigger sin/cos table for new FFT size" -#endif - -#else -#ifdef FFT_USE_SIN_COS_TABLE -#if FFT_SIZE == 256 -static const float sin_table_256[] = { - /* - * float has about 7.2 digits of precision - for (uint8_t i = 0; i < FFT_SIZE - (FFT_SIZE / 4); i++) { - printf("% .8f,%c", sin(2 * M_PI * i / FFT_SIZE), i % 8 == 7 ? '\n' : ' '); - } - */ - // for FFT_SIZE = 256 - 0.00000000, 0.02454123, 0.04906767, 0.07356456, 0.09801714, 0.12241068, 0.14673047, 0.17096189, - 0.19509032, 0.21910124, 0.24298018, 0.26671276, 0.29028468, 0.31368174, 0.33688985, 0.35989504, - 0.38268343, 0.40524131, 0.42755509, 0.44961133, 0.47139674, 0.49289819, 0.51410274, 0.53499762, - 0.55557023, 0.57580819, 0.59569930, 0.61523159, 0.63439328, 0.65317284, 0.67155895, 0.68954054, - 0.70710678, 0.72424708, 0.74095113, 0.75720885, 0.77301045, 0.78834643, 0.80320753, 0.81758481, - 0.83146961, 0.84485357, 0.85772861, 0.87008699, 0.88192126, 0.89322430, 0.90398929, 0.91420976, - 0.92387953, 0.93299280, 0.94154407, 0.94952818, 0.95694034, 0.96377607, 0.97003125, 0.97570213, - 0.98078528, 0.98527764, 0.98917651, 0.99247953, 0.99518473, 0.99729046, 0.99879546, 0.99969882, - 1.00000000,/* 0.99969882, 0.99879546, 0.99729046, 0.99518473, 0.99247953, 0.98917651, 0.98527764, - 0.98078528, 0.97570213, 0.97003125, 0.96377607, 0.95694034, 0.94952818, 0.94154407, 0.93299280, - 0.92387953, 0.91420976, 0.90398929, 0.89322430, 0.88192126, 0.87008699, 0.85772861, 0.84485357, - 0.83146961, 0.81758481, 0.80320753, 0.78834643, 0.77301045, 0.75720885, 0.74095113, 0.72424708, - 0.70710678, 0.68954054, 0.67155895, 0.65317284, 0.63439328, 0.61523159, 0.59569930, 0.57580819, - 0.55557023, 0.53499762, 0.51410274, 0.49289819, 0.47139674, 0.44961133, 0.42755509, 0.40524131, - 0.38268343, 0.35989504, 0.33688985, 0.31368174, 0.29028468, 0.26671276, 0.24298018, 0.21910124, - 0.19509032, 0.17096189, 0.14673047, 0.12241068, 0.09801714, 0.07356456, 0.04906767, 0.02454123, - 0.00000000, -0.02454123, -0.04906767, -0.07356456, -0.09801714, -0.12241068, -0.14673047, -0.17096189, - -0.19509032, -0.21910124, -0.24298018, -0.26671276, -0.29028468, -0.31368174, -0.33688985, -0.35989504, - -0.38268343, -0.40524131, -0.42755509, -0.44961133, -0.47139674, -0.49289819, -0.51410274, -0.53499762, - -0.55557023, -0.57580819, -0.59569930, -0.61523159, -0.63439328, -0.65317284, -0.67155895, -0.68954054, - -0.70710678, -0.72424708, -0.74095113, -0.75720885, -0.77301045, -0.78834643, -0.80320753, -0.81758481, - -0.83146961, -0.84485357, -0.85772861, -0.87008699, -0.88192126, -0.89322430, -0.90398929, -0.91420976, - -0.92387953, -0.93299280, -0.94154407, -0.94952818, -0.95694034, -0.96377607, -0.97003125, -0.97570213, - -0.98078528, -0.98527764, -0.98917651, -0.99247953, -0.99518473, -0.99729046, -0.99879546, -0.99969882,*/ -}; -// full size table: -// sin = sin_table_256[i ] -// cos = sin_table_256[i+64] -//#define FFT_SIN(i) sin_table_256[(i)] -//#define FFT_COS(i) sin_table_256[(i)+64] - -// for size use only 0-64 indexes -// sin = i > 64 ? sin_table_256[128-i] : sin_table_256[ i]; -// cos = i > 64 ?-sin_table_256[ i-64] : sin_table_256[64-i]; -#define FFT_SIN(i) ((i) > 64 ? sin_table_256[128-(i)] : sin_table_256[ (i)]) -#define FFT_COS(i) ((i) > 64 ?-sin_table_256[ (i)-64] : sin_table_256[64-(i)]) - -#elif FFT_SIZE == 512 -static const float sin_table_512[] = { - /* - * float has about 7.2 digits of precision - for (int i = 0; i < FFT_SIZE - (FFT_SIZE / 4); i++) { - printf("% .8f,%c", sin(2 * M_PI * i / FFT_SIZE), i % 8 == 7 ? '\n' : ' '); - } - */ - // For FFT_SIZE = 512 - 0.00000000, 0.01227154, 0.02454123, 0.03680722, 0.04906767, 0.06132074, 0.07356456, 0.08579731, - 0.09801714, 0.11022221, 0.12241068, 0.13458071, 0.14673047, 0.15885814, 0.17096189, 0.18303989, - 0.19509032, 0.20711138, 0.21910124, 0.23105811, 0.24298018, 0.25486566, 0.26671276, 0.27851969, - 0.29028468, 0.30200595, 0.31368174, 0.32531029, 0.33688985, 0.34841868, 0.35989504, 0.37131719, - 0.38268343, 0.39399204, 0.40524131, 0.41642956, 0.42755509, 0.43861624, 0.44961133, 0.46053871, - 0.47139674, 0.48218377, 0.49289819, 0.50353838, 0.51410274, 0.52458968, 0.53499762, 0.54532499, - 0.55557023, 0.56573181, 0.57580819, 0.58579786, 0.59569930, 0.60551104, 0.61523159, 0.62485949, - 0.63439328, 0.64383154, 0.65317284, 0.66241578, 0.67155895, 0.68060100, 0.68954054, 0.69837625, - 0.70710678, 0.71573083, 0.72424708, 0.73265427, 0.74095113, 0.74913639, 0.75720885, 0.76516727, - 0.77301045, 0.78073723, 0.78834643, 0.79583690, 0.80320753, 0.81045720, 0.81758481, 0.82458930, - 0.83146961, 0.83822471, 0.84485357, 0.85135519, 0.85772861, 0.86397286, 0.87008699, 0.87607009, - 0.88192126, 0.88763962, 0.89322430, 0.89867447, 0.90398929, 0.90916798, 0.91420976, 0.91911385, - 0.92387953, 0.92850608, 0.93299280, 0.93733901, 0.94154407, 0.94560733, 0.94952818, 0.95330604, - 0.95694034, 0.96043052, 0.96377607, 0.96697647, 0.97003125, 0.97293995, 0.97570213, 0.97831737, - 0.98078528, 0.98310549, 0.98527764, 0.98730142, 0.98917651, 0.99090264, 0.99247953, 0.99390697, - 0.99518473, 0.99631261, 0.99729046, 0.99811811, 0.99879546, 0.99932238, 0.99969882, 0.99992470, - 1.00000000,/* 0.99992470, 0.99969882, 0.99932238, 0.99879546, 0.99811811, 0.99729046, 0.99631261, - 0.99518473, 0.99390697, 0.99247953, 0.99090264, 0.98917651, 0.98730142, 0.98527764, 0.98310549, - 0.98078528, 0.97831737, 0.97570213, 0.97293995, 0.97003125, 0.96697647, 0.96377607, 0.96043052, - 0.95694034, 0.95330604, 0.94952818, 0.94560733, 0.94154407, 0.93733901, 0.93299280, 0.92850608, - 0.92387953, 0.91911385, 0.91420976, 0.90916798, 0.90398929, 0.89867447, 0.89322430, 0.88763962, - 0.88192126, 0.87607009, 0.87008699, 0.86397286, 0.85772861, 0.85135519, 0.84485357, 0.83822471, - 0.83146961, 0.82458930, 0.81758481, 0.81045720, 0.80320753, 0.79583690, 0.78834643, 0.78073723, - 0.77301045, 0.76516727, 0.75720885, 0.74913639, 0.74095113, 0.73265427, 0.72424708, 0.71573083, - 0.70710678, 0.69837625, 0.68954054, 0.68060100, 0.67155895, 0.66241578, 0.65317284, 0.64383154, - 0.63439328, 0.62485949, 0.61523159, 0.60551104, 0.59569930, 0.58579786, 0.57580819, 0.56573181, - 0.55557023, 0.54532499, 0.53499762, 0.52458968, 0.51410274, 0.50353838, 0.49289819, 0.48218377, - 0.47139674, 0.46053871, 0.44961133, 0.43861624, 0.42755509, 0.41642956, 0.40524131, 0.39399204, - 0.38268343, 0.37131719, 0.35989504, 0.34841868, 0.33688985, 0.32531029, 0.31368174, 0.30200595, - 0.29028468, 0.27851969, 0.26671276, 0.25486566, 0.24298018, 0.23105811, 0.21910124, 0.20711138, - 0.19509032, 0.18303989, 0.17096189, 0.15885814, 0.14673047, 0.13458071, 0.12241068, 0.11022221, - 0.09801714, 0.08579731, 0.07356456, 0.06132074, 0.04906767, 0.03680722, 0.02454123, 0.01227154, - 0.00000000, -0.01227154, -0.02454123, -0.03680722, -0.04906767, -0.06132074, -0.07356456, -0.08579731, - -0.09801714, -0.11022221, -0.12241068, -0.13458071, -0.14673047, -0.15885814, -0.17096189, -0.18303989, - -0.19509032, -0.20711138, -0.21910124, -0.23105811, -0.24298018, -0.25486566, -0.26671276, -0.27851969, - -0.29028468, -0.30200595, -0.31368174, -0.32531029, -0.33688985, -0.34841868, -0.35989504, -0.37131719, - -0.38268343, -0.39399204, -0.40524131, -0.41642956, -0.42755509, -0.43861624, -0.44961133, -0.46053871, - -0.47139674, -0.48218377, -0.49289819, -0.50353838, -0.51410274, -0.52458968, -0.53499762, -0.54532499, - -0.55557023, -0.56573181, -0.57580819, -0.58579786, -0.59569930, -0.60551104, -0.61523159, -0.62485949, - -0.63439328, -0.64383154, -0.65317284, -0.66241578, -0.67155895, -0.68060100, -0.68954054, -0.69837625, - -0.70710678, -0.71573083, -0.72424708, -0.73265427, -0.74095113, -0.74913639, -0.75720885, -0.76516727, - -0.77301045, -0.78073723, -0.78834643, -0.79583690, -0.80320753, -0.81045720, -0.81758481, -0.82458930, - -0.83146961, -0.83822471, -0.84485357, -0.85135519, -0.85772861, -0.86397286, -0.87008699, -0.87607009, - -0.88192126, -0.88763962, -0.89322430, -0.89867447, -0.90398929, -0.90916798, -0.91420976, -0.91911385, - -0.92387953, -0.92850608, -0.93299280, -0.93733901, -0.94154407, -0.94560733, -0.94952818, -0.95330604, - -0.95694034, -0.96043052, -0.96377607, -0.96697647, -0.97003125, -0.97293995, -0.97570213, -0.97831737, - -0.98078528, -0.98310549, -0.98527764, -0.98730142, -0.98917651, -0.99090264, -0.99247953, -0.99390697, - -0.99518473, -0.99631261, -0.99729046, -0.99811811, -0.99879546, -0.99932238, -0.99969882, -0.99992470*/ -}; -// full size table: -// sin = sin_table_512[i ] -// cos = sin_table_512[i+128] -//#define FFT_SIN(i) sin_table_512[(i) ] -//#define FFT_COS(i) sin_table_512[(i)+128] - -// for size use only 0-128 indexes -// sin = i > 128 ? sin_table_512[256-i] : sin_table_512[ i]; -// cos = i > 128 ?-sin_table_512[i-128] : sin_table_512[128-i]; -#define FFT_SIN(i) ((i) > 128 ? sin_table_512[256-(i)] : sin_table_512[ (i)]) -#define FFT_COS(i) ((i) > 128 ?-sin_table_512[(i)-128] : sin_table_512[128-(i)]) - -#else -#error "Need build table for new FFT size" -#endif - -#else -// Not use FFT_USE_SIN_COS_TABLE, use direct sin/cos calculations -#define FFT_SIN(k) sin(2 * VNA_PI * (k) / FFT_SIZE) -#define FFT_COS(k) cos(2 * VNA_PI * (k) / FFT_SIZE); - -#endif // FFT_USE_SIN_COS_TABLE - -#endif // __VNA_USE_MATH_TABLES__ - -static uint16_t reverse_bits(uint16_t x, int n) { - uint16_t result = 0; - int i; - for (i = 0; i < n; i++, x >>= 1) - result = (result << 1) | (x & 1U); - return result; -} - -/*** - * dir = forward: 0, inverse: 1 - * https://www.nayuki.io/res/free-small-fft-in-multiple-languages/fft.c - */ -static void fft(float array[][2], const uint8_t dir) { -// FFT_SIZE = 2^FFT_N -#if FFT_SIZE == 256 - #define FFT_N 8 -#elif FFT_SIZE == 512 - #define FFT_N 9 -#else - #error "Need define FFT_N for this FFT size" -#endif - const uint16_t n = FFT_SIZE; - const uint8_t levels = FFT_N; // log2(n) - - const uint8_t real = dir & 1; - const uint8_t imag = ~real & 1; - uint16_t i; - - for (i = 0; i < n; i++) { - uint16_t j = reverse_bits(i, levels); - if (j > i) { - float temp = array[i][real]; - array[i][real] = array[j][real]; - array[j][real] = temp; - temp = array[i][imag]; - array[i][imag] = array[j][imag]; - array[j][imag] = temp; - } - } - const uint16_t size = 2; - uint16_t halfsize = size / 2; - uint16_t tablestep = n / size; - uint16_t j, k; - // Cooley-Tukey decimation-in-time radix-2 FFT - for (;tablestep; tablestep>>=1, halfsize<<=1) { - for (i = 0; i < n; i+=2*halfsize) { - for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) { - uint16_t l = j + halfsize; - float s = FFT_SIN(k); - float c = FFT_COS(k); - float tpre = array[l][real] * c + array[l][imag] * s; - float tpim = -array[l][real] * s + array[l][imag] * c; - array[l][real] = array[j][real] - tpre; - array[l][imag] = array[j][imag] - tpim; - array[j][real] += tpre; - array[j][imag] += tpim; - } - } - } -} - -static inline void fft_forward(float array[][2]) { - fft(array, 0); -} - -static inline void fft_inverse(float array[][2]) { - fft(array, 1); -} - -// Return sin/cos value angle in range 0.0 to 1.0 (0 is 0 degree, 1 is 360 degree) -void vna_sin_cos(float angle, float * pSinVal, float * pCosVal) -{ -#ifndef __VNA_USE_MATH_TABLES__ - // Use default sin/cos functions - angle *= 2 * VNA_PI; // Convert to rad - *pSinVal = sin(angle); - *pCosVal = cos(angle); -#else - const float Dn = 2 * VNA_PI / FAST_MATH_TABLE_SIZE; // delta between the two points in table (fixed); - uint16_t indexS, indexC; // Index variable - float f1, f2, d1, d2; // Two nearest output values - float Df, fract, temp; - - // Round angle to range 0.0 to 1.0 - temp = fabsf(angle); - temp-= (uint32_t)temp;//floorf(temp); - // Scale input from range 0.0 to 1.0 to table size - temp*= FAST_MATH_TABLE_SIZE; - - indexS = temp; - indexC = indexS + (FAST_MATH_TABLE_SIZE / 4); // cosine add 0.25 (pi/2) to read from sine table - // Calculation of fractional value - fract = temp - indexS; - // Align indexes to table - indexS&= (FAST_MATH_TABLE_SIZE-1); - indexC&= (FAST_MATH_TABLE_SIZE-1); - - // Read two nearest values of input value from the cos & sin tables -#if 0 - f1 = GET_SIN_TABLE(indexC ); - f2 = GET_SIN_TABLE(indexC+1); - d1 = GET_SIN_TABLE(indexS ); - d2 = GET_SIN_TABLE(indexS+1); -#else - if (indexC < 256){f1 = sin_table_512[indexC +0];f2 = sin_table_512[indexC +1];} - else {f1 =-sin_table_512[indexC-256+0];f2 =-sin_table_512[indexC-256+1];} - if (indexS < 256){d1 = sin_table_512[indexS +0];d2 = sin_table_512[indexS +1];} - else {d1 =-sin_table_512[indexS-256+0];d2 =-sin_table_512[indexS-256+1];} -#endif - - // Calculation of cosine value - Df = f2 - f1; // delta between the values of the functions - temp = Dn * (d1 + d2) + 2 * Df; - temp = (3 * Df + (d2 + 2 * d1) * Dn) - fract * temp; - temp = fract * temp - d1 * Dn; - *pCosVal = fract * temp + f1; - - // Calculation of sine value - Df = d2 - d1; // delta between the values of the functions - temp = Dn * (f1 + f2) - 2 * Df; - temp = fract * temp + (3 * Df - (f2 + 2 * f1) * Dn); - temp = fract * temp + f1 * Dn; - *pSinVal = fract * temp + d1; - if (angle < 0) - *pSinVal = -*pSinVal; -#endif -} diff --git a/flash.c b/flash.c deleted file mode 100644 index f5173c9..0000000 --- a/flash.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com - * Based on 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 "ch.h" -#include "hal.h" -#include "nanovna.h" -#include - -uint16_t lastsaveid = 0; -#if SAVEAREA_MAX >= 8 -#error "Increase checksum_ok type for save more cache slots" -#endif -// properties CRC check cache (max 8 slots) -static uint8_t checksum_ok = 0; - -static inline void flash_wait_for_last_operation(void) -{ - while (FLASH->SR == FLASH_SR_BSY) { - //WWDG->CR = WWDG_CR_T; - } -// return FLASH->SR; -} - -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; -} - -static inline void flash_unlock(void) -{ - // unlock sequence - FLASH->KEYR = 0x45670123; - FLASH->KEYR = 0xCDEF89AB; -} - -static void flash_erase_pages(uint32_t page_address, uint32_t size) -{ - // Unlock for erase - flash_unlock(); - - chSysLock(); - // erase flash pages - size+=page_address; - for (; page_address < size; page_address+=FLASH_PAGESIZE) - flash_erase_page0(page_address); - chSysUnlock(); -} - -static void flash_program_half_word_buffer(uint16_t* dst, uint16_t *data, uint16_t size) -{ - uint32_t i; - // unlock, and erase flash pages for buffer (aligned to FLASH_PAGESIZE) - flash_erase_pages((uint32_t)dst, size); - // Save buffer - __IO uint16_t* p = dst; - for (i = 0; i < size/sizeof(uint16_t); i++){ - flash_wait_for_last_operation(); - FLASH->CR |= FLASH_CR_PG; - p[i] = data[i]; - flash_wait_for_last_operation(); - FLASH->CR &= ~FLASH_CR_PG; - } -} - -static uint32_t -checksum(const void *start, size_t len) -{ - uint32_t *p = (uint32_t*)start; - uint32_t value = 0; - // align by sizeof(uint32_t) - len = (len + sizeof(uint32_t)-1)/sizeof(uint32_t); - while (len-- > 0) - value = __ROR(value, 31) + *p++; - return value; -} - -int -config_save(void) -{ - // Apply magic word and calculate checksum - config.magic = CONFIG_MAGIC; - config.checksum = checksum(&config, sizeof config - sizeof config.checksum); - - // write to flash - flash_program_half_word_buffer((uint16_t*)SAVE_CONFIG_ADDR, (uint16_t*)&config, sizeof(config_t)); - return 0; -} - -int -config_recall(void) -{ - const config_t *src = (const config_t*)SAVE_CONFIG_ADDR; - - if (src->magic != CONFIG_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) - return -1; - // duplicated saved data onto sram to be able to modify marker/trace - memcpy(&config, src, sizeof(config_t)); - return 0; -} - -int -caldata_save(uint32_t id) -{ - if (id >= SAVEAREA_MAX) - return -1; - - // Apply magic word and calculate checksum - current_props.magic = PROPS_MAGIC; - current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum); - - // write to flash - uint16_t *dst = (uint16_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); - flash_program_half_word_buffer(dst, (uint16_t*)¤t_props, sizeof(properties_t)); - - lastsaveid = id; - return 0; -} - -const properties_t * -get_properties(uint32_t id) -{ - if (id >= SAVEAREA_MAX) - return NULL; - // point to saved area on the flash memory - properties_t *src = (properties_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); - // Check crc cache mask (made it only 1 time) - if (checksum_ok&(1<magic != PROPS_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) - return NULL; - checksum_ok|=1<adcm->CR = 0; /* RM 12.4.3.*/ - adcp->adcm->CR = ADC_CR_ADVREGEN_0; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR = ADC_CR_ADVREGEN_0; -#endif - osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 10)); -#endif - -#if defined(STM32L4XX) - adcp->adcm->CR = 0; /* RM 16.3.6.*/ - adcp->adcm->CR = ADC_CR_ADVREGEN; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR = ADC_CR_ADVREGEN; -#endif - osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20)); -#endif -} - -/** - * @brief Disables the ADC voltage regulator. - * - * @param[in] adcp pointer to the @p ADCDriver object - */ -static void adc_lld_vreg_off(ADCDriver *adcp) { - -#if defined(STM32F3XX) - adcp->adcm->CR = 0; /* RM 12.4.3.*/ - adcp->adcm->CR = ADC_CR_ADVREGEN_1; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR = 0; - adcp->adcs->CR = ADC_CR_ADVREGEN_1; -#endif -#endif - -#if defined(STM32L4XX) - adcp->adcm->CR = 0; /* RM 12.4.3.*/ - adcp->adcm->CR = ADC_CR_DEEPPWD; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR = 0; - adcp->adcs->CR = ADC_CR_DEEPPWD; -#endif -#endif -} - -/** - * @brief Enables the ADC analog circuit. - * - * @param[in] adcp pointer to the @p ADCDriver object - */ -static void adc_lld_analog_on(ADCDriver *adcp) { - -#if defined(STM32F3XX) - adcp->adcm->CR |= ADC_CR_ADEN; - while ((adcp->adcm->ISR & ADC_ISR_ADRD) == 0) - ; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR |= ADC_CR_ADEN; - while ((adcp->adcs->ISR & ADC_ISR_ADRD) == 0) - ; -#endif -#endif - -#if defined(STM32L4XX) - adcp->adcm->CR |= ADC_CR_ADEN; - while ((adcp->adcm->ISR & ADC_ISR_ADRDY) == 0) - ; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR |= ADC_CR_ADEN; - while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0) - ; -#endif -#endif -} - -/** - * @brief Disables the ADC analog circuit. - * - * @param[in] adcp pointer to the @p ADCDriver object - */ -static void adc_lld_analog_off(ADCDriver *adcp) { - - adcp->adcm->CR |= ADC_CR_ADDIS; - while ((adcp->adcm->CR & ADC_CR_ADDIS) != 0) - ; -#if STM32_ADC_DUAL_MODE - adcp->adcs->CR |= ADC_CR_ADDIS; - while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0) - ; -#endif -} - -/** - * @brief Calibrates and ADC unit. - * - * @param[in] adcp pointer to the @p ADCDriver object - */ -static void adc_lld_calibrate(ADCDriver *adcp) { - -#if defined(STM32F3XX) - osalDbgAssert(adcp->adcm->CR == ADC_CR_ADVREGEN_0, "invalid register state"); - adcp->adcm->CR |= ADC_CR_ADCAL; - while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0) - ; -#if STM32_ADC_DUAL_MODE - osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN_0, "invalid register state"); - adcp->adcs->CR |= ADC_CR_ADCAL; - while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0) - ; -#endif -#endif - -#if defined(STM32L4XX) - osalDbgAssert(adcp->adcm->CR == ADC_CR_ADVREGEN, "invalid register state"); - adcp->adcm->CR |= ADC_CR_ADCAL; - while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0) - ; -#if STM32_ADC_DUAL_MODE - osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state"); - adcp->adcs->CR |= ADC_CR_ADCAL; - while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0) - ; -#endif -#endif -} - -/** - * @brief Stops an ongoing conversion, if any. - * - * @param[in] adcp pointer to the @p ADCDriver object - */ -static void adc_lld_stop_adc(ADCDriver *adcp) { - - if (adcp->adcm->CR & ADC_CR_ADSTART) { - adcp->adcm->CR |= ADC_CR_ADSTP; - while (adcp->adcm->CR & ADC_CR_ADSTP) - ; - } -} - -/** - * @brief ADC DMA ISR service routine. - * - * @param[in] adcp pointer to the @p ADCDriver object - * @param[in] flags pre-shifted content of the ISR register - */ -static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) { - - /* DMA errors handling.*/ - if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { - /* DMA, this could help only if the DMA tries to access an unmapped - address space or violates alignment rules.*/ - _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); - } - else { - /* It is possible that the conversion group has already be reset by the - ADC error handler, in this case this interrupt is spurious.*/ - if (adcp->grpp != NULL) { - if ((flags & STM32_DMA_ISR_TCIF) != 0) { - /* Transfer complete processing.*/ - _adc_isr_full_code(adcp); - } - else if ((flags & STM32_DMA_ISR_HTIF) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(adcp); - } - } - } -} - -/** - * @brief ADC ISR service routine. - * - * @param[in] adcp pointer to the @p ADCDriver object - * @param[in] isr content of the ISR register - */ -static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) { - - /* It could be a spurious interrupt caused by overflows after DMA disabling, - just ignore it in this case.*/ - if (adcp->grpp != NULL) { - /* Note, an overflow may occur after the conversion ended before the driver - is able to stop the ADC, this is why the DMA channel is checked too.*/ - if ((isr & ADC_ISR_OVR) && - (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) { - /* ADC overflow condition, this could happen only if the DMA is unable - to read data fast enough.*/ - _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW); - } - if (isr & ADC_ISR_AWD1) { - /* Analog watchdog error.*/ - _adc_isr_error_code(adcp, ADC_ERR_AWD1); - } - if (isr & ADC_ISR_AWD2) { - /* Analog watchdog error.*/ - _adc_isr_error_code(adcp, ADC_ERR_AWD2); - } - if (isr & ADC_ISR_AWD3) { - /* Analog watchdog error.*/ - _adc_isr_error_code(adcp, ADC_ERR_AWD3); - } - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || defined(__DOXYGEN__) -/** - * @brief ADC1/ADC2 interrupt handler. - * - * @isr - */ -__attribute__((weak)) OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) { - uint32_t isr; - - OSAL_IRQ_PROLOGUE(); - -#if STM32_ADC_DUAL_MODE - isr = ADC1->ISR; - isr |= ADC2->ISR; - ADC1->ISR = isr; - ADC2->ISR = isr; - - adc_lld_serve_interrupt(&ADCD1, isr); -#else /* !STM32_ADC_DUAL_MODE */ -#if STM32_ADC_USE_ADC1 - isr = ADC1->ISR; - ADC1->ISR = isr; - - adc_lld_serve_interrupt(&ADCD1, isr); -#endif -#if STM32_ADC_USE_ADC2 - isr = ADC2->ISR; - ADC2->ISR = isr; - - adc_lld_serve_interrupt(&ADCD2, isr); -#endif -#endif /* !STM32_ADC_DUAL_MODE */ - - OSAL_IRQ_EPILOGUE(); -} -#endif /* STM32_ADC_USE_ADC1 */ - -#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__) -/** - * @brief ADC3 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) { - uint32_t isr; - - OSAL_IRQ_PROLOGUE(); - - isr = ADC3->ISR; - ADC3->ISR = isr; - - adc_lld_serve_interrupt(&ADCD3, isr); - - OSAL_IRQ_EPILOGUE(); -} - -#if STM32_ADC_DUAL_MODE -/** - * @brief ADC4 interrupt handler (as ADC3 slave). - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) { - uint32_t isr; - - OSAL_IRQ_PROLOGUE(); - - isr = ADC4->ISR; - ADC4->ISR = isr; - - adc_lld_serve_interrupt(&ADCD3, isr); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* STM32_ADC_DUAL_MODE */ -#endif /* STM32_ADC_USE_ADC3 */ - -#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__) -/** - * @brief ADC4 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) { - uint32_t isr; - - OSAL_IRQ_PROLOGUE(); - - isr = ADC4->ISR; - ADC4->ISR = isr; - - adc_lld_serve_interrupt(&ADCD4, isr); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* STM32_ADC_USE_ADC4 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level ADC driver initialization. - * - * @notapi - */ -void adc_lld_init(void) { - - clkmask = 0; - -#if STM32_ADC_USE_ADC1 - /* Driver initialization.*/ - adcObjectInit(&ADCD1); -#if defined(ADC1_2_COMMON) - ADCD1.adcc = ADC1_2_COMMON; -#elif defined(ADC123_COMMON) - ADCD1.adcc = ADC123_COMMON; -#else - ADCD1.adcc = ADC1_COMMON; -#endif - ADCD1.adcm = ADC1; -#if STM32_ADC_DUAL_MODE - ADCD1.adcs = ADC2; -#endif - ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC1_DMA_STREAM); - ADCD1.dmamode = ADC_DMA_SIZE | - STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | - STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; -#endif /* STM32_ADC_USE_ADC1 */ - -#if STM32_ADC_USE_ADC2 - /* Driver initialization.*/ - adcObjectInit(&ADCD2); -#if defined(ADC1_2_COMMON) - ADCD2.adcc = ADC1_2_COMMON; -#elif defined(ADC123_COMMON) - ADCD2.adcc = ADC123_COMMON; -#endif - ADCD2.adcm = ADC2; - ADCD2.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); - ADCD2.dmamode = ADC_DMA_SIZE | - STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | - STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; -#endif /* STM32_ADC_USE_ADC2 */ - -#if STM32_ADC_USE_ADC3 - /* Driver initialization.*/ - adcObjectInit(&ADCD3); -#if defined(ADC3_4_COMMON) - ADCD3.adcc = ADC3_4_COMMON; -#elif defined(ADC123_COMMON) - ADCD1.adcc = ADC123_COMMON; -#else - ADCD3.adcc = ADC3_COMMON; -#endif - ADCD3.adcm = ADC3; -#if STM32_ADC_DUAL_MODE - ADCD3.adcs = ADC4; -#endif - ADCD3.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); - ADCD3.dmamode = ADC_DMA_SIZE | - STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | - STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; -#endif /* STM32_ADC_USE_ADC3 */ - -#if STM32_ADC_USE_ADC4 - /* Driver initialization.*/ - adcObjectInit(&ADCD4); - ADCD4.adcc = ADC3_4_COMMON; - ADCD4.adcm = ADC4; - ADCD4.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC4_DMA_STREAM); - ADCD4.dmamode = ADC_DMA_SIZE | - STM32_DMA_CR_PL(STM32_ADC_ADC4_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | - STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | - STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; -#endif /* STM32_ADC_USE_ADC4 */ - - /* IRQs setup.*/ -#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 - nvicEnableVector(STM32_ADC1_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY); -#endif -#if STM32_ADC_USE_ADC3 - nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); -#if STM32_ADC_DUAL_MODE - nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); -#endif -#endif -#if STM32_ADC_USE_ADC4 - nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); -#endif - - /* ADC units pre-initializations.*/ -#if defined(STM32F3XX) -#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 - rccEnableADC12(FALSE); - rccResetADC12(); - ADC1_2_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; - rccDisableADC12(FALSE); -#endif -#if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4 - rccEnableADC34(FALSE); - rccResetADC34(); - ADC3_4_COMMON->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA; - rccDisableADC34(FALSE); -#endif -#endif - -#if defined(STM32L4XX) - rccEnableADC123(FALSE); - rccResetADC123(); - ADC123_COMMON->CCR = STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA; - rccDisableADC123(FALSE); -#endif -} - -/** - * @brief Configures and activates the ADC peripheral. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_start(ADCDriver *adcp) { - - /* Handling the default configuration.*/ - if (adcp->config == NULL) { - adcp->config = &default_config; - } - - /* If in stopped state then enables the ADC and DMA clocks.*/ - if (adcp->state == ADC_STOP) { -#if STM32_ADC_USE_ADC1 - if (&ADCD1 == adcp) { - bool b; - b = dmaStreamAllocate(adcp->dmastp, - STM32_ADC_ADC1_DMA_IRQ_PRIORITY, - (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, - (void *)adcp); - osalDbgAssert(!b, "stream already allocated"); - - clkmask |= (1 << 0); -#if defined(STM32F3XX) - rccEnableADC12(FALSE); -#endif -#if defined(STM32L4XX) - rccEnableADC123(FALSE); -#endif - } -#endif /* STM32_ADC_USE_ADC1 */ - -#if STM32_ADC_USE_ADC2 - if (&ADCD2 == adcp) { - bool b; - b = dmaStreamAllocate(adcp->dmastp, - STM32_ADC_ADC2_DMA_IRQ_PRIORITY, - (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, - (void *)adcp); - osalDbgAssert(!b, "stream already allocated"); - - clkmask |= (1 << 1); -#if defined(STM32F3XX) - rccEnableADC12(FALSE); -#endif -#if defined(STM32L4XX) - rccEnableADC123(FALSE); -#endif - } -#endif /* STM32_ADC_USE_ADC2 */ - -#if STM32_ADC_USE_ADC3 - if (&ADCD3 == adcp) { - bool b; - b = dmaStreamAllocate(adcp->dmastp, - STM32_ADC_ADC3_DMA_IRQ_PRIORITY, - (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, - (void *)adcp); - osalDbgAssert(!b, "stream already allocated"); - - clkmask |= (1 << 2); -#if defined(STM32F3XX) - rccEnableADC34(FALSE); -#endif -#if defined(STM32L4XX) - rccEnableADC123(FALSE); -#endif - } -#endif /* STM32_ADC_USE_ADC3 */ - -#if STM32_ADC_USE_ADC4 - if (&ADCD4 == adcp) { - bool b; - b = dmaStreamAllocate(adcp->dmastp, - STM32_ADC_ADC4_DMA_IRQ_PRIORITY, - (stm32_dmaisr_t)adc_lld_serve_dma_interrupt, - (void *)adcp); - osalDbgAssert(!b, "stream already allocated"); - - clkmask |= (1 << 3); -#if defined(STM32F3XX) - rccEnableADC34(FALSE); -#endif -#if defined(STM32L4XX) - rccEnableADC123(FALSE); -#endif - } -#endif /* STM32_ADC_USE_ADC4 */ - - /* Setting DMA peripheral-side pointer.*/ -#if STM32_ADC_DUAL_MODE - dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcc->CDR); -#else - dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcm->DR); -#endif - - /* Differential channels setting.*/ -#if STM32_ADC_DUAL_MODE - adcp->adcm->DIFSEL = adcp->config->difsel; - adcp->adcs->DIFSEL = adcp->config->difsel; -#else - adcp->adcm->DIFSEL = adcp->config->difsel; -#endif - - /* Master ADC calibration.*/ - adc_lld_vreg_on(adcp); - adc_lld_calibrate(adcp); - - /* Master ADC enabled here in order to reduce conversions latencies.*/ - adc_lld_analog_on(adcp); - } -} - -/** - * @brief Deactivates the ADC peripheral. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_stop(ADCDriver *adcp) { - - /* If in ready state then disables the ADC clock and analog part.*/ - if (adcp->state == ADC_READY) { - - /* Releasing the associated DMA channel.*/ - dmaStreamRelease(adcp->dmastp); - - /* Stopping the ongoing conversion, if any.*/ - adc_lld_stop_adc(adcp); - - /* Disabling ADC analog circuit and regulator.*/ - adc_lld_analog_off(adcp); - adc_lld_vreg_off(adcp); - -#if defined(STM32L4XX) - /* Resetting CCR options except default ones.*/ - adcp->adcc->CCR = STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA; -#endif - -#if STM32_ADC_USE_ADC1 - if (&ADCD1 == adcp) { -#if defined(STM32F3XX) - /* Resetting CCR options except default ones.*/ - adcp->adcc->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; -#endif - clkmask &= ~(1 << 0); - } -#endif - -#if STM32_ADC_USE_ADC2 - if (&ADCD1 == adcp) { -#if defined(STM32F3XX) - /* Resetting CCR options except default ones.*/ - adcp->adcc->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; -#endif - clkmask &= ~(1 << 1); - } -#endif - -#if STM32_ADC_USE_ADC3 - if (&ADCD1 == adcp) { -#if defined(STM32F3XX) - /* Resetting CCR options except default ones.*/ - adcp->adcc->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA; -#endif - clkmask &= ~(1 << 2); - } -#endif - -#if STM32_ADC_USE_ADC4 - if (&ADCD1 == adcp) { -#if defined(STM32F3XX) - /* Resetting CCR options except default ones.*/ - adcp->adcc->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA; -#endif - clkmask &= ~(1 << 3); - } -#endif - -#if defined(STM32F3XX) - if ((clkmask & 0x3) == 0) { - rccDisableADC12(FALSE); - } - if ((clkmask & 0xC) == 0) { - rccDisableADC34(FALSE); - } -#endif - -#if defined(STM32L4XX) - if ((clkmask & 0x7) == 0) { - rccDisableADC123(FALSE); - } -#endif - } -} - -/** - * @brief Starts an ADC conversion. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t dmamode, cfgr; - const ADCConversionGroup *grpp = adcp->grpp; -#if STM32_ADC_DUAL_MODE - uint32_t ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_MDMA_MASK); -#endif - - osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0), - "odd number of channels in dual mode"); - - /* Calculating control registers values.*/ - dmamode = adcp->dmamode; - cfgr = grpp->cfgr | ADC_CFGR_DMAEN; - if (grpp->circular) { - dmamode |= STM32_DMA_CR_CIRC; -#if STM32_ADC_DUAL_MODE - ccr |= ADC_CCR_DMACFG_CIRCULAR; -#else - cfgr |= ADC_CFGR_DMACFG_CIRCULAR; -#endif - if (adcp->depth > 1) { - /* If circular buffer depth > 1, then the half transfer interrupt - is enabled in order to allow streaming processing.*/ - dmamode |= STM32_DMA_CR_HTIE; - } - } - - /* DMA setup.*/ - dmaStreamSetMemory0(adcp->dmastp, adcp->samples); -#if STM32_ADC_DUAL_MODE - dmaStreamSetTransactionSize(adcp->dmastp, ((uint32_t)grpp->num_channels/2) * - (uint32_t)adcp->depth); -#else - dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * - (uint32_t)adcp->depth); -#endif - dmaStreamSetMode(adcp->dmastp, dmamode); - dmaStreamEnable(adcp->dmastp); - - /* ADC setup, if it is defined a callback for the analog watch dog then it - is enabled.*/ - adcp->adcm->ISR = adcp->adcm->ISR; - adcp->adcm->IER = ADC_IER_OVR | ADC_IER_AWD1; - adcp->adcm->TR1 = grpp->tr1; -#if STM32_ADC_DUAL_MODE - - /* Configuring the CCR register with the user-specified settings - in the conversion group configuration structure, static settings are - preserved.*/ - adcp->adcc->CCR = (adcp->adcc->CCR & - (ADC_CCR_CKMODE_MASK | ADC_CCR_MDMA_MASK)) | ccr; - - adcp->adcm->SMPR1 = grpp->smpr[0]; - adcp->adcm->SMPR2 = grpp->smpr[1]; - adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2); - adcp->adcm->SQR2 = grpp->sqr[1]; - adcp->adcm->SQR3 = grpp->sqr[2]; - adcp->adcm->SQR4 = grpp->sqr[3]; - adcp->adcs->SMPR1 = grpp->ssmpr[0]; - adcp->adcs->SMPR2 = grpp->ssmpr[1]; - adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2); - adcp->adcs->SQR2 = grpp->ssqr[1]; - adcp->adcs->SQR3 = grpp->ssqr[2]; - adcp->adcs->SQR4 = grpp->ssqr[3]; - -#else /* !STM32_ADC_DUAL_MODE */ - adcp->adcm->SMPR1 = grpp->smpr[0]; - adcp->adcm->SMPR2 = grpp->smpr[1]; - adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels); - adcp->adcm->SQR2 = grpp->sqr[1]; - adcp->adcm->SQR3 = grpp->sqr[2]; - adcp->adcm->SQR4 = grpp->sqr[3]; -#endif /* !STM32_ADC_DUAL_MODE */ - - /* ADC configuration.*/ - adcp->adcm->CFGR = cfgr; - - /* Starting conversion.*/ - adcp->adcm->CR |= ADC_CR_ADSTART; -} - -/** - * @brief Stops an ongoing conversion. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adc_lld_stop_conversion(ADCDriver *adcp) { - - dmaStreamDisable(adcp->dmastp); - adc_lld_stop_adc(adcp); -} - -/** - * @brief Enables the VREFEN bit. - * @details The VREFEN bit is required in order to sample the VREF channel. - * @note This is an STM32-only functionality. - * @note This function is meant to be called after @p adcStart(). - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adcSTM32EnableVREF(ADCDriver *adcp) { - - adcp->adcc->CCR |= ADC12_CCR_VREFEN; -} - -/** - * @brief Disables the VREFEN bit. - * @details The VREFEN bit is required in order to sample the VREF channel. - * @note This is an STM32-only functionality. - * @note This function is meant to be called after @p adcStart(). - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adcSTM32DisableVREF(ADCDriver *adcp) { - - adcp->adcc->CCR &= ~ADC12_CCR_VREFEN; -} - -/** - * @brief Enables the TSEN bit. - * @details The TSEN bit is required in order to sample the internal - * temperature sensor and internal reference voltage. - * @note This is an STM32-only functionality. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adcSTM32EnableTS(ADCDriver *adcp) { - - adcp->adcc->CCR |= ADC_CCR_TSEN; -} - -/** - * @brief Disables the TSEN bit. - * @details The TSEN bit is required in order to sample the internal - * temperature sensor and internal reference voltage. - * @note This is an STM32-only functionality. - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adcSTM32DisableTS(ADCDriver *adcp) { - - adcp->adcc->CCR &= ~ADC_CCR_TSEN; -} - -/** - * @brief Enables the VBATEN bit. - * @details The VBATEN bit is required in order to sample the VBAT channel. - * @note This is an STM32-only functionality. - * @note This function is meant to be called after @p adcStart(). - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adcSTM32EnableVBAT(ADCDriver *adcp) { - - adcp->adcc->CCR |= ADC12_CCR_VBATEN; -} - -/** - * @brief Disables the VBATEN bit. - * @details The VBATEN bit is required in order to sample the VBAT channel. - * @note This is an STM32-only functionality. - * @note This function is meant to be called after @p adcStart(). - * - * @param[in] adcp pointer to the @p ADCDriver object - * - * @notapi - */ -void adcSTM32DisableVBAT(ADCDriver *adcp) { - - adcp->adcc->CCR &= ~ADC12_CCR_VBATEN; -} - -#endif /* HAL_USE_ADC */ - -/** @} */ diff --git a/halconf.h b/halconf.h index 7d8683e..3f85806 100644 --- a/halconf.h +++ b/halconf.h @@ -332,6 +332,10 @@ #define SERIAL_USB_TX_BUFFERS_NUMBER 2 #endif +// USB Send timeout +//#define USB_WRITE_TIMEOUT MS2ST(100) // 100ms +//#define USB_READ_TIMEOUT MS2ST(100) // 100ms + //#define STM32_USB_USE_FAST_COPY TRUE //#define STM32_USB_USE_ISOCHRONOUS TRUE /*===========================================================================*/ diff --git a/ili9341.c b/ili9341.c index 21dce2e..e74f231 100644 --- a/ili9341.c +++ b/ili9341.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com + * Copyright (c) 2019-2023, Dmitry (DiSlord) dislordlive@gmail.com * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com * All rights reserved. * @@ -44,6 +44,10 @@ #ifdef LCD_DRIVER_ILI9341 // Set SPI bus speed for LCD #define LCD_SPI_SPEED SPI_BR_DIV2 +#ifdef DISPLAY_ST7789 +#define LCD_SPI_RX_SPEED SPI_BR_DIV16 +#endif + // Read speed, need more slow, not define if need use some as Tx speed //#define LCD_SPI_RX_SPEED SPI_BR_DIV4 // Allow enable DMA for read display data (can not stable on full speed, on less speed slower) @@ -73,6 +77,10 @@ pixel_t background_color = 0; //***************************************************** // SPI functions, settings and data //***************************************************** +void spi_TxByte(const uint8_t data) { + while (SPI_TX_IS_NOT_EMPTY(LCD_SPI)); + SPI_WRITE_8BIT(LCD_SPI, data); +} // Transmit buffer to SPI bus (len should be > 0) void spi_TxBuffer(const uint8_t *buffer, uint16_t len) { while(len--) { @@ -100,7 +108,7 @@ void spi_RxBuffer(uint8_t *buffer, uint16_t len) { void spi_DropRx(void) { // Drop Rx buffer after tx and wait tx complete -#if 0 +#if 1 while (SPI_RX_IS_NOT_EMPTY(LCD_SPI)||SPI_IS_BUSY(LCD_SPI)) (void)SPI_READ_8BIT(LCD_SPI); (void)SPI_READ_8BIT(LCD_SPI); @@ -167,8 +175,8 @@ static void spi_init(void) { | 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) | LCD_SPI_SPEED // Baud rate control -// | SPI_CR1_CPHA // Clock Phase -// | SPI_CR1_CPOL // Clock Polarity + | SPI_CR1_CPHA // Clock Phase + | SPI_CR1_CPOL // Clock Polarity ; LCD_SPI->CR2 = SPI_CR2_8BIT // SPI data size, set to 8 bit | SPI_CR2_FRXTH // SPI_SR_RXNE generated every 8 bit data @@ -290,12 +298,6 @@ static void spi_init(void) { #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) - // Disable inline for this function static void ili9341_send_command(uint8_t cmd, uint16_t len, const uint8_t *data) { // Uncomment on low speed SPI (possible get here before previous tx complete) @@ -331,7 +333,135 @@ uint32_t lcd_send_command(uint8_t cmd, uint8_t len, const uint8_t *data) { return ret; } -#ifdef LCD_DRIVER_ILI9341 +#define ST7789V_NOP 0x00 // No Operation +#define ST7789V_SWRESET 0x01 // Software reset +#define ST7789V_RDDID 0x04 // Read Display ID +#define ST7789V_RDDST 0x09 // Read Display Status +#define ST7789V_RDDPM 0x0A // Read Display Power Mode +#define ST7789V_RDDMADCTL 0x0B // Read Display MADCTL +#define ST7789V_RDDCOLMOD 0x0C // Read Display Pixel Format +#define ST7789V_RDDIM 0x0D // Read Display Image Mode +#define ST7789V_RDDSM 0x0E // Read Display Signal Mode +#define ST7789V_RDDSDR 0x0F // Read Display Self-Diagnostic Result +#define ST7789V_SLPIN 0x10 // Sleep In +#define ST7789V_SLPOUT 0x11 // Sleep Out +#define ST7789V_PTLON 0x12 // Partial Display Mode On +#define ST7789V_NORON 0x13 // Normal Display Mode On +#define ST7789V_INVOFF 0x20 // Display Inversion Off +#define ST7789V_INVON 0x21 // Display Inversion On +#define ST7789V_GAMSET 0x26 // Gamma Set +#define ST7789V_DISPOFF 0x28 // Display Off +#define ST7789V_DISPON 0x29 // Display On +#define ST7789V_CASET 0x2A // Column Address Set +#define ST7789V_RASET 0x2B // Row Address Set +#define ST7789V_RAMWR 0x2C // Memory Write +#define ST7789V_RAMRD 0x2E // Memory Read +#define ST7789V_PTLAR 0x30 // Partial Area +#define ST7789V_VSCRDEF 0x33 // Vertical Scrolling Definition +#define ST7789V_TEOFF 0x34 // Tearing Effect Line OFF +#define ST7789V_TEON 0x35 // Tearing Effect Line ON +#define ST7789V_MADCTL 0x36 // Memory Data Access Control +#define ST7789V_VSCSAD 0x37 // Vertical Scroll Start Address of RAM +#define ST7789V_IDMOFF 0x38 // Idle Mode Off +#define ST7789V_IDMON 0x39 // Idle Mode On +#define ST7789V_COLMOD 0x3A // Interface Pixel Format +#define ST7789V_WRMEMC 0x3C // Write Memory Continue +#define ST7789V_RDMEMC 0x3E // Read Memory Continue +#define ST7789V_STE 0x44 // Set Tear Scanline +#define ST7789V_GSCAN 0x45 // Get Scanline +#define ST7789V_WRDISBV 0x51 // Write Display Brightness +#define ST7789V_RDDISBV 0x52 // Read Display Brightness +#define ST7789V_WRCTRLD 0x53 // Write CTRL Display +#define ST7789V_RDCTRLD 0x54 // Read CTRL Value Display +#define ST7789V_WRCACE 0x55 // Write Content Adaptive Brightness Control and Color Enhancement +#define ST7789V_RDCABC 0x56 // Read Content Adaptive Brightness Control +#define ST7789V_WRCABCMB 0x5E // Write CABC Minimum Brightness +#define ST7789V_RDCABCMB 0x5F // Read CABC Minimum Brightness +#define ST7789V_RDABCSDR 0x68 // Read Automatic Brightness Control Self-Diagnostic Result +#define ST7789V_RDID1 0xDA // Read ID1 Value +#define ST7789V_RDID2 0xDB // Read ID2 Value +#define ST7789V_RDID3 0xDC // Read ID3 Value + +#define ST7789V_RAMCTRL 0xB0 // RAM Control +#define ST7789V_RGBCTRL 0xB1 // RGB Interface Control +#define ST7789V_PORCTRL 0xB2 // Porch Setting +#define ST7789V_FRCTRL1 0xB3 // Frame Rate Control 1 (In partial mode/ idle colors) +#define ST7789V_GCTRL 0xB7 // Gate Control +#define ST7789V_DGMEN 0xBA // Digital Gamma Enable +#define ST7789V_VCOMS 0xBB // VCOM Setting +#define ST7789V_LCMCTRL 0xC0 // LCM Control +#define ST7789V_IDSET 0xC1 // ID Code Setting +#define ST7789V_VDVVRHEN 0xC2 // VDV and VRH Command Enable +#define ST7789V_VRHS 0xC3 // VRH Set +#define ST7789V_VDVS 0xC4 // VDV Set +#define ST7789V_VCMOFSET 0xC5 // VCOM Offset Set +#define ST7789V_FRCTRL2 0xC6 // Frame Rate Control in Normal Mode +#define ST7789V_CABCCTRL 0xC7 // CABC Control +#define ST7789V_REGSEL1 0xC8 // Register Value Selection 1 +#define ST7789V_REGSEL2 0xCA // Register Value Selection 2 +#define ST7789V_PWMFRSEL 0xCC // PWM Frequency Selection +#define ST7789V_PWCTRL1 0xD0 // Power Control 1 +#define ST7789V_VAPVANEN 0xD2 // Enable VAP/VAN signal output +#define ST7789V_CMD2EN 0xDF // Command 2 Enable +#define ST7789V_PVGAMCTRL 0xE0 // Positive Voltage Gamma Control +#define ST7789V_NVGAMCTRL 0xE1 // Negative Voltage Gamma Control +#define ST7789V_DGMLUTR 0xE2 // Digital Gamma Look-up Table for Red +#define ST7789V_DGMLUTB 0xE3 // Digital Gamma Look-up Table for Blue +#define ST7789V_GATECTRL 0xE4 // Gate Control +#define ST7789V_SPI2EN 0xE7 // SPI2 Enable +#define ST7789V_PWCTRL2 0xE8 // Power Control 2 +#define ST7789V_EQCTRL 0xE9 // Equalize time control +#define ST7789V_PROMCTRL 0xEC // Program Mode Control +#define ST7789V_PROMEN 0xFA // Program Mode Enable +#define ST7789V_NVMSET 0xFC // NVM Setting +#define ST7789V_PROMACT 0xFE // Program action + + +#define LCD_MADCTL_MY 0x80 +#define LCD_MADCTL_MX 0x40 +#define LCD_MADCTL_MV 0x20 +#define LCD_MADCTL_ML 0x10 +#define LCD_MADCTL_BGR 0x08 +#define LCD_MADCTL_MH 0x04 +#define LCD_MADCTL_RGB 0x00 + +#ifdef DISPLAY_ST7789 +/* + * ST7789 init + */ +#define DISPLAY_ROTATION_0 (LCD_MADCTL_MX | LCD_MADCTL_MV | LCD_MADCTL_RGB) +#define DISPLAY_ROTATION_90 ( LCD_MADCTL_RGB) +#define DISPLAY_ROTATION_180 (LCD_MADCTL_MY | LCD_MADCTL_MV | LCD_MADCTL_RGB) +#define DISPLAY_ROTATION_270 (LCD_MADCTL_MX | LCD_MADCTL_MY | LCD_MADCTL_RGB) +static const uint8_t ST7796S_init_seq[] = { + // cmd, len, data..., + // SW reset + ST7789V_SWRESET, 0, + // display off + ST7789V_DISPOFF, 0, + ST7789V_MADCTL, 1, DISPLAY_ROTATION_0, + ST7789V_COLMOD, 1, 0x55, +//ST7789V_PORCTRL, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, +//ST7789V_GCTRL, 1, 0x35, + ST7789V_VCOMS, 1, 0x1F, // default 0x20 +//ST7789V_LCMCTRL, 1, 0x2C, + ST7789V_VDVVRHEN, 2, 0x01, 0xC3, // default 0x01, 0xFF !!! why need C3? datasheet say 0xFF +//ST7789V_VDVS, 1, 0x20, +//ST7789V_FRCTRL2, 1, 0x0F, +//ST7789V_PWCTRL1, 2, 0xA4, 0xA1, + ST7789V_SLPOUT, 0, + // display on + ST7789V_DISPON, 0, + 0 // sentinel +}; +#define LCD_INIT ST7796S_init_seq +#else + +#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) static const uint8_t ili9341_init_seq[] = { // cmd, len, data..., // SW reset @@ -687,6 +817,7 @@ void lcd_clear_screen(void) { lcd_fill(0, 0, LCD_WIDTH, LCD_HEIGHT); } + void lcd_set_foreground(uint16_t fg_idx) { foreground_color = GET_PALTETTE_COLOR(fg_idx); } @@ -695,6 +826,11 @@ void lcd_set_background(uint16_t bg_idx) { background_color = GET_PALTETTE_COLOR(bg_idx); } +void lcd_set_colors(uint16_t fg_idx, uint16_t bg_idx) { + foreground_color = GET_PALTETTE_COLOR(fg_idx); + background_color = GET_PALTETTE_COLOR(bg_idx); +} + void lcd_set_flip(bool flip) { dmaChannelWaitCompletionRxTx(); uint8_t memAcc = flip ? DISPLAY_ROTATION_180 : DISPLAY_ROTATION_0; @@ -708,7 +844,7 @@ void ili9341_set_rotation(uint8_t r) { } void lcd_blitBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *b) { -#if 0 +#if 1 // Use this for remote desctop (in this case bulk operation send to remote) pixel_t *buf = spi_buffer; uint8_t bits = 0; for (uint32_t c = 0; c < height; c++) { @@ -841,9 +977,39 @@ int lcd_printfV(int16_t x, int16_t y, const char *fmt, ...) { return retval; } +void lcd_blitBitmapScale(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t size, const uint8_t *b) { + ili9341_setWindow(x, y, w * size, h * size, ILI9341_MEMORY_WRITE); + for (int c = 0; c < h; c++) { + const uint8_t *ptr = b; uint8_t bits = 0; + for (int i = 0; i < size; i++) { + ptr = b; + for (int r = 0; r < w; r++, bits <<= 1) { + if ((r&7) == 0) bits = *ptr++; + for (int j = 0; j < size; j++) { + while (SPI_TX_IS_NOT_EMPTY(LCD_SPI)); + SPI_WRITE_16BIT(LCD_SPI, (0x80 & bits) ? foreground_color : background_color); + } + } + } + b = ptr; + } +} + int lcd_drawchar_size(uint8_t ch, int x, int y, uint8_t size) { const uint8_t *char_buf = FONT_GET_DATA(ch); uint16_t w = FONT_GET_WIDTH(ch); +#if 1 + pixel_t *buf = spi_buffer; + for (uint32_t c = 0; c < FONT_GET_HEIGHT; c++, char_buf++) { + for (uint32_t i = 0; i < size; i++) { + uint8_t bits = *char_buf; + for (uint32_t r = 0; r < w; r++, bits <<= 1) + for (uint32_t j = 0; j < size; j++) + *buf++ = (0x80 & bits) ? foreground_color : background_color; + } + } + lcd_bulk(x, y, w * size, FONT_GET_HEIGHT * size); +#else ili9341_setWindow(x, y, w * size, FONT_GET_HEIGHT * size, ILI9341_MEMORY_WRITE); for (int c = 0; c < FONT_GET_HEIGHT; c++, char_buf++) { for (int i = 0; i < size; i++) { @@ -855,6 +1021,7 @@ int lcd_drawchar_size(uint8_t ch, int x, int y, uint8_t size) { } } } +#endif return w * size; } @@ -951,14 +1118,16 @@ void ili9341_test(int mode) { #define CMD58 (0x40+58) // READ_OCR #define CMD59 (0x40+59) // CRC_ON_OFF // Then send after CMD55 (APP_CMD) interpret as ACMD -#define ACMD41 (0x40+41) // SEND_OP_COND (ACMD) +#define ACMD41 (0xC0+41) // SEND_OP_COND (ACMD) -// MMC card type flags (MMC_GET_TYPE) -#define CT_MMC 0x01 // MMC v3 -#define CT_SD1 0x02 // SDv1 -#define CT_SD2 0x04 // SDv2 -#define CT_SDC 0x06 // SD -#define CT_BLOCK 0x08 // Block addressing +// MMC card type and status flags +#define CT_MMC 0x01 // MMC v3 +#define CT_SD1 0x02 // SDv1 +#define CT_SD2 0x04 // SDv2 +#define CT_SDC 0x06 // SD +#define CT_BLOCK 0x08 // Block addressing +#define CT_WRPROTECT 0x40 // Write protect flag +#define CT_POWER_ON 0x80 // Power ON flag // 7.3.2 Responses // 7.3.2.1 Format R1 (1 byte) @@ -1033,8 +1202,6 @@ void ili9341_test(int mode) { #define CSD_14_TMP_WRITE_PROTECT 0b00010000 #define CSD_14_FILE_FORMAT 0b00001100 #define CSD_15_CRC 0b11111110 - - // 7.3.3.1 Data Response Token #define SD_TOKEN_DATA_ACCEPTED ((uint8_t)0x05) // Data accepted #define SD_TOKEN_WRITE_CRC_ERROR ((uint8_t)0x0b) // Data rejected due to a CRC error @@ -1052,9 +1219,6 @@ void ili9341_test(int mode) { //***************************************************** // SD card module settings //***************************************************** -// Additional state flag definition -#define STA_POWER_ON 0x80 // Power ON flag - // Use for enable CRC check of Tx and Rx data on SPI // If enable both CRC check, on initialization send SD command - CRC_ON_OFF vs ON // And Card begin check received data and answer on CRC errors @@ -1086,8 +1250,7 @@ void ili9341_test(int mode) { #define SD_INIT_SPI_SPEED SPI_BR_DIV256 // Local values for SD card state -static DSTATUS Stat = STA_NOINIT; // Disk Status -static uint8_t CardType = 0; // Type 0:MMC, 1:SDC, 2:Block addressing +static uint8_t CardStatus = 0; // Status: power on, write protect and Type 0:MMC, 1:SDC, 2:Block addressing // Debug functions, 0 to disable #define DEBUG 0 @@ -1101,8 +1264,8 @@ uint32_t r_time; uint32_t total_time; uint32_t crc_time; void testLog(void){ - DEBUG_PRINT(" Read speed = %d Byte/s (count %d, time %d)\r\n", r_cnt*512*10000/r_time, r_cnt, r_time); - DEBUG_PRINT(" Write speed = %d Byte/s (count %d, time %d)\r\n", w_cnt*512*10000/w_time, w_cnt, w_time); + DEBUG_PRINT(" Read speed = %d Byte/s (count %d, time %d)\r\n", r_cnt*512*100000/r_time, r_cnt, r_time); + DEBUG_PRINT(" Write speed = %d Byte/s (count %d, time %d)\r\n", w_cnt*512*100000/w_time, w_cnt, w_time); DEBUG_PRINT(" Total time = %d\r\n", chVTGetSystemTimeX() - total_time); DEBUG_PRINT(" CRC16 time %d\r\n", crc_time); } @@ -1115,12 +1278,14 @@ void testLog(void){ #define SD_CS_HIGH palSetPad(GPIOB, GPIOB_SD_CS) static void SD_Select_SPI(uint32_t speed) { + while (SPI_IS_BUSY(LCD_SPI)); LCD_CS_HIGH; // Unselect LCD SPI_BR_SET(SD_SPI, speed); // Set Baud rate control for SD card SD_CS_LOW; // Select SD Card } static void SD_Unselect_SPI(void) { + while (SPI_IS_BUSY(SD_SPI)); SD_CS_HIGH; // Unselect SD Card spi_RxByte(); // Dummy read/write one Byte recommend for SD after CS up SPI_BR_SET(LCD_SPI, LCD_SPI_SPEED); // Restore Baud rate for LCD @@ -1188,7 +1353,7 @@ static uint16_t crc16(const uint8_t *ptr, uint16_t count) { #endif // Wait and read R1 answer from SD -static inline uint8_t SD_ReadR1(uint32_t cnt) { +static uint8_t SD_ReadR1(uint32_t cnt) { uint8_t r1; // 8th bit R1 always zero, check it spi_DropRx(); @@ -1198,26 +1363,19 @@ static inline uint8_t SD_ReadR1(uint32_t cnt) { } // Wait SD ready token answer (wait time in systick) -static inline bool SD_WaitDataToken(uint8_t token, uint32_t wait_time) { +static bool SD_WaitDataToken(uint8_t token, uint32_t wait_time) { uint8_t res; uint32_t time = chVTGetSystemTimeX(); - uint8_t count = 0; spi_DropRx(); - do{ - if ((res = spi_RxByte()) == token) - return true; - count++; - // Check timeout only every 256 bytes read (~8ms) - if (count == 0 && (chVTGetSystemTimeX() - time) > wait_time) - break; - }while (res == 0xFF); - return false; + while((res = spi_RxByte()) != token && chVTGetSystemTimeX() - time < wait_time) + ; + return res == token; } -static inline uint8_t SD_WaitDataAccept(uint32_t cnt) { +static uint8_t SD_WaitDataAccept(uint32_t cnt) { uint8_t res; spi_DropRx(); - while ((res = spi_RxByte()) == 0xFF && --cnt) + while((res = spi_RxByte()) == 0xFF && --cnt) ; return res&0x1F; } @@ -1226,16 +1384,11 @@ static inline uint8_t SD_WaitDataAccept(uint32_t cnt) { static uint8_t SD_WaitNotBusy(uint32_t wait_time) { uint8_t res; uint32_t time = chVTGetSystemTimeX(); - uint8_t count = 0; spi_DropRx(); - do{ + do { if ((res = spi_RxByte()) == 0xFF) return res; - count++; - // Check timeout only every 256 bytes read (~8ms) - if (count == 0 && (chVTGetSystemTimeX() - time) > wait_time) - break; - }while (1); + } while(chVTGetSystemTimeX() - time < wait_time); return 0; } @@ -1256,8 +1409,8 @@ static bool SD_RxDataBlock(uint8_t *buff, uint16_t len, uint8_t token) { uint16_t crc; spi_RxBuffer((uint8_t*)&crc, 2); #ifdef SD_USE_DATA_CRC uint16_t bcrc = crc16(buff, len); - if (crc!=bcrc){ - DEBUG_PRINT("CRC = %04x , hcalc = %04x, calc = %04x\r\n", (uint32_t)crc, (uint32_t)bcrc, (uint32_t)crc16(buff, len)); + if (crc != bcrc){ + DEBUG_PRINT("CRC = %04x , calc = %04x\r\n", (uint32_t)crc, (uint32_t)bcrc); return FALSE; } #endif @@ -1266,59 +1419,53 @@ static bool SD_RxDataBlock(uint8_t *buff, uint16_t len, uint8_t token) { // Transmit data block to SD static bool SD_TxDataBlock(const uint8_t *buff, uint16_t len, uint8_t token) { - uint8_t resp; + uint8_t r1; // Transmit token - SPI_WRITE_8BIT(SD_SPI, token); -#if 0 // Not use multiple block tx - // if it's not STOP token, transmit data, in multiple block Tx - if (token == SD_TOKEN_STOP_BLOCK) return TRUE; -#endif - uint16_t bcrc = 0xFFFF; + spi_TxByte(token); #ifdef __USE_SDCARD_DMA__ spi_DMATxBuffer(buff, len, false); -#ifdef SD_USE_DATA_CRC - bcrc = crc16(buff, len); -#endif - dmaChannelWaitCompletion(SD_DMA_TX); #else spi_TxBuffer((uint8_t*)buff, len); +#endif + // Calculate and Send CRC #ifdef SD_USE_DATA_CRC - bcrc = crc16(buff, len); + uint16_t bcrc = crc16(buff, len); +#else + uint16_t bcrc = 0xFFFF; #endif +#ifdef __USE_SDCARD_DMA__ + dmaChannelWaitCompletion(SD_DMA_TX); #endif - SPI_WRITE_16BIT(SD_SPI, bcrc); // Send CRC - // Receive transmit data response token on next 100 bytes - resp = SD_WaitDataAccept(100); - if (resp != SD_TOKEN_DATA_ACCEPTED){ - goto error_tx; + spi_TxByte((bcrc>>0) & 0xFF); // Send CRC + spi_TxByte((bcrc>>8) & 0xFF); + // Receive transmit data response token on next 8 bytes + if ((r1 = SD_WaitDataAccept(100)) != SD_TOKEN_DATA_ACCEPTED) { + DEBUG_PRINT(" Tx accept error = %04x\n", (uint32_t)r1); + return FALSE; } -#if 0 - // Wait busy (recommended timeout is 250ms (500ms for SDXC) set 250ms - resp = SD_WaitNotBusy(MS2ST(250)); - if (resp == 0xFF) - return TRUE; -#else +#if 0 // Wait busy in block transfer (recommended timeout is 250ms (500ms for SDXC) set 250ms + if (token == SD_TOKEN_START_M_BLOCK && (r1 = SD_WaitNotBusy(MS2ST(250))) != 0xFF) { + DEBUG_PRINT(" Tx busy error = %04\n", (uint32_t)r1); + return FALSE; + } +#endif // Continue execute, wait not busy on next command return TRUE; -#endif - DEBUG_PRINT(" Tx busy error = %04\r\n", (uint32_t)resp); - return FALSE; -error_tx: - DEBUG_PRINT(" Tx accept error = %04x\r\n", (uint32_t)resp); - return FALSE; } // Transmit command to SD static uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg) { uint8_t buf[6]; uint8_t r1; + // Advanced command (ACMD__), need send CMD55 before + if ((cmd & 0x80) && (r1 = SD_SendCmd(CMD55, 0)) > 1) return r1; // wait SD ready after last Tx (recommended timeout is 250ms (500ms for SDXC) set 250ms if ((r1 = SD_WaitNotBusy(MS2ST(500))) != 0xFF) { DEBUG_PRINT(" SD_WaitNotBusy CMD%d err, %02x\r\n", cmd-0x40, (uint32_t)r1); return 0xFF; } // Transmit command - buf[0] = cmd; + buf[0] = cmd & 0x7F; buf[1] = (arg >> 24)&0xFF; buf[2] = (arg >> 16)&0xFF; buf[3] = (arg >> 8)&0xFF; @@ -1334,43 +1481,17 @@ static uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg) { spi_TxBuffer(buf, 6); // Skip a stuff byte when STOP_TRANSMISSION if (cmd == CMD12) spi_RxByte(); - // Receive response register r1 + // Receive response register r1 (need max 8 cycles, in tests answer on next read) r1 = SD_ReadR1(100); -#if 1 if (r1&(SD_R1_NOT_R1|SD_R1_CRC_ERROR|SD_R1_ERASE_RESET|SD_R1_ERR_ERASE_CLR)){ DEBUG_PRINT(" SD_SendCmd err CMD%d, 0x%x, 0x%08x\r\n", (uint32_t)cmd-0x40, (uint32_t)r1, arg); return r1; } if (r1&(~SD_R1_IDLE)) DEBUG_PRINT(" SD_SendCmd CMD%d, 0x%x, 0x%08x\r\n", (uint32_t)cmd-0x40, (uint32_t)r1, arg); -#endif return r1; } -// Power on SD -static void SD_PowerOn(void) { - uint16_t n; - LCD_CS_HIGH; - // Dummy TxRx 80 bits for power up SD - for (n=0;n<10;n++) - spi_RxByte(); - SD_Select_SPI(SD_INIT_SPI_SPEED); - // Set SD card to idle state - if (SD_SendCmd(CMD0, 0) == SD_R1_IDLE) - Stat|= STA_POWER_ON; - SD_Unselect_SPI(); -} - -// Power off SD -static inline void SD_PowerOff(void) { - Stat &= ~STA_POWER_ON; -} - -// Check power flag -static inline uint8_t SD_CheckPower(void) { - return Stat & STA_POWER_ON; -} - //******************************************************* // diskio.c functions for file system library //******************************************************* @@ -1392,52 +1513,43 @@ DSTATUS disk_initialize(BYTE pdrv) { crc_time = 0; total_time = chVTGetSystemTimeX(); #endif - if (pdrv != 0) return STA_NOINIT; + if (pdrv != 0) return disk_status(pdrv); // Start init SD card - Stat = STA_NOINIT; - // power on, try detect on bus, set card to idle state - SD_PowerOn(); - if (!SD_CheckPower()) return Stat; + CardStatus = 0; + LCD_CS_HIGH; + // Power on, try detect on bus, set card to idle state: + // Dummy TxRx 80 bits for power up SD + for(int n = 0; n < 10; n++) + spi_RxByte(); // check disk type uint8_t type = 0; uint32_t cnt = 100; // Set low SPI bus speed = PLL/256 (on 72MHz =281.250kHz) SD_Select_SPI(SD_INIT_SPI_SPEED); // send GO_IDLE_STATE command - if (SD_SendCmd(CMD0, 0) == SD_R1_IDLE) - { + if (SD_SendCmd(CMD0, 0) == SD_R1_IDLE) { DEBUG_PRINT(" CMD0 Ok\r\n"); // SDC V2+ accept CMD8 command, http://elm-chan.org/docs/mmc/mmc_e.html - if (SD_SendCmd(CMD8, 0x00001AAU) == SD_R1_IDLE) - { - DEBUG_PRINT(" CMD8 Ok\r\n"); + if (SD_SendCmd(CMD8, 0x00001AAU) == SD_R1_IDLE) { uint32_t ocr; spi_RxBuffer((uint8_t *)&ocr, 4); DEBUG_PRINT(" CMD8 0x%x\r\n", ocr); // operation condition register voltage range 2.7-3.6V - if (ocr == _OCR(0x00001AAU)) - { + if (ocr == _OCR(0x00001AAU)) { // ACMD41 with HCS bit can be up to 200ms wait - do { - if (SD_SendCmd(CMD55, 0) <= 1 && // APP_CMD Get Ok or idle state - SD_SendCmd(ACMD41, SD_OCR_CAPACITY) == 0) // Check OCR - break; + while (SD_SendCmd(ACMD41, SD_OCR_CAPACITY) != 0 && --cnt) // Check OCR chThdSleepMilliseconds(10); - } while (--cnt); - DEBUG_PRINT(" CMD55 + ACMD41 %d\r\n", cnt); + DEBUG_PRINT(" ACMD41 %d\r\n", cnt); // READ_OCR - if (cnt && SD_SendCmd(CMD58, 0) == 0) - { + if (cnt && SD_SendCmd(CMD58, 0) == 0) { DWORD ocr; spi_RxBuffer((uint8_t *)&ocr, 4); DEBUG_PRINT(" CMD58 OCR = 0x%08x\r\n", _OCR(ocr)); // Check CCS bit, SDv2 (HC or SC) type = (ocr & _OCR(SD_OCR_CAPACITY)) ? CT_SD2 | CT_BLOCK : CT_SD2; } } -#ifdef SD_USE_COMMAND_CRC -#ifdef SD_USE_DATA_CRC +#if defined(SD_USE_COMMAND_CRC) && defined(SD_USE_DATA_CRC) SD_SendCmd(CMD59, 1); // Enable CRC check on card #endif -#endif // uint8_t csd[16]; // if (SD_SendCmd(CMD9, 0) == 0 && SD_RxDataBlock(csd, 16, SD_TOKEN_START_BLOCK)){ // DEBUG_PRINT(" CSD ="); @@ -1445,63 +1557,48 @@ DSTATUS disk_initialize(BYTE pdrv) { // DEBUG_PRINT(" %02x", csd[i]); // DEBUG_PRINT("\r\n"); // } - } else { - DEBUG_PRINT(" CMD8 Fail\r\n"); - // SDC V1 or MMC - type = (SD_SendCmd(CMD55, 0) <= 1 && // APP_CMD - SD_SendCmd(ACMD41, 0) <= 1) ? CT_SD1 : CT_MMC; - DEBUG_PRINT(" CMD55 %d\r\n", type); - do{ - if (type == CT_SD1) - { - if (SD_SendCmd(CMD55, 0) <= 1 && SD_SendCmd(ACMD41, 0) == 0) break; // ACMD41 - } - else if (SD_SendCmd(CMD1, 0) == 0) break; // CMD1 + } else { // SDC V1 or MMC + uint8_t cmd = (SD_SendCmd(ACMD41, 0) <= 1) ? ACMD41 : CMD1; // cmd for idle state + DEBUG_PRINT(" CMD8 Fail, cmd = 0x%02x\r\n", cmd); + while(SD_SendCmd(cmd, 0) && --cnt) // Wait idle state (depend from card type) chThdSleepMilliseconds(10); - } while (--cnt); - // SET_BLOCKLEN - if (!cnt || SD_SendCmd(CMD16, SD_SECTOR_SIZE) != 0) type = 0; + if (cnt && SD_SendCmd(CMD16, SD_SECTOR_SIZE) == 0) // SET_BLOCKLEN and set type + type = cmd == ACMD41 ? CT_SD1 : CT_MMC; DEBUG_PRINT(" CMD16 %d %d\r\n", cnt, type); } } SD_Unselect_SPI(); - CardType = type; DEBUG_PRINT("CardType %d\r\n", type); - // Clear STA_NOINIT if (type) - Stat&=~STA_NOINIT; - else // Initialization failed - SD_PowerOff(); - return Stat; + CardStatus = CT_POWER_ON | type; + return disk_status(pdrv); } // diskio.c - Return disk status DSTATUS disk_status(BYTE pdrv) { if (pdrv != 0) return STA_NOINIT; - return Stat; + return CardStatus == 0 ? STA_NOINIT : 0; } // diskio.c - Read sector DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { // No disk or wrong block count - if (pdrv != 0 || (Stat & STA_NOINIT)) return RES_NOTRDY; + if (pdrv != 0 || !(CardStatus & CT_POWER_ON)) return RES_NOTRDY; #if DEBUG == 1 - r_cnt++; + r_cnt+= count; r_time-= chVTGetSystemTimeX(); #endif SD_Select_SPI(SD_SPI_RX_SPEED); - uint8_t cmd = count == 1 ? CMD17 : CMD18; - // convert to byte address - if (!(CardType & CT_BLOCK)) sector*= SD_SECTOR_SIZE; - // Read single / multiple block - if (SD_SendCmd(cmd, sector) == 0) { - do { - if (SD_RxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK)) - buff+= SD_SECTOR_SIZE; - else break; - } while(--count); + // convert to byte address if no block mode + if (!(CardStatus & CT_BLOCK)) sector*= SD_SECTOR_SIZE; + if (count == 1) { // Read single block + if (SD_SendCmd(CMD17, sector) == 0 && SD_RxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK)) + count--; + } else if (SD_SendCmd(CMD18, sector) == 0) { // Read multiple blocks + while(SD_RxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK) && --count) + buff+= SD_SECTOR_SIZE; + SD_SendCmd(CMD12, 0); // Finish multiple block read } - if (cmd == CMD18) SD_SendCmd(CMD12, 0); // Finish multiple block transfer SD_Unselect_SPI(); #if DEBUG == 1 r_time+= chVTGetSystemTimeX(); @@ -1518,17 +1615,16 @@ DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { } #endif #endif - return count ? RES_ERROR : RES_OK; } // diskio.c - Write sector DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { - // No disk or wrong count - if (pdrv != 0 || (Stat & STA_NOINIT)) return RES_NOTRDY; + // No disk or wrong block count + if (pdrv != 0 || !(CardStatus & CT_POWER_ON)) return RES_NOTRDY; // Write protection - if (Stat & STA_PROTECT) return RES_WRPRT; - #if DEBUG == 1 + if (CardStatus & CT_WRPROTECT) return RES_WRPRT; +#if DEBUG == 1 #if 0 DEBUG_PRINT("Sector write 0x%08x, %d\r\n", sector, count); for (UINT j = 0; j < 32; j++){ @@ -1537,21 +1633,29 @@ DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { DEBUG_PRINT("\r\n"); } #endif - w_cnt++; + w_cnt+=count; w_time-= chVTGetSystemTimeX(); #endif - SD_Select_SPI(SD_SPI_SPEED); - do { - // WRITE_SINGLE_BLOCK * count - uint32_t sect = (CardType & CT_BLOCK) ? sector : sector * SD_SECTOR_SIZE; - if ((SD_SendCmd(CMD24, sect) == 0) && SD_TxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK)) { - sector++; +#if 1 // Write multiple block mode + // convert to byte address if no block mode + if (!(CardStatus & CT_BLOCK)) sector*= SD_SECTOR_SIZE; + if (count == 1) { // Write single block + if (SD_SendCmd(CMD24, sector) == 0 && SD_TxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK)) + count--; + } else if (SD_SendCmd(CMD25, sector) == 0) { // Write multiple blocks, wait busy + while (SD_TxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_M_BLOCK) && SD_WaitNotBusy(MS2ST(250)) == 0xFF && --count) buff+= SD_SECTOR_SIZE; - } else break; - } while (--count); + spi_TxByte(SD_TOKEN_STOP_M_BLOCK); // Finish multiple block write + } +#else + while(SD_SendCmd(CMD24, (CardStatus & CT_BLOCK) ? sector : sector * SD_SECTOR_SIZE) == 0 && // Write block command + SD_TxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK) && --count) { // Write data, dec count + sector++; + buff+= SD_SECTOR_SIZE; + } +#endif SD_Unselect_SPI(); - #if DEBUG == 1 w_time+= chVTGetSystemTimeX(); if (count) @@ -1567,7 +1671,7 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) { (void)buff; DRESULT res = RES_PARERR; // No disk or not ready - if (pdrv != 0 || Stat & STA_NOINIT) return RES_NOTRDY; + if (pdrv != 0 || !(CardStatus & CT_POWER_ON)) return RES_NOTRDY; SD_Select_SPI(SD_SPI_RX_SPEED); switch (cmd){ // Makes sure that the device has finished pending write process. @@ -1620,8 +1724,8 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) { n = 10; } else { // MMC or SDC V1 - csize = ((uint32_t)csd[8]>>6)|((uint32_t)csd[7]<<2)|((uint32_t)(csd[6]&0x03)<<10); - n = ((csd[5]&0x0F)|((csd[10]&0x80)>>7)|((csd[9]&0x03)<<1)) + 2 - 9; + csize = ((uint32_t)csd[8]>>6)+((uint32_t)csd[7]<<2)+((uint32_t)(csd[6]&0x03)<<10); + n = (csd[5]&0x0F)+((csd[10]&0x80)>>7)+((csd[9]&0x03)<<1) + 2 - 9; } *(uint32_t*)buff = (csize+1)<Version menu, also send by info command const char *info_about[]={ "Board: " BOARD_NAME, - "2019-2022 Copyright NanoVNA.com", + "2019-2024 Copyright NanoVNA.com", "based on @DiSlord @edy555 ... source", "Licensed under GPL.", "Version: " VERSION " ["\ - "p:"define_to_STR(POINTS_COUNT)", "\ + "p:"define_to_STR(SWEEP_POINTS_MAX)", "\ "IF:"define_to_STR(FREQUENCY_IF_K)"k, "\ "ADC:"define_to_STR(AUDIO_ADC_FREQ_K1)"k, "\ "Lcd:"define_to_STR(LCD_WIDTH)"x"define_to_STR(LCD_HEIGHT)\ @@ -262,7 +265,7 @@ static THD_FUNCTION(Thread1, arg) if ((props_mode & DOMAIN_MODE) == DOMAIN_TIME) transform_domain(mask); // STOP_PROFILE; // Prepare draw graphics, cache all lines, mark screen cells for redraw - plot_into_index(); + request_to_redraw(REDRAW_PLOT); } request_to_redraw(REDRAW_BATTERY); #ifndef DEBUG_CONSOLE_SHOW @@ -290,81 +293,71 @@ toggle_sweep(void) sweep_mode ^= SWEEP_ENABLE; } -#if 0 // -// Original kaiser_window functions +// Optimized Kaiser window functions for transform domain // -static float -bessel0(float x) -{ - const float eps = 0.0001f; - - float ret = 0; - float term = 1; - float m = 0; - - while (term > eps * ret) { - ret += term; - ++m; - term *= (x*x) / (4*m*m); - } - return ret; -} - -static float -kaiser_window(float k, float n, float beta) -{ - if (beta == 0.0) return 1.0f; - float r = (2 * k) / (n - 1) - 1; - return bessel0(beta * vna_sqrtf(1 - r * r)) / bessel0(beta); -} -#else -// Zero-order Bessel function -// (x/2)^(2n) -// 1 + ---------- -// (n!)^2 -// set input as (x/2)^2 (input range 0 .. beta*beta/4) -// x^n x x^2 x^3 x^4 x^5 -// 1 + ------ = 1 + ------ + ------ + ------ + ------ + ------ ...... -// (n!)^2 1 4 36 576 14400 -// first 2 (0 and 1) precalculated as simple. - -// Precalculated multiplier step for 1 / ((n!)^2) max SIZE 16 (first 2 use as init) -static const float div[] = {/*0, 1,*/ 1/4.0f, 1/9.0f, 1/16.0f, 1/25.0f, 1/36.0f, 1/49.0f, 1/64.0f, 1/81.0f, 1/100.0f, 1/121.0f, 1/144.0f, 1/169.0f, 1/196.0f, 1/225.0f, 1/256.0f}; -float bessel0_ext(float x_pow_2) -{ -// set calculated count, more SIZE - less error but longer (bigger beta also need more size for less error) -// For beta = 6 SIZE = (11-2) no error -// For beta = 13 SIZE = (13-2) max error 0.0002 (use as default, use constant size faster then check every time limits in float) -#define SIZE (13-2) - int i = SIZE; - float term = x_pow_2; - float ret = 1.0f + term; - do { - term*= x_pow_2 * div[SIZE - i]; - ret += term; - }while(--i); +// Zero-order modified Bessel function +// (x/2)^(2n) +// Bessel I0 = 1 + ---------- => For bessel_I0_ext(z) set input as z = (x/2)^2 (input range 0 .. beta*beta/4) +// (n!)^2 +// +// z^n z z^2 z^3 z^4 z^5 z^n +// 1 + ------ = 1 + --- + --- + --- + --- + ----- ...... + ------ +// (n!)^2 1 4 36 576 14400 (n!)^2 +float bessel_I0_ext(float z) { +// Set calculated elements count, more size - less error but longer (bigger beta also need more size for less error) +// Use BESSEL_SIZE = 12 (last used n = 12), use constant size faster then check every time limits in float +// For beta = 6 and BESSEL_SIZE = 12 max error 4.2e-7 +// For beta = 13 and BESSEL_SIZE = 12 max error 2.5e-4 +#define BESSEL_SIZE 12 + int i = BESSEL_SIZE - 1; + // Precalculated multipliers: 1 / (n!^2) + static const float besseli0_k[BESSEL_SIZE - 1] = { +// 1.0000000000000000000000000000000e+00, // 1 / ( 1!^2) + 2.5000000000000000000000000000000e-01, // 1 / ( 2!^2) + 2.7777777777777777777777777777778e-02, // 1 / ( 3!^2) + 1.7361111111111111111111111111111e-03, // 1 / ( 4!^2) + 6.9444444444444444444444444444444e-05, // 1 / ( 5!^2) + 1.9290123456790123456790123456790e-06, // 1 / ( 6!^2) + 3.9367598891408415217939027462837e-08, // 1 / ( 7!^2) + 6.1511873267825648778029730410683e-10, // 1 / ( 8!^2) + 7.5940584281266233059295963469979e-12, // 1 / ( 9!^2) + 7.5940584281266233059295963469979e-14, // 1 / (10!^2) + 6.2760813455591928148178482206594e-16, // 1 / (11!^2) + 4.3583898233049950102901723754579e-18, // 1 / (12!^2) +// 2.5789288895295828463255457842946e-20, // 1 / (13!^2) +// 1.3157800456783585950640539715789e-22, // 1 / (14!^2) +// 5.8479113141260382002846843181284e-25, // 1 / (15!^2) +// 2.2843403570804836719862048117689e-27, // 1 / (16!^2) +// 7.9042918930120542283259682068128e-30, // 1 / (17!^2) + }; + float term = z, ret = 1.0f + z; + do {ret += (term*= z) * besseli0_k[BESSEL_SIZE - 1 - i];} while(--i); return ret; } -// Move out constant divider: bessel0(beta) +// Kaiser window +// bessel_I0(beta*sqrt(1 - (2*k/N - 1)^2)) +// Kaiser = ------------------------------------- +// bessel_I0(beta) +// Move out constant divider: bessel_I0(beta) = bessel_I0_ext(beta * beta / 4) // Made calculation optimization (in integer) // x = (2*k)/(n-1) - 1 = (set n=n-1) = 2*k/n - 1 = (2*k-n)/n -// calculate kaiser window vs bessel0(w) there: -// n*n - (2*k-n)*(2*k-n) 4*k*(n-k) -// w = beta*sqrt(1 - x*x) = beta*sqrt(---------------------) = beta*sqrt(---------) -// n*n n*n -// bessel0(w) = bessel0_ext(z) (there z = (w/2)^2 for speed) -// return = bessel0_ext(z) -static float -kaiser_window_ext(uint32_t k, uint32_t n, uint16_t beta) -{ +// calculate kaiser window vs bessel_I0(w) there: +// n*n - (2*k-n)*(2*k-n) 4*k*(n-k) +// w = beta*sqrt(1 - x*x) = beta * sqrt(---------------------) = beta * sqrt(---------) +// n*n n*n +// bessel_I0(w) = bessel_I0_ext(z) (there z = (w*w)/4 for speed) +// w^2 k*(n-k) +// z = --- = beta * beta * (-------) +// 4 n*n +// return = bessel_I0_ext(z) +static float kaiser_window_ext(uint32_t k, uint32_t n, uint16_t beta) { if (beta == 0) return 1.0f; n = n - 1; k = k * (n - k) * beta * beta; n = n * n; - return bessel0_ext((float)k / n); + return bessel_I0_ext((float)k / n); } -#endif static void transform_domain(uint16_t ch_mask) @@ -402,7 +395,7 @@ transform_domain(uint16_t ch_mask) // Add amplitude correction for not full size FFT data and also add computed default scale // recalculate the scale factor if any window details are changed. The scale factor is to compensate for windowing. // Add constant multiplier for kaiser_window_ext use 1.0f / bessel0_ext(beta*beta/4.0f) - // Add constant multiplier 1.0f / FFT_SIZE + // Add constant multiplier 1.0f / FFT_SIZE static float window_scale = 0.0f; static uint16_t td_cache = 0; // Check mode cache data @@ -410,18 +403,18 @@ transform_domain(uint16_t ch_mask) if (td_cache!=td_check){ td_cache = td_check; if (domain_func == TD_FUNC_LOWPASS_STEP) - window_scale = 1.0f / (FFT_SIZE * bessel0_ext(beta*beta/4.0f)); + window_scale = FFT_SIZE * bessel_I0_ext(beta*beta/4.0f); else { window_scale = 0.0f; for (int i = 0; i < sweep_points; i++) window_scale += kaiser_window_ext(i + offset, window_size, beta); - if (domain_func == TD_FUNC_BANDPASS) window_scale = 1.0f / ( window_scale); - else window_scale = 1.0f / (2.0f * window_scale); -// window_scale*= FFT_SIZE // add correction from kaiser_window -// window_scale/= FFT_SIZE // add defaut from FFT_SIZE -// window_scale*= bessel0_ext(beta*beta/4.0f) // for get result as kaiser_window -// window_scale/= bessel0_ext(beta*beta/4.0f) // for set correction on calculated kaiser_window for value + if (domain_func == TD_FUNC_LOWPASS_IMPULSE) window_scale*= 2.0f; +// window_scale/= FFT_SIZE // add correction from kaiser_window summ +// window_scale*= FFT_SIZE // add default from FFT_SIZE +// window_scale/= bessel_I0_ext(beta*beta/4.0f) // for get result as kaiser_window summ +// window_scale*= bessel_I0_ext(beta*beta/4.0f) // for set correction on calculated kaiser_window for value } + window_scale = 1.0f / window_scale; #ifdef USE_FFT_WINDOW_BUFFER // Cache window function data to static buffer static float kaiser_data[FFT_SIZE]; @@ -464,10 +457,8 @@ transform_domain(uint16_t ch_mask) tmp[i*2+1] = 0.0f; } if (domain_func == TD_FUNC_LOWPASS_STEP) { - for (i = 1; i < sweep_points; i++) { + for (i = 1; i < sweep_points; i++) tmp[i*2+0]+= tmp[i*2+0-2]; -// tmp[i*2+1]+= tmp[i*2+1-2]; // already zero as is_lowpass - } } // Copy data back memcpy(measured[ch], tmp, sizeof(measured[0])); @@ -627,61 +618,111 @@ my_atof(const char *p) float x = my_atoi(p); while (_isdigit((int)*p)) p++; - if (*p == '.') { + if (*p == '.' || *p == ',') { float d = 1.0f; p++; while (_isdigit((int)*p)) { - d /= 10.0f; + d *= 1e-1f; 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 (*p) { + int exp = 0; + if (*p == 'e' || *p == 'E') exp = my_atoi(&p[1]); + else if (*p == 'G') exp = 9; // Giga + else if (*p == 'M') exp = 6; // Mega + else if (*p == 'k') exp = 3; // kilo + else if (*p == 'm') exp = -3; // milli + else if (*p == 'u') exp = -6; // micro + else if (*p == 'n') exp = -9; // nano + else if (*p == 'p') exp =-12; // pico + if (exp > 0) do {x*= 1e+1f;} while (--exp); + if (exp < 0) do {x*= 1e-1f;} while (++exp); } - if (neg) - x = -x; - return x; + return neg ? -x : x; } #ifdef __USE_SMOOTH__ VNA_SHELL_FUNCTION(cmd_smooth) { - if (argc == 1) { - set_smooth_factor(my_atoui(argv[0])); + if (argc != 1) { + shell_printf("usage: %s" VNA_SHELL_NEWLINE_STR \ + "current: %u" VNA_SHELL_NEWLINE_STR, "smooth {0-8}", smooth_factor); return; } - shell_printf("smooth = %d" VNA_SHELL_NEWLINE_STR, smooth_factor); + set_smooth_factor(my_atoui(argv[0])); } #endif #ifdef ENABLE_CONFIG_COMMAND -VNA_SHELL_FUNCTION(cmd_config) -{ - static const char cmd_mode_list[] = "auto|avg|connection|mode|grid|dot|bk|flip"; +VNA_SHELL_FUNCTION(cmd_config) { + static const char cmd_mode_list[] = + "auto" +#ifdef __USE_SMOOTH__ + "|avg" +#endif +#ifdef __USE_SERIAL_CONSOLE__ + "|connection" +#endif + "|mode" + "|grid" + "|dot" +#ifdef __USE_BACKUP__ + "|bk" +#endif +#ifdef __FLIP_DISPLAY__ + "|flip" +#endif +#ifdef __DIGIT_SEPARATOR__ + "|separator" +#endif +#ifdef __SD_CARD_DUMP_TIFF__ + "|tif" +#endif + ; int idx; if (argc == 2 && (idx = get_str_index(argv[0], cmd_mode_list)) >= 0) { - apply_VNA_mode(idx, my_atoui(argv[1])); + apply_VNA_mode(idx, my_atoui(argv[1])); } else shell_printf("usage: config {%s} [0|1]" VNA_SHELL_NEWLINE_STR, cmd_mode_list); } #endif +#ifdef __VNA_MEASURE_MODULE__ + VNA_SHELL_FUNCTION(cmd_measure) { + static const char cmd_measure_list[] = + "none" +#ifdef __USE_LC_MATCHING__ + "|lc" // Add LC match function +#endif +#ifdef __S21_MEASURE__ + "|lcshunt" // Enable LC shunt measure option + "|lcseries" // Enable LC series measure option + "|xtal" // Enable XTAL measure option +#endif +#ifdef __S11_CABLE_MEASURE__ + "|cable" // Enable S11 cable measure option +#endif +#ifdef __S11_RESONANCE_MEASURE__ + "|resonance" // Enable S11 resonance search option +#endif + ; + int idx; + if (argc == 1 && (idx = get_str_index(argv[0], cmd_measure_list)) >= 0) + plot_set_measure_mode(idx); + else + shell_printf("usage: measure {%s}" VNA_SHELL_NEWLINE_STR, cmd_measure_list); + } +#endif + #ifdef USE_VARIABLE_OFFSET VNA_SHELL_FUNCTION(cmd_offset) { if (argc != 1) { - shell_printf("usage: offset {frequency offset(Hz)}" VNA_SHELL_NEWLINE_STR); + shell_printf("usage: %s" VNA_SHELL_NEWLINE_STR \ + "current: %u" VNA_SHELL_NEWLINE_STR, "offset {frequency offset(Hz)}", IF_OFFSET); return; } si5351_set_frequency_offset(my_atoi(argv[0])); @@ -691,15 +732,13 @@ VNA_SHELL_FUNCTION(cmd_offset) VNA_SHELL_FUNCTION(cmd_freq) { if (argc != 1) { - goto usage; + shell_printf("usage: freq {frequency(Hz)}" VNA_SHELL_NEWLINE_STR); + return; } uint32_t freq = my_atoui(argv[0]); - pause_sweep(); set_frequency(freq); return; -usage: - shell_printf("usage: freq {frequency(Hz)}" VNA_SHELL_NEWLINE_STR); } void set_power(uint8_t value){ @@ -713,16 +752,12 @@ void set_power(uint8_t value){ VNA_SHELL_FUNCTION(cmd_power) { - if (argc == 0) { - shell_printf("power: %d" VNA_SHELL_NEWLINE_STR, current_props._power); - return; - } if (argc != 1) { - shell_printf("usage: power {0-3}|{255 - auto}" VNA_SHELL_NEWLINE_STR); + shell_printf("usage: power {0-3}|{255 - auto}" VNA_SHELL_NEWLINE_STR \ + "power: %d" VNA_SHELL_NEWLINE_STR, current_props._power); return; } set_power(my_atoi(argv[0])); -// set_frequency(frequency); } #ifdef __USE_RTC__ @@ -762,8 +797,8 @@ VNA_SHELL_FUNCTION(cmd_time) VNA_SHELL_FUNCTION(cmd_dac) { if (argc != 1) { - shell_printf("usage: dac {value(0-4095)}" VNA_SHELL_NEWLINE_STR \ - "current value: %d" VNA_SHELL_NEWLINE_STR, config._dac_value); + shell_printf("usage: %s" VNA_SHELL_NEWLINE_STR \ + "current: %u" VNA_SHELL_NEWLINE_STR, "dac {value(0-4095)}", config._dac_value); return; } dac_setvalue_ch2(my_atoui(argv[0])&0xFFF); @@ -774,8 +809,8 @@ VNA_SHELL_FUNCTION(cmd_threshold) { uint32_t value; if (argc != 1) { - shell_printf("usage: threshold {frequency in harmonic mode}" VNA_SHELL_NEWLINE_STR \ - "current: %d" VNA_SHELL_NEWLINE_STR, config._harmonic_freq_threshold); + shell_printf("usage: %s" VNA_SHELL_NEWLINE_STR \ + "current: %u" VNA_SHELL_NEWLINE_STR, "threshold {frequency in harmonic mode}", config._harmonic_freq_threshold); return; } value = my_atoui(argv[0]); @@ -837,6 +872,13 @@ VNA_SHELL_FUNCTION(cmd_capture) #if (SPI_BUFFER_SIZE*LCD_PIXEL_SIZE) < (LCD_RX_PIXEL_SIZE*LCD_WIDTH*READ_ROWS) #error "Low size of spi_buffer for cmd_capture" #endif + // Text on screenshot + if (argc > 0) { + lcd_set_colors(LCD_FG_COLOR, LCD_BG_COLOR); + for (int i = 0; i < argc; i++) + lcd_printf(OFFSETX + CELLOFFSETX + 2, AREA_HEIGHT_NORMAL - (argc - i) * FONT_STR_HEIGHT - 2, argv[i]); + request_to_redraw(REDRAW_AREA); + } // read 2 row pixel time for (y = 0; y < LCD_HEIGHT; y += READ_ROWS) { // use uint16_t spi_buffer[2048] (defined in ili9341) for read buffer @@ -851,7 +893,7 @@ VNA_SHELL_FUNCTION(cmd_gamma) float gamma[2]; (void)argc; (void)argv; - + pause_sweep(); chMtxLock(&mutex); wait_dsp(4); @@ -892,7 +934,7 @@ config_t config = { ._harmonic_freq_threshold = FREQUENCY_THRESHOLD, ._IF_freq = FREQUENCY_OFFSET, ._touch_cal = DEFAULT_TOUCH_CONFIG, - ._vna_mode = VNA_MODE_USB | VNA_MODE_SEARCH_MAX, + ._vna_mode = 0, // USB mode, search max ._brightness = DEFAULT_BRIGHTNESS, ._dac_value = 1922, ._vbat_offset = 450, @@ -902,21 +944,19 @@ config_t config = { ._xtal_freq = XTALFREQ, ._measure_r = MEASURE_DEFAULT_R, ._lever_mode = LM_MARKER, - ._digit_separator = '.', -#ifdef __BAND_MODE__ + #ifdef __MS5351__ ._band_mode = 1, #else ._band_mode = 0, #endif -#endif }; properties_t current_props; // NanoVNA Default settings static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, smith format, scale, refpos - { TRUE, TRC_LOGMAG, 0, MS_REIM, 10.0, NGRIDY-1 }, + { TRUE, TRC_LOGMAG, 0, MS_RX, 10.0, NGRIDY-1 }, { TRUE, TRC_LOGMAG, 1, MS_REIM, 10.0, NGRIDY-1 }, { TRUE, TRC_SMITH, 0, MS_RX, 1.0, 0 }, { TRUE, TRC_PHASE, 1, MS_REIM, 90.0, NGRIDY/2 } @@ -948,10 +988,9 @@ static const marker_t def_markers[MARKERS_MAX] = { }; // Load propeties default settings -void load_default_properties(void) -{ +static void load_default_properties(void) { //Magic add on caldata_save -//current_props.magic = CONFIG_MAGIC; + current_props.magic = PROPERTIES_MAGIC; current_props._frequency0 = 50000; // start = 50kHz current_props._frequency1 = 900000000; // end = 900MHz current_props._var_freq = 0; @@ -965,6 +1004,7 @@ void load_default_properties(void) memcpy(current_props._markers, def_markers, sizeof(def_markers)); //============================================= current_props._electrical_delay = 0.0f; + current_props._var_delay = 0.0f; current_props._s21_offset = 0.0f; current_props._portz = 50.0f; current_props._velocity_factor = 70; @@ -986,7 +1026,7 @@ void load_default_properties(void) // Backup registers support, allow save data on power off (while vbat power enabled) // #ifdef __USE_BACKUP__ -#if POINTS_COUNT > 511 || SAVEAREA_MAX > 15 +#if SWEEP_POINTS_MAX > 511 || SAVEAREA_MAX > 15 #error "Check backup data limits!!" #endif @@ -1018,7 +1058,8 @@ void update_backup_data(void) { } static void load_settings(void) { - if (config_recall() == 0 && VNA_MODE(VNA_MODE_BACKUP)) { // Config loaded ok and need restore backup + load_default_properties(); // Load default settings + if (config_recall() == 0 && VNA_MODE(VNA_MODE_BACKUP)) { // Config loaded ok and need restore backup if enabled backup_0 bk = {.v = get_backup_data32(0)}; if (bk.v != 0) { // if backup data valid if (bk.id < SAVEAREA_MAX && caldata_recall(bk.id) == 0) { // Slot valid and Load ok @@ -1034,8 +1075,7 @@ static void load_settings(void) { config._vna_mode = get_backup_data32(4) | (1< POINTS_COUNT) +void set_sweep_points(uint16_t points) { + if (points > SWEEP_POINTS_MAX) points = SWEEP_POINTS_MAX; + if (points < SWEEP_POINTS_MIN) points = SWEEP_POINTS_MIN; + if (points == sweep_points) return; - sweep_points = points; update_frequencies(); } @@ -1357,7 +1398,7 @@ void set_sweep_points(uint16_t points){ * Frequency list functions */ #ifdef __USE_FREQ_TABLE__ -static freq_t frequencies[POINTS_COUNT]; +static freq_t frequencies[SWEEP_POINTS_MAX]; static void set_frequencies(freq_t start, freq_t stop, uint16_t points) { @@ -1372,7 +1413,7 @@ set_frequencies(freq_t start, freq_t stop, uint16_t points) if ((df+=error) >= step) {f++; df-= step;} } // disable at out of sweep range - for (; i < POINTS_COUNT; i++) + for (; i < SWEEP_POINTS_MAX; i++) frequencies[i] = 0; } #define _c_start frequencies[0] @@ -1428,8 +1469,8 @@ VNA_SHELL_FUNCTION(cmd_scan) } if (argc >= 3) { points = my_atoui(argv[2]); - if (points == 0 || points > POINTS_COUNT) { - shell_printf("sweep points exceeds range " define_to_STR(POINTS_COUNT) VNA_SHELL_NEWLINE_STR); + if (points == 0 || points > SWEEP_POINTS_MAX) { + shell_printf("sweep points exceeds range " define_to_STR(SWEEP_POINTS_MAX) VNA_SHELL_NEWLINE_STR); return; } sweep_points = points; @@ -1473,10 +1514,9 @@ VNA_SHELL_FUNCTION(cmd_scan) if (mask & SCAN_MASK_OUT_DATA0) shell_write(&measured[0][i][0], sizeof(float)* 2); // 4+4 bytes .. S11 real/imag if (mask & SCAN_MASK_OUT_DATA1) shell_write(&measured[1][i][0], sizeof(float)* 2); // 4+4 bytes .. S21 real/imag } - } - else{ + } else { for (int i = 0; i < points; i++) { - if (mask & SCAN_MASK_OUT_FREQ ) shell_printf("%u ", getFrequency(i)); + if (mask & SCAN_MASK_OUT_FREQ ) shell_printf(VNA_FREQ_FMT_STR " ", getFrequency(i)); if (mask & SCAN_MASK_OUT_DATA0) shell_printf("%f %f ", measured[0][i][0], measured[0][i][1]); if (mask & SCAN_MASK_OUT_DATA1) shell_printf("%f %f ", measured[1][i][0], measured[1][i][1]); shell_printf(VNA_SHELL_NEWLINE_STR); @@ -1496,9 +1536,12 @@ VNA_SHELL_FUNCTION(cmd_scan_bin) VNA_SHELL_FUNCTION(cmd_tcxo) { - if (argc == 1) - si5351_set_tcxo(my_atoui(argv[0])); - shell_printf("tcxo = %u Hz" VNA_SHELL_NEWLINE_STR, config._xtal_freq); + if (argc != 1) { + shell_printf("usage: %s" VNA_SHELL_NEWLINE_STR \ + "current: %u" VNA_SHELL_NEWLINE_STR, "tcxo {TCXO frequency(Hz)}", config._xtal_freq); + return; + } + si5351_set_tcxo(my_atoui(argv[0])); } void set_marker_index(int m, int idx) @@ -1519,27 +1562,25 @@ freq_t get_marker_frequency(int marker) } static void -update_marker_index(void) +update_marker_index(freq_t fstart, freq_t fstop, uint16_t points) { int m, idx; - freq_t fstart = get_sweep_frequency(ST_START); - freq_t fstop = get_sweep_frequency(ST_STOP); for (m = 0; m < MARKERS_MAX; m++) { // Update index for all markers !! - uint32_t f = markers[m].frequency; + freq_t f = markers[m].frequency; if (f == 0) idx = markers[m].index; // Not need update index in no freq - else if (f < fstart) idx = 0; - else if (f >= fstop) idx = sweep_points-1; + else if (f <= fstart) idx = 0; + else if (f >= fstop ) idx = points-1; else { // Search frequency index for marker frequency #if 0 - for (idx = 1; idx < sweep_points; idx++) { + for (idx = 1; idx < points; idx++) { if (frequencies[idx] <= f) continue; if (f < (frequencies[idx-1]/2 + frequencies[idx]/2)) idx--; // Correct closest idx break; } #else float r = ((float)(f - fstart))/(fstop - fstart); - idx = r * (sweep_points-1); + idx = r * (points-1); #endif } set_marker_index(m, idx); @@ -1554,16 +1595,16 @@ update_frequencies(void) set_frequencies(start, stop, sweep_points); - update_marker_index(); + update_marker_index(start, stop, sweep_points); // set grid layout - update_grid(); + update_grid(start, stop); // Update interpolation flag if (needInterpolate(start, stop, sweep_points)) cal_status|= CALSTAT_INTERPOLATED; else cal_status&= ~CALSTAT_INTERPOLATED; - request_to_redraw(REDRAW_BACKUP | REDRAW_CAL_STATUS | REDRAW_FREQUENCY | REDRAW_AREA); + request_to_redraw(REDRAW_BACKUP | REDRAW_PLOT | REDRAW_CAL_STATUS | REDRAW_FREQUENCY | REDRAW_AREA); RESET_SWEEP; } @@ -1571,10 +1612,16 @@ void set_sweep_frequency(uint16_t type, freq_t freq) { // 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; + if (type < ST_SPAN && freq < FREQUENCY_MIN) + freq = FREQUENCY_MIN; + // One point step input, so change stop freq or span depend from mode + if (type == ST_STEP) { + freq*= (sweep_points - 1); + type = FREQ_IS_CENTERSPAN() ? ST_SPAN : ST_STOP; + if (type == ST_STOP) freq+= frequency0; + } + if (freq > FREQUENCY_MAX) + freq = FREQUENCY_MAX; freq_t center, span; switch (type) { case ST_START: @@ -1592,22 +1639,22 @@ set_sweep_frequency(uint16_t type, freq_t freq) case ST_CENTER: FREQ_CENTERSPAN(); center = freq; - span = (frequency1 - frequency0)>>1; - if (span > center - START_MIN) - span = (center - START_MIN); - if (span > STOP_MAX - center) - span = (STOP_MAX - center); + span = (frequency1 - frequency0 + 1)>>1; + if (span > center - FREQUENCY_MIN) + span = (center - FREQUENCY_MIN); + if (span > FREQUENCY_MAX - center) + span = (FREQUENCY_MAX - center); frequency0 = center - span; frequency1 = center + span; break; case ST_SPAN: FREQ_CENTERSPAN(); - center = (frequency0>>1) + (frequency1>>1); + center = get_sweep_frequency(ST_CENTER); span = freq>>1; - if (center < START_MIN + span) - center = START_MIN + span; - if (center > STOP_MAX - span) - center = STOP_MAX - span; + if (center < FREQUENCY_MIN + span) + center = FREQUENCY_MIN + span; + if (center > FREQUENCY_MAX - span) + center = FREQUENCY_MAX - span; frequency0 = center - span; frequency1 = center + span; break; @@ -1634,7 +1681,7 @@ void reset_sweep_frequency(void){ VNA_SHELL_FUNCTION(cmd_sweep) { if (argc == 0) { - shell_printf("%u %u %d" VNA_SHELL_NEWLINE_STR, get_sweep_frequency(ST_START), get_sweep_frequency(ST_STOP), sweep_points); + shell_printf(VNA_FREQ_FMT_STR " " VNA_FREQ_FMT_STR " %d" VNA_SHELL_NEWLINE_STR, get_sweep_frequency(ST_START), get_sweep_frequency(ST_STOP), sweep_points); return; } else if (argc > 3) { goto usage; @@ -1648,9 +1695,9 @@ VNA_SHELL_FUNCTION(cmd_sweep) #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"; + // Parse sweep {start|stop|center|span|cw|step|var} {freq(Hz)} + // get enum ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW, ST_STEP, ST_VAR + static const char sweep_cmd[] = "start|stop|center|span|cw|step|var"; if (argc == 2 && value0 == 0) { int type = get_str_index(argv[0], sweep_cmd); if (type == -1) @@ -1671,7 +1718,6 @@ VNA_SHELL_FUNCTION(cmd_sweep) "\tsweep {%s} {freq(Hz)}" VNA_SHELL_NEWLINE_STR, sweep_cmd); } - static void eterm_set(int term, float re, float im) { @@ -2002,7 +2048,7 @@ static void cal_interpolate(int idx, freq_t f, float data[CAL_TYPE_COUNT][2]){ // Not need interpolate if (f == src_f0) goto copy_point; - float k1 = (delta == 0) ? 0.0 : (float)(f - src_f0) / delta; + float k1 = (delta == 0) ? 0.0f : (float)(f - src_f0) / delta; // avoid glitch between freqs in different harmonics mode uint32_t hf0 = si5351_get_harmonic_lvl(src_f0); if (hf0 != si5351_get_harmonic_lvl(src_f1)) { @@ -2020,7 +2066,7 @@ static void cal_interpolate(int idx, freq_t f, float data[CAL_TYPE_COUNT][2]){ } } // Interpolate by k1 - float k0 = 1.0 - k1; + float k0 = 1.0f - k1; for (eterm = 0; eterm < CAL_TYPE_COUNT; eterm++) { data[eterm][0] = cal_data[eterm][idx][0] * k0 + cal_data[eterm][idx+1][0] * k1; data[eterm][1] = cal_data[eterm][idx][1] * k0 + cal_data[eterm][idx+1][1] * k1; @@ -2087,34 +2133,24 @@ VNA_SHELL_FUNCTION(cmd_cal) VNA_SHELL_FUNCTION(cmd_save) { - if (argc != 1) - goto usage; - - int id = my_atoi(argv[0]); - if (id < 0 || id >= SAVEAREA_MAX) - goto usage; - caldata_save(id); - request_to_redraw(REDRAW_CAL_STATUS); - return; - - usage: - shell_printf("save {id}" VNA_SHELL_NEWLINE_STR); + uint32_t id; + if (argc == 1 && (id = my_atoui(argv[0])) < SAVEAREA_MAX) { + caldata_save(id); + request_to_redraw(REDRAW_CAL_STATUS); + return; + } + shell_printf("usage: %s 0..%d" VNA_SHELL_NEWLINE_STR, SAVEAREA_MAX-1, "save"); } VNA_SHELL_FUNCTION(cmd_recall) { - if (argc != 1) - goto usage; - - int id = my_atoi(argv[0]); - if (id < 0 || id >= SAVEAREA_MAX) - goto usage; - // Check for success - if (load_properties(id)) - shell_printf("Err, default load" VNA_SHELL_NEWLINE_STR); - return; - usage: - shell_printf("recall {id}" VNA_SHELL_NEWLINE_STR); + uint32_t id; + if (argc == 1 && (id = my_atoui(argv[0])) < SAVEAREA_MAX) { + if (load_properties(id)) // Check for success + shell_printf("Err, default load" VNA_SHELL_NEWLINE_STR); + return; + } + shell_printf("usage: %s 0..%d" VNA_SHELL_NEWLINE_STR, SAVEAREA_MAX-1, "recall"); } static const char * const trc_channel_name[] = { @@ -2134,13 +2170,12 @@ void set_trace_type(int t, int type, int channel) if (trace[t].type != type) { trace[t].type = type; // Set default trace refpos - trace[t].refpos = trace_info_list[type].refpos; + set_trace_refpos(t, trace_info_list[type].refpos); // Set default trace scale - trace[t].scale = trace_info_list[type].scale_unit; + set_trace_scale(t, trace_info_list[type].scale_unit); + request_to_redraw(REDRAW_AREA); // need for update grid } - trace[t].channel = channel; - plot_into_index(); - request_to_redraw(REDRAW_AREA); + set_trace_channel(t, channel); } void set_trace_channel(int t, int channel) @@ -2148,7 +2183,7 @@ void set_trace_channel(int t, int channel) channel&= 1; if (trace[t].channel != channel) { trace[t].channel = channel; - plot_into_index(); + request_to_redraw(REDRAW_MARKER | REDRAW_PLOT); } } @@ -2162,8 +2197,7 @@ void set_trace_scale(int t, float scale) { if (trace[t].scale != scale) { trace[t].scale = scale; - plot_into_index(); - request_to_redraw(REDRAW_MARKER | REDRAW_GRID_VALUE); + request_to_redraw(REDRAW_MARKER | REDRAW_GRID_VALUE | REDRAW_PLOT); } } @@ -2171,8 +2205,7 @@ void set_trace_refpos(int t, float refpos) { if (trace[t].refpos != refpos) { trace[t].refpos = refpos; - plot_into_index(); - request_to_redraw(REDRAW_REFERENCE | REDRAW_GRID_VALUE); + request_to_redraw(REDRAW_REFERENCE | REDRAW_GRID_VALUE | REDRAW_PLOT); } } @@ -2187,11 +2220,10 @@ void set_trace_enable(int t, bool enable) request_to_redraw(REDRAW_AREA); } -void set_electrical_delay(float picoseconds) +void set_electrical_delay(float seconds) { - picoseconds*= 1e-12; - if (electrical_delay != picoseconds) { - electrical_delay = picoseconds; + if (electrical_delay != seconds) { + electrical_delay = seconds; request_to_redraw(REDRAW_MARKER); } } @@ -2240,11 +2272,12 @@ VNA_SHELL_FUNCTION(cmd_trace) set_trace_enable(t, false); return; } -#if MAX_TRACE_TYPE != 28 +#if MAX_TRACE_TYPE != 30 #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_Z, TRC_ZPHASE, TRC_G, TRC_B, TRC_Y, TRC_Rp, TRC_Xp, TRC_sC, TRC_sL, TRC_pC, TRC_pL, TRC_Q, TRC_Rser, TRC_Xser,TRC_Rsh, TRC_Xsh, TRC_Qs21 - static const char cmd_type_list[] = "logmag|phase|delay|smith|polar|linear|swr|real|imag|r|x|z|zp|g|b|y|rp|xp|sc|sl|pc|pl|q|rser|xser|rsh|xsh|q21"; + // enum TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_Z, TRC_ZPHASE, + // TRC_G, TRC_B, TRC_Y, TRC_Rp, TRC_Xp, TRC_sC, TRC_sL, TRC_pC, TRC_pL, TRC_Q, TRC_Rser, TRC_Xser, TRC_Zser, TRC_Rsh, TRC_Xsh, TRC_Zsh, TRC_Qs21 + static const char cmd_type_list[] = "logmag|phase|delay|smith|polar|linear|swr|real|imag|r|x|z|zp|g|b|y|rp|xp|sc|sl|pc|pl|q|rser|xser|zser|rsh|xsh|zsh|q21"; int type = get_str_index(argv[1], cmd_type_list); if (type >= 0) { int src = trace[t].channel; @@ -2258,7 +2291,7 @@ VNA_SHELL_FUNCTION(cmd_trace) return; } - static const char cmd_marker_smith[] = "lin|log|ri|rx|rlc|gb|glc|rpxp|rplc|rxsh|rxser"; + static const char cmd_marker_smith[] = "lin|log|ri|rx|rlc|gb|glc|rpxp|rplc|rxsh|rlcsh|rxser|rlcser"; // Set marker smith format int format = get_str_index(argv[1], cmd_marker_smith); if (format >=0) { @@ -2288,7 +2321,7 @@ VNA_SHELL_FUNCTION(cmd_edelay) shell_printf("%f" VNA_SHELL_NEWLINE_STR, electrical_delay * (1.0f / 1e-12f)); // return in picoseconds return; } - set_electrical_delay(my_atof(argv[0])); // input value in picoseconds + set_electrical_delay(my_atof(argv[0]) * 1e-12); // input value in seconds } VNA_SHELL_FUNCTION(cmd_s21offset) @@ -2307,7 +2340,7 @@ VNA_SHELL_FUNCTION(cmd_marker) if (argc == 0) { for (t = 0; t < MARKERS_MAX; t++) { if (markers[t].enabled) { - shell_printf("%d %d %u" VNA_SHELL_NEWLINE_STR, t+1, markers[t].index, markers[t].frequency); + shell_printf("%d %d " VNA_FREQ_FMT_STR "" VNA_SHELL_NEWLINE_STR, t+1, markers[t].index, markers[t].frequency); } } return; @@ -2326,7 +2359,7 @@ VNA_SHELL_FUNCTION(cmd_marker) if (t < 0 || t >= MARKERS_MAX) goto usage; if (argc == 1) { - shell_printf("%d %d %u" VNA_SHELL_NEWLINE_STR, t+1, markers[t].index, markers[t].frequency); + shell_printf("%d %d " VNA_FREQ_FMT_STR "" VNA_SHELL_NEWLINE_STR, t+1, markers[t].index, markers[t].frequency); active_marker = t; // select active marker markers[t].enabled = TRUE; @@ -2348,20 +2381,6 @@ VNA_SHELL_FUNCTION(cmd_marker) shell_printf("marker [n] [%s|{index}]" VNA_SHELL_NEWLINE_STR, cmd_marker_list); } -#if 0 -VNA_SHELL_FUNCTION(cmd_grid) -{ - if (argc != 1) { - shell_printf("grid %s" VNA_SHELL_NEWLINE_STR, config._mode&VNA_MODE_SHOW_GRID ? "on" : "off"); - return; - } - if (my_atoi(argv[0])) - config._mode|= VNA_MODE_SHOW_GRID; - else - config._mode&=~VNA_MODE_SHOW_GRID; -} -#endif - VNA_SHELL_FUNCTION(cmd_touchcal) { (void)argc; @@ -2387,7 +2406,7 @@ VNA_SHELL_FUNCTION(cmd_frequencies) (void)argc; (void)argv; for (i = 0; i < sweep_points; i++) { - shell_printf("%u" VNA_SHELL_NEWLINE_STR, getFrequency(i)); + shell_printf(VNA_FREQ_FMT_STR VNA_SHELL_NEWLINE_STR, getFrequency(i)); } } @@ -2756,18 +2775,20 @@ VNA_SHELL_FUNCTION(cmd_threads) #ifdef ENABLE_USART_COMMAND VNA_SHELL_FUNCTION(cmd_usart_cfg) { - if (argc != 1) goto result; + if (argc != 1) { +// shell_printf("usage: %s" VNA_SHELL_NEWLINE_STR "current: %u" VNA_SHELL_NEWLINE_STR, "usart_cfg {baudrate}", config._serial_speed); + shell_printf("Serial: %u baud" VNA_SHELL_NEWLINE_STR, config._serial_speed); + return; + } uint32_t speed = my_atoui(argv[0]); if (speed < 300) speed = 300; shell_update_speed(speed); -result: - shell_printf("Serial: %u baud" VNA_SHELL_NEWLINE_STR, config._serial_speed); } VNA_SHELL_FUNCTION(cmd_usart) { uint32_t time = MS2ST(200); // 200ms wait answer by default - if (argc == 0 || argc > 2 || VNA_MODE(VNA_MODE_SERIAL)) return; + if (argc == 0 || argc > 2 || VNA_MODE(VNA_MODE_CONNECTION)) return; // Not work in serial mode if (argc == 2) time = MS2ST(my_atoui(argv[1])); sdWriteTimeout(&SD1, (uint8_t *)argv[0], strlen(argv[0]), time); sdWriteTimeout(&SD1, (uint8_t *)VNA_SHELL_NEWLINE_STR, sizeof(VNA_SHELL_NEWLINE_STR)-1, time); @@ -2847,7 +2868,6 @@ VNA_SHELL_FUNCTION(cmd_sd_list) case 1: search = argv[0];break; default: shell_printf("usage: sd_list {pattern}" VNA_SHELL_NEWLINE_STR); return; } - shell_printf("sd_list:" VNA_SHELL_NEWLINE_STR); res = f_findfirst(&dj, &fno, "", search); while (res == FR_OK && fno.fname[0]) { @@ -2902,6 +2922,21 @@ VNA_SHELL_FUNCTION(cmd_sd_delete) } #endif +#ifdef __SD_CARD_LOAD__ +VNA_SHELL_FUNCTION(cmd_msg) +{ + if (argc == 0) { + shell_printf("usage: msg delay [text] [header]" VNA_SHELL_NEWLINE_STR); + return; + } + uint32_t delay = my_atoui(argv[0]); + char *header = 0, *text = 0; + if (argc > 1) text = argv[1]; + if (argc > 2) header = argv[2]; + drawMessageBox(header, text, delay); +} +#endif + //============================================================================= VNA_SHELL_FUNCTION(cmd_help); @@ -2941,9 +2976,9 @@ static const VNAShellCommand commands[] = {"time" , cmd_time , CMD_RUN_IN_UI}, #endif #ifdef ENABLE_SD_CARD_COMMAND - { "sd_list", cmd_sd_list , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, - { "sd_read", cmd_sd_read , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, - { "sd_delete", cmd_sd_delete , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, + {"sd_list" , cmd_sd_list , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, + {"sd_read" , cmd_sd_read , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, + {"sd_delete" , cmd_sd_delete , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, #endif #ifdef __VNA_ENABLE_DAC__ {"dac" , cmd_dac , CMD_RUN_IN_LOAD}, @@ -2972,6 +3007,9 @@ static const VNAShellCommand commands[] = {"touchtest" , cmd_touchtest , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP}, {"pause" , cmd_pause , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI|CMD_RUN_IN_LOAD}, {"resume" , cmd_resume , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI|CMD_RUN_IN_LOAD}, +#ifdef __SD_CARD_LOAD__ + {"msg" , cmd_msg , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_LOAD}, +#endif {"cal" , cmd_cal , CMD_WAIT_MUTEX}, {"save" , cmd_save , CMD_RUN_IN_LOAD}, {"recall" , cmd_recall , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI|CMD_RUN_IN_LOAD}, @@ -2980,6 +3018,9 @@ static const VNAShellCommand commands[] = {"edelay" , cmd_edelay , CMD_RUN_IN_LOAD}, {"s21offset" , cmd_s21offset , CMD_RUN_IN_LOAD}, {"capture" , cmd_capture , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, +#ifdef __VNA_MEASURE_MODULE__ + {"measure" , cmd_measure , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI|CMD_RUN_IN_LOAD}, +#endif #ifdef __REMOTE_DESKTOP__ {"refresh" , cmd_refresh , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, {"touch" , cmd_touch , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI}, @@ -2987,7 +3028,7 @@ static const VNAShellCommand commands[] = #endif {"vbat" , cmd_vbat , CMD_RUN_IN_LOAD}, {"tcxo" , cmd_tcxo , CMD_RUN_IN_LOAD}, - {"reset" , cmd_reset , CMD_RUN_IN_LOAD}, + {"reset" , cmd_reset , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_LOAD}, #ifdef __USE_SMOOTH__ {"smooth" , cmd_smooth , CMD_WAIT_MUTEX|CMD_BREAK_SWEEP|CMD_RUN_IN_UI|CMD_RUN_IN_LOAD}, #endif diff --git a/mcuconf_F303.h b/mcuconf_F303.h deleted file mode 100644 index 2d10142..0000000 --- a/mcuconf_F303.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 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. -*/ - -#ifndef MCUCONF_H -#define MCUCONF_H - -/* - * STM32F3xx drivers configuration. - * The following settings override the default settings present in - * the various device driver implementation headers. - * Note that the settings for each driver only have effect if the whole - * driver is enabled in halconf.h. - * - * IRQ priorities: - * 15...0 Lowest...Highest. - * - * DMA priorities: - * 0...3 Lowest...Highest. - */ - -#define STM32F3xx_MCUCONF - -/* - * HAL driver system settings. - */ -#define STM32_NO_INIT FALSE -#define STM32_PVD_ENABLE FALSE -#define STM32_PLS STM32_PLS_LEV0 -#define STM32_HSI_ENABLED FALSE -#define STM32_LSI_ENABLED TRUE -#define STM32_HSE_ENABLED TRUE -#define STM32_LSE_ENABLED FALSE -#define STM32_SW STM32_SW_PLL -#define STM32_PLLSRC STM32_PLLSRC_HSE -#define STM32_PREDIV_VALUE 1 -#define STM32_PLLMUL_VALUE 9 -#define STM32_HPRE STM32_HPRE_DIV1 -#define STM32_PPRE1 STM32_PPRE1_DIV2 -//#define STM32_PPRE2 STM32_PPRE2_DIV1 -#define STM32_MCOSEL STM32_MCOSEL_PLLDIV2 -#define STM32_ADC12PRES STM32_ADC12PRES_DIV1 -//#define STM32_ADC34PRES STM32_ADC34PRES_DIV1 -#define STM32_USART1SW STM32_USART1SW_PCLK -//#define STM32_USART2SW STM32_USART2SW_PCLK -//#define STM32_USART3SW STM32_USART3SW_PCLK -#define STM32_I2C1SW STM32_I2C1SW_SYSCLK -//#define STM32_I2C2SW STM32_I2C2SW_SYSCLK -#define STM32_TIM1SW STM32_TIM1SW_PCLK2 -#define STM32_TIM8SW STM32_TIM8SW_PCLK2 -#define STM32_RTCSEL STM32_RTCSEL_LSI -#define STM32_USB_CLOCK_REQUIRED TRUE -#define STM32_USBPRE STM32_USBPRE_DIV1P5 - -/* - * ADC driver system settings. - */ -#define STM32_ADC_USE_ADC1 TRUE -#define STM32_ADC_USE_ADC2 TRUE -#define STM32_ADC_USE_ADC3 FALSE -#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) -#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) -//#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) -//#define STM32_ADC_ADC4_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) -#define STM32_ADC_ADC12_DMA_PRIORITY 2 -//#define STM32_ADC_ADC34_DMA_PRIORITY 2 -#define STM32_ADC_ADC12_IRQ_PRIORITY 2 -//#define STM32_ADC_ADC34_IRQ_PRIORITY 5 -#define STM32_ADC_ADC12_DMA_IRQ_PRIORITY 2 -//#define STM32_ADC_ADC34_DMA_IRQ_PRIORITY 5 -//#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_ADCCK -//#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV2 -#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 -//#define STM32_ADC_ADC34_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 -#define STM32_ADC_DUAL_MODE FALSE - -/* - * CAN driver system settings. - */ -#define STM32_CAN_USE_CAN1 FALSE -#define STM32_CAN_CAN1_IRQ_PRIORITY 11 - -/* - * DAC driver system settings. - */ -#define STM32_DAC_DUAL_MODE FALSE -#define STM32_DAC_USE_DAC1_CH1 TRUE -#define STM32_DAC_USE_DAC1_CH2 TRUE -#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 -#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 -#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 -#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 - -/* - * EXT driver system settings. - */ -#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3 -#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3 -#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3 -#define STM32_EXT_EXTI16_IRQ_PRIORITY 3 -#define STM32_EXT_EXTI17_IRQ_PRIORITY 3 -#define STM32_EXT_EXTI21_22_IRQ_PRIORITY 3 - -#define STM32_DISABLE_EXTI2122_HANDLER TRUE - -/* - * GPT driver system settings. - */ -#define STM32_GPT_USE_TIM1 FALSE -#define STM32_GPT_USE_TIM2 FALSE -#define STM32_GPT_USE_TIM3 TRUE -#define STM32_GPT_USE_TIM4 FALSE -#define STM32_GPT_TIM1_IRQ_PRIORITY 2 -#define STM32_GPT_TIM2_IRQ_PRIORITY 2 -#define STM32_GPT_TIM3_IRQ_PRIORITY 2 -#define STM32_GPT_TIM4_IRQ_PRIORITY 2 - -/* - * I2C driver system settings. - */ -#define STM32_I2C_USE_I2C1 TRUE -#define STM32_I2C_USE_I2C2 FALSE -#define STM32_I2C_BUSY_TIMEOUT 50 -#define STM32_I2C_I2C1_IRQ_PRIORITY 3 -#define STM32_I2C_I2C2_IRQ_PRIORITY 3 -#define STM32_I2C_USE_DMA TRUE -#define STM32_I2C_I2C1_DMA_PRIORITY 1 -#define STM32_I2C_I2C2_DMA_PRIORITY 1 -#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") - -/* - * I2S driver system settings. - */ -#define STM32_I2S_USE_SPI1 FALSE -#define STM32_I2S_USE_SPI2 TRUE -#define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \ - STM32_I2S_MODE_RX) -#define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_SLAVE | \ - STM32_I2S_MODE_RX ) -#define STM32_I2S_SPI1_IRQ_PRIORITY 2 -#define STM32_I2S_SPI2_IRQ_PRIORITY 2 -#define STM32_I2S_SPI1_DMA_PRIORITY 1 -#define STM32_I2S_SPI2_DMA_PRIORITY 1 -#define STM32_I2S_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) -#define STM32_I2S_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) -#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) -#define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) -#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") - -/* - * ICU driver system settings. - */ -#define STM32_ICU_USE_TIM1 FALSE -#define STM32_ICU_USE_TIM2 FALSE -#define STM32_ICU_USE_TIM3 FALSE -#define STM32_ICU_TIM1_IRQ_PRIORITY 3 -#define STM32_ICU_TIM2_IRQ_PRIORITY 3 -#define STM32_ICU_TIM3_IRQ_PRIORITY 3 - -/* - * PWM driver system settings. - */ -#define STM32_PWM_USE_ADVANCED FALSE -#define STM32_PWM_USE_TIM1 FALSE -#define STM32_PWM_USE_TIM2 FALSE -#define STM32_PWM_USE_TIM3 FALSE -#define STM32_PWM_TIM1_IRQ_PRIORITY 3 -#define STM32_PWM_TIM2_IRQ_PRIORITY 3 -#define STM32_PWM_TIM3_IRQ_PRIORITY 3 - -/* - * SERIAL driver system settings. - */ -#define STM32_SERIAL_USE_USART1 TRUE -#define STM32_SERIAL_USE_USART2 FALSE -#define STM32_SERIAL_USART1_PRIORITY 3 -#define STM32_SERIAL_USART2_PRIORITY 3 - -/* - * SPI driver system settings. - */ -#define STM32_SPI_USE_SPI1 TRUE -#define STM32_SPI_USE_SPI2 FALSE -#define STM32_SPI_USE_SPI3 FALSE -#define STM32_SPI_SPI1_DMA_PRIORITY 1 -#define STM32_SPI_SPI2_DMA_PRIORITY 1 -#define STM32_SPI_SPI1_IRQ_PRIORITY 2 -#define STM32_SPI_SPI2_IRQ_PRIORITY 2 -#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") - -/* - * ST driver system settings. - */ -#define STM32_ST_IRQ_PRIORITY 2 -#define STM32_ST_USE_TIMER 2 - -/* - * UART driver system settings. - */ -#define STM32_UART_USE_USART1 FALSE -#define STM32_UART_USE_USART2 FALSE -#define STM32_UART_USART1_IRQ_PRIORITY 3 -#define STM32_UART_USART2_IRQ_PRIORITY 3 -#define STM32_UART_USART1_DMA_PRIORITY 0 -#define STM32_UART_USART2_DMA_PRIORITY 0 -#define STM32_UART_USART3_DMA_PRIORITY 0 -#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") - -/* - * USB driver system settings. - */ -#define STM32_USB_USE_USB1 TRUE -#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE -#define STM32_USB_USB1_LP_IRQ_PRIORITY 3 - -/* - * WDG driver system settings. - */ -#define STM32_WDG_USE_IWDG FALSE - -#endif /* MCUCONF_H */ diff --git a/lc_matching.c b/measure.c similarity index 77% rename from lc_matching.c rename to measure.c index d2beafc..34722ce 100644 --- a/lc_matching.c +++ b/measure.c @@ -1,11 +1,21 @@ /* - * (c) Yury Kuchura - * kuchura@gmail.com + * Copyright (c) 2019-2023, Dmitry (DiSlord) dislordlive@gmail.com + * All rights reserved. * - * This code can be used on terms of WTFPL Version 2 (http://www.wtfpl.net/). + * 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. * - * Heavily messed about with by OneOfEleven July 2020 - * DiSlord adaptation to use on NanoVNA + * 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. */ #ifdef __VNA_MEASURE_MODULE__ @@ -14,8 +24,7 @@ static char measure_memory[128]; // Measure math functions // quadratic function solver -static void match_quadratic_equation(float a, float b, float c, float *x) -{ +static void match_quadratic_equation(float a, float b, float c, float *x){ const float a_x_2 = 2.0f * a; const float d = (b * b) - (2.0f * a_x_2 * c); if (d < 0){ @@ -35,7 +44,7 @@ typedef float (*get_value_t)(uint16_t idx); // Used bilinear interpolation, return value = frequency of this point #define MEASURE_SEARCH_LEFT -1 #define MEASURE_SEARCH_RIGHT 1 -static float measure_search_value(uint16_t *idx, float y, get_value_t get, int16_t mode){ +static float measure_search_value(uint16_t *idx, float y, get_value_t get, int16_t mode) { uint16_t x = *idx; float y1, y2, y3; y1 = y2 = y3 = get(x); @@ -86,7 +95,7 @@ static float search_peak_value(uint16_t *xp, get_value_t get, bool mode){ // const float b = 0.5f * (y3 - y1); // const float c = y2; // return c - b*b/(4*a); - const float a = 8*(y1 - 2*y2 + y3); + const float a = 8.0f * (y1 - 2.0f * y2 + y3); const float b = y3 - y1; const float c = y2; return c - b * b / a; @@ -112,7 +121,7 @@ static bool measure_get_value(uint16_t ch, freq_t f, float *data){ freq_t src_f0 = frequency0 + (v ) / _points; freq_t src_f1 = frequency0 + (v + span) / _points; freq_t delta = src_f1 - src_f0; - float k1 = (delta == 0) ? 0.0 : (float)(f - src_f0) / delta; + float k1 = (delta == 0) ? 0.0f : (float)(f - src_f0) / delta; #if 1 // Bilinear interpolation by k1 data[0] = bilinear_interpolation(measured[ch][idx-1][0], measured[ch][idx ][0], measured[ch][idx+1][0],k1); @@ -148,10 +157,8 @@ typedef struct static lc_match_array_t *lc_match_array = (lc_match_array_t *)measure_memory; // Calculate two solutions for ZL where (R + X * X / R) > R0 -static void lc_match_calc_hi(float R0, float RL, float XL, t_lc_match *matches) -{ +static void lc_match_calc_hi(float R0, float RL, float XL, t_lc_match *matches) { float xp[2]; - const float a = R0 - RL; const float b = 2.0f * XL * R0; const float c = R0 * (XL * XL + RL * RL); @@ -160,26 +167,19 @@ static void lc_match_calc_hi(float R0, float RL, float XL, t_lc_match *matches) // found two impedances parallel to load // // now calculate serial impedances - const float RL1 = -XL * xp[0]; - const float XL1 = RL * xp[0]; - const float RL2 = RL;// + 0.0f; - const float XL2 = XL + xp[0]; - matches[0].xs = (RL1 * XL2 - RL2 * XL1) / (RL2 * RL2 + XL2 * XL2); + const float XL1 = XL + xp[0]; + matches[0].xs = xp[0] * xp[0] * XL1 / (RL * RL + XL1 * XL1) - xp[0]; matches[0].xps = 0.0f; matches[0].xpl = xp[0]; - const float RL3 = -XL * xp[1]; - const float XL3 = RL * xp[1]; - const float RL4 = RL;// + 0.0f; - const float XL4 = XL + xp[1]; - matches[1].xs = (RL3 * XL4 - RL4 * XL3) / (RL4 * RL4 + XL4 * XL4); + const float XL2 = XL + xp[1]; + matches[1].xs = xp[1] * xp[1] * XL2 / (RL * RL + XL2 * XL2) - xp[1]; matches[1].xps = 0.0f; matches[1].xpl = xp[1]; } // Calculate two solutions for ZL where R < R0 -static void lc_match_calc_lo(float R0, float RL, float XL, t_lc_match *matches) -{ +static void lc_match_calc_lo(float R0, float RL, float XL, t_lc_match *matches) { float xs[2]; // Calculate Xs const float a = 1.0f; @@ -190,29 +190,19 @@ static void lc_match_calc_lo(float R0, float RL, float XL, t_lc_match *matches) // got two serial impedances that change ZL to the Y.real = 1/R0 // // now calculate impedances parallel to source - const float RL1 = RL;// + 0.0f; - const float XL1 = XL + xs[0]; - const float RL3 = RL1 * R0; - const float XL3 = XL1 * R0; - const float RL5 = RL1 - R0; - const float XL5 = XL1;// - 0.0f; + const float XL1 = XL + xs[0]; + const float RL1 = RL - R0; matches[0].xs = xs[0]; - matches[0].xps = (RL5 * XL3 - RL3 * XL5) / (RL5 * RL5 + XL5 * XL5); + matches[0].xps = - R0 * R0 * XL1 / (RL1 * RL1 + XL1 * XL1); matches[0].xpl = 0.0f; - const float RL2 = RL;// + 0.0f; - const float XL2 = XL + xs[1]; - const float RL4 = RL2 * R0; - const float XL4 = XL2 * R0; - const float RL6 = RL2 - R0; - const float XL6 = XL2;// - 0.0f; + const float XL2 = XL + xs[1]; matches[1].xs = xs[1]; - matches[1].xps = (RL6 * XL4 - RL4 * XL6) / (RL6 * RL6 + XL6 * XL6); + matches[1].xps = - R0 * R0 * XL2 / (RL1 * RL1 + XL2 * XL2); matches[1].xpl = 0.0f; } -static int lc_match_calc(int index) -{ +static int16_t lc_match_calc(int index) { const float R0 = lc_match_array->R0; // compute the impedance at the chosen frequency const float *coeff = measured[0][index]; @@ -231,31 +221,23 @@ static int lc_match_calc(int index) // only one solution is enough: just a serial reactance // this gives SWR < 1.1 if R is within the range 0.91 .. 1.1 of R0 t_lc_match *matches = lc_match_array->matches; - if ((RL * 1.1f) > R0 && RL < (R0 * 1.1f)){ + if ((RL * 1.1f) > R0 && RL < (R0 * 1.1f)) { matches[0].xpl = 0.0f; matches[0].xps = 0.0f; matches[0].xs = -XL; return 1; } - - if (RL >= R0) - { // two Hi-Z solutions - lc_match_calc_hi(R0, RL, XL, &matches[0]); - return 2; + int16_t n = 0; + if (RL >= R0 || RL * RL + XL * XL > R0 * RL) { + lc_match_calc_hi(R0, RL, XL, &matches[0]); // Compute Hi-Z solutions + if (RL >= R0) return 2; // Only Hi-Z solution present + n = 2; } - - // compute Lo-Z solutions - lc_match_calc_lo(R0, RL, XL, &matches[0]); - if ((RL + (XL * q_factor)) <= R0) - return 2; - - // two more Hi-Z solutions exist - lc_match_calc_hi(R0, RL, XL, &matches[2]); - return 4; + lc_match_calc_lo(R0, RL, XL, &matches[n]); // Compute Lo-Z solutions + return n + 2; } -static void prepare_lc_match(uint8_t mode, uint8_t update_mask) -{ +static void prepare_lc_match(uint8_t mode, uint8_t update_mask) { (void)mode; (void)update_mask; // Made calculation only one time for current sweep and frequency @@ -263,17 +245,14 @@ static void prepare_lc_match(uint8_t mode, uint8_t update_mask) if (freq == 0)// || lc_match_array->Hz == freq) return; - lc_match_array->R0 = 50.0f; + lc_match_array->R0 = PORT_Z; // 50.0f lc_match_array->Hz = freq; - // compute the possible LC matches lc_match_array->num_matches = lc_match_calc(markers[active_marker].index); // Mark to redraw area under L/C match text - int n = lc_match_array->num_matches; - if (n < 0) n = 0; invalidate_rect(STR_MEASURE_X , STR_MEASURE_Y, - STR_MEASURE_X + 3 * STR_MEASURE_WIDTH, STR_MEASURE_Y + (n + 2)*STR_MEASURE_HEIGHT); + STR_MEASURE_X + 3 * STR_MEASURE_WIDTH, STR_MEASURE_Y + (4 + 2) * STR_MEASURE_HEIGHT); } // @@ -285,11 +264,11 @@ static void lc_match_x_str(uint32_t FHz, float X, int xp, int yp) char type; #if 0 float val; - if (X < 0.0f) {val = 1.0f / (2.0f * VNA_PI * FHz * -X); type = 'F';} - else {val = X / (2.0f * VNA_PI * FHz); type = 'H';} + if (X < 0.0f) {val = 1.0f / (2.0f * VNA_PI * FHz * -X); type = S_FARAD[0];} + else {val = X / (2.0f * VNA_PI * FHz); type = S_HENRY[0];} #else - if (X < 0.0f) {X = -1.0 / X; type = 'F';} - else { type = 'H';} + if (X < 0.0f) {X = -1.0f / X; type = S_FARAD[0];} + else { type = S_HENRY[0];} float val = X / ((2.0f * VNA_PI) * FHz); #endif cell_printf(xp, yp, "%4.2F%c", val, type); @@ -300,10 +279,10 @@ static void draw_lc_match(int x0, int y0) { int xp = STR_MEASURE_X - x0; int yp = STR_MEASURE_Y - y0; - cell_printf(xp, yp, "L/C match for source Z0 = %0.1f"S_OHM, lc_match_array->R0); + cell_printf(xp, yp, "L/C match for source Z0 = %0.1f" S_OHM, lc_match_array->R0); #if 0 yp += STR_MEASURE_HEIGHT; - cell_printf(xp, yp, "%qHz %0.1f %c j%0.1f"S_OHM, match_array->Hz, match_array->RL, (match_array->XL >= 0) ? '+' : '-', vna_fabsf(match_array->XL)); + cell_printf(xp, yp, "%q" S_Hz " %0.1f %c j%0.1f" S_OHM, match_array->Hz, match_array->RL, (match_array->XL >= 0) ? '+' : '-', vna_fabsf(match_array->XL)); #endif yp += STR_MEASURE_HEIGHT; if (yp >= CELLHEIGHT) return; @@ -328,7 +307,7 @@ static void draw_lc_match(int x0, int y0) #ifdef __S21_MEASURE__ typedef struct { - char *header; + const char *header; freq_t freq; // resonant frequency freq_t freq1; // fp float l; @@ -364,11 +343,11 @@ static void analysis_lcshunt(void) { float ypeak = search_peak_value(&xp, s21pow2, MEASURE_SEARCH_MIN); // peak frequency, R float att = vna_sqrtf(ypeak); - s21_measure->r = config._measure_r * att / (2 * (1 - att)); - if(s21_measure->r < 0) return; + s21_measure->r = config._measure_r * att / (2.0f * (1.0f - att)); + if(s21_measure->r < 0.0f) return; set_marker_index(0, xp); - float tan45 = config._measure_r/(config._measure_r + 4 * s21_measure->r); + float tan45 = config._measure_r/(config._measure_r + 4.0f * s21_measure->r); // s21_measure->tan45 = tan45; // -45 degree search at left x2 = xp; @@ -382,13 +361,13 @@ static void analysis_lcshunt(void) { if (f2 == 0) return; set_marker_index(2, x2); - // L,C,Q calculations + // L, C, Q calculations float bw = f2 - f1; float fpeak = vna_sqrtf(f2 * f1); s21_measure->freq = fpeak; s21_measure->q = fpeak / bw; - s21_measure->l = s21_measure->q * s21_measure->r / ((2 * VNA_PI) * fpeak); - s21_measure->c = 1 / ((2 * VNA_PI) * fpeak * s21_measure->q * s21_measure->r); + s21_measure->l = s21_measure->r / ((2.0f * VNA_PI) * bw); + s21_measure->c = bw / ((2.0f * VNA_PI) * fpeak * fpeak * s21_measure->r); } static void analysis_lcseries(void) { @@ -402,7 +381,7 @@ static void analysis_lcseries(void) { if(s21_measure->r < 0) return; set_marker_index(0, xp); - const float tan45 = 1.0f; // tand(45) = 1.0f + const float tan45 = 1.0f; // tang(45) = 1.0f // Lookup +45 phase at left of xp index x2 = xp; float f1 = measure_search_value(&x2, tan45, s21tan, MEASURE_SEARCH_LEFT); @@ -415,18 +394,17 @@ static void analysis_lcseries(void) { if (f2 == 0) return; // not found set_marker_index(2, x2); - // L,C,Q calculation + // L, C, Q calculation float bw = f2 - f1; - float fpeak = vna_sqrtf(f2*f1); + float fpeak = vna_sqrtf(f2 * f1); // The total resistance, REFF, seen by the crystal is the sum of the load resistance (input and output) and the motional resistance, Rm: - float reff = 2 * config._measure_r + s21_measure->r; + float reff = 2.0f * config._measure_r + s21_measure->r; s21_measure->freq = fpeak; - s21_measure->l = reff / ((2 * VNA_PI) * bw); - s21_measure->c = bw / ((2 * VNA_PI) * fpeak * fpeak * reff); - // q = 2*pi * Fp * Ls / R - s21_measure->q = (2 * VNA_PI) * fpeak * s21_measure->l / s21_measure->r; - + s21_measure->l = reff / ((2.0f * VNA_PI) * bw); + s21_measure->c = bw / ((2.0f * VNA_PI) * fpeak * fpeak * reff); + // q = 2 * pi * Fp * Ls / R + s21_measure->q = (2.0f * VNA_PI) * fpeak * s21_measure->l / s21_measure->r; // s21_measure->f1 = f1; // s21_measure->f2 = f2; } @@ -443,8 +421,8 @@ static void analysis_xtalseries(void) { freq_t freq1 = getFrequency(xp); if(freq1 < s21_measure->freq) return; s21_measure->freq1 = freq1; - // df = f * c / (2*c1) => c1 = f * c / (2*df) - s21_measure->c1 = s21_measure->c * s21_measure->freq / (2*(s21_measure->freq1 - s21_measure->freq)); + // df = f * c / (2 * c1) => c1 = f * c / (2 * df) + s21_measure->c1 = s21_measure->c * s21_measure->freq / (2.0f * (s21_measure->freq1 - s21_measure->freq)); } static void draw_serial_result(int x0, int y0){ @@ -457,15 +435,15 @@ static void draw_serial_result(int x0, int y0){ } if (s21_measure->freq) { - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Fs=%qHz", s21_measure->freq); - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Lm=%FH Cm=%FF Rm=%F" S_OHM, s21_measure->l, s21_measure->c, s21_measure->r); + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Fs=%q" S_Hz, s21_measure->freq); + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Lm=%F" S_HENRY " Cm=%F" S_FARAD " Rm=%F" S_OHM, s21_measure->l, s21_measure->c, s21_measure->r); cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Q=%.3f", s21_measure->q); // cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "tan45=%.4f", s21_measure->tan45); -// cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "F1=%qHz F2=%qHz", s21_measure->f1, s21_measure->f2); +// cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "F1=%q" S_Hz " F2=%q" S_Hz, s21_measure->f1, s21_measure->f2); } if (s21_measure->freq1){ - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Fp=%qHz", s21_measure->freq1); - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Cp=%FF", s21_measure->c1); + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Fp=%q" S_Hz, s21_measure->freq1); + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Cp=%F" S_FARAD, s21_measure->c1); } } @@ -494,10 +472,12 @@ typedef struct { float R; float len; float loss; + float vf; float C0; float a, b, c; } s11_cable_measure_t; static s11_cable_measure_t *s11_cable = (s11_cable_measure_t *)measure_memory; +float real_cable_len = 0.0f; static float s11imag(uint16_t i) { return measured[0][i][1]; @@ -509,11 +489,13 @@ static void draw_s11_cable(int x0, int y0){ cell_printf(xp, yp, "S11 CABLE"); if (s11_cable->R){ cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Z0 = %F" S_OHM, s11_cable->R); -// cell_printf(xp, yp+=FONT_STR_HEIGHT, "C0 = %FF", s11_cable->C0); +// cell_printf(xp, yp+=FONT_STR_HEIGHT, "C0 = %F" S_FARAD, s11_cable->C0); } - if (s11_cable->len) - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Length = %Fm (K=%d%%)", s11_cable->len, velocity_factor); - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Loss = %FdB", s11_cable->loss); + if (s11_cable->vf) + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "VF=%.2f%% (Length = %F" S_METRE ")", s11_cable->vf, real_cable_len); + else if (s11_cable->len) + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Length = %F" S_METRE " (VF=%d%%)", s11_cable->len, velocity_factor); + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "Loss = %F" S_dB, s11_cable->loss); } static void prepare_s11_cable(uint8_t type, uint8_t update_mask) @@ -523,10 +505,13 @@ static void prepare_s11_cable(uint8_t type, uint8_t update_mask) if (update_mask & MEASURE_UPD_SWEEP) { s11_cable->R = 0.0f; s11_cable->len = 0.0f; + s11_cable->vf = 0.0f; uint16_t x = 0; f1 = measure_search_value(&x, 0, s11imag, MEASURE_SEARCH_RIGHT); if (f1){ - s11_cable->len = velocity_factor * (SPEED_OF_LIGHT / 400.0f) / f1; + float electric_lengh = (SPEED_OF_LIGHT / 400.0f) / f1; + s11_cable->len = velocity_factor * electric_lengh; + if (real_cable_len != 0.0f) s11_cable->vf = real_cable_len / electric_lengh; float data[2]; if (measure_get_value(0, f1/2, data)){ s11_cable->R = vna_fabsf(reactance(0, data)); @@ -536,7 +521,7 @@ static void prepare_s11_cable(uint8_t type, uint8_t update_mask) } if ((update_mask & MEASURE_UPD_ALL) && active_marker != MARKER_INVALID) { int idx = markers[active_marker].index; - s11_cable->loss = vna_fabsf(logmag(idx, measured[0][idx]) / 2); + s11_cable->loss = vna_fabsf(logmag(idx, measured[0][idx]) / 2.0f); } // Prepare for update invalidate_rect(STR_MEASURE_X , STR_MEASURE_Y, @@ -575,7 +560,7 @@ static void draw_s11_resonance(int x0, int y0){ return; } for (int i = 0; i < s11_resonance->count; i++) - cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "%qHz, %F%+jF" S_OHM, s11_resonance->data[i].f, s11_resonance->data[i].r, s11_resonance->data[i].x); + cell_printf(xp, yp+=STR_MEASURE_HEIGHT, "%q" S_Hz ", %F%+jF" S_OHM, s11_resonance->data[i].f, s11_resonance->data[i].r, s11_resonance->data[i].x); } static bool add_resonance_value(int i, uint16_t x, freq_t f) { @@ -619,4 +604,4 @@ static void prepare_s11_resonance(uint8_t type, uint8_t update_mask) } #endif //__S11_RESONANCE_MEASURE__ -#endif // __VNA_MEASURE__ +#endif // __VNA_MEASURE_MODULE__ diff --git a/nanovna.h b/nanovna.h index aa491ba..0b7f01d 100644 --- a/nanovna.h +++ b/nanovna.h @@ -20,12 +20,15 @@ */ #include "ch.h" +#define __MS5351__ + // Define LCD display driver and size #if defined(NANOVNA_F303) #define LCD_DRIVER_ST7796S #define LCD_480x320 #else #define LCD_DRIVER_ILI9341 +//#define DISPLAY_ST7789 #define LCD_320x240 #endif @@ -40,11 +43,7 @@ // Use DAC (in H4 used for brightness used DAC, so need enable __LCD_BRIGHTNESS__ for it) //#define __VNA_ENABLE_DAC__ // Allow enter to DFU from menu or command -#if defined(NANOVNA_F303) -//#define __DFU_SOFTWARE_MODE__ -#else #define __DFU_SOFTWARE_MODE__ -#endif // Add RTC clock support #define __USE_RTC__ // Add RTC backup registers support @@ -91,10 +90,12 @@ #ifdef __USE_SD_CARD__ // Allow run commands from SD card (config.ini in root) #define __SD_CARD_LOAD__ +// Allow screenshots in TIFF format +#define __SD_CARD_DUMP_TIFF__ // Allow dump firmware to SD card #define __SD_CARD_DUMP_FIRMWARE__ // Enable SD card file browser, and allow load files from it -//#define __SD_FILE_BROWSER__ +#define __SD_FILE_BROWSER__ #endif // If measure module enabled, add submodules @@ -131,7 +132,7 @@ #define USE_VARIABLE_OFFSET // Maximum sweep point count (limit by flash and RAM size) -#define POINTS_COUNT 401 +#define SWEEP_POINTS_MAX 401 #define AUDIO_ADC_FREQ_K1 384 #else @@ -152,8 +153,10 @@ //#define USE_VARIABLE_OFFSET // Maximum sweep point count (limit by flash and RAM size) -#define POINTS_COUNT 101 +#define SWEEP_POINTS_MAX 101 #endif +// Minimum sweep point count +#define SWEEP_POINTS_MIN 21 // Dirty hack for H4 ADC speed in version screen (Need for correct work NanoVNA-App) #ifndef AUDIO_ADC_FREQ_K1 @@ -164,9 +167,9 @@ * main.c */ // Minimum frequency set -#define START_MIN 1600 +#define FREQUENCY_MIN 1600 // Maximum frequency set -#define STOP_MAX 2000000000U +#define FREQUENCY_MAX 2000000000U // Frequency threshold (max frequency for si5351, harmonic mode after) #define FREQUENCY_THRESHOLD 290000100U // XTAL frequency on si5351 @@ -251,25 +254,25 @@ typedef uint32_t freq_t; // Optional sweep point (in UI menu) -#if POINTS_COUNT >=401 +#if SWEEP_POINTS_MAX >=401 #define POINTS_SET_COUNT 5 -#define POINTS_SET {51, 101, 201, 301, POINTS_COUNT} +#define POINTS_SET {51, 101, 201, 301, SWEEP_POINTS_MAX} #define POINTS_COUNT_DEFAULT 101 -#elif POINTS_COUNT >=301 +#elif SWEEP_POINTS_MAX >=301 #define POINTS_SET_COUNT 4 -#define POINTS_SET {51, 101, 201, POINTS_COUNT} +#define POINTS_SET {51, 101, 201, SWEEP_POINTS_MAX} #define POINTS_COUNT_DEFAULT 101 -#elif POINTS_COUNT >=201 +#elif SWEEP_POINTS_MAX >=201 #define POINTS_SET_COUNT 3 -#define POINTS_SET {51, 101, POINTS_COUNT} +#define POINTS_SET {51, 101, SWEEP_POINTS_MAX} #define POINTS_COUNT_DEFAULT 101 -#elif POINTS_COUNT >=101 +#elif SWEEP_POINTS_MAX >=101 #define POINTS_SET_COUNT 2 -#define POINTS_SET {51, POINTS_COUNT} -#define POINTS_COUNT_DEFAULT POINTS_COUNT +#define POINTS_SET {51, SWEEP_POINTS_MAX} +#define POINTS_COUNT_DEFAULT SWEEP_POINTS_MAX #endif -extern float measured[2][POINTS_COUNT][2]; +extern float measured[2][SWEEP_POINTS_MAX][2]; #define CAL_TYPE_COUNT 5 #define CAL_LOAD 0 @@ -297,9 +300,9 @@ extern float measured[2][POINTS_COUNT][2]; #define ETERM_ET 3 /* error term transmission tracking */ #define ETERM_EX 4 /* error term isolation */ -#if POINTS_COUNT <= 256 +#if SWEEP_POINTS_MAX <= 256 #define FFT_SIZE 256 -#elif POINTS_COUNT <= 512 +#elif SWEEP_POINTS_MAX <= 512 #define FFT_SIZE 512 #endif @@ -308,7 +311,7 @@ void cal_done(void); #define MAX_FREQ_TYPE 5 enum stimulus_type { - ST_START=0, ST_STOP, ST_CENTER, ST_CW, ST_SPAN, ST_VAR + ST_START=0, ST_STOP, ST_CENTER, ST_CW, ST_SPAN, ST_STEP, ST_VAR }; freq_t getFrequency(uint16_t idx); @@ -335,7 +338,6 @@ int parse_line(char *line, char* args[], int max_cnt); void pause_sweep(void); void toggle_sweep(void); -void load_default_properties(void); int load_properties(uint32_t id); #ifdef __USE_BACKUP__ @@ -530,7 +532,7 @@ void tlv320aic3204_write_reg(uint8_t page, uint8_t reg, uint8_t data); #define FREQUENCIES_XPOS1 OFFSETX #define FREQUENCIES_XPOS2 (LCD_WIDTH - 23 * sFONT_WIDTH) -#define FREQUENCIES_XPOS3 (LCD_WIDTH/2 + OFFSETX - 14 * sFONT_WIDTH / 2) +#define FREQUENCIES_XPOS3 (LCD_WIDTH/2 + OFFSETX - 16 * sFONT_WIDTH / 2) #define FREQUENCIES_YPOS (AREA_HEIGHT_NORMAL) #endif // end 320x240 display plot definitions @@ -733,6 +735,25 @@ extern const uint8_t numfont16x22[]; #define NUM_FONT_GET_HEIGHT 22 #define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*2*NUM_FONT_GET_HEIGHT]) +// Glyph names from numfont16x22.c +enum { + KP_0 = 0, KP_1, KP_2, KP_3, KP_4, KP_5, KP_6, KP_7, KP_8, KP_9, + KP_PERIOD, + KP_MINUS, + KP_BS, + KP_k, KP_M, KP_G, + KP_m, KP_u, KP_n, KP_p, + KP_X1, KP_ENTER, KP_PERCENT, // Enter values +#if 0 + KP_INF, + KP_DB, + KP_PLUSMINUS, + KP_KEYPAD, + KP_SPACE, + KP_PLUS +#endif +}; + /* * LC match text output settings */ @@ -783,7 +804,7 @@ extern const uint8_t numfont16x22[]; #define MAX_PALETTE 32 // trace -#define MAX_TRACE_TYPE 28 +#define MAX_TRACE_TYPE 30 enum trace_type { TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_Z, TRC_ZPHASE, @@ -791,10 +812,11 @@ enum trace_type { TRC_sC, TRC_sL, TRC_pC, TRC_pL, TRC_Q, - TRC_Rser, TRC_Xser, - TRC_Rsh, TRC_Xsh, + TRC_Rser, TRC_Xser, TRC_Zser, + TRC_Rsh, TRC_Xsh, TRC_Zsh, TRC_Qs21 }; + // Mask for define rectangular plot #define RECTANGULAR_GRID_MASK ((1<>1) + (frequency1>>1) + (frequency0&1); case ST_SPAN: return frequency1 - frequency0; case ST_CW: return frequency0; } @@ -1318,7 +1355,6 @@ get_sweep_frequency(uint16_t type) int caldata_save(uint32_t id); int caldata_recall(uint32_t id); -const properties_t *caldata_reference(void); const properties_t *get_properties(uint32_t id); int config_save(void); @@ -1341,6 +1377,8 @@ void touch_cal_exec(void); void touch_draw_test(void); void enter_dfu(void); +void drawMessageBox(const char *header, const char *text, uint32_t delay); + // Irq operation process set #define OP_NONE 0x00 #define OP_LEVER 0x01 @@ -1349,13 +1387,6 @@ void enter_dfu(void); extern uint8_t operation_requested; #define TOUCH_THRESHOLD 2000 - -// Update config._vna_mode flags -#define VNA_MODE_CLR 0 -#define VNA_MODE_SET 1 -#define VNA_MODE_TOGGLE 2 -void apply_VNA_mode(uint16_t idx, uint16_t value); - /* * misclinous */ diff --git a/numfont16x22.c b/numfont16x22.c new file mode 100644 index 0000000..846fee4 --- /dev/null +++ b/numfont16x22.c @@ -0,0 +1,693 @@ +/* + * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@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 "nanovna.h" + +const uint8_t numfont16x22[] = { + _BMP16(0b0000111111110000), + _BMP16(0b0011111111111100), + _BMP16(0b0111111111111110), + _BMP16(0b0111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111110), + _BMP16(0b0111111111111110), + _BMP16(0b0011111111111100), + _BMP16(0b0000111111110000), + + _BMP16(0b0000000011110000), + _BMP16(0b0000000111110000), + _BMP16(0b0000001111110000), + _BMP16(0b0000011111110000), + _BMP16(0b0000111111110000), + _BMP16(0b0000111111110000), + _BMP16(0b0000111011110000), + _BMP16(0b0000110011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000011110000), + _BMP16(0b0000001111111100), + _BMP16(0b0000001111111100), + _BMP16(0b0000001111111100), + + _BMP16(0b0000111111110000), + _BMP16(0b0011111111111100), + _BMP16(0b0111111111111110), + _BMP16(0b0111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b0000000000011111), + _BMP16(0b0000000000111111), + _BMP16(0b0000000001111110), + _BMP16(0b0000000011111100), + _BMP16(0b0000000111111000), + _BMP16(0b0000001111110000), + _BMP16(0b0000011111100000), + _BMP16(0b0000111111000000), + _BMP16(0b0001111110000000), + _BMP16(0b0011111100000000), + _BMP16(0b0111111000000000), + _BMP16(0b1111110000000000), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + + _BMP16(0b0000111111110000), + _BMP16(0b0011111111111100), + _BMP16(0b0111111111111110), + _BMP16(0b0111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b0000000000011110), + _BMP16(0b0000000000111110), + _BMP16(0b0000000111111100), + _BMP16(0b0000000111111000), + _BMP16(0b0000000111111100), + _BMP16(0b0000000001111110), + _BMP16(0b0000000000011111), + _BMP16(0b0000000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111110), + _BMP16(0b0111111111111110), + _BMP16(0b0011111111111100), + _BMP16(0b0000111111110000), + + _BMP16(0b0000000111111000), + _BMP16(0b0000000111111000), + _BMP16(0b0000001111111000), + _BMP16(0b0000001111111000), + _BMP16(0b0000011111111000), + _BMP16(0b0000011111111000), + _BMP16(0b0000111111111000), + _BMP16(0b0000111101111000), + _BMP16(0b0001111101111000), + _BMP16(0b0001111001111000), + _BMP16(0b0011111001111000), + _BMP16(0b0011110001111000), + _BMP16(0b0111110001111000), + _BMP16(0b0111100001111000), + _BMP16(0b1111100001111000), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b0000000001111000), + _BMP16(0b0000000001111000), + _BMP16(0b0000000001111000), + _BMP16(0b0000000001111000), + + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111011111110000), + _BMP16(0b1111111111111100), + _BMP16(0b1111111111111110), + _BMP16(0b1111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111110), + _BMP16(0b0111111111111110), + _BMP16(0b0011111111111100), + _BMP16(0b0000111111110000), + + _BMP16(0b0000111111110000), + _BMP16(0b0011111111111100), + _BMP16(0b0111111111111110), + _BMP16(0b0111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111011111110000), + _BMP16(0b1111111111111100), + _BMP16(0b1111111111111110), + _BMP16(0b1111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111110), + _BMP16(0b0111111111111110), + _BMP16(0b0011111111111100), + _BMP16(0b0000111111110000), + + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b0000000000011111), + _BMP16(0b0000000000111110), + _BMP16(0b0000000001111100), + _BMP16(0b0000000011111000), + _BMP16(0b0000000111110000), + _BMP16(0b0000000111100000), + _BMP16(0b0000001111100000), + _BMP16(0b0000001111000000), + _BMP16(0b0000011111000000), + _BMP16(0b0000011110000000), + _BMP16(0b0000011110000000), + _BMP16(0b0000111110000000), + _BMP16(0b0000111100000000), + _BMP16(0b0000111100000000), + _BMP16(0b0000111100000000), + _BMP16(0b0000111100000000), + _BMP16(0b0000111100000000), + _BMP16(0b0000111100000000), + _BMP16(0b0000111100000000), + + _BMP16(0b0000011111100000), + _BMP16(0b0001111111111000), + _BMP16(0b0011111111111100), + _BMP16(0b0111110000111110), + _BMP16(0b0111100000011110), + _BMP16(0b0111100000011110), + _BMP16(0b0111100000011110), + _BMP16(0b0011110000111100), + _BMP16(0b0001111111111000), + _BMP16(0b0000111111110000), + _BMP16(0b0011111111111100), + _BMP16(0b0111110000111110), + _BMP16(0b0111100000011110), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111110), + _BMP16(0b0111111111111110), + _BMP16(0b0011111111111100), + _BMP16(0b0000111111110000), + + _BMP16(0b0000111111110000), + _BMP16(0b0011111111111100), + _BMP16(0b0111111111111110), + _BMP16(0b0111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111111), + _BMP16(0b0111111111111111), + _BMP16(0b0011111111111111), + _BMP16(0b0000111111111111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111110), + _BMP16(0b0111111111111110), + _BMP16(0b0011111111111100), + _BMP16(0b0000111111110000), + + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000011111000000), + _BMP16(0b0000011111000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000000000000000), + + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0011111111111100), + _BMP16(0b0011111111111100), + _BMP16(0b0011111111111100), + _BMP16(0b0011111111111100), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000001000000), + _BMP16(0b0000000011000000), + _BMP16(0b0000000111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000011111000000), + _BMP16(0b0000111111111111), + _BMP16(0b0001111111111111), + _BMP16(0b0011111111111111), + _BMP16(0b0111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b0111111111111111), + _BMP16(0b0011111111111111), + _BMP16(0b0001111111111111), + _BMP16(0b0000111111111111), + _BMP16(0b0000011111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000000111000000), + _BMP16(0b0000000011000000), + _BMP16(0b0000000001000000), + _BMP16(0b0000000000000000), + + _BMP16(0b1111000000000000), // kilo + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000111110), + _BMP16(0b1111000001111100), + _BMP16(0b1111000011111000), + _BMP16(0b1111000111110000), + _BMP16(0b1111001111100000), + _BMP16(0b1111011111000000), + _BMP16(0b1111111110000000), + _BMP16(0b1111111100000000), + _BMP16(0b1111111100000000), + _BMP16(0b1111111110000000), + _BMP16(0b1111011111000000), + _BMP16(0b1111001111100000), + _BMP16(0b1111000111110000), + _BMP16(0b1111000011111000), + _BMP16(0b1111000001111100), + _BMP16(0b1111000000111110), + + _BMP16(0b1111000000001111), // Mega + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b1111100000011111), + _BMP16(0b1111110000111111), + _BMP16(0b1111110000111111), + _BMP16(0b1111111001111111), + _BMP16(0b1111111001111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111011111101111), + _BMP16(0b1111011111101111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111000110001111), + _BMP16(0b1111000110001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + + _BMP16(0b0000111111110000), // Giga + _BMP16(0b0011111111111100), + _BMP16(0b0111111111111110), + _BMP16(0b0111110000111110), + _BMP16(0b1111100000011111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000111111), + _BMP16(0b1111000000111111), + _BMP16(0b1111000000111111), + _BMP16(0b1111000000000111), + _BMP16(0b1111000000001111), + _BMP16(0b1111100000011111), + _BMP16(0b0111110000111111), + _BMP16(0b0111111111111111), + _BMP16(0b0011111111110111), + _BMP16(0b0000111111100111), + + _BMP16(0b0000000000000000), // milli + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b1110111000011100), + _BMP16(0b1111111100111110), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + _BMP16(0b1111001111001111), + + _BMP16(0b0000000000000000), // micro + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111000000011110), + _BMP16(0b1111100000111110), + _BMP16(0b1111110001111110), + _BMP16(0b1111111111111110), + _BMP16(0b1111111111111111), + _BMP16(0b1111011111001111), + _BMP16(0b1111001110000111), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + + _BMP16(0b0000000000000000), // nano + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b1111000111110000), + _BMP16(0b1111011111111100), + _BMP16(0b1111111111111110), + _BMP16(0b1111111000111110), + _BMP16(0b1111110000011111), + _BMP16(0b1111100000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + _BMP16(0b1111000000001111), + + _BMP16(0b0000000000000000), // pico + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b1111001111110000), + _BMP16(0b1111011111111100), + _BMP16(0b1111111111111110), + _BMP16(0b1111111000011111), + _BMP16(0b1111110000001111), + _BMP16(0b1111100000000111), + _BMP16(0b1111100000000111), + _BMP16(0b1111100000000111), + _BMP16(0b1111110000001111), + _BMP16(0b1111111000011111), + _BMP16(0b1111111111111110), + _BMP16(0b1111011111111100), + _BMP16(0b1111001111110000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + _BMP16(0b1111000000000000), + + _BMP16(0b0000000000000011), // x1 + _BMP16(0b0000000000000111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000011111), + _BMP16(0b0000000000111111), + _BMP16(0b0000000001111111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0110000011001111), + _BMP16(0b1111000111101111), + _BMP16(0b0111101111001111), + _BMP16(0b0011111110001111), + _BMP16(0b0001111100001111), + _BMP16(0b0001111100001111), + _BMP16(0b0011111110001111), + _BMP16(0b0111101111001111), + _BMP16(0b1111000111101111), + _BMP16(0b0110000011001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + + _BMP16(0b1111010001011111), // ENTER + _BMP16(0b1000011001000100), + _BMP16(0b1111010101000100), + _BMP16(0b1000010011000100), + _BMP16(0b1111010001000100), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0000000000001111), + _BMP16(0b0001100000001111), + _BMP16(0b0011100000001111), + _BMP16(0b0111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b1111111111111111), + _BMP16(0b0111111111111111), + _BMP16(0b0011100000000000), + _BMP16(0b0001100000000000), + + _BMP16(0b0000000000000000), // % + _BMP16(0b0011110000000000), + _BMP16(0b0111111000000000), + _BMP16(0b1110011100000011), + _BMP16(0b1100001100000111), + _BMP16(0b1100001100001111), + _BMP16(0b1110011100011110), + _BMP16(0b0111111000111100), + _BMP16(0b0011110001111000), + _BMP16(0b0000000011110000), + _BMP16(0b0000000111100000), + _BMP16(0b0000001111000000), + _BMP16(0b0000011110000000), + _BMP16(0b0000111100000000), + _BMP16(0b0001111000111100), + _BMP16(0b0011110001111110), + _BMP16(0b0111100011100111), + _BMP16(0b1111000011000011), + _BMP16(0b1110000011000011), + _BMP16(0b1100000011100111), + _BMP16(0b0000000001111110), + _BMP16(0b0000000000111100), + +#if 0 + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0001111000111100), + _BMP16(0b0011111101111110), + _BMP16(0b0111001111100110), + _BMP16(0b0110000111000011), + _BMP16(0b1110000111000011), + _BMP16(0b1100000110000011), + _BMP16(0b1100000110000011), + _BMP16(0b1100000110000011), + _BMP16(0b1100000110000011), + _BMP16(0b1100001110000111), + _BMP16(0b1100001110000110), + _BMP16(0b0110011111001110), + _BMP16(0b0111111011111100), + _BMP16(0b0011110001111000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000011101111100), + _BMP16(0b0000011101111110), + _BMP16(0b0000001101100110), + _BMP16(0b0000001101100110), + _BMP16(0b0000001101100110), + _BMP16(0b0000001101100110), + _BMP16(0b0000001101100110), + _BMP16(0b0011101101111100), + _BMP16(0b0111111101111110), + _BMP16(0b1110011101100111), + _BMP16(0b1100001101100011), + _BMP16(0b1100001101100011), + _BMP16(0b1100001101100011), + _BMP16(0b1100001101100011), + _BMP16(0b1100001101100011), + _BMP16(0b1100001101100011), + _BMP16(0b1110011101100111), + _BMP16(0b0111111101111110), + _BMP16(0b0011101101111100), + + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000001110000000), + _BMP16(0b0011111111111000), + _BMP16(0b0011111111111000), + _BMP16(0b0011111111111000), + _BMP16(0b0000001110000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000001110000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0011111111111000), + _BMP16(0b0011111111111000), + _BMP16(0b0011111111111000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + + _BMP16(0b0000000000000000), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0000000000000000), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0000000000000000), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0000000000000000), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0111101111011110), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + + _BMP16(0b0000000000000000), // Space + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + + _BMP16(0b0000000000000000), // Plus + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0011111111111100), + _BMP16(0b0011111111111100), + _BMP16(0b0011111111111100), + _BMP16(0b0011111111111100), + _BMP16(0b0000001111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000001111000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), + _BMP16(0b0000000000000000), +#endif +}; diff --git a/plot.c b/plot.c index 65390c0..4a06134 100644 --- a/plot.c +++ b/plot.c @@ -59,17 +59,17 @@ static map_t markmap[MAX_MARKMAP_Y]; // Trace data cache, for faster redraw cells typedef struct { - uint16_t y; uint16_t x; + uint16_t y; } index_t; -static index_t trace_index[TRACE_INDEX_COUNT][POINTS_COUNT]; +static index_t trace_index[TRACE_INDEX_COUNT][SWEEP_POINTS_MAX]; #if 1 // All used in plot v > 0 #define float2int(v) ((int)((v)+0.5f)) #else -static int -float2int(float v) +static int +float2int(float v) { if (v < 0) return v - 0.5; if (v > 0) return v + 0.5; @@ -145,7 +145,7 @@ smith_grid(int x, int y) if (y < 0) y = -y; // mirror by y axis if (x >= 0) { // valid only if x >= 0 - if (x >= r/2){ // valid only if x >= P_RADIUS/2 + if (x >= P_RADIUS/2){ // valid only if x >= P_RADIUS/2 // Constant Reactance Circle: 2j : R/2 = P_RADIUS/2 (mirror by y) if (circle_inout(x - P_RADIUS, y - P_RADIUS/2, P_RADIUS/2) == 0) return 1; @@ -216,8 +216,8 @@ cell_smith_grid(int x0, int y0, int w, int h, pixel_t color) { int x, y; // offset to center - x0 -= P_CENTER_X; - y0 -= P_CENTER_Y; + x0-= P_CENTER_X; + y0-= P_CENTER_Y; for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (smith_grid(x + x0, y + y0)) cell_buffer[y * CELLWIDTH + x] = color; @@ -228,35 +228,34 @@ cell_admit_grid(int x0, int y0, int w, int h, pixel_t color) { int x, y; // offset to center - x0 = P_CENTER_X - x0; - y0 -= P_CENTER_Y; + x0 = P_CENTER_X - x0; + y0-= P_CENTER_Y; for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (smith_grid(- x + x0, y + y0)) cell_buffer[y * CELLWIDTH + x] = color; } -void update_grid(void) +void update_grid(freq_t fstart, freq_t fstop) { - freq_t gdigit = 100000000; - freq_t fstart = get_sweep_frequency(ST_START); - freq_t fspan = get_sweep_frequency(ST_SPAN); + freq_t fspan = fstop - fstart; freq_t grid; - - while (gdigit > 100) { - grid = 5 * gdigit; - if (fspan / grid >= 4) - break; - grid = 2 * gdigit; - if (fspan / grid >= 4) - break; - grid = gdigit; - if (fspan / grid >= 4) - break; - gdigit /= 10; + if (fspan < 1000) { + grid_offset = 0; + grid_width = 0; + } else { + freq_t gdigit = 100000000; + while (gdigit > 100) { + grid = 5 * gdigit; + if (fspan / grid >= 4) break; + grid = 2 * gdigit; + if (fspan / grid >= 4) break; + grid = gdigit; + if (fspan / grid >= 4) break; + gdigit /= 10; + } + grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); + grid_width = (WIDTH) * (grid / 100) / (fspan / 1000); } - - grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); - grid_width = (WIDTH) * (grid / 100) / (fspan / 1000); } static inline int @@ -281,34 +280,42 @@ rectangular_grid_y(int y) // NanoVNA measures // This functions used for plot traces, and markers data output // Also can used in measure calculations +//************************************************************************************** +#ifdef __VNA_Z_RENORMALIZATION__ +#define PORT_Z current_props._portz +#else +#define PORT_Z 50.0f +#endif +// Help functions +static float get_l(float re, float im) {return (re*re + im*im);} +static float get_w(int i) {return 2 * VNA_PI * getFrequency(i);} +static float get_s11_r(float re, float im, float z) {return vna_fabsf(2.0f * z * re / get_l(re, im) - z);} +static float get_s21_r(float re, float im, float z) {return 1.0f * z * re / get_l(re, im) - z;} +static float get_s11_x(float re, float im, float z) {return -2.0f * z * im / get_l(re, im);} +static float get_s21_x(float re, float im, float z) {return -1.0f * z * im / get_l(re, im);} + //************************************************************************************** // LINEAR = |S| //************************************************************************************** -static float -linear(int i, const float *v) -{ +static float linear(int i, const float *v) { (void) i; - return vna_sqrtf(v[0]*v[0] + v[1]*v[1]); + return vna_sqrtf(get_l(v[0], v[1])); } + //************************************************************************************** // LOGMAG = 20*log10f(|S|) //************************************************************************************** -static float -logmag(int i, const float *v) -{ +static float logmag(int i, const float *v) { (void) i; - float x = v[0]*v[0] + v[1]*v[1]; -// return log10f(x) * 10.0f; -// return vna_logf(x) * (10.0f / logf(10.0f)); - return vna_log10f_x_10(x); +// return log10f(get_l(v[0], v[1])) * 10.0f; +// return vna_logf(get_l(v[0], v[1])) * (10.0f / logf(10.0f)); + return vna_log10f_x_10(get_l(v[0], v[1])); } //************************************************************************************** // PHASE angle in degree = atan2(im, re) * 180 / PI //************************************************************************************** -static float -phase(int i, const float *v) -{ +static float phase(int i, const float *v) { (void) i; return (180.0f / VNA_PI) * vna_atan2f(v[1], v[0]); } @@ -316,11 +323,9 @@ phase(int i, const float *v) //************************************************************************************** // Group delay //************************************************************************************** -static float -groupdelay(const float *v, const float *w, uint32_t deltaf) -{ +static float groupdelay(const float *v, const float *w, uint32_t deltaf) { #if 1 - // atan(w)-atan(v) = atan((w-v)/(1+wv)) + // atan(w)-atan(v) = atan((w-v)/(1+wv)), for complex v and w result q = v / w float r = w[0]*v[0] + w[1]*v[1]; float i = w[0]*v[1] - w[1]*v[0]; return vna_atan2f(i, r) / (2 * VNA_PI * deltaf); @@ -332,9 +337,7 @@ groupdelay(const float *v, const float *w, uint32_t deltaf) //************************************************************************************** // REAL //************************************************************************************** -static float -real(int i, const float *v) -{ +static float real(int i, const float *v) { (void) i; return v[0]; } @@ -342,9 +345,7 @@ real(int i, const float *v) //************************************************************************************** // IMAG //************************************************************************************** -static float -imag(int i, const float *v) -{ +static float imag(int i, const float *v) { (void) i; return v[1]; } @@ -352,9 +353,7 @@ imag(int i, const float *v) //************************************************************************************** // SWR = (1 + |S|)/(1 - |S|) //************************************************************************************** -static float -swr(int i, const float *v) -{ +static float swr(int i, const float *v) { (void) i; float x = linear(i, v); if (x > 0.99f) @@ -362,87 +361,56 @@ swr(int i, const float *v) return (1 + x)/(1 - x); } -#ifdef __VNA_Z_RENORMALIZATION__ -#define PORT_Z current_props._portz -#else -#define PORT_Z 50.0f -#endif - -static float get_d(float re, float im) {return (1.0f - re)*(1.0f - re) + im*im;} -static float get_r(float re, float im) {return (1.0f - re*re - im*im);} -static float get_l(float re, float im) {return (re*re + im*im);} -static float get_a(float re, float im) {return (re - re*re - im*im);} -static float get_x(float im) {return 2.0f * im;} -static float get_w(int i) {return 2 * VNA_PI * getFrequency(i);} - //************************************************************************************** -// Z parameters calculations from complex gamma -// Z = R_ref * (1 + gamma) / (1 - gamma) = R + jX -// Resolve this in complex give: -// R = z0 * (1 - re*re - im*im) / ((1-re)*(1-re) + im*im)) -// X = z0 * 2*im / ((1-re)*(1-re) + im*im)) +// Z parameters calculations from complex S +// Z = z0 * (1 + S) / (1 - S) = R + jX // |Z| = sqrtf(R*R+X*X) -// -// replace r = (1 - re*re - im*im); x = 2*im; d = ((1-re)*(1-re) + im*im)) -// R = z0 * r / d -// X = z0 * x / d -// |Z| = z0 * sqrt(4 * re / d + 1) +// Resolve this in complex give: +// let S` = 1 - S => re` = 1 - re and im` = -im +// l` = re` * re` + im` * im` +// Z = z0 * (2 - S`) / S` = z0 * 2 / S` - z0 +// R = z0 * 2 * re` / l` - z0 +// X =-z0 * 2 * im` / l` +// |Z| = z0 * sqrt(4 * re / l` + 1) // Z phase = atan(X, R) //************************************************************************************** -static float -resistance(int i, const float *v) -{ +static float resistance(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float r = get_r(v[0], v[1]); - return d < 0.0f ? INFINITY : z0 * r / d; + return get_s11_r(1.0f - v[0], -v[1], PORT_Z); } -static float -reactance(int i, const float *v) -{ +static float reactance(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float x = get_x(v[1]); - return z0 * x / d; + return get_s11_x(1.0f - v[0], -v[1], PORT_Z); } -static float -mod_z(int i, const float *v) -{ +static float mod_z(int i, const float *v) { (void) i; const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - return z0 * vna_sqrtf(4 * v[0] / d + 1); // always >= 0 + const float l = get_l(1.0f - v[0], v[1]); + return z0 * vna_sqrtf(4.0f * v[0] / l + 1.0f); // always >= 0 } -static float -phase_z(int i, const float *v) -{ +static float phase_z(int i, const float *v) { (void) i; - const float r = get_r(v[0], v[1]); - const float x = get_x(v[1]); + const float r = 1.0f - get_l(v[0], v[1]); + const float x = 2.0f * v[1]; return (180.0f / VNA_PI) * vna_atan2f(x, r); } + //************************************************************************************** // Use w = 2 * pi * frequency // Get Series L and C from X // C = -1 / (w * X) // L = X / w //************************************************************************************** -static float -series_c(int i, const float *v) -{ +static float series_c(int i, const float *v) { const float zi = reactance(i, v); const float w = get_w(i); return -1.0f / (w * zi); } -static float -series_l(int i, const float *v) -{ +static float series_l(int i, const float *v) { const float zi = reactance(i, v); const float w = get_w(i); return zi / w; @@ -450,73 +418,35 @@ series_l(int i, const float *v) //************************************************************************************** // Q factor = abs(X / R) +// Q = 2 * im / (1 - re * re - im * im) //************************************************************************************** -static float -qualityfactor(int i, const float *v) -{ +static float qualityfactor(int i, const float *v) { (void) i; - const float x = get_x(v[1]); - const float r = get_r(v[0], v[1]); + const float r = 1.0f - get_l(v[0], v[1]); + const float x = 2.0f * v[1]; return vna_fabsf(x / r); } //************************************************************************************** -// Y parameters (conductance and susceptance) calculations from complex Z -// Y = 1 / Z = 1 / (R + jX) = B + jG -// G = R / (R*R + X*X) -// B = -X / (R*R + X*X) +// Y parameters (conductance and susceptance) calculations from complex S +// Y = (1 / z0) * (1 - S) / (1 + S) = G + jB +// Resolve this in complex give: +// let S` = 1 + S => re` = 1 + re and im` = im +// l` = re` * re` + im` * im` +// z0` = (1 / z0) +// Y = z0` * (2 - S`) / S` = 2 * z0` / S` - z0` +// G = 2 * z0` * re` / l` - z0` +// B = -2 * z0` * im` / l` // |Y| = 1 / |Z| //************************************************************************************** -static float -conductance(int i, const float *v) -{ +static float conductance(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float r = get_r(v[0], v[1]); - const float x = get_x(v[1]); - const float rx = z0 * (r*r + x*x); - return /* rx == 0 ? INFINITY :*/ r * d / rx; + return get_s11_r(1.0f + v[0], v[1], 1.0f / PORT_Z); } -static float -susceptance(int i, const float *v) -{ +static float susceptance(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float r = get_r(v[0], v[1]); - const float x = get_x(v[1]); - const float rx = z0 * (r*r + x*x); - return /* rx == 0 ? INFINITY :*/ -x * d / rx; -} - -//************************************************************************************** -// Use w = 2 * pi * frequency -// Get Parallel L and C from B -// C = B / w -// L = -1 / (w * B) -//************************************************************************************** -static float -parallel_c(int i, const float *v) -{ - const float zi = susceptance(i, v); - const float w = get_w(i); - return zi / w; -} - -static float -parallel_l(int i, const float *v) -{ - const float zi = susceptance(i, v); - const float w = get_w(i); - return -1.0f / (w * zi); -} - -static float -mod_y(int i, const float *v) -{ - return 1.0f / mod_z(i, v); // always >= 0 + return get_s11_x(1.0f + v[0], v[1], 1.0f / PORT_Z); } //************************************************************************************** @@ -524,84 +454,101 @@ mod_y(int i, const float *v) // Rp = 1 / G // Xp =-1 / B //************************************************************************************** -static float -parallel_r(int i, const float *v) -{ +static float parallel_r(int i, const float *v) { #if 1 return 1.0f / conductance(i, v); #else (void) i; + const float re = 1.0f + v[0], im = v[1]; const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float r = get_r(v[0], v[1]); - const float x = get_x(v[1]); - const float rx = z0 * (r*r + x*x); - return rx / (r * d); + const float l = get_l(re, im); + return z0 * l / (2.0f * re - l); #endif } -static float -parallel_x(int i, const float *v) -{ +static float parallel_x(int i, const float *v) { #if 1 return -1.0f / susceptance(i, v); #else (void) i; const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float r = get_r(v[0], v[1]); - const float x = get_x(v[1]); - const float rx = z0 * (r*r + x*x); - return rx / (x * d); + return z0 * get_l(1.0f + v[0], v[1]) / (2.0f * v[1]); #endif } +//************************************************************************************** +// Use w = 2 * pi * frequency +// Get Parallel L and C from B +// C = B / w +// L = -1 / (w * B) = Xp / w +//************************************************************************************** +static float parallel_c(int i, const float *v) { + const float yi = susceptance(i, v); + const float w = get_w(i); + return yi / w; +} + +static float parallel_l(int i, const float *v) { + const float xp = parallel_x(i, v); + const float w = get_w(i); + return xp / w; +} + +static float mod_y(int i, const float *v) { + return 1.0f / mod_z(i, v); // always >= 0 +} + //************************************************************************************** // S21 series and shunt -// S21 shunt Z = 0.5f * z0 * z / (1 - z) -// S21 series Z = 2.0f * z0 * (1 - z) / z +// S21 shunt Z = 0.5f * z0 * S / (1 - S) +// replace S` = (1 - S) +// S21 shunt Z = 0.5f * z0 * (1 - S`) / S` +// S21 series Z = 2.0f * z0 * (1 - S ) / S +// Q21 = im / re //************************************************************************************** static float s21shunt_r(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - const float a = get_a(v[0], v[1]); - return 0.5f * z0 * a / d; + return get_s21_r(1.0f - v[0], -v[1], 0.5f * PORT_Z); } static float s21shunt_x(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float d = get_d(v[0], v[1]); - return 0.5f * z0 * v[1] / d; + return get_s21_x(1.0f - v[0], -v[1], 0.5f * PORT_Z); +} + +static float s21shunt_z(int i, const float *v) { + (void) i; + float l1 = get_l(v[0], v[1]); + float l2 = get_l(1.0f - v[0], v[1]); + return 0.5f * PORT_Z * vna_sqrtf(l1 / l2); } static float s21series_r(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float l = get_l(v[0], v[1]); - return 2.0f * z0 * (v[0] - l) / l; + return get_s21_r(v[0], v[1], 2.0f * PORT_Z); } static float s21series_x(int i, const float *v) { (void) i; - const float z0 = PORT_Z; - const float l = get_l(v[0], v[1]); - return -2.0f * z0 * v[1] / l; + return get_s21_x(v[0], v[1], 2.0f * PORT_Z); +} + +static float s21series_z(int i, const float *v) { + (void) i; + float l1 = get_l(v[0], v[1]); + float l2 = get_l(1.0f - v[0], v[1]); + return 2.0f * PORT_Z * vna_sqrtf(l2 / l1); } static float s21_qualityfactor(int i, const float *v) { (void) i; - const float a = get_a(v[0], v[1]); - return vna_fabsf(v[1] / a); + return vna_fabsf(v[1] / (v[0] - get_l(v[0], v[1]))); } //************************************************************************************** // Group delay //************************************************************************************** -float -groupdelay_from_array(int i, const float *v) -{ +float groupdelay_from_array(int i, const float *v) { int bottom = (i == 0) ? 0 : -1; // get prev point int top = (i == sweep_points-1) ? 0 : 1; // get next point freq_t deltaf = get_sweep_frequency(ST_SPAN) / ((sweep_points - 1) / (top - bottom)); @@ -609,8 +556,7 @@ groupdelay_from_array(int i, const float *v) } static inline void -cartesian_scale(const float *v, int16_t *xp, int16_t *yp, float scale) -{ +cartesian_scale(const float *v, int16_t *xp, int16_t *yp, float scale) { int16_t x = P_CENTER_X + float2int(v[0] * scale); int16_t y = P_CENTER_Y - float2int(v[1] * scale); if (x < 0) x = 0; @@ -621,14 +567,14 @@ cartesian_scale(const float *v, int16_t *xp, int16_t *yp, float scale) *yp = y; } -#if MAX_TRACE_TYPE != 28 +#if MAX_TRACE_TYPE != 30 #error "Redefined trace_type list, need check format_list" #endif const trace_info_t trace_info_list[MAX_TRACE_TYPE] = { // Type name format delta format symbol ref scale get value [TRC_LOGMAG] = {"LOGMAG", "%.2f%s", S_DELTA "%.2f%s", S_dB, NGRIDY-1, 10.0f, logmag }, -[TRC_PHASE] = {"PHASE", "%.1f%s", S_DELTA "%.2f%s", S_DEGREE, NGRIDY/2, 90.0f, phase }, +[TRC_PHASE] = {"PHASE", "%.2f%s", S_DELTA "%.2f%s", S_DEGREE, NGRIDY/2, 90.0f, phase }, [TRC_DELAY] = {"DELAY", "%.4F%s", "%.4F%s", S_SECOND, NGRIDY/2, 1e-9f, groupdelay_from_array}, [TRC_SMITH] = {"SMITH", NULL, NULL, "", 0, 1.00f, NULL }, // Custom [TRC_POLAR] = {"POLAR", NULL, NULL, "", 0, 1.00f, NULL }, // Custom @@ -652,8 +598,10 @@ const trace_info_t trace_info_list[MAX_TRACE_TYPE] = { [TRC_Q] = {"Q", "%.4f%s", S_DELTA "%.3f%s", "", 0, 10.0f, qualityfactor }, [TRC_Rser] = {"Rser", "%.3F%s", S_DELTA "%.3F%s", S_OHM, NGRIDY/2, 100.0f, s21series_r }, [TRC_Xser] = {"Xser", "%.3F%s", S_DELTA "%.3F%s", S_OHM, NGRIDY/2, 100.0f, s21series_x }, +[TRC_Zser] = {"|Zser|", "%.3F%s", S_DELTA "%.3F%s", S_OHM, NGRIDY/2, 100.0f, s21series_z }, [TRC_Rsh] = {"Rsh", "%.3F%s", S_DELTA "%.3F%s", S_OHM, NGRIDY/2, 100.0f, s21shunt_r }, [TRC_Xsh] = {"Xsh", "%.3F%s", S_DELTA "%.3F%s", S_OHM, NGRIDY/2, 100.0f, s21shunt_x }, +[TRC_Zsh] = {"|Zsh|", "%.3F%s", S_DELTA "%.3F%s", S_OHM, NGRIDY/2, 100.0f, s21shunt_z }, [TRC_Qs21] = {"Q", "%.4f%s", S_DELTA "%.3f%s", "", 0, 10.0f, s21_qualityfactor }, }; @@ -669,7 +617,9 @@ const marker_info_t marker_info_list[MS_END] = { [MS_RpXp] = {"Rp + jXp", "%F%+jF" S_OHM, parallel_r, parallel_x }, [MS_RpLC] = {"Rp + L/C", "%F" S_OHM " %F%c", parallel_r, parallel_x }, // use LC calc for imag [MS_SHUNT_RX] = {"R+jX SHUNT", "%F%+jF" S_OHM, s21shunt_r, s21shunt_x }, +[MS_SHUNT_RLC] = {"R+L/C SH..", "%F" S_OHM " %F%c", s21shunt_r, s21shunt_x }, // use LC calc for imag [MS_SERIES_RX] = {"R+jX SERIES","%F%+jF" S_OHM, s21series_r, s21series_x }, +[MS_SERIES_RLC]= {"R+L/C SER..", "%F" S_OHM " %F%c", s21series_r, s21series_x }, // use LC calc for imag }; const char *get_trace_typename(int t, int marker_smith_format) @@ -687,12 +637,11 @@ static void mark_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { x1/= CELLWIDTH; x2/= CELLWIDTH; y1/= CELLHEIGHT; y2/= CELLHEIGHT; if (x1 == x2 && y1 == y2) { - markmap[y1] |= 1 << x1; + markmap[y1]|= 1 << x1; return; } - uint32_t mask = 0; if (x1 > x2) SWAP(uint16_t, x1, x2); - for (; x1 <= x2; x1++) mask|= 1 << x1; + uint32_t mask = ((1 << (x2 - x1 + 1)) - 1) << x1; if (y1 > y2) SWAP(uint16_t, y1, y2); for (; y1 <= y2; y1++) markmap[y1]|= mask; @@ -743,7 +692,7 @@ trace_into_index(int t) { return; } // Smith/Polar grid - if (type & ((1<=MAX_MARKMAP_Y) y1 = MAX_MARKMAP_Y-1; - uint32_t mask = 0; - for (; x0 <= x1; x0++) mask|= 1 << x0; +static void invalidate_rect_func(int x0, int y0, int x1, int y1) { + uint32_t mask = ((1 << (x1 - x0 + 1)) - 1) << x0; for (; y0 <= y1; y0++) if ((uint32_t)y0 < MAX_MARKMAP_Y) - markmap[y0]|= mask; + markmap[y0]|= mask; } #define invalidate_rect(x0, y0, x1, y1) invalidate_rect_func((x0)/CELLWIDTH, (y0)/CELLHEIGHT, (x1)/CELLWIDTH, (y1)/CELLHEIGHT) @@ -900,7 +838,7 @@ static int marker_area_max(void) { int extra = 0; if (electrical_delay != 0.0f) extra+= 2; if (s21_offset != 0.0f) extra+= 2; -#ifdef __VNA_Z_NORMALIZATION__ +#ifdef __VNA_Z_RENORMALIZATION__ if (current_props._portz != 50.0f) extra+= 2; #endif if (extra < 2) extra = 2; @@ -1027,11 +965,15 @@ cell_blit_bitmap_shadow(int16_t x, int16_t y, uint16_t w, uint16_t h, const uint return; // Prepare shadow bitmap uint16_t dst[16]; - uint16_t p0 = 0, p1 = 0, c = 8 - w; - uint16_t mask = (0xFF>>c)<>c)< ARRAY_COUNT(dst) - 2) h = ARRAY_COUNT(dst) - 2; for (i = 0; i < h; i++) { - c = (bmp[i] & mask)<<8; // extend from 8 bit width to 16 bit +#if 1 + c = (bmp[i]<<8) & mask; // extend from 8 bit width to 16 bit +#else + c = (((bmp[2*i]<<8)|bmp[2*i+1]) & mask); // extend from 16 bit width to 16 bit +#endif c|= (c>>1) | (c>>2); // shadow horizontally c = (c>>8) | (c<<8); // swap bytes (render do by 8 bit) dst[i] = c | p0 | p1; // shadow vertically @@ -1119,21 +1061,20 @@ static int cell_printf(int16_t x, int16_t y, const char *fmt, ...) { typedef void (*measure_cell_cb_t)(int x0, int y0); typedef void (*measure_prepare_cb_t)(uint8_t mode, uint8_t update_mask); -static measure_cell_cb_t measure_cell_handler = NULL; static uint8_t data_update = 0; -#define MESAURE_NONE 0 -#define MESAURE_S11 1 -#define MESAURE_S21 2 -#define MESAURE_ALL 3 +#define MESAURE_NONE 0 +#define MESAURE_S11 1 // For calculate need only S11 data +#define MESAURE_S21 2 // For calculate need only S21 data +#define MESAURE_ALL (MESAURE_S11 | MESAURE_S21) // For calculate need S11 and S21 data -#define MEASURE_UPD_SWEEP 1 -#define MEASURE_UPD_FREQ 2 -#define MEASURE_UPD_ALL 3 +#define MEASURE_UPD_SWEEP 1 // Recalculate on sweep done +#define MEASURE_UPD_FREQ 2 // Recalculate on marker change position +#define MEASURE_UPD_ALL (MEASURE_UPD_SWEEP | MEASURE_UPD_FREQ) -// Include L/C match functions -#ifdef __USE_LC_MATCHING__ - #include "lc_matching.c" +// Include measure functions +#ifdef __VNA_MEASURE_MODULE__ + #include "measure.c" #endif static const struct { @@ -1141,7 +1082,7 @@ static const struct { uint8_t update; measure_cell_cb_t measure_cell; measure_prepare_cb_t measure_prepare; -} measure[]={ +} measure[] = { [MEASURE_NONE] = {MESAURE_NONE, 0, NULL, NULL }, #ifdef __USE_LC_MATCHING__ [MEASURE_LC_MATH] = {MESAURE_NONE, MEASURE_UPD_ALL, draw_lc_match, prepare_lc_match }, @@ -1165,7 +1106,6 @@ static inline void measure_set_flag(uint8_t flag) { void plot_set_measure_mode(uint8_t mode) { if (mode >= MEASURE_END) return; - measure_cell_handler = measure[mode].measure_cell; current_props._measure = mode; data_update = 0xFF; request_to_redraw(REDRAW_AREA); @@ -1176,7 +1116,7 @@ uint16_t plot_get_measure_channels(void) { } static void measure_prepare(void) { - if (current_props._measure == 0) return; + if (current_props._measure >= MEASURE_END) return; measure_prepare_cb_t measure_cb = measure[current_props._measure].measure_prepare; // Do measure and cache data only if update flags some if (measure_cb && (data_update & measure[current_props._measure].update)) @@ -1185,10 +1125,12 @@ static void measure_prepare(void) { } static void cell_draw_measure(int x0, int y0){ - if (measure_cell_handler == NULL) return; - lcd_set_background(LCD_BG_COLOR); - lcd_set_foreground(LCD_LC_MATCH_COLOR); - measure_cell_handler(x0, y0); + if (current_props._measure >= MEASURE_END) return; + measure_cell_cb_t measure_draw_cb = measure[current_props._measure].measure_cell; + if (measure_draw_cb) { + lcd_set_colors(LCD_MEASURE_COLOR, LCD_BG_COLOR); + measure_draw_cb(x0, y0); + } } #endif @@ -1263,7 +1205,7 @@ marker_search_dir(int16_t from, int16_t dir) // Select compare function (depend from config settings) bool (*compare)(int x, int y) = VNA_MODE(VNA_MODE_SEARCH) ? _lesser : _greater; // Search next - for (i = from + dir, value = index[from].y; i >= 0 && i < sweep_points; i+=dir) { + for (i = from + dir, value = index[from].y; i >= 0 && i < sweep_points; i+=dir) { if ((*compare)(value, index[i].y)) break; value = index[i].y; @@ -1306,7 +1248,7 @@ search_nearest_index(int x, int y, int t) // // Build graph data and cache it for output // -void +static void plot_into_index(void) { // Mark old markers for erase @@ -1361,10 +1303,7 @@ static void markmap_grid_values(void) { #endif static void -draw_cell(int m, int n) -{ - int x0 = m * CELLWIDTH; - int y0 = n * CELLHEIGHT; +draw_cell(int x0, int y0) { int w = CELLWIDTH; int h = CELLHEIGHT; int x, y; @@ -1384,7 +1323,7 @@ draw_cell(int m, int n) #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, GET_PALTETTE_COLOR(LCD_BG_COLOR), (h*CELLWIDTH)*sizeof(uint16_t)); + memset(spi_buffer, GET_PALTETTE_COLOR(LCD_BG_COLOR), (h*CELLWIDTH)*sizeof(uint16_t)); #else // use direct set 35 system ticks for all screen calls #if CELLWIDTH%8 != 0 @@ -1395,30 +1334,29 @@ draw_cell(int m, int n) int count = h*CELLWIDTH / 8; uint32_t *p = (uint32_t *)cell_buffer; uint32_t clr = GET_PALTETTE_COLOR(LCD_BG_COLOR) | (GET_PALTETTE_COLOR(LCD_BG_COLOR) << 16); - while (count--) { + do { p[0] = clr; p[1] = clr; p[2] = clr; p[3] = clr; p += 4; - } + } while(--count); #elif LCD_PIXEL_SIZE == 1 // Set DEFAULT_BG_COLOR for 16 pixels in one cycle int count = h*CELLWIDTH / 16; uint32_t *p = (uint32_t *)cell_buffer; uint32_t clr = (GET_PALTETTE_COLOR(LCD_BG_COLOR)<< 0)|(GET_PALTETTE_COLOR(LCD_BG_COLOR)<< 8) | (GET_PALTETTE_COLOR(LCD_BG_COLOR)<<16)|(GET_PALTETTE_COLOR(LCD_BG_COLOR)<<24); - while (count--) { + do { p[0] = clr; p[1] = clr; p[2] = clr; p[3] = clr; p += 4; - } + } while(--count); #else #error "Write cell fill for different LCD_PIXEL_SIZE" #endif - #endif // Draw grid @@ -1464,14 +1402,14 @@ draw_cell(int m, int n) // PULSE; // Draw traces (50-600 system ticks for all screen calls, depend from lines count and size) #if 1 - for (t = TRACE_INDEX_COUNT-1; t >=0; t--) { + for (t = TRACE_INDEX_COUNT-1; t >= 0; t--) { if (!needProcessTrace(t)) continue; c = GET_PALTETTE_COLOR(LCD_TRACE_1_COLOR + t); index_t *index = trace_index[t]; i0 = i1 = 0; // draw rectangular plot (search index range in cell, save 50-70 system ticks for all screen calls) - if (((1 << trace[t].type) & RECTANGULAR_GRID_MASK) && !enabled_store_trace){ + if (((1 << trace[t].type) & RECTANGULAR_GRID_MASK) && !enabled_store_trace && sweep_points > 30){ search_index_range_x(x0, x0 + w, index, &i0, &i1); }else{ // draw polar plot (check all points) @@ -1489,13 +1427,13 @@ draw_cell(int m, int n) #else for (x = 0; x < area_width; x += 6) cell_drawline(x - x0, 0 - y0, area_width - x - x0, area_height - y0, - config.trace_color[0]); + GET_PALTETTE_COLOR(LCD_TRACE_1_COLOR)); #endif // PULSE; #ifdef __USE_GRID_VALUES__ // Only right cells - if (VNA_MODE(VNA_MODE_SHOW_GRID) && m >= (GRID_X_TEXT)/CELLWIDTH) + if (VNA_MODE(VNA_MODE_SHOW_GRID) && x0 > (GRID_X_TEXT - CELLWIDTH)) cell_grid_line_info(x0, y0); #endif @@ -1533,12 +1471,11 @@ draw_cell(int m, int n) } } } - #endif #if 1 // Draw trace and marker info on the top - if (n <= marker_area_max() / CELLHEIGHT) + if (y0 <= marker_area_max()) cell_draw_marker_info(x0, y0); #endif @@ -1587,7 +1524,7 @@ draw_all_cells(void) map_t update_map = markmap[n]; for (m = 0; update_map; update_map>>=1, m++) if (update_map & 1) - draw_cell(m, n); + draw_cell(m * CELLWIDTH, n * CELLHEIGHT); } #if 0 @@ -1612,6 +1549,7 @@ draw_all(void) if (redraw_request & REDRAW_BACKUP) update_backup_data(); #endif + if (redraw_request & REDRAW_PLOT) plot_into_index(); if (area_width == 0) {redraw_request = 0; return;} if (redraw_request & REDRAW_CLRSCR){ lcd_set_background(LCD_BG_COLOR); @@ -1626,7 +1564,7 @@ draw_all(void) if (redraw_request & REDRAW_GRID_VALUE) markmap_grid_values(); #endif } - if (redraw_request & (REDRAW_CELLS | REDRAW_MARKER | REDRAW_REFERENCE | REDRAW_AREA)) + if (redraw_request & (REDRAW_CELLS | REDRAW_MARKER | REDRAW_GRID_VALUE | REDRAW_REFERENCE | REDRAW_AREA)) draw_all_cells(); if (redraw_request & REDRAW_FREQUENCY) draw_frequencies(); @@ -1657,7 +1595,7 @@ redraw_marker(int8_t marker) { } // Marker and trace data position -static const struct {uint16_t x, y;} marker_pos[]={ +static const struct {uint16_t x, y;} marker_pos[MARKERS_MAX] = { { 1 + CELLOFFSETX, 1 }, { 1 + (WIDTH/2) + CELLOFFSETX, 1 }, { 1 + CELLOFFSETX, 1 + FONT_STR_HEIGHT}, { 1 + (WIDTH/2) + CELLOFFSETX, 1 + FONT_STR_HEIGHT}, { 1 + CELLOFFSETX, 1 + 2*FONT_STR_HEIGHT}, { 1 + (WIDTH/2) + CELLOFFSETX, 1 + 2*FONT_STR_HEIGHT}, @@ -1744,7 +1682,7 @@ cell_draw_marker_info(int x0, int y0) // draw marker delta if (!(props_mode & TD_MARKER_DELTA) && active_marker != previous_marker) { int previous_marker_idx = markers[previous_marker].index; - cell_printf(xpos, ypos, S_DELTA"%d-%d:", active_marker+1, previous_marker+1); + cell_printf(xpos, ypos, S_DELTA "%d-%d:", active_marker+1, previous_marker+1); xpos += 5*FONT_WIDTH + 2; if ((props_mode & DOMAIN_MODE) == DOMAIN_FREQ) { freq_t freq = get_marker_frequency(active_marker); @@ -1763,7 +1701,6 @@ cell_draw_marker_info(int x0, int y0) cell_printf(xpos, ypos, S_SARROW); xpos += FONT_WIDTH; cell_printf(xpos, ypos, "M%d:", active_marker+1); - //cell_drawstring(buf, xpos, ypos); xpos += 3*FONT_WIDTH + 4; if ((props_mode & DOMAIN_MODE) == DOMAIN_FREQ) cell_printf(xpos, ypos, "%q" S_Hz, get_marker_frequency(active_marker)); @@ -1798,9 +1735,8 @@ draw_frequencies(void) char lm0 = lever_mode == LM_FREQ_0 ? S_SARROW[0] : ' '; char lm1 = lever_mode == LM_FREQ_1 ? S_SARROW[0] : ' '; // Draw frequency string - lcd_set_foreground(LCD_FG_COLOR); - lcd_set_background(LCD_BG_COLOR); - lcd_fill(0, FREQUENCIES_YPOS, LCD_WIDTH, LCD_HEIGHT - FREQUENCIES_YPOS); + lcd_set_colors(LCD_FG_COLOR, LCD_BG_COLOR); + lcd_fill(0, HEIGHT + OFFSETY + 1, LCD_WIDTH, LCD_HEIGHT - HEIGHT - OFFSETY - 1); lcd_set_font(FONT_SMALL); // Prepare text for frequency string if ((props_mode & DOMAIN_MODE) == DOMAIN_FREQ) { @@ -1819,7 +1755,7 @@ draw_frequencies(void) } // Draw bandwidth and point count lcd_set_foreground(LCD_BW_TEXT_COLOR); - lcd_printf(FREQUENCIES_XPOS3, FREQUENCIES_YPOS,"bw:%u" S_Hz " %up", get_bandwidth_frequency(config._bandwidth), sweep_points); + lcd_printf(FREQUENCIES_XPOS3, FREQUENCIES_YPOS,"BW:%u" S_Hz " %up", get_bandwidth_frequency(config._bandwidth), sweep_points); lcd_set_font(FONT_NORMAL); } @@ -1832,8 +1768,7 @@ draw_cal_status(void) uint32_t i; int x = CALIBRATION_INFO_POSX; int y = CALIBRATION_INFO_POSY; - lcd_set_background(LCD_BG_COLOR); - lcd_set_foreground(LCD_DISABLE_CAL_COLOR); + lcd_set_colors(LCD_DISABLE_CAL_COLOR, LCD_BG_COLOR); lcd_fill(x, y, OFFSETX - x, 10*(sFONT_STR_HEIGHT)); lcd_set_font(FONT_SMALL); if (cal_status & CALSTAT_APPLY) { @@ -1889,8 +1824,7 @@ static void draw_battery_status(void) return; uint8_t string_buf[24]; // Set battery color - lcd_set_foreground(vbat < BATTERY_WARNING_LEVEL ? LCD_LOW_BAT_COLOR : LCD_NORMAL_BAT_COLOR); - lcd_set_background(LCD_BG_COLOR); + lcd_set_colors(vbat < BATTERY_WARNING_LEVEL ? LCD_LOW_BAT_COLOR : LCD_NORMAL_BAT_COLOR, LCD_BG_COLOR); // plot_printf(string_buf, sizeof string_buf, "V:%d", vbat); // lcd_drawstringV(string_buf, 1, 60); // Prepare battery bitmap image @@ -1922,7 +1856,7 @@ request_to_draw_cells_behind_menu(void) { // Values Hardcoded from ui.c invalidate_rect(LCD_WIDTH-MENU_BUTTON_WIDTH-OFFSETX, 0, LCD_WIDTH-OFFSETX, LCD_HEIGHT-1); - request_to_redraw(REDRAW_CELLS); + request_to_redraw(REDRAW_CELLS | REDRAW_FREQUENCY); } /* @@ -1933,7 +1867,7 @@ request_to_draw_cells_behind_numeric_input(void) { // Values Hardcoded from ui.c invalidate_rect(0, LCD_HEIGHT-NUM_INPUT_HEIGHT, LCD_WIDTH-1, LCD_HEIGHT-1); - request_to_redraw(REDRAW_CELLS); + request_to_redraw(REDRAW_CELLS | REDRAW_FREQUENCY); } /* @@ -1948,7 +1882,6 @@ request_to_redraw(uint16_t mask) void plot_init(void) { - plot_into_index(); - request_to_redraw(REDRAW_AREA | REDRAW_BATTERY | REDRAW_CAL_STATUS | REDRAW_FREQUENCY); + request_to_redraw(REDRAW_AREA | REDRAW_PLOT | REDRAW_BATTERY | REDRAW_CAL_STATUS | REDRAW_FREQUENCY); draw_all(); } diff --git a/rtc.c b/rtc.c deleted file mode 100644 index dee4384..0000000 --- a/rtc.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@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 "ch.h" -#include "hal.h" -#include "nanovna.h" - -#ifdef __USE_RTC__ - -// Compact STM32 RTC time library -#if HAL_USE_RTC == TRUE -#error "Error VNA use self RTC lib, define HAL_USE_RTC = FALSE in halconf.h" -#endif - -// Get RTC time as binary structure in 0x00HHMMSS -uint32_t rtc_get_tr_bin(void){ - uint32_t tr = RTC->TR; - uint32_t v = (tr&0x0F0F0F) + ((tr&0x707070)>>1) + ((tr&0x707070)>>3); - return v; -} - -// Get RTC time as binary structure in 0x00YYMMDD -uint32_t rtc_get_dr_bin(void){ - uint32_t dr = RTC->DR; - uint32_t v = (dr&0x000F0F0F) + ((dr&0x00F01030)>>1) + ((dr&0x00F01030)>>3); - return v;// | ((dr&0xE000)<<15); // day of week at end -} - -uint32_t rtc_get_FAT(void) { - uint32_t fattime; - uint32_t tr = rtc_get_tr_bin(); - uint32_t dr = rtc_get_dr_bin(); - fattime = ((tr>> 0)&0xFF) >> 1U; // Seconds / 2 - fattime |= ((tr>> 8)&0xFF) << 5U; // Minutes - fattime |= ((tr>>16)&0xFF) << 11U; // Hour - fattime |= ((dr>> 0)&0xFF) << 16U; // Day - fattime |= ((dr>> 8)&0xFF) << 21U; // Month - fattime |= (((dr>>16)&0xFF) + RTC_START_YEAR - 1980) << 25U; // Local year begin from 2000, fat from 1980 - return fattime; -} - -// Finish of configuration procedure. -static void rtc_exit_init(void) { - RTC->ISR &= ~RTC_ISR_INIT; -} - -// Beginning of configuration procedure. -static bool rtc_enter_init(void){ - RTC->ISR |= RTC_ISR_INIT; - uint32_t count = 4*65536; - while (--count) - if (RTC->ISR & RTC_ISR_INITF) - return true; - return false; -} - -void rtc_set_time(uint32_t dr, uint32_t tr) { - if (rtc_enter_init()){ - RTC->TR = tr; // Write TR register - RTC->DR = dr; // Write TD register - } - rtc_exit_init(); -} - -#ifdef VNA_AUTO_SELECT_RTC_SOURCE - -// Enable LSE bypass if need -#if defined(STM32_LSE_BYPASS) -#define STM32_LSE_BYPASS RCC_BDCR_LSEBYP -#else -#define STM32_LSE_BYPASS 0 -#endif - -// Startup LSE or if not work, LSI generator -static void rtc_start_source(void){ - // LSE already work (enabled and ready) - if ((RCC->BDCR & (RCC_BDCR_LSEON|RCC_BDCR_LSERDY|STM32_LSE_BYPASS)) == (RCC_BDCR_LSEON|RCC_BDCR_LSERDY|STM32_LSE_BYPASS)) - return; - - // If LSE not enabled, try startup - RCC->BDCR |= STM32_LSEDRV | STM32_LSE_BYPASS | RCC_BDCR_LSEON; - // Waits until LSE is stable (need ~150ms for startup). - chThdSleepMilliseconds(200); - if (RCC->BDCR & RCC_BDCR_LSERDY) return; - - // Startup LSI if not allow start LSE - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0); -} - -static void resetBCDR(uint32_t rtc_drv){ - // Backup domain reset, for change source. - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - // Startup again source generator - rtc_start_source(); - // Select new clock source. And enable - RCC->BDCR|= rtc_drv; -} - -void auto_backup_domain_init(void){ - // Init Backup domain, RTC clock source - uint32_t rtc_drv; - // Backup domain access enabled and left open. - PWR->CR |= PWR_CR_DBP; - // Start/check source - rtc_start_source(); - // Check LSE ready, if ok, select as source - rtc_drv = RCC->BDCR & RCC_BDCR_LSERDY ? STM32_RTCSEL_LSE|RCC_BDCR_RTCEN : // Select LSE as source - STM32_RTCSEL_LSI|RCC_BDCR_RTCEN; // Select LSI as source - // If the backup domain hasn't been initialized yet or work on different source, then proceed with initialization - if ((RCC->BDCR & (STM32_RTCSEL_MASK|RCC_BDCR_RTCEN)) != rtc_drv) - resetBCDR(rtc_drv); -/* - // Check RTC clock, and reset backup domain to LSI if clock not start - if (rtc_enter_init()) - rtc_exit_init(); - else - resetBCDR(STM32_RTCSEL_LSI|RCC_BDCR_RTCEN); -*/ -} -#endif - -// Initiate RTC clock -void rtc_init(void){ -#ifdef VNA_AUTO_SELECT_RTC_SOURCE - // Auto start LSE or LSI source for RTC - auto_backup_domain_init(); -#else - // ChibiOS init BDCR LSE or LSI source by self from user defined in mcuconf.h source - // For add auto select RTC source need rewrite it - // see hal_lld_backup_domain_init() in hal_lld.c for every CPU - // Default RTC clock is LSE, but it possible not launch if no quartz installed -#endif - uint32_t src = RCC->BDCR & STM32_RTCSEL_MASK; - if (src == STM32_RTCSEL_NOCLOCK) return; - // If calendar has not been initialized yet or different PRER settings then proceed with the initial setup. - // Disable write protection. - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - uint32_t rtc_prer = (src == STM32_RTCSEL_LSE) ? STM32_RTC_LSE_PRER : - STM32_RTC_LSI_PRER; - // If calendar has not been initialized yet then proceed with the initial setup. - if ((RTC->ISR & RTC_ISR_INITS) == 0 || RTC->PRER != rtc_prer) { - if (rtc_enter_init()){ - RTC->CR = 0; - RTC->ISR = RTC_ISR_INIT; // Clearing all but RTC_ISR_INIT. - RTC->PRER = rtc_prer; // Prescaler value loaded in registers 2 times - RTC->PRER = rtc_prer; - } - // Finalizing of configuration procedure. - rtc_exit_init(); - } - else - RTC->ISR &= ~RTC_ISR_RSF; -} -#endif // __USE_RTC__ diff --git a/tlv320aic3204.c b/tlv320aic3204.c index 84aec90..c35a078 100644 --- a/tlv320aic3204.c +++ b/tlv320aic3204.c @@ -123,7 +123,8 @@ #define REG_27_INTERFACE_LJF (3<<6) // Set the interface mode: 16 bit, BCLK, WCLK as output, DSP mode -#define REG_27 (REG_27_DATA_16 | REG_27_INTERFACE_DSP | REG_27_WCLK_OUT | REG_27_BCLK_OUT) +#define REG_27 (REG_27_DATA_16 | REG_27_INTERFACE_DSP | REG_27_WCLK_OUT | REG_27_BCLK_OUT) +#define REG_30(n) (0x80 + ((n)*sizeof(int16_t)/sizeof(audio_sample_t))) static const uint8_t conf_data[] = { // reg, data, // PLL clock config @@ -177,7 +178,7 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 32,// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) + 0x1e, REG_30(32),// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) #elif AUDIO_ADC_FREQ == 24000 // Clock config, default fs=24kHz // from PLL 98.304MHz/(4*8*128) = 24kHz @@ -193,7 +194,7 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 32,// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) + 0x1e, REG_30(32),// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) #elif AUDIO_ADC_FREQ == 48000 // Clock config, default fs=48kHz // from PLL 98.304MHz/(2*8*128) = 48kHz @@ -209,7 +210,7 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 32,// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) + 0x1e, REG_30(32),// Enable the BCLKN divider with value 32 (I2S clock = 98.304MHz/(NDAC*32) = 48kHz * (16+16) #elif AUDIO_ADC_FREQ == 96000 // Clock config, default fs=96kHz // from PLL 98.304MHz/(2*8*64) = 96kHz @@ -225,7 +226,7 @@ static const uint8_t conf_data[] = { 0x3d, 0x01, // Select ADC PRB_R1 (AOSR = 64 (Use with PRB_R1 to PRB_R12, ADC Filter Type A or B)) 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 16,// Enable the BCLKN divider with value 16 (I2S clock = 98.304MHz/(NDAC*16) = 96kHz * (16+16) + 0x1e, REG_30(16),// Enable the BCLKN divider with value 16 (I2S clock = 98.304MHz/(NDAC*16) = 96kHz * (16+16) #elif AUDIO_ADC_FREQ == 192000 // Clock config, default fs=192kHz // from PLL 98.304MHz/(2*4*64) = 192kHz @@ -240,8 +241,9 @@ static const uint8_t conf_data[] = { 0x13, 0x84, // Power up the MADC divider with value 4 0x14, 0x40, // ADC Oversampling (AOSR) set OSR of ADC to 64 0x3d, 7, // Select ADC PRB_R7 + 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 8, // Enable the BCLKN divider with value 8 (I2S clock = 98.304MHz/(NDAC*8) = 192kHz * (16+16) + 0x1e, REG_30(8),// Enable the BCLKN divider with value 8 (I2S clock = 98.304MHz/(NDAC*8) = 192kHz * (16+16) #elif AUDIO_ADC_FREQ == 384000 // Clock config, default fs=384kHz // from PLL 98.304MHz/(2*4*32) = 384kHz @@ -258,7 +260,7 @@ static const uint8_t conf_data[] = { 0x3d, 7, // Select ADC PRB_R7 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 4, // Enable the BCLKN divider with value 4 (I2S clock = 98.304MHz/(NDAC*4) = 384kHz * (16+16) + 0x1e, REG_30(4),// Enable the BCLKN divider with value 4 (I2S clock = 98.304MHz/(NDAC*4) = 384kHz * (16+16) #elif AUDIO_ADC_FREQ == 768000 // Clock config, default fs=768kHz // from PLL 98.304MHz/(2*4*16) = 768kHz @@ -275,7 +277,7 @@ static const uint8_t conf_data[] = { 0x3d, 7, // Select ADC PRB_R7 0x1b, REG_27, // Set the interface mode - 0x1e, 0x80 + 2, // Enable the BCLKN divider with value 2 (I2S clock = 98.304MHz/(NDAC*2) = 768kHz * (16+16) + 0x1e, REG_30(2),// Enable the BCLKN divider with value 2 (I2S clock = 98.304MHz/(NDAC*2) = 768kHz * (16+16) #else #error "Need set correct ADC clock for aic3204" #endif diff --git a/ui.c b/ui.c index 5ab2a56..031e1f8 100644 --- a/ui.c +++ b/ui.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com + * Copyright (c) 2019-2023, Dmitry (DiSlord) dislordlive@gmail.com * Based on TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com * All rights reserved. * @@ -26,13 +26,17 @@ #include "nanovna.h" #include "si5351.h" +// Use size optimization (UI not need fast speed, better have smallest size) +#pragma GCC optimize ("Os") + +// Hardware UI buttons/touch data / functions #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 EVT_UP 0x10 +#define EVT_DOWN 0x20 +#define EVT_REPEAT 0x40 #define BUTTON_DOWN_LONG_TICKS MS2ST(500) // 500ms #define BUTTON_DOUBLE_TICKS MS2ST(250) // 250ms @@ -40,19 +44,29 @@ #define BUTTON_DEBOUNCE_TICKS MS2ST( 20) // 20ms /* lever switch assignment */ -#define BIT_UP1 3 -#define BIT_PUSH 2 -#define BIT_DOWN1 1 - -#define READ_PORT() palReadPort(GPIOA) -#define BUTTON_MASK 0b1111 +#define BUTTON_DOWN (1<>GPIOA_LEVER1)^(cur_button>>GPIOA_LEVER2))&1)) cur_button^= (1<= BUTTON_DOWN_LONG_TICKS && (cur_button & (1<= BUTTON_DOWN_LONG_TICKS && (cur_button & BUTTON_PUSH)) return EVT_BUTTON_DOWN_LONG; - if (changed & (1< BUTTON_DOWN_LONG_TICKS && ticks > last_button_repeat_ticks) { uint16_t status = 0; - if (cur_button & (1<=LCD_WIDTH ) tx = LCD_WIDTH -1; int ty = ((LCD_HEIGHT-1-CALIBRATION_OFFSET)*(last_touch_y - config._touch_cal[1]) + CALIBRATION_OFFSET * (config._touch_cal[3] - last_touch_y)) / (config._touch_cal[3] - config._touch_cal[1]); if (ty<0) ty = 0; else if (ty>=LCD_HEIGHT) ty = LCD_HEIGHT-1; +#ifdef __FLIP_DISPLAY__ if (VNA_MODE(VNA_MODE_FLIP_DISPLAY)) { tx = LCD_WIDTH - 1 - tx; ty = LCD_HEIGHT - 1 - ty; } +#endif *x = tx; *y = ty; } @@ -567,14 +582,14 @@ show_version(void) { int x = 5, y = 5, i = 1; int str_height = FONT_STR_HEIGHT + 2; - lcd_set_background(LCD_BG_COLOR); + lcd_set_colors(LCD_FG_COLOR, LCD_BG_COLOR); lcd_clear_screen(); uint16_t shift = 0b00010010000; - lcd_set_foreground(LCD_TRACE_2_COLOR); + lcd_set_colors(LCD_TRACE_2_COLOR, LCD_BG_COLOR); lcd_drawstring_size(BOARD_NAME, x , y, 3); y+=FONT_GET_HEIGHT*3+3-5; - lcd_set_foreground(LCD_FG_COLOR); + lcd_set_colors(LCD_FG_COLOR, LCD_BG_COLOR); while (info_about[i]) { do {shift>>=1; y+=5;} while (shift&1); lcd_drawstring(x, y+=str_height-5, info_about[i++]); @@ -617,15 +632,12 @@ enter_dfu(void) { touch_stop_watchdog(); int x = 5, y = 20; - lcd_set_foreground(LCD_FG_COLOR); - lcd_set_background(LCD_BG_COLOR); + lcd_set_colors(LCD_FG_COLOR, LCD_BG_COLOR); // leave a last message lcd_clear_screen(); lcd_drawstring(x, y, "DFU: Device Firmware Update Mode\n" "To exit DFU mode, please reset device yourself."); - // see __early_init in ./NANOVNA_STM32_F072/board.c - *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) = BOOT_FROM_SYTEM_MEMORY_MAGIC; - NVIC_SystemReset(); + boardDFUEnter(); } #endif @@ -644,7 +656,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_calop_acb) [CAL_LOAD] = {CALSTAT_LOAD, 3}, [CAL_OPEN] = {CALSTAT_OPEN, 1}, [CAL_SHORT]= {CALSTAT_SHORT, 2}, - [CAL_THRU] = {CALSTAT_THRU, 5},//Calibration screen does not show electrical delay + [CAL_THRU] = {CALSTAT_THRU, 5}, // to cal done [CAL_ISOLN]= {CALSTAT_ISOLN, 4}, }; if (b){ @@ -675,27 +687,23 @@ static UI_FUNCTION_CALLBACK(menu_cal_reset_cb) set_power(SI5351_CLK_DRIVE_STRENGTH_AUTO); } -static UI_FUNCTION_ADV_CALLBACK(menu_cal_range_acb){ +static UI_FUNCTION_ADV_CALLBACK(menu_cal_range_acb) { (void)data; bool calibrated = cal_status & (CALSTAT_ES|CALSTAT_ER|CALSTAT_ET|CALSTAT_ED|CALSTAT_EX|CALSTAT_OPEN|CALSTAT_SHORT|CALSTAT_THRU); + if (!calibrated) return; if (b){ - if (calibrated){ b->bg = (cal_status&CALSTAT_INTERPOLATED) ? LCD_INTERP_CAL_COLOR : LCD_MENU_COLOR; plot_printf(b->label, sizeof(b->label), "CAL: %dp\n %.6F" S_Hz "\n %.6F" S_Hz, cal_sweep_points, (float)cal_frequency0, (float)cal_frequency1); - } - else - plot_printf(b->label, sizeof(b->label), "RESET\nCAL RANGE"); return; } // Reset range to calibration - if (calibrated && (cal_status&CALSTAT_INTERPOLATED)){ + if (cal_status & CALSTAT_INTERPOLATED){ reset_sweep_frequency(); set_power(cal_power); } } -static UI_FUNCTION_ADV_CALLBACK(menu_cal_apply_acb) -{ +static UI_FUNCTION_ADV_CALLBACK(menu_cal_apply_acb) { (void)data; if (b){ b->icon = (cal_status&CALSTAT_APPLY) ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; @@ -711,9 +719,9 @@ static UI_FUNCTION_ADV_CALLBACK(menu_recall_acb) if (b){ const properties_t *p = get_properties(data); if (p) - plot_printf(b->label, sizeof(b->label), "%.6F" S_Hz "\n%.6F" S_Hz, (float)p->_frequency0, (float)p->_frequency1, data); + plot_printf(b->label, sizeof(b->label), "%.6F" S_Hz "\n%.6F" S_Hz, (float)p->_frequency0, (float)p->_frequency1); else - plot_printf(b->label, sizeof(b->label), "Empty %d", data); + b->p1.u = data; if (lastsaveid == data) b->icon = BUTTON_ICON_CHECK; return; } @@ -772,14 +780,14 @@ static UI_FUNCTION_ADV_CALLBACK(menu_save_acb) if (b){ const properties_t *p = get_properties(data); if (p) - plot_printf(b->label, sizeof(b->label), "%.6F" S_Hz "\n%.6F" S_Hz, (float)p->_frequency0, (float)p->_frequency1, data); + plot_printf(b->label, sizeof(b->label), "%.6F" S_Hz "\n%.6F" S_Hz, (float)p->_frequency0, (float)p->_frequency1); else - plot_printf(b->label, sizeof(b->label), "Empty %d", data); + b->p1.u = data; return; } if (caldata_save(data) == 0) { menu_move_back(true); - request_to_redraw(REDRAW_CAL_STATUS); + request_to_redraw(REDRAW_BACKUP | REDRAW_CAL_STATUS); } } @@ -797,7 +805,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_trace_acb) } if (trace[data].enabled && data != current_trace) // for enabled trace and not current trace - set_active_trace(data); // make active + set_active_trace(data); // make active else // set_trace_enable(data, !trace[data].enabled); // toggle trace enable } @@ -822,25 +830,22 @@ static UI_FUNCTION_ADV_CALLBACK(menu_marker_smith_acb) #define F_S21 0x80 static UI_FUNCTION_ADV_CALLBACK(menu_format_acb) { + if (current_trace == TRACE_INVALID) return; // Not apply any for invalid traces uint16_t format = data & (~F_S21); uint16_t channel = data & F_S21 ? 1 : 0; if (b) { + if (trace[current_trace].type == format && trace[current_trace].channel == channel) + b->icon = BUTTON_ICON_CHECK; if (format == TRC_SMITH) { - const char *txt; uint8_t marker_smith_format = get_smith_format(); if ((channel == 0 && !S11_SMITH_VALUE(marker_smith_format)) || - (channel == 1 && !S21_SMITH_VALUE(marker_smith_format))) {txt = "%s"; marker_smith_format = 0;} - else txt = "%s\n" R_LINK_COLOR " %s"; - plot_printf(b->label, sizeof(b->label), txt, get_trace_typename(TRC_SMITH, marker_smith_format), get_smith_format_names(marker_smith_format)); + (channel == 1 && !S21_SMITH_VALUE(marker_smith_format))) return; + plot_printf(b->label, sizeof(b->label), "%s\n" R_LINK_COLOR "%s", get_trace_typename(TRC_SMITH, marker_smith_format), get_smith_format_names(marker_smith_format)); } else b->p1.text = get_trace_typename(format, -1); - - if (current_trace != TRACE_INVALID && trace[current_trace].type == format && trace[current_trace].channel == channel) - b->icon = BUTTON_ICON_CHECK; return; } - if (current_trace == TRACE_INVALID) return; if (format == TRC_SMITH && trace[current_trace].type == TRC_SMITH && trace[current_trace].channel == channel) menu_push_submenu(channel == 0 ? menu_marker_s11smith : menu_marker_s21smith); @@ -895,7 +900,6 @@ static UI_FUNCTION_ADV_CALLBACK(menu_transform_filter_acb) return; } props_mode = (props_mode & ~TD_FUNC) | data; -// ui_mode_normal(); } const menuitem_t menu_bandwidth[]; @@ -919,6 +923,39 @@ static UI_FUNCTION_ADV_CALLBACK(menu_bandwidth_acb) set_bandwidth(data); } +#pragma pack(push, 2) +typedef struct { + const char* text; + uint16_t update_flag; +} vna_mode_data_t; +#pragma pack(pop) + +const vna_mode_data_t vna_mode_data[] = { +// text (if 0 use checkbox) Redraw flags on change + [VNA_MODE_AUTO_NAME] = {0, REDRAW_BACKUP}, +#ifdef __USE_SMOOTH__ + [VNA_MODE_SMOOTH] = {"Geom\0Arith", REDRAW_BACKUP}, +#endif +#ifdef __USE_SERIAL_CONSOLE__ + [VNA_MODE_CONNECTION] = {"USB\0SERIAL", REDRAW_BACKUP}, +#endif + [VNA_MODE_SEARCH] = {"MAXIMUM\0MINIMUM", REDRAW_BACKUP}, + [VNA_MODE_SHOW_GRID] = {0, REDRAW_BACKUP | REDRAW_AREA}, + [VNA_MODE_DOT_GRID] = {0, REDRAW_BACKUP | REDRAW_AREA}, +#ifdef __USE_BACKUP__ + [VNA_MODE_BACKUP] = {0, REDRAW_BACKUP}, +#endif +#ifdef __FLIP_DISPLAY__ + [VNA_MODE_FLIP_DISPLAY]= {0, REDRAW_BACKUP | REDRAW_CLRSCR | REDRAW_AREA | REDRAW_BATTERY | REDRAW_CAL_STATUS | REDRAW_FREQUENCY}, +#endif +#ifdef __DIGIT_SEPARATOR__ + [VNA_MODE_SEPARATOR] = {"DOT '.'\0COMMA ','", REDRAW_BACKUP | REDRAW_MARKER | REDRAW_FREQUENCY}, +#endif +#ifdef __SD_CARD_DUMP_TIFF__ + [VNA_MODE_TIFF] = {"BMP\0TIFF", REDRAW_BACKUP}, +#endif +}; + void apply_VNA_mode(uint16_t idx, uint16_t value) { uint16_t m = 1<icon = VNA_MODE(data) ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; - else { - const char *t = vna_mode_text[data]; + else b->p1.text = VNA_MODE(data) ? t + strlen(t) + 1 : t; - } return; } apply_VNA_mode(data, VNA_MODE_TOGGLE); @@ -1021,9 +1037,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_power_sel_acb) { (void)data; if (b){ - if (current_props._power == SI5351_CLK_DRIVE_STRENGTH_AUTO) - plot_printf(b->label, sizeof(b->label), "POWER AUTO"); - else + if (current_props._power != SI5351_CLK_DRIVE_STRENGTH_AUTO) plot_printf(b->label, sizeof(b->label), "POWER" R_LINK_COLOR " %um" S_AMPER, 2+current_props._power*2); return; } @@ -1040,17 +1054,13 @@ static UI_FUNCTION_ADV_CALLBACK(menu_power_acb) set_power(data); } +// Process keyboard button callback, and run keyboard function extern const keypads_list keypads_mode_tbl[]; static UI_FUNCTION_ADV_CALLBACK(menu_keyboard_acb) { - if ((data == KM_SCALE || data == KM_REFPOS) && current_trace == TRACE_INVALID) return; - if (data == KM_SCALE) { // Scale button type auto set - if ((1<p1.text = sweep_mode&SWEEP_ENABLE ? "PAUSE" : "RESUME"; -#endif - b->icon = sweep_mode&SWEEP_ENABLE ? BUTTON_ICON_NOCHECK : BUTTON_ICON_CHECK; + b->p1.text = (sweep_mode & SWEEP_ENABLE) ? "PAUSE" : "RESUME"; + b->icon = (sweep_mode & SWEEP_ENABLE) ? BUTTON_ICON_NOCHECK : BUTTON_ICON_CHECK; return; } toggle_sweep(); @@ -1101,13 +1121,13 @@ static UI_FUNCTION_CALLBACK(menu_marker_op_cb) } break; case UI_MARKER_EDELAY: - { + { if (current_trace == TRACE_INVALID) break; float (*array)[2] = measured[trace[current_trace].channel]; int index = markers[active_marker].index; float v = groupdelay_from_array(index, array[index]); - set_electrical_delay((electrical_delay + v) / 1e-12f); + set_electrical_delay(electrical_delay + v); } break; } @@ -1134,6 +1154,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_marker_tracking_acb) } #ifdef __VNA_MEASURE_MODULE__ +extern const menuitem_t *menu_measure_list[]; static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) { (void)data; @@ -1142,6 +1163,12 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) return; } plot_set_measure_mode(data); + menu_set_submenu(menu_measure_list[current_props._measure]); +} + +static UI_FUNCTION_CALLBACK(menu_measure_cb) { + (void)data; + menu_push_submenu(menu_measure_list[current_props._measure]); } #endif @@ -1273,8 +1300,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_brightness_acb) return; } int16_t value = config._brightness; - lcd_set_foreground(LCD_MENU_TEXT_COLOR); - lcd_set_background(LCD_MENU_COLOR); + lcd_set_colors(LCD_MENU_TEXT_COLOR, LCD_MENU_COLOR); lcd_fill(LCD_WIDTH/2-12*FONT_WIDTH, LCD_HEIGHT/2-20, 23*FONT_WIDTH, 40); lcd_printf(LCD_WIDTH/2-8*FONT_WIDTH, LCD_HEIGHT/2-13, "BRIGHTNESS %3d%% ", value); lcd_printf(LCD_WIDTH/2-11*FONT_WIDTH, LCD_HEIGHT/2+2, S_LARROW " USE LEVELER BUTTON " S_RARROW); @@ -1301,9 +1327,13 @@ static UI_FUNCTION_ADV_CALLBACK(menu_brightness_acb) #endif #ifdef __USE_SD_CARD__ -// Save format enum +// Save/Load format enum enum { - FMT_S1P_FILE=0, FMT_S2P_FILE, FMT_BMP_FILE, FMT_CAL_FILE, + FMT_S1P_FILE=0, FMT_S2P_FILE, FMT_BMP_FILE, +#ifdef __SD_CARD_DUMP_TIFF__ + FMT_TIF_FILE, +#endif + FMT_CAL_FILE, #ifdef __SD_CARD_DUMP_FIRMWARE__ FMT_BIN_FILE, #endif @@ -1312,11 +1342,14 @@ enum { #endif }; -// Save file extension +// Save/Load file extension static const char *file_ext[] = { [FMT_S1P_FILE] = "s1p", [FMT_S2P_FILE] = "s2p", [FMT_BMP_FILE] = "bmp", +#ifdef __SD_CARD_DUMP_TIFF__ + [FMT_TIF_FILE] = "tif", +#endif [FMT_CAL_FILE] = "cal", #ifdef __SD_CARD_DUMP_FIRMWARE__ [FMT_BIN_FILE] = "bin", @@ -1334,14 +1367,14 @@ static const char s1_file_header[] = "# Hz S RI R 50\r\n"; static const char s1_file_param[] = - "%10u % f % f\r\n"; + "%u % f % f\r\n"; static const char s2_file_header[] = "!File created by NanoVNA\r\n"\ "# Hz S RI R 50\r\n"; static const char s2_file_param[] = - "%10u % f % f % f % f 0 0 0 0\r\n"; + "%u % f % f % f % f 0 0 0 0\r\n"; //******************************************************************************************* // Bitmap file header for LCD_WIDTH x LCD_HEIGHT image 16bpp (v4 format allow set RGB mask) @@ -1392,6 +1425,104 @@ static const uint8_t bmp_header_v4[BMP_H1_SIZE + BMP_V4_SIZE] = { BMP_UINT32(0), // GammaBlue }; +#ifdef __SD_CARD_DUMP_TIFF__ +//******************************************************************************************* +// TIFF header for LCD_WIDTH x LCD_HEIGHT image 24bpp and RLE compression (packbits) +//******************************************************************************************* +#define IFD_ENTRY(type, val_t, count, value) \ + BMP_UINT16(type), \ + BMP_UINT16(val_t), \ + BMP_UINT32(count), \ + BMP_UINT32(value) + +#define IFD_BYTE 1 // 8-bit unsigned integer. +#define IFD_ASCII 2 // 8-bit byte that contains a 7-bit ASCII code; the last byte must be NUL (binary zero). +#define IFD_SHORT 3 // 16-bit (2-byte) unsigned integer. +#define IFD_LONG 4 // 32-bit (4-byte) unsigned integer. +#define IFD_RATIONAL 5 // Two LONGs: the first represents the numerator of a fraction; the second, the denominator. + +// TIFF Compression +#define TIFF_UNCOMPRESSED 1 +#define TIFF_CCITT_1D 2 +#define TIFF_CCITT_Group3 3 +#define TIFF_CCITT_Group4 4 +#define TIFF_LZW 5 +#define TIFF_JPEG 6 +#define TIFF_UNCOMPR 0x8003 +#define TIFF_PACKBITS 0x8005 + +#define TIFF_PHOTOMETRIC_MINISWHITE 0 +#define TIFF_PHOTOMETRIC_MINISBLACK 1 +#define TIFF_PHOTOMETRIC_RGB 2 +#define TIFF_PHOTOMETRIC_PALETTE 3 +#define TIFF_PHOTOMETRIC_MASK 4 +#define TIFF_PHOTOMETRIC_SEPARATED 5 +#define TIFF_PHOTOMETRIC_YCBCR 6 +#define TIFF_PHOTOMETRIC_CIELAB 8 +#define TIFF_PHOTOMETRIC_ICCLAB 9 +#define TIFF_PHOTOMETRIC_ITULAB 10 +#define TIFF_PHOTOMETRIC_LOGL 32844 +#define TIFF_PHOTOMETRIC_LOGLUV 32845 + +#define TIFF_RESUNIT_NONE 1 +#define TIFF_RESUNIT_INCH 2 +#define TIFF_RESUNIT_CENTIMETER 3 + +// TIFF file header data +#define IFD_ENTRIES_COUNT 7 +#define IFD_DATA_OFFSET (10 + 12 * IFD_ENTRIES_COUNT + 4) + +#define IFD_BPS_OFFSET IFD_DATA_OFFSET +//#define IFD_XR_OFFSET IFD_DATA_OFFSET + 6 +//#define IFD_YR_OFFSET IFD_DATA_OFFSET + 6 + 8 +#define IFD_STRIP_OFFSET IFD_DATA_OFFSET + 6 // + 8 + 8 + +static const uint8_t tif_header[] = { + 0x49, 0x49, // Byte order 'II' (0x4949) - little indian or 'MM' (0x4D4D) - big indian + BMP_UINT16(0x002A), // TIFF version number (always 2Ah) + BMP_UINT32(0x0008), // IFD offset + BMP_UINT16(IFD_ENTRIES_COUNT), // IFD entries NUM + IFD_ENTRY(0x0100, IFD_SHORT, 1, LCD_WIDTH), // Image Width + IFD_ENTRY(0x0101, IFD_SHORT, 1, LCD_HEIGHT), // Image Height + IFD_ENTRY(0x0102, IFD_SHORT, 3, IFD_BPS_OFFSET), // BitsPerSample = 0x0008 0x0008 0x0008 + IFD_ENTRY(0x0103, IFD_SHORT, 1, TIFF_PACKBITS), // Compression + IFD_ENTRY(0x0106, IFD_SHORT, 1, TIFF_PHOTOMETRIC_RGB),// PhotometricInterpretation = RGB + IFD_ENTRY(0x0111, IFD_LONG, 1, IFD_STRIP_OFFSET), // StripOffsets = Offset to image data + IFD_ENTRY(0x0115, IFD_SHORT, 1, 0x03), // SamplesPerPixel = 3 +//IFD_ENTRY(0x0116, IFD_SHORT, 1, LCD_HEIGHT), // RowsPerStrip = LCD_HEIGHT +//IFD_ENTRY(0x0117, IFD_LONG, 1, 0x00000000), // StripByteCounts = Image Width * Image Height * SamplesPerPixel (if set to 0, possible open any size image) +//IFD_ENTRY(0x011A, IFD_RATIONAL,1, IFD_XR_OFFSET), // XResolution +//IFD_ENTRY(0x011B, IFD_RATIONAL,1, IFD_YR_OFFSET), // YResolution +//IFD_ENTRY(0x0128, IFD_SHORT, 1, TIFF_RESUNIT_INCH), // ResolutionUnit = Inch + 0x00, 0x00, 0x00, 0x00, + // IDF data + BMP_UINT16(8), // BitsPerSample + BMP_UINT16(8), + BMP_UINT16(8), +//BMP_UINT32(72), BMP_UINT32(1), // XResolution 72 / 1 +//BMP_UINT32(72), BMP_UINT32(1), // YResolution 72 / 1 + // After Image data +}; + +// RLE packbits algorithm +static int packbits(char *source, char *dest, int size) { + int i = 0, rle, l, pk = 0, sz = 0; + while ((l = size - i) > 0) { + if (l > 128) l = 128; // Limit search RLE block size to 128 + char c = source[i++]; // Get next byte and write to block + for (rle = 0; c == source[i + rle] && --l; rle++); // Calculate this byte RLE sequence size = rle + 1 + if (sz && rle < 2) rle = 0; // Ignore (rle + 1) < 3 sequence on run non RLE input + else if (sz == 0 || rle > 0) sz = pk++; // Reset state or RLE sequence found -> start new block + dest[pk++] = c; // Write char to block + if (rle > 0) {i+= rle; dest[sz] = -rle;} // Write RLE sequence size and go to new block + else if ((dest[sz] = pk - sz - 2) < 127) // Continue write non RLE data while 1 + (non_rle + 1) < 127 + continue; + sz = 0; // Block complete + } + return pk; +} +#endif + static void swap_bytes(uint16_t *buf, int size) { for (int i = 0; i < size; i++) buf[i] = __REVSH(buf[i]); // swap byte order (example 0x10FF to 0xFF10) @@ -1419,7 +1550,11 @@ static void vna_save_file(char *name, uint8_t format) char fs_filename[FF_LFN_BUF]; // For screenshot need back to normal mode and redraw screen before capture!! // Redraw use spi_buffer so need do it before any file ops - if (format == FMT_BMP_FILE && ui_mode != UI_NORMAL){ + if (ui_mode != UI_NORMAL && (format == FMT_BMP_FILE +#ifdef __SD_CARD_DUMP_TIFF__ + || format == FMT_TIF_FILE +#endif + )) { ui_mode_normal(); draw_all(); } @@ -1439,7 +1574,7 @@ static void vna_save_file(char *name, uint8_t format) // UINT total_size = 0; // systime_t time = chVTGetSystemTimeX(); - // Prepare filename = .s1p / .s2p / .bmp and open for write + // Prepare filename = .s1p / .s2p / .bmp .... and open for write FRESULT res = vna_create_file(fs_filename); if (res == FR_OK) { const char *s_file_format; @@ -1476,7 +1611,7 @@ static void vna_save_file(char *name, uint8_t format) */ case FMT_BMP_FILE: buf_16 = spi_buffer; - res = f_write(fs_file, bmp_header_v4, BMP_HEAD_SIZE, &size); // Write header struct + res = f_write(fs_file, bmp_header_v4, sizeof(bmp_header_v4), &size); // Write header struct // total_size+=size; lcd_set_background(LCD_SWEEP_LINE_COLOR); for (y = LCD_HEIGHT-1; y >= 0 && res == FR_OK; y--) { @@ -1487,6 +1622,30 @@ static void vna_save_file(char *name, uint8_t format) lcd_fill(LCD_WIDTH-1, y, 1, 1); } break; +#ifdef __SD_CARD_DUMP_TIFF__ + case FMT_TIF_FILE: + buf_16 = spi_buffer; + lcd_set_background(LCD_SWEEP_LINE_COLOR); + res = f_write(fs_file, tif_header, sizeof(tif_header), &size); // Write header struct + for (y = 0; y < LCD_HEIGHT && res == FR_OK; y++) { + // Use LCD_WIDTH + 128 bytes offset for RGB888 data + // Use 0 offset for compressed RLE (maximum need WIDTH * 4 + 128 bytes in spi_buffer) + buf_8 = (char *)spi_buffer + 128; + // Read LCD line in RGB565 format (swapped bytes) + lcd_read_memory(0, y, LCD_WIDTH, 1, buf_16); + // Convert to RGB888 + for (int x = LCD_WIDTH - 1; x >= 0; x--) { + uint16_t color = (buf_16[x] << 8) | (buf_16[x] >> 8); + buf_8[3*x + 0] = (color>>8) & 0xF8;// if (buf_8[3*x + 0] < 0) buf_8[3*x + 0]+= 7; + buf_8[3*x + 1] = (color>>3) & 0xFC;// if (buf_8[3*x + 1] < 0) buf_8[3*x + 1]+= 3; + buf_8[3*x + 2] = (color<<3) & 0xF8;// if (buf_8[3*x + 2] < 0) buf_8[3*x + 2]+= 7; + } + size = packbits(buf_8, (char *)spi_buffer, LCD_WIDTH * 3); + res = f_write(fs_file, spi_buffer, size, &size); + lcd_fill(LCD_WIDTH-1, y, 1, 1); + } + break; +#endif /* * Save calibration */ @@ -1522,8 +1681,16 @@ static void vna_save_file(char *name, uint8_t format) ui_mode_normal(); } +static uint16_t fixScreenshotFormat(uint16_t data) { +#ifdef __SD_CARD_DUMP_TIFF__ + if (data == FMT_BMP_FILE && VNA_MODE(VNA_MODE_TIFF)) return FMT_TIF_FILE; +#endif + return data; +} + static UI_FUNCTION_CALLBACK(menu_sdcard_cb) { + data = fixScreenshotFormat(data); if (VNA_MODE(VNA_MODE_AUTO_NAME)) vna_save_file(NULL, data); else @@ -1546,18 +1713,6 @@ static UI_FUNCTION_ADV_CALLBACK(menu_band_sel_acb) si5351_set_band_mode(config._band_mode); } -#ifdef __DIGIT_SEPARATOR__ -static UI_FUNCTION_ADV_CALLBACK(menu_separator_acb) -{ - (void)data; - if (b){ - b->p1.text = DIGIT_SEPARATOR == '.' ? " DOT '.'" : " COMMA ','"; - return; - } - DIGIT_SEPARATOR = DIGIT_SEPARATOR == '.' ? ',' : '.'; -} -#endif - #if STORED_TRACES > 0 static UI_FUNCTION_ADV_CALLBACK(menu_stored_trace_acb) { @@ -1577,18 +1732,18 @@ static UI_FUNCTION_CALLBACK(menu_back_cb) // Back button submenu list static const menuitem_t menu_back[] = { - { MT_CALLBACK, 0, S_LARROW" BACK", menu_back_cb }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_CALLBACK, 0, S_LARROW " BACK", menu_back_cb }, + { MT_NEXT, 0, NULL, NULL } // sentinel }; #ifdef __USE_SD_CARD__ #ifdef __SD_FILE_BROWSER__ static const menuitem_t menu_sdcard_browse[] = { - { MT_CALLBACK, FMT_BMP_FILE, "LOAD BMP", menu_sdcard_browse_cb }, + { MT_CALLBACK, FMT_BMP_FILE, "LOAD\nSCREENSHOT", menu_sdcard_browse_cb }, { MT_CALLBACK, FMT_S1P_FILE, "LOAD S1P", menu_sdcard_browse_cb }, { MT_CALLBACK, FMT_S2P_FILE, "LOAD S2P", menu_sdcard_browse_cb }, { MT_CALLBACK, FMT_CAL_FILE, "LOAD CAL", menu_sdcard_browse_cb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #endif @@ -1600,8 +1755,11 @@ static const menuitem_t menu_sdcard[] = { { MT_CALLBACK, FMT_S2P_FILE, "SAVE S2P", menu_sdcard_cb }, { MT_CALLBACK, FMT_BMP_FILE, "SCREENSHOT", menu_sdcard_cb }, { MT_CALLBACK, FMT_CAL_FILE, "SAVE\nCALIBRATION", menu_sdcard_cb }, - { MT_ADV_CALLBACK,VNA_MODE_AUTO_NAME, "AUTO NAME", menu_vna_mode_acb}, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_ADV_CALLBACK, VNA_MODE_AUTO_NAME, "AUTO NAME", menu_vna_mode_acb}, +#ifdef __SD_CARD_DUMP_TIFF__ + { MT_ADV_CALLBACK, VNA_MODE_TIFF, "IMAGE FORMAT\n " R_LINK_COLOR "%s", menu_vna_mode_acb }, +#endif + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #endif @@ -1611,54 +1769,54 @@ static const menuitem_t menu_calop[] = { { MT_ADV_CALLBACK, CAL_LOAD, "LOAD", menu_calop_acb }, { MT_ADV_CALLBACK, CAL_ISOLN, "ISOLN", menu_calop_acb }, { MT_ADV_CALLBACK, CAL_THRU, "THRU", menu_calop_acb }, - // { MT_ADV_CALLBACK, KM_EDELAY, "E-DELAY\n" R_LINK_COLOR " %b.7F" S_SECOND, menu_keyboard_acb }, { MT_CALLBACK, 0, "DONE", menu_caldone_cb }, { MT_CALLBACK, 1, "DONE IN RAM", menu_caldone_cb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_ADV_CALLBACK, KM_EDELAY, "E-DELAY\n " R_LINK_COLOR "%b.7F" S_SECOND, menu_keyboard_acb }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_save[] = { -#ifdef __SD_FILE_BROWSER__ - { MT_CALLBACK, FMT_CAL_FILE, "SAVE TO\n SD CARD", menu_sdcard_cb }, -#endif - { MT_ADV_CALLBACK, 0, MT_CUSTOM_LABEL, menu_save_acb }, - { MT_ADV_CALLBACK, 1, MT_CUSTOM_LABEL, menu_save_acb }, - { MT_ADV_CALLBACK, 2, MT_CUSTOM_LABEL, menu_save_acb }, + { MT_ADV_CALLBACK, 0, "Empty %d", menu_save_acb },//87632 + { MT_ADV_CALLBACK, 1, "Empty %d", menu_save_acb }, + { MT_ADV_CALLBACK, 2, "Empty %d", menu_save_acb }, #if SAVEAREA_MAX > 3 - { MT_ADV_CALLBACK, 3, MT_CUSTOM_LABEL, menu_save_acb }, + { MT_ADV_CALLBACK, 3, "Empty %d", menu_save_acb }, #endif #if SAVEAREA_MAX > 4 - { MT_ADV_CALLBACK, 4, MT_CUSTOM_LABEL, menu_save_acb }, + { MT_ADV_CALLBACK, 4, "Empty %d", menu_save_acb }, #endif #if SAVEAREA_MAX > 5 - { MT_ADV_CALLBACK, 5, MT_CUSTOM_LABEL, menu_save_acb }, + { MT_ADV_CALLBACK, 5, "Empty %d", menu_save_acb }, #endif #if SAVEAREA_MAX > 6 - { MT_ADV_CALLBACK, 6, MT_CUSTOM_LABEL, menu_save_acb }, + { MT_ADV_CALLBACK, 6, "Empty %d", menu_save_acb }, +#endif +#ifdef __SD_FILE_BROWSER__ + { MT_CALLBACK, FMT_CAL_FILE, "SAVE TO\n SD CARD", menu_sdcard_cb }, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_recall[] = { -#ifdef __SD_FILE_BROWSER__ - { MT_CALLBACK, FMT_CAL_FILE, "LOAD FROM\n SD CARD", menu_sdcard_browse_cb }, -#endif - { MT_ADV_CALLBACK, 0, MT_CUSTOM_LABEL, menu_recall_acb }, - { MT_ADV_CALLBACK, 1, MT_CUSTOM_LABEL, menu_recall_acb }, - { MT_ADV_CALLBACK, 2, MT_CUSTOM_LABEL, menu_recall_acb }, + { MT_ADV_CALLBACK, 0, "Empty %d", menu_recall_acb }, + { MT_ADV_CALLBACK, 1, "Empty %d", menu_recall_acb }, + { MT_ADV_CALLBACK, 2, "Empty %d", menu_recall_acb }, #if SAVEAREA_MAX > 3 - { MT_ADV_CALLBACK, 3, MT_CUSTOM_LABEL, menu_recall_acb }, + { MT_ADV_CALLBACK, 3, "Empty %d", menu_recall_acb }, #endif #if SAVEAREA_MAX > 4 - { MT_ADV_CALLBACK, 4, MT_CUSTOM_LABEL, menu_recall_acb }, + { MT_ADV_CALLBACK, 4, "Empty %d", menu_recall_acb }, #endif #if SAVEAREA_MAX > 5 - { MT_ADV_CALLBACK, 5, MT_CUSTOM_LABEL, menu_recall_acb }, + { MT_ADV_CALLBACK, 5, "Empty %d", menu_recall_acb }, #endif #if SAVEAREA_MAX > 6 - { MT_ADV_CALLBACK, 6, MT_CUSTOM_LABEL, menu_recall_acb }, + { MT_ADV_CALLBACK, 6, "Empty %d", menu_recall_acb }, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back +#ifdef __SD_FILE_BROWSER__ + { MT_CALLBACK, FMT_CAL_FILE, "LOAD FROM\n SD CARD", menu_sdcard_browse_cb }, +#endif + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_power[] = { @@ -1667,17 +1825,17 @@ const menuitem_t menu_power[] = { { MT_ADV_CALLBACK, SI5351_CLK_DRIVE_STRENGTH_4MA, "%u m" S_AMPER, menu_power_acb }, { MT_ADV_CALLBACK, SI5351_CLK_DRIVE_STRENGTH_6MA, "%u m" S_AMPER, menu_power_acb }, { MT_ADV_CALLBACK, SI5351_CLK_DRIVE_STRENGTH_8MA, "%u m" S_AMPER, menu_power_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_cal[] = { { MT_SUBMENU, 0, "CALIBRATE", menu_calop }, - { MT_ADV_CALLBACK, 0, MT_CUSTOM_LABEL, menu_power_sel_acb }, + { MT_ADV_CALLBACK, 0, "POWER AUTO", menu_power_sel_acb }, { MT_SUBMENU, 0, "SAVE", menu_save }, - { MT_ADV_CALLBACK, 0, MT_CUSTOM_LABEL, menu_cal_range_acb }, + { MT_ADV_CALLBACK, 0, "RANGE", menu_cal_range_acb }, { MT_CALLBACK, 0, "RESET", menu_cal_reset_cb }, { MT_ADV_CALLBACK, 0, "APPLY", menu_cal_apply_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_trace[] = { @@ -1694,28 +1852,31 @@ const menuitem_t menu_trace[] = { { MT_ADV_CALLBACK, 2, "%s TRACE C", menu_stored_trace_acb}, #endif #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_format4[] = { { MT_ADV_CALLBACK, F_S21|TRC_Rser, "SERIES R", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_Xser, "SERIES X", menu_format_acb }, + { MT_ADV_CALLBACK, F_S21|TRC_Zser, "SERIES |Z|", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_Rsh, "SHUNT R", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_Xsh, "SHUNT X", menu_format_acb }, + { MT_ADV_CALLBACK, F_S21|TRC_Zsh, "SHUNT |Z|", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_Qs21, "Q FACTOR", menu_format_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; + const menuitem_t menu_formatS21[] = { { MT_ADV_CALLBACK, F_S21|TRC_LOGMAG, "LOGMAG", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_PHASE, "PHASE", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_DELAY, "DELAY", menu_format_acb }, - { MT_ADV_CALLBACK, F_S21|TRC_SMITH, MT_CUSTOM_LABEL,menu_format_acb }, + { MT_ADV_CALLBACK, F_S21|TRC_SMITH, "SMITH", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_POLAR, "POLAR", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_LINEAR, "LINEAR", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_REAL, "REAL", menu_format_acb }, { MT_ADV_CALLBACK, F_S21|TRC_IMAG, "IMAG", menu_format_acb }, { MT_SUBMENU, 0, S_RARROW " MORE", menu_format4 }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_format3[] = { @@ -1726,7 +1887,7 @@ const menuitem_t menu_format3[] = { { MT_ADV_CALLBACK, F_S11|TRC_Xp, "PARALLEL X", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_pC, "PARALLEL C", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_pL, "PARALLEL L", menu_format_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_format2[] = { @@ -1739,32 +1900,34 @@ const menuitem_t menu_format2[] = { { MT_ADV_CALLBACK, F_S11|TRC_B, "SUSCEPTANCE", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_Y, "|Y|", menu_format_acb }, { MT_SUBMENU, 0, S_RARROW " MORE", menu_format3 }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_formatS11[] = { { MT_ADV_CALLBACK, F_S11|TRC_LOGMAG, "LOGMAG", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_PHASE, "PHASE", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_DELAY, "DELAY", menu_format_acb }, - { MT_ADV_CALLBACK, F_S11|TRC_SMITH, MT_CUSTOM_LABEL, menu_format_acb }, + { MT_ADV_CALLBACK, F_S11|TRC_SMITH, "SMITH", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_SWR, "SWR", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_R, "RESISTANCE", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_X, "REACTANCE", menu_format_acb }, { MT_ADV_CALLBACK, F_S11|TRC_Z, "|Z|", menu_format_acb }, { MT_SUBMENU, 0, S_RARROW " MORE", menu_format2 }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_scale[] = { - { MT_ADV_CALLBACK, KM_SCALE, "SCALE/DIV", menu_keyboard_acb }, - { MT_ADV_CALLBACK, KM_REFPOS, "REFERENCE\nPOSITION", menu_keyboard_acb }, - { MT_ADV_CALLBACK, KM_EDELAY, "E-DELAY\n" R_LINK_COLOR " %b.7F" S_SECOND, menu_keyboard_acb }, - { MT_ADV_CALLBACK, KM_S21OFFSET, "S21 OFFSET\n" R_LINK_COLOR " %b.3F" S_dB, menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_TOP, "TOP", menu_scale_keyboard_acb }, + { MT_ADV_CALLBACK, KM_BOTTOM, "BOTTOM", menu_scale_keyboard_acb }, + { MT_ADV_CALLBACK, KM_SCALE, "SCALE/DIV", menu_scale_keyboard_acb }, + { MT_ADV_CALLBACK, KM_REFPOS, "REFERENCE\nPOSITION", menu_scale_keyboard_acb }, + { MT_ADV_CALLBACK, KM_EDELAY, "E-DELAY\n " R_LINK_COLOR "%b.7F" S_SECOND, menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_S21OFFSET, "S21 OFFSET\n " R_LINK_COLOR "%b.3F" S_dB, menu_keyboard_acb }, #ifdef __USE_GRID_VALUES__ { MT_ADV_CALLBACK, VNA_MODE_SHOW_GRID, "SHOW GRID\nVALUES", menu_vna_mode_acb }, { MT_ADV_CALLBACK, VNA_MODE_DOT_GRID , "DOT GRID", menu_vna_mode_acb }, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_transform[] = { @@ -1772,9 +1935,9 @@ const menuitem_t menu_transform[] = { { MT_ADV_CALLBACK, TD_FUNC_LOWPASS_IMPULSE, "LOW PASS\nIMPULSE", menu_transform_filter_acb }, { MT_ADV_CALLBACK, TD_FUNC_LOWPASS_STEP, "LOW PASS\nSTEP", menu_transform_filter_acb }, { MT_ADV_CALLBACK, TD_FUNC_BANDPASS, "BANDPASS", menu_transform_filter_acb }, - { MT_ADV_CALLBACK, 0, "WINDOW\n" R_LINK_COLOR " %s", menu_transform_window_acb }, - { MT_ADV_CALLBACK, KM_VELOCITY_FACTOR, "VELOCITY\nFACTOR" R_LINK_COLOR " %d%%%%", menu_keyboard_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_ADV_CALLBACK, 0, "WINDOW\n " R_LINK_COLOR "%s", menu_transform_window_acb }, + { MT_ADV_CALLBACK, KM_VELOCITY_FACTOR, "VELOCITY F.\n " R_LINK_COLOR "%d%%%%", menu_keyboard_acb }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_bandwidth[] = { @@ -1802,19 +1965,19 @@ const menuitem_t menu_bandwidth[] = { #ifdef BANDWIDTH_10 { MT_ADV_CALLBACK, BANDWIDTH_10, "%u " S_Hz, menu_bandwidth_acb }, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #ifdef __USE_SMOOTH__ const menuitem_t menu_smooth_count[] = { - { MT_ADV_CALLBACK, VNA_MODE_SMOOTH, "SMOOTH\n" R_LINK_COLOR "%s avg",menu_vna_mode_acb }, + { MT_ADV_CALLBACK, VNA_MODE_SMOOTH, "SMOOTH\n " R_LINK_COLOR "%s avg",menu_vna_mode_acb }, { MT_ADV_CALLBACK, 0, "SMOOTH\nOFF",menu_smooth_acb }, { MT_ADV_CALLBACK, 1, "x%d", menu_smooth_acb }, { MT_ADV_CALLBACK, 2, "x%d", menu_smooth_acb }, { MT_ADV_CALLBACK, 4, "x%d", menu_smooth_acb }, { MT_ADV_CALLBACK, 5, "x%d", menu_smooth_acb }, { MT_ADV_CALLBACK, 6, "x%d", menu_smooth_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #endif @@ -1822,20 +1985,21 @@ const menuitem_t menu_display[] = { { MT_SUBMENU, 0, "TRACE", menu_trace }, { MT_SUBMENU, 0, "FORMAT\n S11 (REFL)", menu_formatS11 }, { MT_SUBMENU, 0, "FORMAT\n S21 (THRU)", menu_formatS21 }, - { MT_ADV_CALLBACK, 0, "CHANNEL\n" R_LINK_COLOR " %s", menu_channel_acb }, + { MT_ADV_CALLBACK, 0, "CHANNEL\n " R_LINK_COLOR "%s", menu_channel_acb }, { MT_SUBMENU, 0, "SCALE", menu_scale }, { MT_SUBMENU, 0, "TRANSFORM", menu_transform }, - { MT_ADV_CALLBACK, 0, "BANDWIDTH\n" R_LINK_COLOR " %u" S_Hz, menu_bandwidth_sel_acb }, + { MT_ADV_CALLBACK, 0, "IF BANDWIDTH\n " R_LINK_COLOR "%u" S_Hz, menu_bandwidth_sel_acb }, #ifdef __USE_SMOOTH__ { MT_SUBMENU, 0, "DATA SMOOTH", menu_smooth_count }, #endif #ifdef __VNA_Z_RENORMALIZATION__ - { MT_ADV_CALLBACK, KM_Z_PORT, "PORT-Z\n" R_LINK_COLOR " 50 " S_RARROW " %bF" S_OHM, menu_keyboard_acb}, + { MT_ADV_CALLBACK, KM_Z_PORT, "PORT-Z\n " R_LINK_COLOR "50 " S_RARROW "%bF" S_OHM, menu_keyboard_acb}, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_sweep_points[] = { + { MT_ADV_CALLBACK, KM_POINTS, "SET POINTS\n " R_LINK_COLOR "%d", (const void *)menu_keyboard_acb }, { MT_ADV_CALLBACK, 0, "%d point", menu_points_acb }, #if POINTS_SET_COUNT > 1 { MT_ADV_CALLBACK, 1, "%d point", menu_points_acb }, @@ -1849,7 +2013,7 @@ const menuitem_t menu_sweep_points[] = { #if POINTS_SET_COUNT > 4 { MT_ADV_CALLBACK, 4, "%d point", menu_points_acb }, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_stimulus[] = { @@ -1858,9 +2022,10 @@ const menuitem_t menu_stimulus[] = { { MT_ADV_CALLBACK, KM_CENTER, "CENTER", menu_keyboard_acb }, { MT_ADV_CALLBACK, KM_SPAN, "SPAN", menu_keyboard_acb }, { MT_ADV_CALLBACK, KM_CW, "CW FREQ", menu_keyboard_acb }, - { MT_ADV_CALLBACK, KM_VAR, MT_CUSTOM_LABEL, menu_keyboard_acb }, - { MT_ADV_CALLBACK, 0, "SWEEP POINTS\n" R_LINK_COLOR " %u", menu_points_sel_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_ADV_CALLBACK, KM_STEP, "FREQ STEP\n " R_LINK_COLOR "%bF" S_Hz, menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_VAR, "JOG STEP\n " R_LINK_COLOR "AUTO", menu_keyboard_acb }, + { MT_ADV_CALLBACK, 0, "SWEEP POINTS\n " R_LINK_COLOR "%u", menu_points_sel_acb }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_marker_sel[] = { @@ -1888,7 +2053,7 @@ const menuitem_t menu_marker_sel[] = { #endif { MT_CALLBACK, 0, "ALL OFF", menu_marker_disable_all_cb }, { MT_ADV_CALLBACK, 0, "DELTA", menu_marker_delta_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_marker_ops[] = { @@ -1897,7 +2062,7 @@ const menuitem_t menu_marker_ops[] = { { MT_CALLBACK, ST_CENTER, S_RARROW" CENTER", menu_marker_op_cb }, { MT_CALLBACK, ST_SPAN, S_RARROW" SPAN", menu_marker_op_cb }, { MT_CALLBACK, UI_MARKER_EDELAY, S_RARROW" E-DELAY", menu_marker_op_cb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_marker_s21smith[] = { @@ -1905,8 +2070,10 @@ const menuitem_t menu_marker_s21smith[] = { { MT_ADV_CALLBACK, MS_LOG, "%s", menu_marker_smith_acb }, { MT_ADV_CALLBACK, MS_REIM, "%s", menu_marker_smith_acb }, { MT_ADV_CALLBACK, MS_SHUNT_RX, "%s", menu_marker_smith_acb }, + { MT_ADV_CALLBACK, MS_SHUNT_RLC, "%s", menu_marker_smith_acb }, { MT_ADV_CALLBACK, MS_SERIES_RX,"%s", menu_marker_smith_acb }, - { MT_NONE, 0, NULL, (const void *)menu_back } // next-> menu_back + { MT_ADV_CALLBACK, MS_SERIES_RLC,"%s", menu_marker_smith_acb }, + { MT_NEXT, 0, NULL, (const void *)menu_back } // next-> menu_back }; const menuitem_t menu_marker_s11smith[] = { @@ -1919,11 +2086,49 @@ const menuitem_t menu_marker_s11smith[] = { { MT_ADV_CALLBACK, MS_GLC, "%s", menu_marker_smith_acb }, { MT_ADV_CALLBACK, MS_RpXp,"%s", menu_marker_smith_acb }, { MT_ADV_CALLBACK, MS_RpLC,"%s", menu_marker_smith_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #ifdef __VNA_MEASURE_MODULE__ -const menuitem_t menu_marker_measure[] = { +// Select menu depend from measure mode +#ifdef __USE_LC_MATCHING__ +const menuitem_t menu_measure_lc[] = { + { MT_ADV_CALLBACK, MEASURE_NONE, "OFF", menu_measure_acb }, + { MT_ADV_CALLBACK, MEASURE_LC_MATH, "L/C MATCH", menu_measure_acb }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back +}; +#endif + +#ifdef __S11_CABLE_MEASURE__ +const menuitem_t menu_measure_cable[] = { + { MT_ADV_CALLBACK, MEASURE_NONE, "OFF", menu_measure_acb }, + { MT_ADV_CALLBACK, MEASURE_S11_CABLE, "CABLE\n (S11)", menu_measure_acb }, + { MT_ADV_CALLBACK, KM_VELOCITY_FACTOR, "VELOCITY F.\n " R_LINK_COLOR "%d%%%%", menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_ACTUAL_CABLE_LEN, "CABLE LENGTH", menu_keyboard_acb }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back +}; +#endif + +#ifdef __S11_RESONANCE_MEASURE__ +const menuitem_t menu_measure_resonance[] = { + { MT_ADV_CALLBACK, MEASURE_NONE, "OFF", menu_measure_acb }, + { MT_ADV_CALLBACK, MEASURE_S11_RESONANCE,"RESONANCE\n (S11)", menu_measure_acb }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back +}; +#endif + +#ifdef __S21_MEASURE__ +const menuitem_t menu_measure_s21[] = { + { MT_ADV_CALLBACK, MEASURE_NONE, "OFF", menu_measure_acb }, + { MT_ADV_CALLBACK, MEASURE_SHUNT_LC, "SHUNT LC\n (S21)", menu_measure_acb }, + { MT_ADV_CALLBACK, MEASURE_SERIES_LC, "SERIES LC\n (S21)", menu_measure_acb }, + { MT_ADV_CALLBACK, MEASURE_SERIES_XTAL, "SERIES\nXTAL (S21)", menu_measure_acb }, + { MT_ADV_CALLBACK, KM_MEASURE_R, " Rl = " R_LINK_COLOR "%b.4F" S_OHM, menu_keyboard_acb}, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back +}; +#endif + +const menuitem_t menu_measure[] = { { MT_ADV_CALLBACK, MEASURE_NONE, "OFF", menu_measure_acb }, #ifdef __USE_LC_MATCHING__ { MT_ADV_CALLBACK, MEASURE_LC_MATH, "L/C MATCH", menu_measure_acb }, @@ -1938,26 +2143,44 @@ const menuitem_t menu_marker_measure[] = { { MT_ADV_CALLBACK, MEASURE_SHUNT_LC, "SHUNT LC\n (S21)", menu_measure_acb }, { MT_ADV_CALLBACK, MEASURE_SERIES_LC, "SERIES LC\n (S21)", menu_measure_acb }, { MT_ADV_CALLBACK, MEASURE_SERIES_XTAL, "SERIES\nXTAL (S21)", menu_measure_acb }, - { MT_ADV_CALLBACK, KM_MEASURE_R, "MEASURE\n Rl =" R_LINK_COLOR " %b.4F"S_OHM, menu_keyboard_acb}, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back +}; + +// Dynamic menu selector depend from measure mode +const menuitem_t *menu_measure_list[] = { + [MEASURE_NONE] = menu_measure, +#ifdef __USE_LC_MATCHING__ + [MEASURE_LC_MATH] = menu_measure_lc, +#endif +#ifdef __S21_MEASURE__ + [MEASURE_SHUNT_LC] = menu_measure_s21, + [MEASURE_SERIES_LC] = menu_measure_s21, + [MEASURE_SERIES_XTAL] = menu_measure_s21, +#endif +#ifdef __S11_CABLE_MEASURE__ + [MEASURE_S11_CABLE] = menu_measure_cable, +#endif +#ifdef __S11_RESONANCE_MEASURE__ + [MEASURE_S11_RESONANCE] = menu_measure_resonance, +#endif }; #endif const menuitem_t menu_marker[] = { { MT_SUBMENU, 0, "SELECT\nMARKER", menu_marker_sel }, - { MT_ADV_CALLBACK,VNA_MODE_SEARCH,"SEARCH\n" R_LINK_COLOR " %s", menu_vna_mode_acb }, - { MT_CALLBACK, MK_SEARCH_LEFT, "SEARCH\n " S_LARROW" LEFT", menu_marker_search_dir_cb }, - { MT_CALLBACK, MK_SEARCH_RIGHT, "SEARCH\n " S_RARROW" RIGHT", menu_marker_search_dir_cb }, + { MT_ADV_CALLBACK,VNA_MODE_SEARCH,"SEARCH\n " R_LINK_COLOR "%s", menu_vna_mode_acb }, + { MT_CALLBACK, MK_SEARCH_LEFT, "SEARCH\n " S_LARROW "LEFT", menu_marker_search_dir_cb }, + { MT_CALLBACK, MK_SEARCH_RIGHT, "SEARCH\n " S_RARROW "RIGHT", menu_marker_search_dir_cb }, { MT_SUBMENU, 0, "OPERATIONS", menu_marker_ops }, { MT_ADV_CALLBACK, 0, "TRACKING", menu_marker_tracking_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #ifdef __DFU_SOFTWARE_MODE__ const menuitem_t menu_dfu[] = { { MT_CALLBACK, 0, "RESET AND\nENTER DFU", menu_dfu_cb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #endif @@ -1973,19 +2196,19 @@ const menuitem_t menu_serial_speed[] = { { MT_ADV_CALLBACK, 7, "%u", menu_serial_speed_acb }, { MT_ADV_CALLBACK, 8, "%u", menu_serial_speed_acb }, { MT_ADV_CALLBACK, 9, "%u", menu_serial_speed_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_connection[] = { { MT_ADV_CALLBACK, VNA_MODE_CONNECTION, "CONNECTION\n " R_LINK_COLOR "%s", menu_vna_mode_acb }, { MT_ADV_CALLBACK, 0, "SERIAL SPEED\n " R_LINK_COLOR "%u", menu_serial_speed_sel_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #endif const menuitem_t menu_clear[] = { { MT_CALLBACK, MENU_CONFIG_RESET, "CLEAR ALL\nAND RESET", menu_config_cb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #ifdef USE_VARIABLE_OFFSET_MENU @@ -1998,35 +2221,35 @@ const menuitem_t menu_offset[] = { { MT_ADV_CALLBACK, 5, "%d" S_Hz, menu_offset_acb }, { MT_ADV_CALLBACK, 6, "%d" S_Hz, menu_offset_acb }, { MT_ADV_CALLBACK, 7, "%d" S_Hz, menu_offset_acb }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; #endif const menuitem_t menu_device1[] = { - { MT_ADV_CALLBACK, 0, "MODE\n" R_LINK_COLOR " %s", menu_band_sel_acb }, + { MT_ADV_CALLBACK, 0, "MODE\n " R_LINK_COLOR "%s", menu_band_sel_acb }, #ifdef __DIGIT_SEPARATOR__ - { MT_ADV_CALLBACK, 0, "SEPARATOR\n" R_LINK_COLOR "%s", menu_separator_acb }, + { MT_ADV_CALLBACK, VNA_MODE_SEPARATOR, "SEPARATOR\n " R_LINK_COLOR "%s", menu_vna_mode_acb }, #endif #ifdef __SD_CARD_DUMP_FIRMWARE__ - { MT_CALLBACK, FMT_BIN_FILE, "DUMP\nFIRMWARE", menu_sdcard_cb }, + { MT_CALLBACK, FMT_BIN_FILE, "DUMP\nFIRMWARE", menu_sdcard_cb }, #endif #ifdef __SD_CARD_LOAD__ #ifdef __SD_FILE_BROWSER__ - { MT_CALLBACK, FMT_CMD_FILE, "LOAD COMMAND\n SCRIPT", menu_sdcard_browse_cb }, + { MT_CALLBACK, FMT_CMD_FILE, "LOAD COMMAND\n SCRIPT", menu_sdcard_browse_cb }, #else - { MT_CALLBACK, MENU_CONFIG_LOAD, "LOAD\nCONFIG.INI", menu_config_cb }, + { MT_CALLBACK, MENU_CONFIG_LOAD, "LOAD\nCONFIG.INI", menu_config_cb }, #endif #endif - { MT_SUBMENU, 0, "CLEAR CONFIG", menu_clear }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_SUBMENU, 0, "CLEAR CONFIG", menu_clear }, + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_device[] = { - { MT_ADV_CALLBACK, KM_THRESHOLD, "THRESHOLD\n" R_LINK_COLOR " %.6q", menu_keyboard_acb }, - { MT_ADV_CALLBACK, KM_XTAL, "TCXO\n" R_LINK_COLOR " %.6q", menu_keyboard_acb }, - { MT_ADV_CALLBACK, KM_VBAT, "VBAT OFFSET\n" R_LINK_COLOR " %um" S_VOLT, menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_THRESHOLD, "THRESHOLD\n " R_LINK_COLOR "%.6q", menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_XTAL, "TCXO\n " R_LINK_COLOR "%.6q", menu_keyboard_acb }, + { MT_ADV_CALLBACK, KM_VBAT, "VBAT OFFSET\n " R_LINK_COLOR "%um" S_VOLT, menu_keyboard_acb }, #ifdef USE_VARIABLE_OFFSET_MENU - { MT_ADV_CALLBACK, 0, "IF OFFSET\n" R_LINK_COLOR " %d" S_Hz, menu_offset_sel_acb }, + { MT_ADV_CALLBACK, 0, "IF OFFSET\n " R_LINK_COLOR "%d" S_Hz, menu_offset_sel_acb }, #endif #ifdef __USE_BACKUP__ { MT_ADV_CALLBACK, VNA_MODE_BACKUP,"REMEMBER\nSTATE", menu_vna_mode_acb}, @@ -2039,7 +2262,7 @@ const menuitem_t menu_device[] = { { MT_ADV_CALLBACK, KM_RTC_TIME, "SET TIME", menu_keyboard_acb }, #endif { MT_SUBMENU, 0, S_RARROW" MORE", menu_device1 }, - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_config[] = { @@ -2052,12 +2275,12 @@ const menuitem_t menu_config[] = { #endif { MT_CALLBACK, MENU_CONFIG_VERSION, "VERSION", menu_config_cb }, #ifdef __LCD_BRIGHTNESS__ - { MT_ADV_CALLBACK, 0, "BRIGHTNESS\n" R_LINK_COLOR " %d%%%%", menu_brightness_acb }, + { MT_ADV_CALLBACK, 0, "BRIGHTNESS\n " R_LINK_COLOR "%d%%%%", menu_brightness_acb }, #endif #ifdef __DFU_SOFTWARE_MODE__ - { MT_SUBMENU, 0, S_RARROW"DFU", menu_dfu }, + { MT_SUBMENU, 0, S_RARROW "DFU", menu_dfu }, #endif - { MT_NONE, 0, NULL, menu_back } // next-> menu_back + { MT_NEXT, 0, NULL, menu_back } // next-> menu_back }; const menuitem_t menu_top[] = { @@ -2067,14 +2290,14 @@ const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "CALIBRATE", menu_cal }, { MT_SUBMENU, 0, "RECALL", menu_recall }, #ifdef __VNA_MEASURE_MODULE__ - { MT_SUBMENU, 0, "MEASURE", menu_marker_measure }, + { MT_CALLBACK,0, "MEASURE", menu_measure_cb }, #endif #ifdef __USE_SD_CARD__ { MT_SUBMENU, 0, "SD CARD", menu_sdcard }, #endif { MT_SUBMENU, 0, "CONFIG", menu_config }, - { MT_ADV_CALLBACK, 0, "PAUSE\nSWEEP", menu_pause_acb }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_ADV_CALLBACK, 0, "%s\nSWEEP", menu_pause_acb }, + { MT_NEXT, 0, NULL, NULL } // sentinel }; #define MENU_STACK_DEPTH_MAX 5 @@ -2085,22 +2308,30 @@ const menuitem_t *menu_stack[MENU_STACK_DEPTH_MAX] = { static const menuitem_t *menu_next_item(const menuitem_t *m){ if (m == NULL) return NULL; m++; // Next item - return m->type == MT_NONE ? (menuitem_t *)m->reference : m; + return m->type == MT_NEXT ? (menuitem_t *)m->reference : m; } -static const menuitem_t *current_menu_item(int i){ +static const menuitem_t *current_menu_item(int i) { const menuitem_t *m = menu_stack[menu_current_level]; while (i--) m = menu_next_item(m); return m; } -static int current_menu_get_count(void){ +static int current_menu_get_count(void) { int i = 0; const menuitem_t *m = menu_stack[menu_current_level]; while (m){m = menu_next_item(m); i++;} return i; } +static int get_lines_count(const char *label) { + int n = 1; + while (*label) + if (*label++ == '\n') + n++; + return n; +} + static void ensure_selection(void) { @@ -2126,14 +2357,18 @@ menu_move_back(bool leave_ui) } static void -menu_push_submenu(const menuitem_t *submenu) -{ - if (menu_current_level < MENU_STACK_DEPTH_MAX-1) - menu_current_level++; +menu_set_submenu(const menuitem_t *submenu) { menu_stack[menu_current_level] = submenu; ensure_selection(); } +static void +menu_push_submenu(const menuitem_t *submenu) { + if (menu_current_level < MENU_STACK_DEPTH_MAX-1) + menu_current_level++; + menu_set_submenu(submenu); +} + /* static void menu_move_top(void) @@ -2168,36 +2403,59 @@ menu_invoke(int item) draw_menu(-1); } +// Draw button function +static void +draw_button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, button_t *b) { + uint16_t type = b->border; + uint16_t bw = type & BUTTON_BORDER_WIDTH_MASK; + // Draw border if width > 0 + if (bw) { + uint16_t br = LCD_RISE_EDGE_COLOR; + uint16_t bd = LCD_FALLEN_EDGE_COLOR; + lcd_set_background(type&BUTTON_BORDER_TOP ? br : bd);lcd_fill(x, y, w, bw); // top + lcd_set_background(type&BUTTON_BORDER_LEFT ? br : bd);lcd_fill(x, y, bw, h); // left + lcd_set_background(type&BUTTON_BORDER_RIGHT ? br : bd);lcd_fill(x + w - bw, y, bw, h); // right + lcd_set_background(type&BUTTON_BORDER_BOTTOM ? br : bd);lcd_fill(x, y + h - bw, w, bw); // bottom + } + // Set colors for button and text + lcd_set_colors(b->fg, b->bg); + if (type & BUTTON_BORDER_NO_FILL) return; + lcd_fill(x + bw, y + bw, w - (bw * 2), h - (bw * 2)); +} + +// Draw message box function +void drawMessageBox(const char *header, const char *text, uint32_t delay) { + button_t b; + int x , y; + b.bg = LCD_MENU_COLOR; + b.fg = LCD_MENU_TEXT_COLOR; + b.border = BUTTON_BORDER_FLAT|1; + if (header) {// Draw header + draw_button((LCD_WIDTH-MESSAGE_BOX_WIDTH)/2, LCD_HEIGHT/2-40, MESSAGE_BOX_WIDTH, 60, &b); + x = (LCD_WIDTH-MESSAGE_BOX_WIDTH)/2 + 10; + y = LCD_HEIGHT/2-40 + 5; + lcd_drawstring(x, y, header); + request_to_redraw(REDRAW_AREA); + } + if (text) { // Draw window + lcd_set_colors(LCD_MENU_TEXT_COLOR, LCD_FG_COLOR); + lcd_fill((LCD_WIDTH-MESSAGE_BOX_WIDTH)/2+3, LCD_HEIGHT/2-40+FONT_STR_HEIGHT+8, MESSAGE_BOX_WIDTH-6, 60-FONT_STR_HEIGHT-8-3); + x = (LCD_WIDTH-MESSAGE_BOX_WIDTH)/2 + 20; + y = LCD_HEIGHT/2-40 + FONT_STR_HEIGHT + 8 + 14; + lcd_drawstring(x, y, text); + request_to_redraw(REDRAW_AREA); + } + + do { + chThdSleepMilliseconds(delay == 0 ? 50 : delay); + } while (delay == 0 && btn_check() != EVT_BUTTON_SINGLE_CLICK && touch_check() != EVT_TOUCH_PRESSED); +} + // -// KEYBOARD input functions +// KEYBOARD functions // -// Key names (use numfont16x22.c glyph) -#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_ENTER 23 - enum {NUM_KEYBOARD, TXT_KEYBOARD}; + // Keyboard size and position data static const keypad_pos_t key_pos[] = { [NUM_KEYBOARD] = {KP_X_OFFSET, KP_Y_OFFSET, KP_WIDTH, KP_HEIGHT}, @@ -2205,12 +2463,12 @@ static const keypad_pos_t key_pos[] = { }; static const keypads_t keypads_freq[] = { - { 16 , NUM_KEYBOARD }, // size and position + { 16, NUM_KEYBOARD }, // 16 buttons NUM keyboard (4x4 size) { 0x13, KP_PERIOD }, - { 0x03, KP_0 }, - { 0x02, KP_1 }, - { 0x12, KP_2 }, - { 0x22, KP_3 }, + { 0x03, KP_0 }, // 7 8 9 G + { 0x02, KP_1 }, // 4 5 6 M + { 0x12, KP_2 }, // 1 2 3 k + { 0x22, KP_3 }, // 0 . < x { 0x01, KP_4 }, { 0x11, KP_5 }, { 0x21, KP_6 }, @@ -2219,18 +2477,18 @@ static const keypads_t keypads_freq[] = { { 0x20, KP_9 }, { 0x30, KP_G }, { 0x31, KP_M }, - { 0x32, KP_K }, + { 0x32, KP_k }, { 0x33, KP_X1 }, { 0x23, KP_BS } }; static const keypads_t keypads_ufloat[] = { // - { 13, NUM_KEYBOARD }, // size and position + { 13, NUM_KEYBOARD }, // 13 buttons NUM keyboard (4x4 size) { 0x13, KP_PERIOD }, - { 0x03, KP_0 }, - { 0x02, KP_1 }, - { 0x12, KP_2 }, - { 0x22, KP_3 }, + { 0x03, KP_0 }, // 7 8 9 + { 0x02, KP_1 }, // 4 5 6 + { 0x12, KP_2 }, // 1 2 3 + { 0x22, KP_3 }, // 0 . < x { 0x01, KP_4 }, { 0x11, KP_5 }, { 0x21, KP_6 }, @@ -2241,54 +2499,113 @@ static const keypads_t keypads_ufloat[] = { // { 0x23, KP_BS } }; +static const keypads_t keypads_percent[] = { // + { 13, NUM_KEYBOARD }, // 13 buttons NUM keyboard (4x4 size) + { 0x13, KP_PERIOD }, + { 0x03, KP_0 }, // 7 8 9 + { 0x02, KP_1 }, // 4 5 6 + { 0x12, KP_2 }, // 1 2 3 + { 0x22, KP_3 }, // 0 . < % + { 0x01, KP_4 }, + { 0x11, KP_5 }, + { 0x21, KP_6 }, + { 0x00, KP_7 }, + { 0x10, KP_8 }, + { 0x20, KP_9 }, + { 0x33, KP_PERCENT }, + { 0x23, KP_BS } +}; + static const keypads_t keypads_float[] = { - { 14, NUM_KEYBOARD }, // size and position + { 14, NUM_KEYBOARD }, // 14 buttons NUM keyboard (4x4 size) + { 0x13, KP_PERIOD }, + { 0x03, KP_0 }, // 7 8 9 + { 0x02, KP_1 }, // 4 5 6 + { 0x12, KP_2 }, // 1 2 3 - + { 0x22, KP_3 }, // 0 . < x + { 0x01, KP_4 }, + { 0x11, KP_5 }, + { 0x21, KP_6 }, + { 0x00, KP_7 }, + { 0x10, KP_8 }, + { 0x20, KP_9 }, + { 0x32, KP_MINUS }, + { 0x33, KP_ENTER }, + { 0x23, KP_BS } +}; + +static const keypads_t keypads_mfloat[] = { + { 16, NUM_KEYBOARD }, // 16 buttons NUM keyboard (4x4 size) { 0x13, KP_PERIOD }, - { 0x03, KP_0 }, - { 0x02, KP_1 }, - { 0x12, KP_2 }, - { 0x22, KP_3 }, + { 0x03, KP_0 }, // 7 8 9 u + { 0x02, KP_1 }, // 4 5 6 m + { 0x12, KP_2 }, // 1 2 3 - + { 0x22, KP_3 }, // 0 . < x { 0x01, KP_4 }, { 0x11, KP_5 }, { 0x21, KP_6 }, { 0x00, KP_7 }, { 0x10, KP_8 }, { 0x20, KP_9 }, + { 0x30, KP_u }, + { 0x31, KP_m }, { 0x32, KP_MINUS }, { 0x33, KP_ENTER }, { 0x23, KP_BS } }; +static const keypads_t keypads_mkufloat[] = { + { 15, NUM_KEYBOARD }, // 15 buttons NUM keyboard (4x4 size) + { 0x13, KP_PERIOD }, + { 0x03, KP_0 }, // 7 8 9 + { 0x02, KP_1 }, // 4 5 6 m + { 0x12, KP_2 }, // 1 2 3 k + { 0x22, KP_3 }, // 0 . < x + { 0x01, KP_4 }, + { 0x11, KP_5 }, + { 0x21, KP_6 }, + { 0x00, KP_7 }, + { 0x10, KP_8 }, + { 0x20, KP_9 }, + { 0x31, KP_m }, + { 0x32, KP_k }, + { 0x33, KP_ENTER }, + { 0x23, KP_BS } +}; + static const keypads_t keypads_nfloat[] = { - { 15, NUM_KEYBOARD }, // size and position + { 16, NUM_KEYBOARD }, // 16 buttons NUM keyboard (4x4 size) { 0x13, KP_PERIOD }, - { 0x03, KP_0 }, - { 0x02, KP_1 }, - { 0x12, KP_2 }, - { 0x22, KP_3 }, + { 0x03, KP_0 }, // 7 8 9 u + { 0x02, KP_1 }, // 4 5 6 n + { 0x12, KP_2 }, // 1 2 3 p + { 0x22, KP_3 }, // 0 . < - { 0x01, KP_4 }, { 0x11, KP_5 }, { 0x21, KP_6 }, { 0x00, KP_7 }, { 0x10, KP_8 }, { 0x20, KP_9 }, - { 0x31, KP_N }, - { 0x32, KP_P }, + { 0x30, KP_u }, + { 0x31, KP_n }, + { 0x32, KP_p }, { 0x33, KP_MINUS }, { 0x23, KP_BS } }; #if 0 +// ABCD keyboard static const keypads_t keypads_text[] = { - {40, TXT_KEYBOARD }, // size and position + {40, TXT_KEYBOARD }, // 40 buttons TXT keyboard (10x4 size) {0x00, '0'}, {0x10, '1'}, {0x20, '2'}, {0x30, '3'}, {0x40, '4'}, {0x50, '5'}, {0x60, '6'}, {0x70, '7'}, {0x80, '8'}, {0x90, '9'}, {0x01, 'A'}, {0x11, 'B'}, {0x21, 'C'}, {0x31, 'D'}, {0x41, 'E'}, {0x51, 'F'}, {0x61, 'G'}, {0x71, 'H'}, {0x81, 'I'}, {0x91, 'J'}, {0x02, 'K'}, {0x12, 'L'}, {0x22, 'M'}, {0x32, 'N'}, {0x42, 'O'}, {0x52, 'P'}, {0x62, 'Q'}, {0x72, 'R'}, {0x82, 'S'}, {0x92, 'T'}, {0x03, 'U'}, {0x13, 'V'}, {0x23, 'W'}, {0x33, 'X'}, {0x43, 'Y'}, {0x53, 'Z'}, {0x63, '_'}, {0x73, '-'}, {0x83, S_LARROW[0]}, {0x93, S_ENTER[0]}, }; #else +// QWERTY keyboard static const keypads_t keypads_text[] = { - {40, TXT_KEYBOARD }, // size and position + {40, TXT_KEYBOARD }, // 40 buttons TXT keyboard (10x4 size) {0x00, '1'}, {0x10, '2'}, {0x20, '3'}, {0x30, '4'}, {0x40, '5'}, {0x50, '6'}, {0x60, '7'}, {0x70, '8'}, {0x80, '9'}, {0x90, '0'}, {0x01, 'Q'}, {0x11, 'W'}, {0x21, 'E'}, {0x31, 'R'}, {0x41, 'T'}, {0x51, 'Y'}, {0x61, 'U'}, {0x71, 'I'}, {0x81, 'O'}, {0x91, 'P'}, {0x02, 'A'}, {0x12, 'S'}, {0x22, 'D'}, {0x32, 'F'}, {0x42, 'G'}, {0x52, 'H'}, {0x62, 'J'}, {0x72, 'K'}, {0x82, 'L'}, {0x92, '_'}, @@ -2296,39 +2613,83 @@ static const keypads_t keypads_text[] = { }; #endif -enum {KEYPAD_FREQ, KEYPAD_UFLOAT, KEYPAD_FLOAT, KEYPAD_NFLOAT, KEYPAD_TEXT}; +enum {KEYPAD_FREQ, KEYPAD_UFLOAT, KEYPAD_PERCENT, KEYPAD_FLOAT, KEYPAD_MFLOAT, KEYPAD_MKUFLOAT, KEYPAD_NFLOAT, KEYPAD_TEXT}; static const keypads_t *keypad_type_list[] = { [KEYPAD_FREQ] = keypads_freq, // frequency input [KEYPAD_UFLOAT] = keypads_ufloat, // unsigned float input + [KEYPAD_PERCENT]= keypads_percent,// unsigned float input in percent [KEYPAD_FLOAT] = keypads_float, // signed float input - [KEYPAD_NFLOAT] = keypads_nfloat, // signed pico/nano float input + [KEYPAD_MFLOAT] = keypads_mfloat, // signed milli/micro float input + [KEYPAD_MKUFLOAT] = keypads_mkufloat,// unsigned milli/kilo float input + [KEYPAD_NFLOAT] = keypads_nfloat, // signed micro/nano/pico float input [KEYPAD_TEXT] = keypads_text // text input }; -static float keyboard_get_float(void) {return my_atof(kp_buf);} -static freq_t keyboard_get_freq(void) {return my_atoui(kp_buf);} -static uint32_t keyboard_get_uint(void) {return my_atoui(kp_buf);} +// Get value from keyboard functions +float keyboard_get_float(void) {return my_atof(kp_buf);} +freq_t keyboard_get_freq(void) {return my_atoui(kp_buf);} +uint32_t keyboard_get_uint(void) {return my_atoui(kp_buf);} -// Call back functions for MT_CALLBACK type +// Keyboard call back functions, allow get value for Keyboard menu button (see menu_keyboard_acb) and apply on finish input UI_KEYBOARD_CALLBACK(input_freq) { if (b) { - if (data == ST_VAR) - plot_printf(b->label, sizeof(b->label), var_freq ? "JOG STEP\n" R_LINK_COLOR " %.3q" S_Hz : "JOG STEP\n AUTO", var_freq); + if (data == ST_VAR && var_freq) + plot_printf(b->label, sizeof(b->label), "JOG STEP\n " R_LINK_COLOR "%.3q" S_Hz, var_freq); + if (data == ST_STEP) b->p1.f = (float)get_sweep_frequency(ST_SPAN) / (sweep_points - 1); return; } set_sweep_frequency(data, keyboard_get_freq()); } -UI_KEYBOARD_CALLBACK(input_scale) { - if (b) {/*b->p1.f = current_trace != TRACE_INVALID ? get_trace_scale(current_trace) : 0;*/return;} - float scale = keyboard_get_float(); - if (data != KM_SCALE) scale*= 1e-12; +UI_KEYBOARD_CALLBACK(input_var_delay) { + (void)data; + if (b) { + if (current_props._var_delay) + plot_printf(b->label, sizeof(b->label), "JOG STEP\n " R_LINK_COLOR "%F" S_SECOND, current_props._var_delay); + return; + } + current_props._var_delay = keyboard_get_float(); +} + +// Call back functions for MT_CALLBACK type +UI_KEYBOARD_CALLBACK(input_points) { + (void)data; + if (b) {b->p1.u = sweep_points; return;} + set_sweep_points(keyboard_get_uint()); +} + +UI_KEYBOARD_CALLBACK(input_amplitude) { + int type = trace[current_trace].type; + float scale = get_trace_scale(current_trace); + float ref = get_trace_refpos(current_trace); + float bot = (0 - ref) * scale; + float top = (NGRIDY - ref) * scale; + + if (b) { + float val = data == 0 ? top : bot; + if (type == TRC_SWR) val+= 1.0f; + plot_printf(b->label, sizeof(b->label), "%s\n " R_LINK_COLOR "%.4F%s", data == 0 ? "TOP" : "BOTTOM", val, trace_info_list[type].symbol); + return; + } + float value = keyboard_get_float(); + if (type == TRC_SWR) value-= 1.0f; // Hack for SWR trace! + if (data == 0) top = value; // top value input + else bot = value; // bottom value input + scale = (top - bot) / NGRIDY; + ref = (top == bot) ? -value : -bot / scale; set_trace_scale(current_trace, scale); + set_trace_refpos(current_trace, ref); +} + +UI_KEYBOARD_CALLBACK(input_scale) { + (void)data; + if (b) {b->p1.f = get_trace_scale(current_trace); return;} + set_trace_scale(current_trace, keyboard_get_float()); } UI_KEYBOARD_CALLBACK(input_ref) { (void)data; - if (b) return; + if (b) {b->p1.f = get_trace_refpos(current_trace); return;} set_trace_refpos(current_trace, keyboard_get_float()); } @@ -2350,7 +2711,20 @@ UI_KEYBOARD_CALLBACK(input_velocity) { velocity_factor = keyboard_get_uint(); } -UI_KEYBOARD_CALLBACK(input_xtal) { +#ifdef __S11_CABLE_MEASURE__ +extern float real_cable_len; +UI_KEYBOARD_CALLBACK(input_cable_len) { + (void)data; + if (b) { + if (real_cable_len == 0.0f) return; + plot_printf(b->label, sizeof(b->label), "%s\n " R_LINK_COLOR "%.4F%s", "CABLE LENGTH", real_cable_len, S_METRE); + return; + } + real_cable_len = keyboard_get_float(); +} +#endif + +UI_KEYBOARD_CALLBACK(input_xtal) { (void)data; if (b) {b->p1.u = config._xtal_freq; return;} si5351_set_tcxo(keyboard_get_uint()); @@ -2431,19 +2805,29 @@ UI_KEYBOARD_CALLBACK(input_filename) { #endif const keypads_list keypads_mode_tbl[KM_NONE] = { +// key format data for cb text at bottom callback function [KM_START] = {KEYPAD_FREQ, ST_START, "START", input_freq }, // start [KM_STOP] = {KEYPAD_FREQ, ST_STOP, "STOP", input_freq }, // stop [KM_CENTER] = {KEYPAD_FREQ, ST_CENTER, "CENTER", input_freq }, // center [KM_SPAN] = {KEYPAD_FREQ, ST_SPAN, "SPAN", input_freq }, // span [KM_CW] = {KEYPAD_FREQ, ST_CW, "CW FREQ", input_freq }, // cw freq +[KM_STEP] = {KEYPAD_FREQ, ST_STEP, "FREQ STEP", input_freq }, // freq as point step [KM_VAR] = {KEYPAD_FREQ, ST_VAR, "JOG STEP", input_freq }, // VAR freq step +[KM_POINTS] = {KEYPAD_UFLOAT, 0, "POINTS", input_points }, // Points num +[KM_TOP] = {KEYPAD_MFLOAT, 0, "TOP", input_amplitude}, // top graph value +[KM_nTOP] = {KEYPAD_NFLOAT, 0, "TOP", input_amplitude}, // top graph value +[KM_BOTTOM] = {KEYPAD_MFLOAT, 1, "BOTTOM", input_amplitude}, // bottom graph value +[KM_nBOTTOM] = {KEYPAD_NFLOAT, 1, "BOTTOM", input_amplitude}, // bottom graph value [KM_SCALE] = {KEYPAD_UFLOAT, KM_SCALE, "SCALE", input_scale }, // scale [KM_nSCALE] = {KEYPAD_NFLOAT, KM_nSCALE, "SCALE", input_scale }, // nano / pico scale value -[KM_SCALEDELAY] = {KEYPAD_NFLOAT, KM_SCALEDELAY, "DELAY", input_scale }, // nano / pico delay value [KM_REFPOS] = {KEYPAD_FLOAT, 0, "REFPOS", input_ref }, // refpos [KM_EDELAY] = {KEYPAD_NFLOAT, 0, "E-DELAY", input_edelay }, // electrical delay +[KM_VAR_DELAY] = {KEYPAD_NFLOAT, 0, "JOG STEP", input_var_delay}, // VAR electrical delay [KM_S21OFFSET] = {KEYPAD_FLOAT, 0, "S21 OFFSET", input_s21_offset},// S21 level offset -[KM_VELOCITY_FACTOR] = {KEYPAD_UFLOAT, 0, "VELOCITY%%", input_velocity }, // velocity factor +[KM_VELOCITY_FACTOR] = {KEYPAD_PERCENT,0, "VELOCITY%%", input_velocity }, // velocity factor +#ifdef __S11_CABLE_MEASURE__ +[KM_ACTUAL_CABLE_LEN]= {KEYPAD_MKUFLOAT,0, "CABLE LENGTH", input_cable_len}, // real cable length input for VF calculation +#endif [KM_XTAL] = {KEYPAD_FREQ, 0, "TCXO 26M" S_Hz, input_xtal }, // XTAL frequency [KM_THRESHOLD] = {KEYPAD_FREQ, 0, "THRESHOLD", input_harmonic }, // Harmonic threshold frequency [KM_VBAT] = {KEYPAD_UFLOAT, 0, "BAT OFFSET", input_vbat }, // Vbat offset input in mV @@ -2454,68 +2838,29 @@ const keypads_list keypads_mode_tbl[KM_NONE] = { [KM_Z_PORT] = {KEYPAD_UFLOAT, 0, "PORT Z 50" S_RARROW, input_portz }, // Port Z renormalization impedance #endif #ifdef __USE_RTC__ -[KM_RTC_DATE] = {KEYPAD_UFLOAT, KM_RTC_DATE, "SET DATE\n YYMMDD", input_date_time}, // Date -[KM_RTC_TIME] = {KEYPAD_UFLOAT, KM_RTC_TIME, "SET TIME\n HHMMSS", input_date_time}, // Time +[KM_RTC_DATE] = {KEYPAD_UFLOAT, KM_RTC_DATE, "SET DATE\nYY MM DD", input_date_time}, // Date +[KM_RTC_TIME] = {KEYPAD_UFLOAT, KM_RTC_TIME, "SET TIME\nHH MM SS", input_date_time}, // Time #endif #ifdef __USE_SD_CARD__ -[KM_S1P_NAME] = {KEYPAD_TEXT, FMT_S1P_FILE, "S1P", input_filename }, // s1p filename -[KM_S2P_NAME] = {KEYPAD_TEXT, FMT_S2P_FILE, "S2P", input_filename }, // s2p filename -[KM_BMP_NAME] = {KEYPAD_TEXT, FMT_BMP_FILE, "BMP", input_filename }, // bmp filename -[KM_CAL_NAME] = {KEYPAD_TEXT, FMT_CAL_FILE, "CAL", input_filename }, // cal filename +[KM_S1P_NAME] = {KEYPAD_TEXT, FMT_S1P_FILE, "S1P", input_filename }, // s1p filename +[KM_S2P_NAME] = {KEYPAD_TEXT, FMT_S2P_FILE, "S2P", input_filename }, // s2p filename +[KM_BMP_NAME] = {KEYPAD_TEXT, FMT_BMP_FILE, "BMP", input_filename }, // bmp filename +#ifdef __SD_CARD_DUMP_TIFF__ +[KM_TIF_NAME] = {KEYPAD_TEXT, FMT_TIF_FILE, "TIF", input_filename }, // tif filename +#endif +[KM_CAL_NAME] = {KEYPAD_TEXT, FMT_CAL_FILE, "CAL", input_filename }, // cal filename #ifdef __SD_CARD_DUMP_FIRMWARE__ -[KM_BIN_NAME] = {KEYPAD_TEXT, FMT_BIN_FILE, "BIN", input_filename }, // bin filename +[KM_BIN_NAME] = {KEYPAD_TEXT, FMT_BIN_FILE, "BIN", input_filename }, // bin filename #endif #endif }; static void -keypad_set_value(void) -{ +keypad_set_value(void) { const keyboard_cb_t cb = keypads_mode_tbl[keypad_mode].cb; if (cb) cb(keypads_mode_tbl[keypad_mode].data, NULL); } -static void -draw_button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, button_t *b) -{ - uint16_t type = b->border; - uint16_t bw = type & BUTTON_BORDER_WIDTH_MASK; - // Draw border if width > 0 - if (bw) { - uint16_t br = LCD_RISE_EDGE_COLOR; - uint16_t bd = LCD_FALLEN_EDGE_COLOR; - lcd_set_background(type&BUTTON_BORDER_TOP ? br : bd);lcd_fill(x, y, w, bw); // top - lcd_set_background(type&BUTTON_BORDER_LEFT ? br : bd);lcd_fill(x, y, bw, h); // left - lcd_set_background(type&BUTTON_BORDER_RIGHT ? br : bd);lcd_fill(x + w - bw, y, bw, h); // right - lcd_set_background(type&BUTTON_BORDER_BOTTOM ? br : bd);lcd_fill(x, y + h - bw, w, bw); // bottom - } - // Set colors for button and text - lcd_set_foreground(b->fg); - lcd_set_background(b->bg); - if (type & BUTTON_BORDER_NO_FILL) return; - lcd_fill(x + bw, y + bw, w - (bw * 2), h - (bw * 2)); -} - -void drawMessageBox(const char *header, const char *text, uint32_t delay){ - button_t b; - int x , y; - b.bg = LCD_MENU_COLOR; - b.fg = LCD_MENU_TEXT_COLOR; - b.border = BUTTON_BORDER_FLAT|1; - // Draw header - draw_button((LCD_WIDTH-MESSAGE_BOX_WIDTH)/2, LCD_HEIGHT/2-40, MESSAGE_BOX_WIDTH, 60, &b); - x = (LCD_WIDTH-MESSAGE_BOX_WIDTH)/2 + 10; - y = LCD_HEIGHT/2-40 + 5; - lcd_drawstring(x, y, header); - // Draw window - lcd_set_background(LCD_FG_COLOR); - lcd_fill((LCD_WIDTH-MESSAGE_BOX_WIDTH)/2+3, LCD_HEIGHT/2-40+FONT_STR_HEIGHT+8, MESSAGE_BOX_WIDTH-6, 60-FONT_STR_HEIGHT-8-3); - x = (LCD_WIDTH-MESSAGE_BOX_WIDTH)/2 + 20; - y = LCD_HEIGHT/2-40 + FONT_STR_HEIGHT + 8 + 14; - lcd_drawstring(x, y, text); - chThdSleepMilliseconds(delay); -} - static void draw_keypad_button(int id) { if (id < 0) return; @@ -2525,8 +2870,7 @@ draw_keypad_button(int id) { if (id == selection) { button.bg = LCD_MENU_ACTIVE_COLOR; button.border = KEYBOARD_BUTTON_BORDER|BUTTON_BORDER_FALLING; - } - else{ + } else{ button.bg = LCD_MENU_COLOR; button.border = KEYBOARD_BUTTON_BORDER|BUTTON_BORDER_RISE; } @@ -2560,15 +2904,14 @@ draw_keypad(void) draw_keypad_button(i); } -static int period_pos(void) {int j; for (j = 0; j < kp_index && kp_buf[j] != '.'; j++); return j;} +static int period_pos(void) {int j; for (j = 0; kp_buf[j] && kp_buf[j] != '.'; j++); return j;} -static void -draw_numeric_area_frame(void) -{ - lcd_set_foreground(LCD_INPUT_TEXT_COLOR); - lcd_set_background(LCD_INPUT_BG_COLOR); +static void draw_numeric_area_frame(void) { + lcd_set_colors(LCD_INPUT_TEXT_COLOR, LCD_INPUT_BG_COLOR); lcd_fill(0, LCD_HEIGHT-NUM_INPUT_HEIGHT, LCD_WIDTH, NUM_INPUT_HEIGHT); - lcd_drawstring(10, LCD_HEIGHT-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2, keypads_mode_tbl[keypad_mode].name); + const char *label = keypads_mode_tbl[keypad_mode].name; + int lines = get_lines_count(label); + lcd_drawstring(10, LCD_HEIGHT-(FONT_STR_HEIGHT * lines + NUM_INPUT_HEIGHT)/2, label); } static void @@ -2583,35 +2926,28 @@ draw_numeric_input(const char *buf) else #endif xsim = (0b00100100100100100 >>(2-(period_pos()%3)))&(~1); - int c; + lcd_set_colors(LCD_INPUT_TEXT_COLOR, LCD_INPUT_BG_COLOR); while(*buf) { - c = *buf++; + int c = *buf++; if (c == '.'){c = KP_PERIOD;xsim<<=4;} else if (c == '-'){c = KP_MINUS; xsim&=~3;} - else// if (c >= '0' && c <= '9') - c = c - '0'; - if (c < 0) c = 0; - lcd_set_foreground(LCD_INPUT_TEXT_COLOR); - lcd_set_background(LCD_INPUT_BG_COLOR); - + else if (c >= '0' && c <= '9') c-= '0'; + else continue; // Add space before char uint16_t space = xsim&1 ? 2 + 10 : 2; xsim>>=1; lcd_fill(x, y, space, NUM_FONT_GET_HEIGHT); x+=space; - if (c < 0) continue; // c is number lcd_drawfont(c, x, y); x+=NUM_FONT_GET_WIDTH; } - lcd_set_background(LCD_INPUT_BG_COLOR); lcd_fill(x, y, NUM_FONT_GET_WIDTH+2+10, NUM_FONT_GET_HEIGHT); } static void draw_text_input(const char *buf) { - lcd_set_foreground(LCD_INPUT_TEXT_COLOR); - lcd_set_background(LCD_INPUT_BG_COLOR); + lcd_set_colors(LCD_INPUT_TEXT_COLOR, LCD_INPUT_BG_COLOR); #if 0 uint16_t x = 14 + 5 * FONT_WIDTH; uint16_t y = LCD_HEIGHT-(FONT_GET_HEIGHT + NUM_INPUT_HEIGHT)/2; @@ -2626,16 +2962,147 @@ draw_text_input(const char *buf) #endif } +/* + * Keyboard UI processing + */ static int -menu_is_multiline(const char *label) +num_keypad_click(int c, int kp_index) { + if (c >= KP_k && c <= KP_PERCENT) { + if (kp_index == 0) + return KP_CANCEL; + if (c >= KP_k && c <= KP_G) { // Apply k, M, G input (add zeroes and shift . right) + uint16_t scale = c - KP_k + 1; + scale+= (scale<<1); + int i = period_pos(); if (scale + i > NUMINPUT_LEN) scale = NUMINPUT_LEN - i; + do { + char v = kp_buf[i+1]; if (v == 0 || kp_buf[i] == 0) {v = '0'; kp_buf[i+2] = 0;} + kp_buf[i+1] = kp_buf[i]; + kp_buf[i++] = v; + } while (--scale); + } else if (c >= KP_m && c <= KP_p) { // Apply m, u, n, p input (add format at end for atof function) + const char prefix[] = {'m', 'u', 'n', 'p'}; + kp_buf[kp_index ] = prefix[c - KP_m]; + kp_buf[kp_index+1] = 0; + } + return KP_DONE; + } +#ifdef __USE_RTC__ + int maxlength = (1< 0; i--) kp_buf[i] = kp_buf[i-1]; kp_buf[0] = '-'; if (kp_index < maxlength) ++kp_index;} +// if (kp_index == 0) +// kp_buf[kp_index++] = '-'; + } else if (kp_index < maxlength) { + if (c <= KP_9) + kp_buf[kp_index++] = '0' + c; + else if (c == KP_PERIOD && kp_index == period_pos() && maxlength == NUMINPUT_LEN) // append period if there are no period and for num input (skip for date/time) + kp_buf[kp_index++] = '.'; + } + kp_buf[kp_index] = '\0'; + draw_numeric_input(kp_buf); + return KP_CONTINUE; +} + +static int +txt_keypad_click(int c, int kp_index) { - int n = 1; - while (*label) - if (*label++ == '\n') - n++; - return n; + if (c == S_ENTER[0]) { // Enter + return kp_index == 0 ? KP_CANCEL : KP_DONE; + } + if (c == S_LARROW[0]) { // Backspace + if (kp_index == 0) + return KP_CANCEL; + --kp_index; + } else if (kp_index < TXTINPUT_LEN) { // any other text input + kp_buf[kp_index++] = c; + } + kp_buf[kp_index] = '\0'; + draw_text_input(kp_buf); + return KP_CONTINUE; +} + +static void +ui_mode_keypad(int _keypad_mode) +{ + if (ui_mode == UI_KEYPAD) + return; + set_area_size(0, 0); + // keypads array + keypad_mode = _keypad_mode; + keypads = keypad_type_list[keypads_mode_tbl[keypad_mode].keypad_type]; + selection = -1; + kp_buf[0] = 0; + ui_mode = UI_KEYPAD; + draw_menu(-1); + draw_keypad(); + draw_numeric_area_frame(); +} + +static void +keypad_click(int key) { + int c = keypads[key+1].c; // !!! Use key + 1 (zero key index used or size define) + int index = strlen(kp_buf); + int result = keypads[0].c == NUM_KEYBOARD ? num_keypad_click(c, index) : txt_keypad_click(c, index); + if (result == KP_DONE) keypad_set_value(); // apply input done + // Exit loop on done or cancel + if (result != KP_CONTINUE) + ui_mode_normal(); +} + +static void +ui_keypad_touch(int touch_x, int touch_y) +{ + const keypad_pos_t *p = &key_pos[keypads[0].c]; + if (touch_x < p->x_offs || touch_y < p->y_offs) return; + // Calculate key position from touch x and y + touch_x-= p->x_offs; touch_x/= p->width; + touch_y-= p->y_offs; touch_y/= p->height; + uint8_t pos = (touch_y & 0x0F) | (touch_x<<4); + for (int i = 0; i < keypads[0].pos; i++) { + if (keypads[i+1].pos != pos) continue; + int old = selection; + draw_keypad_button(selection = i); // draw new focus + draw_keypad_button(old); // Erase old focus + touch_wait_release(); + selection = -1; + draw_keypad_button(i); // erase new focus + keypad_click(i); // Process input + return; + } + return; +} + +static void +ui_keypad_lever(uint16_t status) +{ + if (status == EVT_BUTTON_SINGLE_CLICK) { + if (selection >= 0) // Process input + keypad_click(selection); + return; + } + int keypads_last_index = keypads[0].pos - 1; + do { + int old = selection; + if ((status & EVT_DOWN) && --selection < 0) selection = keypads_last_index; + if ((status & EVT_UP) && ++selection > keypads_last_index) selection = 0; + draw_keypad_button(old); + draw_keypad_button(selection); + chThdSleepMilliseconds(100); + } while ((status = btn_wait_release()) != 0); } +//========================== end keyboard input ======================= +// +// UI Menu functions +// static void draw_menu_buttons(const menuitem_t *m, uint32_t mask) { @@ -2650,18 +3117,18 @@ draw_menu_buttons(const menuitem_t *m, uint32_t mask) if (ui_mode == UI_MENU && i == selection){ button.bg = LCD_MENU_ACTIVE_COLOR; button.border = MENU_BUTTON_BORDER|BUTTON_BORDER_FALLING; - } - else{ + } else{ button.bg = LCD_MENU_COLOR; button.border = MENU_BUTTON_BORDER|BUTTON_BORDER_RISE; } // Custom button, apply custom settings/label from callback char *text; uint16_t text_offs; - if (m->type == MT_ADV_CALLBACK){ + if (m->type == MT_ADV_CALLBACK) { + button.label[0] = 0; if (m->reference) ((menuaction_acb_t)m->reference)(m->data, &button); // Apply custom text, from button label and - if (m->label != MT_CUSTOM_LABEL) + if (button.label[0] == 0) plot_printf(button.label, sizeof(button.label), m->label, button.p1.u); text = button.label; } @@ -2676,22 +3143,22 @@ draw_menu_buttons(const menuitem_t *m, uint32_t mask) } else text_offs = LCD_WIDTH-MENU_BUTTON_WIDTH+MENU_BUTTON_BORDER + MENU_TEXT_OFFSET; // Draw button text - int lines = menu_is_multiline(text); + int lines = get_lines_count(text); #if _USE_FONT_ != _USE_SMALL_FONT_ - if (menu_button_height < lines*FONT_GET_HEIGHT + 2) { + if (menu_button_height < lines * FONT_GET_HEIGHT + 2) { lcd_set_font(FONT_SMALL); - lcd_drawstring(text_offs, y+(menu_button_height-lines*sFONT_GET_HEIGHT - 1)/2, text); + lcd_drawstring(text_offs, y+(menu_button_height - lines * sFONT_GET_HEIGHT - 1)/2, text); } else { lcd_set_font(FONT_NORMAL); - lcd_drawstring(text_offs, y+(menu_button_height-lines*FONT_GET_HEIGHT)/2, text); + lcd_drawstring(text_offs, y+(menu_button_height - lines * FONT_GET_HEIGHT)/2, text); } #else - lcd_drawstring(text_offs, y+(menu_button_height-lines*FONT_GET_HEIGHT)/2, text); + lcd_drawstring(text_offs, y+(menu_button_height - lines * FONT_GET_HEIGHT)/2, text); #endif } // Erase empty buttons - if (AREA_HEIGHT_NORMAL + OFFSETY > y){ + if (AREA_HEIGHT_NORMAL + OFFSETY > y) { lcd_set_background(LCD_BG_COLOR); lcd_fill(LCD_WIDTH-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, AREA_HEIGHT_NORMAL + OFFSETY - y); } @@ -2713,9 +3180,7 @@ erase_menu_buttons(void) } #endif -/* - * Menu mode processing - */ +// Menu mode processing static void ui_mode_menu(void) { @@ -2730,13 +3195,17 @@ ui_mode_menu(void) } static void -ui_process_menu_lever(uint16_t status) +ui_menu_lever(uint16_t status) { + uint16_t count = current_menu_get_count(); if (status & EVT_BUTTON_SINGLE_CLICK) { - menu_invoke(selection); + if ((uint16_t)selection >= count) + ui_mode_normal(); + else + menu_invoke(selection); return; } - uint16_t count = current_menu_get_count(); + do { uint32_t mask = 1<= KP_X1 && c <= KP_G) || c == KP_N || c == KP_P) { - if (kp_index == 0) - return KP_CANCEL; - uint16_t scale = 0; - if (c > KP_X1 && c <= KP_G) scale = c - KP_X1; - if (c == KP_N) scale = 1; - if (scale){ - scale+= (scale<<1); - int i = period_pos(); if (i+scale>NUMINPUT_LEN) scale = NUMINPUT_LEN - 1 - i; - while (scale--) { - char v = kp_buf[i+1]; if (v == 0 || kp_buf[i] == 0) {v = '0'; kp_buf[i+2] = 0;} - kp_buf[i+1] = kp_buf[i]; - kp_buf[i ] = v; - i++; - } - } - return KP_DONE; - } - - if (c == KP_BS) { - if (kp_index == 0) return KP_CANCEL; - --kp_index; - } else if (c == KP_MINUS) { - if (kp_index == 0) - kp_buf[kp_index++] = '-'; - } else if (kp_index < NUMINPUT_LEN) { - if (c <= KP_9) - kp_buf[kp_index++] = '0' + c; - else if (c == KP_PERIOD && kp_index == period_pos()) // append period if there are no period - kp_buf[kp_index++] = '.'; - } - - kp_buf[kp_index] = '\0'; - draw_numeric_input(kp_buf); - return KP_CONTINUE; -} - -static int -full_keypad_click(int c) -{ - if (c == S_ENTER[0]) { // Enter - return kp_index == 0 ? KP_CANCEL : KP_DONE; - } - if (c == S_LARROW[0]) { // Backspace - if (kp_index == 0) - return KP_CANCEL; - --kp_index; - } - else if (kp_index < TXTINPUT_LEN) { // any other text input - kp_buf[kp_index++] = c; - } - kp_buf[kp_index] = '\0'; - draw_text_input(kp_buf); - return KP_CONTINUE; -} - -static void -keypad_click(int key) { - int c = keypads[key+1].c; // !!! Use key + 1 (zero key index used or size define) - int result = keypads[0].c == NUM_KEYBOARD ? num_keypad_click(c) : full_keypad_click(c); - if (result == KP_DONE) keypad_set_value(); // apply input done - // Exit loop on done or cancel - if (result != KP_CONTINUE) - ui_mode_normal(); -} - -static void -keypad_apply_touch(int touch_x, int touch_y) -{ - const keypad_pos_t *p = &key_pos[keypads[0].c]; - if (touch_x < p->x_offs || touch_y < p->y_offs) return; - // Calculate key position from touch x and y - touch_x-= p->x_offs; touch_x/= p->width; - touch_y-= p->y_offs; touch_y/= p->height; - uint8_t pos = (touch_y & 0x0F) | (touch_x<<4); - for (int i = 0; i < keypads[0].pos; i++) { - if (keypads[i+1].pos != pos) continue; - int old = selection; - draw_keypad_button(selection = i); // draw new focus - draw_keypad_button(old); // Erase old focus - touch_wait_release(); - selection = -1; - draw_keypad_button(i); // erase new focus - keypad_click(i); // Process input - return; - } - return; -} - -static void -ui_process_keypad_lever(uint16_t status) -{ - if (status == EVT_BUTTON_SINGLE_CLICK) { - if (selection >= 0) // Process input - keypad_click(selection); - return; - } - int keypads_last_index = keypads[0].pos - 1; - do { - int old = selection; - if ((status & EVT_DOWN) && --selection < 0) - selection = keypads_last_index; - if ((status & EVT_UP) && ++selection > keypads_last_index) - selection = 0; - draw_keypad_button(old); - draw_keypad_button(selection); - chThdSleepMilliseconds(100); - } while ((status = btn_wait_release()) != 0); -} -//========================== end keyboard input ======================= - /* * Normal plot processing */ @@ -2925,7 +3259,6 @@ ui_mode_normal(void) if (ui_mode == UI_KEYPAD) request_to_redraw(REDRAW_CLRSCR | REDRAW_AREA | REDRAW_BATTERY | REDRAW_CAL_STATUS | REDRAW_FREQUENCY); #endif - request_to_redraw(REDRAW_FREQUENCY); ui_mode = UI_NORMAL; } @@ -2937,15 +3270,8 @@ lever_move_marker(uint16_t status) uint16_t step = 1<>MARKER_SPEEDUP; - if (idx < 0) idx = 0; - } - if (status & EVT_UP) { - idx+= step>>MARKER_SPEEDUP; - if (idx > sweep_points-1) - idx = sweep_points-1 ; - } + if ((status & EVT_DOWN) && (idx-= step>>MARKER_SPEEDUP) < 0) idx = 0; + if ((status & EVT_UP ) && (idx+= step>>MARKER_SPEEDUP) > sweep_points - 1) idx = sweep_points-1; set_marker_index(active_marker, idx); redraw_marker(active_marker); step++; @@ -2967,11 +3293,10 @@ lever_search_marker(int status) // ex. 10942 -> 10000 // 6791 -> 5000 // 341 -> 200 -static uint32_t -step_round(uint32_t v) -{ +static freq_t +step_round(freq_t v) { // decade step - uint32_t nx, x = 1; + freq_t nx, x = 1; while((nx = x*10) < v) x = nx; // 1-2-5 step if (x * 2 > v) return x; @@ -2980,32 +3305,42 @@ step_round(uint32_t v) } static void -lever_frequency(uint16_t status, int mode) -{ - freq_t freq = get_sweep_frequency(mode); - if (mode == ST_SPAN){ - if (status & EVT_UP ) freq = var_freq ? (freq + var_freq) : step_round(freq*4 + 1); - if (status & EVT_DOWN) freq = var_freq ? (freq - var_freq) : step_round(freq - 1); +lever_frequency(uint16_t status) { + uint16_t mode; + freq_t freq; + if (lever_mode == LM_FREQ_0) { + if (FREQ_IS_STARTSTOP()) {mode = ST_START; freq = get_sweep_frequency(ST_START);} + else {mode = ST_CENTER;freq = get_sweep_frequency(ST_CENTER);} + } else { + if (FREQ_IS_STARTSTOP()) {mode = ST_STOP; freq = get_sweep_frequency(ST_STOP);} + else {mode = ST_SPAN; freq = get_sweep_frequency(ST_SPAN);} } - else{ - freq_t span = var_freq ? var_freq : step_round(get_sweep_frequency(ST_SPAN) / 4); - if (status & EVT_UP ) freq+= span; - if (status & EVT_DOWN) freq-= span; + if (mode == ST_SPAN && !var_freq) { + if (status & EVT_UP ) freq = step_round(freq*4 + 1); + if (status & EVT_DOWN) freq = step_round(freq - 1); + } else { + freq_t step = var_freq ? var_freq : step_round(get_sweep_frequency(ST_SPAN) / 4); + if (status & EVT_UP ) freq+= step; + if (status & EVT_DOWN) freq-= step; } - if (freq > STOP_MAX || freq < START_MIN) return; + while (btn_wait_release() != 0); + if (freq > FREQUENCY_MAX || freq < FREQUENCY_MIN) return; set_sweep_frequency(mode, freq); } -#define STEPRATIO 0.2 +#define STEPRATIO 0.2f static void lever_edelay(uint16_t status) { float value = electrical_delay; - float ratio = value > 0 ? STEPRATIO : -STEPRATIO; - if (status & EVT_UP) - value*= (1 - ratio); - if (status & EVT_DOWN) - value*= (1 + ratio); + if (current_props._var_delay == 0.0f) { + float ratio = value > 0 ? STEPRATIO : -STEPRATIO; + if (status & EVT_UP ) value*= (1.0f + ratio); + if (status & EVT_DOWN) value*= (1.0f - ratio); + } else { + if (status & EVT_UP ) value+= current_props._var_delay; + if (status & EVT_DOWN) value-= current_props._var_delay; + } set_electrical_delay(value); while (btn_wait_release() != 0); } @@ -3064,7 +3399,7 @@ static bool touch_lever_mode_select(int touch_x, int touch_y) { int mode = -1; - if (touch_y > HEIGHT) + if (touch_y > HEIGHT && (props_mode & DOMAIN_MODE) == DOMAIN_FREQ) // Only for frequency domain mode = touch_x < FREQUENCIES_XPOS2 ? LM_FREQ_0 : LM_FREQ_1; if (touch_y < UI_MARKER_Y0) mode = (touch_x < (LCD_WIDTH / 2) && electrical_delay != 0.0) ? LM_EDELAY : LM_MARKER; @@ -3074,7 +3409,7 @@ touch_lever_mode_select(int touch_x, int touch_y) // Check already selected if (select_lever_mode(mode)) return TRUE; // Call keyboard for enter - switch(mode){ + switch(mode) { case LM_FREQ_0: ui_mode_keypad(FREQ_IS_CENTERSPAN() ? KM_CENTER : KM_START); break; case LM_FREQ_1: ui_mode_keypad(FREQ_IS_CENTERSPAN() ? KM_SPAN : KM_STOP ); break; case LM_EDELAY: ui_mode_keypad(KM_EDELAY); break; @@ -3083,7 +3418,7 @@ touch_lever_mode_select(int touch_x, int touch_y) } static void -ui_process_normal_lever(uint16_t status) +ui_normal_lever(uint16_t status) { if (status & EVT_BUTTON_SINGLE_CLICK) { ui_mode_menu(); @@ -3094,38 +3429,36 @@ ui_process_normal_lever(uint16_t status) #ifdef UI_USE_LEVELER_SEARCH_MODE case LM_SEARCH: lever_search_marker(status); break; #endif - case LM_FREQ_0: lever_frequency(status, FREQ_IS_STARTSTOP() ? ST_START : ST_CENTER); break; - case LM_FREQ_1: lever_frequency(status, FREQ_IS_STARTSTOP() ? ST_STOP : ST_SPAN ); break; + case LM_FREQ_0: + case LM_FREQ_1: lever_frequency(status); break; case LM_EDELAY: lever_edelay(status); break; } } static bool -normal_apply_ref_scale(int touch_x, int touch_y){ +touch_apply_ref_scale(int touch_x, int touch_y) { int t = current_trace; // do not scale invalid or smith chart if (t == TRACE_INVALID || trace[t].type == TRC_SMITH) return FALSE; if (touch_x < UI_SCALE_REF_X0 || touch_x > UI_SCALE_REF_X1 || touch_y < OFFSETY || touch_y > AREA_HEIGHT_NORMAL) return FALSE; - float ref = trace[t].refpos; - float scale = trace[t].scale; + float ref = get_trace_refpos(t); + float scale = get_trace_scale(t); if (touch_y < GRIDY*1*NGRIDY/4) ref+=0.5f; - else if (touch_y < GRIDY*2*NGRIDY/4) {scale*=2.0f;ref=ref/2-NGRIDY/4 + NGRIDY/2;} - else if (touch_y < GRIDY*3*NGRIDY/4) {scale/=2.0f;ref=2*ref-NGRIDY + NGRIDY/2;} + else if (touch_y < GRIDY*2*NGRIDY/4) {scale*=2.0f;ref=ref/2.0f - NGRIDY/4 + NGRIDY/2;} + else if (touch_y < GRIDY*3*NGRIDY/4) {scale/=2.0f;ref=ref*2.0f - NGRIDY + NGRIDY/2;} else ref-=0.5f; - if (trace[t].scale != scale) {request_to_redraw(REDRAW_MARKER | REDRAW_GRID_VALUE); trace[t].scale = scale;} - if (trace[t].refpos != ref) {request_to_redraw(REDRAW_REFERENCE | REDRAW_GRID_VALUE); trace[t].refpos = ref;} - plot_into_index(); + set_trace_scale(t, scale); + set_trace_refpos(t, ref); chThdSleepMilliseconds(200); return TRUE; } #ifdef __USE_SD_CARD__ static bool -made_screenshot(int touch_x, int touch_y) -{ +touch_made_screenshot(int touch_x, int touch_y) { if (touch_y < HEIGHT || touch_x < FREQUENCIES_XPOS3 || touch_x > FREQUENCIES_XPOS2) return FALSE; touch_wait_release(); @@ -3135,16 +3468,16 @@ made_screenshot(int touch_x, int touch_y) #endif static void -normal_apply_touch(int touch_x, int touch_y){ +ui_normal_touch(int touch_x, int touch_y) { // Try drag marker if (touch_pickup_marker(touch_x, touch_y)) return; #ifdef __USE_SD_CARD__ // Try made screenshot - if (made_screenshot(touch_x, touch_y)) + if (touch_made_screenshot(touch_x, touch_y)) return; #endif - if (normal_apply_ref_scale(touch_x, touch_y)) + if (touch_apply_ref_scale(touch_x, touch_y)) return; // Try select lever mode (top and bottom screen) if (touch_lever_mode_select(touch_x, touch_y)) @@ -3157,22 +3490,20 @@ normal_apply_touch(int touch_x, int touch_y){ static const struct { void (*button)(uint16_t status); void (*touch)(int touch_x, int touch_y); -} ui_handler[UI_END] = { - [UI_NORMAL ] = {ui_process_normal_lever , normal_apply_touch}, - [UI_MENU ] = {ui_process_menu_lever , menu_apply_touch}, - [UI_KEYPAD ] = {ui_process_keypad_lever , keypad_apply_touch}, +} ui_handler[] = { + [UI_NORMAL ] = {ui_normal_lever , ui_normal_touch}, + [UI_MENU ] = {ui_menu_lever , ui_menu_touch}, + [UI_KEYPAD ] = {ui_keypad_lever , ui_keypad_touch}, #ifdef __SD_FILE_BROWSER__ - [UI_BROWSER] = {ui_process_browser_lever, browser_apply_touch}, + [UI_BROWSER] = {ui_browser_lever, ui_browser_touch}, #endif }; static void -ui_process_lever(void) -{ -// last_button = 0; +ui_process_lever(void) { uint16_t status = btn_check(); - if (status == 0) return; - ui_handler[ui_mode].button(status); + if (status) + ui_handler[ui_mode].button(status); } static @@ -3201,7 +3532,7 @@ ui_process(void) void handle_button_interrupt(uint16_t channel) { (void)channel; - operation_requested|=OP_LEVER; + operation_requested|= OP_LEVER; //cur_button = READ_PORT() & BUTTON_MASK; } diff --git a/usbcfg.c b/usbcfg.c index aad5f0c..bfb5d4b 100644 --- a/usbcfg.c +++ b/usbcfg.c @@ -60,7 +60,7 @@ static const uint8_t vcom_configuration_descriptor_data[67] = { 0x01, /* bConfigurationValue. */ 0, /* iConfiguration. */ 0xC0, /* bmAttributes (self powered). */ - 50), /* bMaxPower (100mA). */ + 500 / 2), /* bMaxPower in 2mA units (500mA). */ /* Interface Descriptor.*/ USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */ 0x00, /* bAlternateSetting. */ @@ -150,23 +150,24 @@ static const uint8_t vcom_string0[] = { * Vendor string. */ static const uint8_t vcom_string1[] = { - USB_DESC_BYTE(38), /* bLength. */ + USB_DESC_BYTE(24), /* bLength. */ USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ - 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0, - 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0, - 'c', 0, 's', 0 + 'n', 0, 'a', 0, 'n', 0, 'o', 0, 'v', 0, 'n', 0, 'a', 0, '.', 0, 'c', 0, 'o', 0, 'm', 0 }; /* * Device Description string. */ static const uint8_t vcom_string2[] = { - USB_DESC_BYTE(56), /* bLength. */ +#if defined(NANOVNA_F303) + USB_DESC_BYTE(22), /* bLength. */ USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ - 'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0, - 'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, - 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, - 'o', 0, 'r', 0, 't', 0 + 'N', 0, 'a', 0, 'n', 0, 'o', 0, 'V', 0, 'N', 0, 'A', 0, '-', 0, 'H', 0, '4', 0 +#else + USB_DESC_BYTE(20), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'N', 0, 'a', 0, 'n', 0, 'o', 0, 'V', 0, 'N', 0, 'A', 0, '-', 0, 'H', 0, +#endif }; /* diff --git a/vna_math.c b/vna_math.c index 5a24229..e12ab55 100644 --- a/vna_math.c +++ b/vna_math.c @@ -793,7 +793,7 @@ float vna_atan2f(float y, float x) // give 0.31 degree error r*= 0.970562748477141f - 0.189514164974601f * s; //r*= vna_fmaf(-s, 0.189514164974601f, 0.970562748477141f); -#elif 1 +#elif 0 // give 0.04 degree error r*= 0.994949366116654f - s * (0.287060635532652f - 0.078037176446441f * s); //r*= vna_fmaf(-s, vna_fmaf(-s, 0.078037176446441f, 0.287060635532652f), 0.994949366116654f); diff --git a/vna_modules/vna_browser.c b/vna_modules/vna_browser.c index d1a6b9d..312d3f9 100644 --- a/vna_modules/vna_browser.c +++ b/vna_modules/vna_browser.c @@ -1,13 +1,88 @@ +/* + * Copyright (c) 2019-2023, Dmitry (DiSlord) dislordlive@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. + */ static uint16_t file_count; static uint16_t page_count; static uint16_t current_page; +static uint16_t browser_mode; + +#define BROWSER_DELETE 1 + +// Buttons in browser +enum {FILE_BUTTON_LEFT = 0, FILE_BUTTON_RIGHT, FILE_BUTTON_EXIT, FILE_BUTTON_DEL, FILE_BUTTON_FILE}; +// Button position on screen +typedef struct { + uint16_t x; + uint16_t y; + uint16_t w; + uint8_t h; + uint8_t ofs; +} browser_btn_t; +static const browser_btn_t browser_btn[] = { + [FILE_BUTTON_LEFT] = { 0 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // < previous + [FILE_BUTTON_RIGHT]= {LCD_WIDTH/2 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // > next + [FILE_BUTTON_EXIT] = {LCD_WIDTH - 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - FONT_WIDTH)/2}, // X exit + [FILE_BUTTON_DEL] = { 0 + 0, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - 3*FONT_WIDTH)/2}, // DEL + // File button, only size and start position, must be idx = FILE_BUTTON_FILE + [FILE_BUTTON_FILE] = { 0, 0, LCD_WIDTH/FILES_COLUMNS, FILE_BUTTON_HEIGHT, 5}, +}; + +static void browser_get_button_pos(int idx, browser_btn_t *b) { + int n = idx >= FILE_BUTTON_FILE ? FILE_BUTTON_FILE : idx; +#if 0 + memcpy(b, &browser_btn[n], sizeof(browser_btn_t)); +#else + b->x = browser_btn[n].x; + b->y = browser_btn[n].y; + b->w = browser_btn[n].w; + b->h = browser_btn[n].h; + b->ofs = browser_btn[n].ofs; +#endif + if (idx > FILE_BUTTON_FILE) { // for file buttons use multiplier from start offset + idx-= FILE_BUTTON_FILE; + b->x+= b->w * (idx / FILES_ROWS); + b->y+= b->h * (idx % FILES_ROWS); + } +} + +static void browser_draw_button(int idx, const char *txt) { + if (idx < 0) return; + button_t b; + browser_btn_t btn; + browser_get_button_pos(idx, &btn); + // Mark DEL button in file delete mode + b.bg = (idx == FILE_BUTTON_DEL && (browser_mode & BROWSER_DELETE)) ? LCD_LOW_BAT_COLOR : LCD_MENU_COLOR; + b.fg = LCD_MENU_TEXT_COLOR; + b.border = (idx == selection) ? BROWSER_BUTTON_BORDER|BUTTON_BORDER_FALLING : BROWSER_BUTTON_BORDER|BUTTON_BORDER_RISE; + if (txt == NULL) b.border|= BUTTON_BORDER_NO_FILL; + draw_button(btn.x, btn.y, btn.w, btn.h, &b); + if (txt) lcd_printf(btn.x + btn.ofs, btn.y + (btn.h - FONT_STR_HEIGHT) / 2, txt); +} + static char to_lower(char c) {return (c >='A' && c <= 'Z') ? c - 'A' + 'a' : c;} + static bool strcmpi(const char *t1, const char *t2) { int i = 0; while (1) { char ch1 = to_lower(t1[i]), ch2 = to_lower(t2[i]); if (ch1 != ch2) return false; - if (ch1 == 0) return true; + if (ch1 == 0) return true; i++; } } @@ -42,19 +117,21 @@ static void browser_open_file(int sel) { if ((uint16_t)sel >= file_count) return; if (f_mount(fs_volume, "", 1) != FR_OK) return; repeat: - lcd_set_background(LCD_BG_COLOR); - lcd_set_foreground(LCD_FG_COLOR); cnt = sel; if (sd_open_dir(&dj, "", file_ext[keypad_mode]) != FR_OK) return; // open dir while (sd_findnext(&dj, &fno) == FR_OK && cnt != 0) cnt--; // skip cnt files f_closedir(&dj); if (cnt != 0) return; + // Delete file if in delete mode + if (browser_mode & BROWSER_DELETE) {f_unlink(fno.fname); return;} + const char *error = NULL; bool leave_show = true; UINT size; if (f_open(fs_file, fno.fname, FA_READ) != FR_OK) return; + lcd_set_colors(LCD_FG_COLOR, LCD_BG_COLOR); switch (keypad_mode) { /* * S1P or S2P touchstone file loader @@ -78,7 +155,7 @@ static void browser_open_file(int sel) { int nargs = parse_line(line, args, 16); // Parse line to 16 args if (nargs < 2 || args[0][0] == '#' || args[0][0] == '!') continue; // No data or comment or settings f = my_atoui(args[0]); // Get frequency - if (count >= POINTS_COUNT || f > STOP_MAX) {error = "Format err"; goto finish;} + if (count >= SWEEP_POINTS_MAX || f > FREQUENCY_MAX) {error = "Format err"; goto finish;} if (count == 0) start = f; // For index 0 set as start stop = f; // last set as stop measured[0][count][0] = my_atof(args[1]); @@ -94,18 +171,40 @@ static void browser_open_file(int sel) { } else if (c < 0x20) continue; // Others (skip) else if (j < line_size) line[j++] = (char)c; // Store + } } - } finish: - if (count != 0) { // Points count not zero, so apply data to traces - pause_sweep(); - current_props._sweep_points = count; - set_sweep_frequency(ST_START, start); - set_sweep_frequency(ST_STOP, stop); - plot_into_index(); + if (count != 0) { // Points count not zero, so apply data to traces + pause_sweep(); + current_props._sweep_points = count; + set_sweep_frequency(ST_START, start); + set_sweep_frequency(ST_STOP, stop); + request_to_redraw(REDRAW_PLOT); + } + break; } - break; +#ifdef __SD_CARD_LOAD__ + case FMT_CMD_FILE: + { + const int buffer_size = 256; + const int line_size = 128; + char *buf_8 = (char *)spi_buffer; // must be greater then buffer_size + line_size + char *line = buf_8 + buffer_size; + uint16_t j = 0, i; + while (f_read(fs_file, buf_8, buffer_size, &size) == FR_OK && size > 0) { + for (i = 0; i < size; i++) { + uint8_t c = buf_8[i]; + if (c == '\r') { // New line (Enter) + line[j] = 0; j = 0; + VNAShell_executeCMDLine(line); + } + else if (c < 0x20) continue; // Others (skip) + else if (j < line_size) line[j++] = (char)c; // Store + } + } + break; } +#endif /* * BMP file load procedure, load only device screenshots */ @@ -114,7 +213,7 @@ static void browser_open_file(int sel) { int y; leave_show = false; // allow step up/down load bitmap uint16_t *buf_16 = spi_buffer; // prepare buffer - res = f_read(fs_file, (void *)buf_16, sizeof(bmp_header_v4), &size); // read heaser + res = f_read(fs_file, (void *)buf_16, sizeof(bmp_header_v4), &size); // read header if (res != FR_OK || buf_16[9] != LCD_WIDTH || buf_16[11] != LCD_HEIGHT || buf_16[14] != 16) {error = "Format err"; break;} for (y = LCD_HEIGHT-1; y >=0 && res == FR_OK; y--) { res = f_read(fs_file, (void *)buf_16, LCD_WIDTH * sizeof(uint16_t), &size); @@ -124,6 +223,41 @@ static void browser_open_file(int sel) { lcd_printf(0, LCD_HEIGHT - 3*FONT_STR_HEIGHT, fno.fname); } break; +#ifdef __SD_CARD_DUMP_TIFF__ + case FMT_TIF_FILE: + { + int x, y; + leave_show = false; // allow step up/down load bitmap + uint8_t *buf_8 = (uint8_t *)spi_buffer; // prepare buffer + uint16_t *buf_16 = spi_buffer; + res = f_read(fs_file, (void *)buf_16, sizeof(tif_header), &size); // read header + // Quick check for valid (not parse TIFF, use hardcoded values, for less code size) + // Check header id, width, height, compression (pass only self saved images) + if (res != FR_OK || + buf_16[0] != 0x4949 || // Check header ID + buf_16[9] != LCD_WIDTH || // Check Width + buf_16[15] != LCD_HEIGHT || // Check Height + buf_16[27] != 0x8005) {error = "Format err"; break;} + for (y = 0; y < LCD_HEIGHT && res == FR_OK; y++) { + // Unpack RLE compression sequence + for (x = 0; x < LCD_WIDTH * 3;) { + int8_t data[2]; res = f_read(fs_file, data, 2, &size); // Read count and value + int count = data[0]; // count + buf_8[x++] = data[1]; // copy first value + if (count > 0) { // if count > 0 need read additional values + res = f_read(fs_file, &buf_8[x], count, &size); + x+= count; + } else while (count++ < 0) buf_8[x++] = data[1]; // if count < 0 need repeat value -count times + } + // Convert from RGB888 to RGB565 and copy to screen + for (x = 0; x < LCD_WIDTH; x++) + buf_16[x] = RGB565(buf_8[3 * x + 0], buf_8[3 * x + 1], buf_8[3 * x + 2]); + lcd_bulk(0, y, LCD_WIDTH, 1); + } + lcd_printf(0, LCD_HEIGHT - 3 * FONT_STR_HEIGHT, fno.fname); + } + break; +#endif /* * Load calibration */ @@ -134,7 +268,7 @@ static void browser_open_file(int sel) { uint32_t total = sizeof(current_props) - sizeof(magic); // Compare file size and try read magic header, if all OK load it if (fno.fsize == sizeof(current_props) && f_read(fs_file, &magic, sizeof(magic), &size) == FR_OK && - magic == PROPS_MAGIC && f_read(fs_file, src, total, &size) == FR_OK) + magic == PROPERTIES_MAGIC && f_read(fs_file, src, total, &size) == FR_OK) load_properties(NO_SAVE_SLOT); else error = "Format err"; } @@ -144,7 +278,7 @@ static void browser_open_file(int sel) { f_close(fs_file); if (error) { lcd_clear_screen(); - drawMessageBox(error, fno.fname, leave_show ? 2000 : 0); + drawMessageBox(error, fno.fname, leave_show ? 2000 : 10); } if (leave_show) return; // Process input @@ -159,9 +293,9 @@ static void browser_open_file(int sel) { if (status == EVT_TOUCH_PRESSED || status == EVT_TOUCH_DOWN) { int touch_x, touch_y; touch_position(&touch_x, &touch_y); - if (touch_x < LCD_WIDTH*1/3) key = 0; - else if (touch_x < LCD_WIDTH*2/3) key = 2; - else key = 1; + if (touch_x < LCD_WIDTH *1/3) key = 0; + else if (touch_x < LCD_WIDTH *2/3) key = 2; + else key = 1; touch_wait_release(); } chThdSleepMilliseconds(100); @@ -173,52 +307,11 @@ static void browser_open_file(int sel) { } } -#define FILE_BUTTON_OFFS 3 -typedef struct { - uint16_t x; - uint16_t y; - uint16_t w; - uint8_t h; - uint8_t ofs; -} browser_btn_t; - -static const browser_btn_t browser_btn[] = { - { 0 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // < previous - {LCD_WIDTH/2 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // > next - {LCD_WIDTH - 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - FONT_WIDTH)/2}, // X exit - // File button, only size and start position, must be idx = FILE_BUTTON_OFFS - { 0, 0, LCD_WIDTH/FILES_COLUMNS, FILE_BUTTON_HEIGHT, 5}, -}; - -static void browser_get_button_pos(int idx, browser_btn_t *b) { - int n = idx >= FILE_BUTTON_OFFS ? FILE_BUTTON_OFFS : idx; -#if 0 - memcpy(b, &browser_btn[n], sizeof(browser_btn_t)); -#else - b->x = browser_btn[n].x; - b->y = browser_btn[n].y; - b->w = browser_btn[n].w; - b->h = browser_btn[n].h; - b->ofs = browser_btn[n].ofs; -#endif - if (idx > FILE_BUTTON_OFFS) { // for file buttons use multiplier from start offset - idx-= FILE_BUTTON_OFFS; - b->x+= b->w * (idx/FILES_ROWS); - b->y+= b->h * (idx%FILES_ROWS); - } -} - -static void browser_draw_button(int idx, const char *txt) { - if (idx < 0) return; - button_t b; - browser_btn_t btn; - browser_get_button_pos(idx, &btn); - b.bg = LCD_MENU_COLOR; - b.fg = LCD_MENU_TEXT_COLOR; - b.border = (idx == selection) ? BROWSER_BUTTON_BORDER|BUTTON_BORDER_FALLING : BROWSER_BUTTON_BORDER|BUTTON_BORDER_RISE; - if (txt == NULL) b.border|= BUTTON_BORDER_NO_FILL; - draw_button(btn.x, btn.y, btn.w, btn.h, &b); - if (txt) lcd_printf(btn.x + btn.ofs, btn.y + (btn.h - FONT_STR_HEIGHT) / 2, txt); +static void browser_draw_buttons(void) { + browser_draw_button(FILE_BUTTON_DEL, "DEL"); + browser_draw_button(FILE_BUTTON_LEFT, "<"); + browser_draw_button(FILE_BUTTON_RIGHT, ">"); + browser_draw_button(FILE_BUTTON_EXIT, "X"); } static void browser_draw_page(int page) { @@ -235,7 +328,7 @@ static void browser_draw_page(int page) { int cnt = 0; uint16_t start_file = (page - 1) * FILES_PER_PAGE; lcd_set_background(LCD_MENU_COLOR); - lcd_clear_screen(); + //lcd_clear_screen(); while (sd_findnext(&dj, &fno) == FR_OK) { if (cnt >= start_file && cnt < (start_file + FILES_PER_PAGE)) { //uint16_t sec = ((fno.ftime<<1) & 0x3F); @@ -245,7 +338,7 @@ static void browser_draw_page(int page) { //uint16_t m = ((fno.fdate>>5) & 0x0F); //uint16_t year= ((fno.fdate>>9) & 0x3F) + 1980; //lcd_printf(x, y, "%2d %s %u - %u/%02u/%02u %02u:%02u:%02u", cnt, fno.fname, fno.fsize, year, m, d, h, min, sec); - browser_draw_button(cnt - start_file + FILE_BUTTON_OFFS, fno.fname); + browser_draw_button(cnt - start_file + FILE_BUTTON_FILE, fno.fname); } cnt++; if (file_count && (start_file + FILES_PER_PAGE == cnt)) break; @@ -256,37 +349,63 @@ static void browser_draw_page(int page) { file_count = cnt; page_count = cnt == 0 ? 1 : (file_count + FILES_PER_PAGE - 1) / FILES_PER_PAGE; } - browser_draw_button(0, "<"); - browser_draw_button(1, ">"); - browser_draw_button(2, "X"); + // Erase not used button + cnt-= start_file; + while(cnt < FILES_PER_PAGE) { + browser_btn_t btn; + browser_get_button_pos(cnt + FILE_BUTTON_FILE, &btn); + lcd_fill(btn.x, btn.y, btn.w, btn.h); + cnt++; + } + lcd_fill(0, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH, FILE_BOTTOM_HEIGHT); + + browser_draw_buttons(); lcd_printf(LCD_WIDTH / 2 - 3 * FONT_WIDTH, LCD_HEIGHT - (FILE_BOTTOM_HEIGHT + FONT_STR_HEIGHT) / 2, "- %u | %u -", page, page_count); return; } static void browser_key_press(int key) { - if (key >= 2) { - if (key >= FILE_BUTTON_OFFS) // Open file - browser_open_file(key - FILE_BUTTON_OFFS + (current_page - 1) * FILES_PER_PAGE); - ui_mode_normal(); // Exit - return; + int page; + switch (key) { + case FILE_BUTTON_LEFT: + case FILE_BUTTON_RIGHT: // Switch page on left / right change + page = current_page; + if (key == FILE_BUTTON_LEFT && --current_page < 1) current_page = page_count; + if (key == FILE_BUTTON_RIGHT && ++current_page > page_count) current_page = 1; + if (page != current_page) + browser_draw_page(current_page); + break; + case FILE_BUTTON_EXIT: //Exit + ui_mode_normal(); + break; + case FILE_BUTTON_DEL: // Toggle delete mode + browser_mode^= BROWSER_DELETE; + browser_draw_buttons(); + break; + case FILE_BUTTON_FILE: // Open or delete file + default: + browser_open_file(key - FILE_BUTTON_FILE + (current_page - 1) * FILES_PER_PAGE); + if (browser_mode & BROWSER_DELETE) { + file_count = 0; // Reeset file count (recalculate on draw page) + selection = -1; // Reset delection + browser_mode&=~BROWSER_DELETE; // Exit file delete mode + browser_draw_page(current_page); + return; + } + ui_mode_normal(); // Exit + break; } - // Switch page on left / right change - int page = current_page; - if (key == 0 && --current_page < 1) current_page = page_count; - if (key == 1 && ++current_page > page_count) current_page = 1; - if (page != current_page) - browser_draw_page(current_page); } static int browser_get_max(void) { // get max buttons depend from page and file count int max = current_page == page_count ? (file_count % FILES_PER_PAGE) : FILES_PER_PAGE; if (file_count > 0 && max == 0) max = FILES_PER_PAGE; - return max + FILE_BUTTON_OFFS - 1; + return max + FILE_BUTTON_FILE - 1; } // Process UI input for browser -static void browser_apply_touch(int touch_x, int touch_y) { +static void ui_browser_touch(int touch_x, int touch_y) { browser_btn_t btn; int old = selection; int max = browser_get_max(); @@ -305,7 +424,7 @@ static void browser_apply_touch(int touch_x, int touch_y) { } } -static void ui_process_browser_lever(uint16_t status) { +static void ui_browser_lever(uint16_t status) { if (status == EVT_BUTTON_SINGLE_CLICK) { if (selection >= 0) browser_key_press(selection); // Process click return; @@ -328,9 +447,10 @@ static UI_FUNCTION_CALLBACK(menu_sdcard_browse_cb) { return; set_area_size(0, 0); ui_mode = UI_BROWSER; - keypad_mode = data; + keypad_mode = fixScreenshotFormat(data); current_page = 1; file_count = 0; selection = -1; + browser_mode = 0; browser_draw_page(current_page); } diff --git a/vna_modules/vna_renorm.c b/vna_modules/vna_renorm.c deleted file mode 100644 index 9bb38be..0000000 --- a/vna_modules/vna_renorm.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@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. - */ - -#ifdef __VNA_Z_RENORMALIZATION__ -static void apply_renormalization(float data[4], uint16_t mask) -{ -// if (current_props._portz == 50.0f) return; -// S -> Z parameter -> S -// newS11 = (g*s21^2)/((1-g*s11)^2-g^2*s21^2)+((s11-g)*(1-g*s11))/((1-g*s11)^2-g^2*s21^2) -// newS21 = ((1-g*s11)*s21)/((1-g*s11)^2-g^2*s21^2)+(g*(s11-g)*s21)/((1-g*s11)^2-g^2*s21^2) -#if 0 - complexf s11 = refl; - complexf s21 = thru; - float z = current_props._portz; - float g = (z-50.f)/(z+50.f); - complexf g_s11 = 1.f - g * s11; - complexf g_s21 = g * s21; - complexf s11_g = s11 - g; - complexf denom_r = 1.f / (g_s11 * g_s11 - g_s21 * g_s21); - - refl = (g_s21 * s21 + s11_g * g_s11) * denom_r; - thru = (g_s11 * s21 + s11_g * g_s21) * denom_r; -#elif 0 - float k = (1.0f - g*g); - complexf pow = 2.0f*s11 - g*(s11*s11 - s21*s21) - g; - complexf den = 1.0f / (k - g*pow); - refl = (pow - s11*k) * den; - thru = s21*k * den; -#endif - float s11_re = mask & SWEEP_CH0_MEASURE ? data[0] : 0.0f; - float s11_im = mask & SWEEP_CH0_MEASURE ? data[1] : 0.0f; - - float s21_re = mask & SWEEP_CH1_MEASURE ? data[2] : 0.0f; - float s21_im = mask & SWEEP_CH1_MEASURE ? data[3] : 0.0f; - - float z = current_props._portz; - float g = (z - 50.f) / (z + 50.f); -#if 0 - float g_s11_re = 1.0f - g * s11_re; // 1 - g * s11 - float g_s11_im = 0.0f - g * s11_im; - - float s11_g_re = s11_re - g; // g_s11 = s11 - g - float s11_g_im = s11_im; - - float g_s21_re = g * s21_re; // g_s21 = g * s21 - float g_s21_im = g * s21_im; - -// denom_r calc - float g_s11_pow2_re = g_s11_re * g_s11_re - g_s11_im * g_s11_im; // g_s11 * g_s11 - float g_s11_pow2_im = 2 * g_s11_re * g_s11_im; - - float g_s21_pow2_re = g_s21_re * g_s21_re - g_s21_im * g_s21_im; // g_s21 * g_s21 - float g_s21_pow2_im = 2 * g_s21_re * g_s21_im; - - float denom_r_re = g_s11_pow2_re - g_s21_pow2_re; // g_s11 * g_s11 - g_s21 * g_s21 - float denom_r_im = g_s11_pow2_im - g_s21_pow2_im; - - float d = denom_r_re * denom_r_re + denom_r_im * denom_r_im; - float d_re = denom_r_re / d; // d = 1 / denom_d - float d_im =-denom_r_im / d; - - if (mask & SWEEP_CH0_MEASURE) { - float r1_re = g_s21_re * s21_re - g_s21_im * s21_im; // g_s21 * s21 - float r1_im = g_s21_re * s21_im + g_s21_im * s21_re; - - float r2_re = s11_g_re * g_s11_re - s11_g_im * g_s11_im; // s11_g * g_s11 - float r2_im = s11_g_re * g_s11_im + s11_g_im * g_s11_re; - - float r_re = r1_re + r2_re; // g_s21 * s21 + s11_g * g_s11 - float r_im = r1_im + r2_im; - - data[0] = r_re * d_re - r_im * d_im; // refl = (g_s21 * s21 + s11_g * g_s11) / denom_r - data[1] = r_re * d_im + r_im * d_re; - } - - if (mask & SWEEP_CH1_MEASURE) { - float t1_re = g_s11_re * s21_re - g_s11_im * s21_im; // g_s11 * s21 - float t1_im = g_s11_re * s21_im + g_s11_im * s21_re; - - float t2_re = s11_g_re * g_s21_re - s11_g_im * g_s21_im; // s11_g * g_s21 - float t2_im = s11_g_re * g_s21_im + s11_g_im * g_s21_re; - - float t_re = t1_re + t2_re; // g_s11 * s21 + s11_g * g_s21 - float t_im = t1_im + t2_im; - - data[2] = t_re * d_re - t_im * d_im; // thru = (g_s11 * s21 + s11_g * g_s21) / denom_r - data[3] = t_re * d_im + t_im * d_re; - } -#else - float k = (1.0f - g*g); - //complexf pow = 2.0f*s11 - g*(s11*s11 - s21*s21) - g; - float pow_re = 2.0f * s11_re - g * (s11_re * s11_re - s11_im*s11_im - s21_re * s21_re + s21_im*s21_im) - g; - float pow_im = 2.0f * (s11_im - g * (s11_re * s11_im - s21_re * s21_im)); - //complexf den = 1.0f / (k - g*pow); - float d_re = k - g * pow_re; - float d_im = g * pow_im; - float d = d_re*d_re + d_im*d_im; - d_re/= d; - d_im/= d; - //refl = (pow - s11*k) * den; - if (mask & SWEEP_CH0_MEASURE) { - float r_re = pow_re - s11_re * k; - float r_im = pow_im - s11_im * k; - data[0] = r_re * d_re - r_im * d_im; - data[1] = r_re * d_im + r_im * d_re; - } - // thru = s21*k * den; - if (mask & SWEEP_CH1_MEASURE) { - float r_re = s21_re * k; - float r_im = s21_im * k; - data[2] = r_re * d_re - r_im * d_im; - data[3] = r_re * d_im + r_im * d_re; - } -#endif -} -#endif