From a3ebb0cca17122ba7b625e1ee7f42fcd2404afea Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 21 Mar 2020 10:51:02 +0100 Subject: [PATCH 001/193] Start of conversion --- .cproject | 44 +++++++++++++++++++++++++++++++++ .project | 26 +++++++++++++++++++ .settings/language.settings.xml | 15 +++++++++++ 3 files changed, 85 insertions(+) create mode 100644 .cproject create mode 100644 .project create mode 100644 .settings/language.settings.xml diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..ec54bde --- /dev/null +++ b/.cproject @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..7f853bc --- /dev/null +++ b/.project @@ -0,0 +1,26 @@ + + + nanoVNA-Erik + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..1d1c7aa --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + From 4353721ec5e886fe28eeaef05eeccddd938ed7d0 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 22 Mar 2020 13:10:02 +0100 Subject: [PATCH 002/193] First running port --- Makefile | 5 +- NANOVNA_STM32_F072/board.h | 86 +-- dsp.c | 131 ---- ffconf.h | 193 ------ fft.h | 90 --- halconf.h | 4 +- main.c | 330 ++++++++-- mcuconf.h | 4 +- nanovna.h | 164 ++++- plot.c | 250 +++++++- sa_core.c | 1180 ++++++++++++++++++++++++++++++++++++ si4432.c | 371 ++++++++++++ si4432.h | 22 + si5351.c | 473 --------------- si5351.h | 77 --- tlv320aic3204.c | 144 ----- ui.c | 55 +- ui_sa.c | 826 +++++++++++++++++++++++++ 18 files changed, 3153 insertions(+), 1252 deletions(-) delete mode 100644 dsp.c delete mode 100644 ffconf.h delete mode 100644 fft.h create mode 100644 sa_core.c create mode 100644 si4432.c create mode 100644 si4432.h delete mode 100644 si5351.c delete mode 100644 si5351.h delete mode 100644 tlv320aic3204.c create mode 100644 ui_sa.c diff --git a/Makefile b/Makefile index bec51b8..7fdcd84 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). @@ -119,7 +120,7 @@ CSRC = $(STARTUPSRC) \ $(BOARDSRC) \ $(STREAMSSRC) \ usbcfg.c \ - main.c si5351.c tlv320aic3204.c dsp.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c flash.c adc.c + main.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c flash.c adc.c si4432.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index c64cf75..1a43c50 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -21,8 +21,8 @@ * Board identifier. */ #define BOARD_NANOVNA_STM32_F072 -#define BOARD_NAME "NanoVNA" - +#define BOARD_NAME "tinySA" +#define BOARD_VERSION 0 /* * Board frequencies. */ @@ -47,11 +47,12 @@ /* on-board */ -#define GPIOA_BUTTON 0 +#define GPIOA_PE_SEL 0 #define GPIOA_LEVER1 1 #define GPIOA_LEVER2 2 #define GPIOA_PUSH 3 -#define GPIOA_DAC2 5 +#define GPIOA_RX_SEL 4 +#define GPIOA_LO_SEL 5 #define GPIOA_XP 6 #define GPIOA_YP 7 #define GPIOA_MCO 8 @@ -74,9 +75,9 @@ #define GPIOB_I2C1_SDA 9 #define GPIOB_SD_GP2 10 #define GPIOB_SD_CS 11 -#define GPIOB_I2S2_WCLK 12 -#define GPIOB_I2S2_BCLK 13 -#define GPIOB_I2S2_MOSI 15 +#define GPIOB_SPI2_CLK 12 +#define GPIOB_SPI2_SDO 13 +#define GPIOB_SPI2_SDI 15 #define GPIOC_LED 13 @@ -115,23 +116,23 @@ * PA13 - SWDIO (alternate 0). * PA14 - SWCLK (alternate 0). */ -#define VAL_GPIOA_MODER (PIN_MODE_INPUT(0U) | \ +#define VAL_GPIOA_MODER (PIN_MODE_OUTPUT(GPIOA_PE_SEL) | \ PIN_MODE_INPUT(1U) | \ PIN_MODE_INPUT(2U) | \ PIN_MODE_INPUT(3U) | \ - PIN_MODE_INPUT(4U) | \ - PIN_MODE_ANALOG(GPIOA_DAC2) | \ + PIN_MODE_OUTPUT(GPIOA_RX_SEL) | \ + PIN_MODE_OUTPUT(GPIOA_LO_SEL) | \ PIN_MODE_ANALOG(GPIOA_XP) | \ PIN_MODE_ANALOG(GPIOA_YP) | \ PIN_MODE_ALTERNATE(GPIOA_MCO) | \ PIN_MODE_INPUT(9U) | \ PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \ - PIN_MODE_ALTERNATE(GPIOA_USB_DM) | \ - PIN_MODE_ALTERNATE(GPIOA_USB_DP) | \ + PIN_MODE_INPUT(GPIOA_USB_DM) | \ + PIN_MODE_INPUT(GPIOA_USB_DP) | \ PIN_MODE_ALTERNATE(GPIOA_JTMS) | \ PIN_MODE_ALTERNATE(GPIOA_JTCK) | \ PIN_MODE_OUTPUT(GPIOA_LCD_RESET)) -#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(0U) | \ +#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_PE_SEL) | \ PIN_OTYPE_PUSHPULL(1U) | \ PIN_OTYPE_PUSHPULL(2U) | \ PIN_OTYPE_PUSHPULL(3U) | \ @@ -147,44 +148,44 @@ PIN_OTYPE_PUSHPULL(GPIOA_JTMS) | \ PIN_OTYPE_PUSHPULL(GPIOA_JTCK) | \ PIN_OTYPE_PUSHPULL(GPIOA_LCD_RESET)) -#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_2M(0) | \ +#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_100M(GPIOA_PE_SEL) | \ PIN_OSPEED_2M(1) | \ PIN_OSPEED_2M(2) | \ PIN_OSPEED_2M(3) | \ - PIN_OSPEED_2M(4) | \ - PIN_OSPEED_2M(5) | \ + PIN_OSPEED_100M(4) | \ + PIN_OSPEED_100M(5) | \ PIN_OSPEED_2M(6) | \ PIN_OSPEED_2M(7) | \ PIN_OSPEED_100M(GPIOA_MCO) | \ PIN_OSPEED_100M(9) | \ - PIN_OSPEED_100M(GPIOA_USB_DISC) | \ + PIN_OSPEED_100M(10) | \ PIN_OSPEED_100M(GPIOA_USB_DM) | \ PIN_OSPEED_100M(GPIOA_USB_DP) | \ PIN_OSPEED_100M(GPIOA_JTMS) | \ PIN_OSPEED_100M(GPIOA_JTCK) | \ PIN_OSPEED_100M(GPIOA_LCD_RESET)) -#define VAL_GPIOA_PUPDR (PIN_PUPDR_PULLDOWN(0) | \ +#define VAL_GPIOA_PUPDR (PIN_PUPDR_PULLDOWN(GPIOA_PE_SEL) | \ PIN_PUPDR_PULLDOWN(1) | \ PIN_PUPDR_PULLDOWN(2) | \ PIN_PUPDR_PULLDOWN(3) | \ - PIN_PUPDR_PULLUP(4) | \ - PIN_PUPDR_FLOATING(5) | \ + PIN_PUPDR_PULLDOWN(4) | \ + PIN_PUPDR_PULLDOWN(5) | \ PIN_PUPDR_FLOATING(6) | \ PIN_PUPDR_FLOATING(7) | \ PIN_PUPDR_PULLUP(GPIOA_MCO) | \ PIN_PUPDR_PULLUP(9) | \ - PIN_PUPDR_FLOATING(GPIOA_USB_DISC) | \ + PIN_PUPDR_PULLUP(GPIOA_USB_DISC) | \ PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \ PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \ PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \ PIN_PUPDR_PULLDOWN(GPIOA_JTCK) | \ PIN_PUPDR_PULLDOWN(GPIOA_LCD_RESET)) -#define VAL_GPIOA_ODR (PIN_ODR_HIGH(0) | \ +#define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_PE_SEL) | \ PIN_ODR_HIGH(1) | \ PIN_ODR_HIGH(2) | \ PIN_ODR_HIGH(3) | \ PIN_ODR_HIGH(4) | \ - PIN_ODR_LOW(5) | \ + PIN_ODR_HIGH(5) | \ PIN_ODR_HIGH(6) | \ PIN_ODR_HIGH(7) | \ PIN_ODR_HIGH(GPIOA_MCO) | \ @@ -195,7 +196,7 @@ PIN_ODR_HIGH(GPIOA_JTMS) | \ PIN_ODR_HIGH(GPIOA_JTCK) | \ PIN_ODR_HIGH(GPIOA_LCD_RESET)) -#define VAL_GPIOA_AFRL (PIN_AFIO_AF(0, 0) | \ +#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PE_SEL, 0) | \ PIN_AFIO_AF(1, 0) | \ PIN_AFIO_AF(2, 0) | \ PIN_AFIO_AF(3, 0) | \ @@ -238,10 +239,10 @@ PIN_MODE_ALTERNATE(GPIOB_I2C1_SDA) | \ PIN_MODE_OUTPUT(10) | \ PIN_MODE_OUTPUT(11) | \ - PIN_MODE_ALTERNATE(GPIOB_I2S2_WCLK) | \ - PIN_MODE_ALTERNATE(GPIOB_I2S2_BCLK) | \ + PIN_MODE_OUTPUT(GPIOB_SPI2_CLK) | \ + PIN_MODE_INPUT(GPIOB_SPI2_SDO) | \ PIN_MODE_ALTERNATE(14) | \ - PIN_MODE_ALTERNATE(GPIOB_I2S2_MOSI)) + PIN_MODE_OUTPUT(GPIOB_SPI2_SDI)) #define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(0) | \ PIN_OTYPE_PUSHPULL(1) | \ PIN_OTYPE_PUSHPULL(2) | \ @@ -254,10 +255,10 @@ PIN_OTYPE_PUSHPULL(GPIOB_I2C1_SDA) | \ PIN_OTYPE_PUSHPULL(10) | \ PIN_OTYPE_PUSHPULL(11) | \ - PIN_OTYPE_PUSHPULL(GPIOB_I2S2_WCLK) | \ - PIN_OTYPE_PUSHPULL(GPIOB_I2S2_BCLK) | \ + PIN_OTYPE_PUSHPULL(GPIOB_SPI2_CLK) | \ + PIN_OTYPE_PUSHPULL(GPIOB_SPI2_SDO) | \ PIN_OTYPE_PUSHPULL(14) | \ - PIN_OTYPE_PUSHPULL(GPIOB_I2S2_MOSI)) + PIN_OTYPE_PUSHPULL(GPIOB_SPI2_SDI)) #define VAL_GPIOB_OSPEEDR (PIN_PUPDR_FLOATING(GPIOB_XN) | \ PIN_PUPDR_FLOATING(GPIOB_YN) | \ PIN_OSPEED_100M(2) | \ @@ -270,10 +271,10 @@ PIN_OSPEED_100M(GPIOB_I2C1_SDA) | \ PIN_OSPEED_100M(10) | \ PIN_OSPEED_100M(11) | \ - PIN_OSPEED_100M(GPIOB_I2S2_WCLK) | \ - PIN_OSPEED_100M(GPIOB_I2S2_BCLK) | \ + PIN_OSPEED_100M(GPIOB_SPI2_CLK) | \ + PIN_OSPEED_100M(GPIOB_SPI2_SDO) | \ PIN_OSPEED_100M(14) | \ - PIN_OSPEED_100M(GPIOB_I2S2_MOSI)) + PIN_OSPEED_100M(GPIOB_SPI2_SDI)) #define VAL_GPIOB_PUPDR (PIN_PUPDR_PULLUP(0) | \ PIN_PUPDR_PULLUP(1) | \ PIN_PUPDR_PULLUP(2) | \ @@ -286,10 +287,10 @@ PIN_PUPDR_PULLUP(GPIOB_I2C1_SDA) | \ PIN_PUPDR_PULLUP(10) | \ PIN_PUPDR_PULLUP(11) | \ - PIN_PUPDR_PULLUP(GPIOB_I2S2_WCLK) | \ - PIN_PUPDR_PULLUP(GPIOB_I2S2_BCLK) | \ + PIN_PUPDR_PULLUP(GPIOB_SPI2_CLK) | \ + PIN_PUPDR_PULLUP(GPIOB_SPI2_SDO) | \ PIN_PUPDR_PULLUP(14) | \ - PIN_PUPDR_PULLUP(GPIOB_I2S2_MOSI)) + PIN_PUPDR_PULLUP(GPIOB_SPI2_SDI)) #define VAL_GPIOB_ODR (PIN_ODR_HIGH(0) | \ PIN_ODR_HIGH(1) | \ PIN_ODR_HIGH(2) | \ @@ -302,10 +303,10 @@ PIN_ODR_HIGH(GPIOB_I2C1_SDA) | \ PIN_ODR_HIGH(10) | \ PIN_ODR_HIGH(11) | \ - PIN_ODR_HIGH(GPIOB_I2S2_WCLK) | \ - PIN_ODR_HIGH(GPIOB_I2S2_BCLK) | \ + PIN_ODR_HIGH(GPIOB_SPI2_CLK) | \ + PIN_ODR_HIGH(GPIOB_SPI2_SDO) | \ PIN_ODR_HIGH(14) | \ - PIN_ODR_HIGH(GPIOB_I2S2_MOSI)) + PIN_ODR_HIGH(GPIOB_SPI2_SDI)) #define VAL_GPIOB_AFRL (PIN_AFIO_AF(0, 0) | \ PIN_AFIO_AF(1, 0) | \ PIN_AFIO_AF(2, 0) | \ @@ -318,10 +319,10 @@ PIN_AFIO_AF(GPIOB_I2C1_SDA, 1) | \ PIN_AFIO_AF(10, 0) | \ PIN_AFIO_AF(11, 0) | \ - PIN_AFIO_AF(GPIOB_I2S2_WCLK, 0) | \ - PIN_AFIO_AF(GPIOB_I2S2_BCLK, 0) | \ + PIN_AFIO_AF(GPIOB_SPI2_CLK, 0) | \ + PIN_AFIO_AF(GPIOB_SPI2_SDO, 0) | \ PIN_AFIO_AF(14, 0) | \ - PIN_AFIO_AF(GPIOB_I2S2_MOSI, 0)) + PIN_AFIO_AF(GPIOB_SPI2_SDI, 0)) /* * GPIOC setup: * @@ -743,6 +744,7 @@ PIN_AFIO_AF(14, 0) | \ PIN_AFIO_AF(15, 0)) + #if !defined(_FROM_ASM_) #ifdef __cplusplus extern "C" { diff --git a/dsp.c b/dsp.c deleted file mode 100644 index 6e9f607..0000000 --- a/dsp.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com - * All rights reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include -#include "nanovna.h" - -#ifdef ENABLED_DUMP -int16_t samp_buf[SAMPLE_LEN]; -int16_t ref_buf[SAMPLE_LEN]; -#endif - -const int16_t sincos_tbl[48][2] = { - { 10533, 31029 }, { 27246, 18205 }, { 32698, -2143 }, { 24636, -21605 }, - { 6393, -32138 }, {-14493, -29389 }, {-29389, -14493 }, {-32138, 6393 }, - {-21605, 24636 }, { -2143, 32698 }, { 18205, 27246 }, { 31029, 10533 }, - { 31029, -10533 }, { 18205, -27246 }, { -2143, -32698 }, {-21605, -24636 }, - {-32138, -6393 }, {-29389, 14493 }, {-14493, 29389 }, { 6393, 32138 }, - { 24636, 21605 }, { 32698, 2143 }, { 27246, -18205 }, { 10533, -31029 }, - {-10533, -31029 }, {-27246, -18205 }, {-32698, 2143 }, {-24636, 21605 }, - { -6393, 32138 }, { 14493, 29389 }, { 29389, 14493 }, { 32138, -6393 }, - { 21605, -24636 }, { 2143, -32698 }, {-18205, -27246 }, {-31029, -10533 }, - {-31029, 10533 }, {-18205, 27246 }, { 2143, 32698 }, { 21605, 24636 }, - { 32138, 6393 }, { 29389, -14493 }, { 14493, -29389 }, { -6393, -32138 }, - {-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 } -}; - -int32_t acc_samp_s; -int32_t acc_samp_c; -int32_t acc_ref_s; -int32_t acc_ref_c; - -void -dsp_process(int16_t *capture, size_t length) -{ - uint32_t *p = (uint32_t*)capture; - uint32_t len = length / 2; - uint32_t i; - int32_t samp_s = 0; - int32_t samp_c = 0; - int32_t ref_s = 0; - int32_t ref_c = 0; - - for (i = 0; i < len; i++) { - uint32_t sr = *p++; - int16_t ref = sr & 0xffff; - int16_t smp = (sr>>16) & 0xffff; -#ifdef ENABLED_DUMP - ref_buf[i] = ref; - samp_buf[i] = smp; -#endif - int32_t s = sincos_tbl[i][0]; - int32_t c = sincos_tbl[i][1]; - samp_s += smp * s / 16; - samp_c += smp * c / 16; - ref_s += ref * s / 16; - ref_c += ref * c / 16; -#if 0 - uint32_t sc = *(uint32_t)&sincos_tbl[i]; - samp_s = __SMLABB(sr, sc, samp_s); - samp_c = __SMLABT(sr, sc, samp_c); - ref_s = __SMLATB(sr, sc, ref_s); - ref_c = __SMLATT(sr, sc, ref_c); -#endif - } - acc_samp_s = samp_s; - acc_samp_c = samp_c; - acc_ref_s = ref_s; - acc_ref_c = ref_c; -} - -void -calculate_gamma(float gamma[2]) -{ -#if 1 - // calculate reflection coeff. by samp divide by ref - float rs = acc_ref_s; - float rc = acc_ref_c; - float rr = rs * rs + rc * rc; - //rr = sqrtf(rr) * 1e8; - float ss = acc_samp_s; - float sc = acc_samp_c; - gamma[0] = (sc * rc + ss * rs) / rr; - gamma[1] = (ss * rc - sc * rs) / rr; -#elif 0 - gamma[0] = acc_samp_s; - gamma[1] = acc_samp_c; -#else - gamma[0] = acc_ref_s; - gamma[1] = acc_ref_c; -#endif -} - -void -fetch_amplitude(float gamma[2]) -{ - gamma[0] = acc_samp_s * 1e-9; - gamma[1] = acc_samp_c * 1e-9; -} - -void -fetch_amplitude_ref(float gamma[2]) -{ - gamma[0] = acc_ref_s * 1e-9; - gamma[1] = acc_ref_c * 1e-9; -} - -void -reset_dsp_accumerator(void) -{ - acc_ref_s = 0; - acc_ref_c = 0; - acc_samp_s = 0; - acc_samp_c = 0; -} diff --git a/ffconf.h b/ffconf.h deleted file mode 100644 index ae0d38d..0000000 --- a/ffconf.h +++ /dev/null @@ -1,193 +0,0 @@ -/* CHIBIOS FIX */ -#include "ch.h" - -/*---------------------------------------------------------------------------/ -/ FatFs - FAT file system module configuration file R0.09 (C)ChaN, 2011 -/----------------------------------------------------------------------------/ -/ -/ CAUTION! Do not forget to make clean the project after any changes to -/ the configuration options. -/ -/----------------------------------------------------------------------------*/ -#ifndef _FFCONF -#define _FFCONF 6502 /* Revision ID */ - - -/*---------------------------------------------------------------------------/ -/ Functions and Buffer Configurations -/----------------------------------------------------------------------------*/ - -#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ -/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system -/ object instead of the sector buffer in the individual file object for file -/ data transfer. This reduces memory consumption 512 bytes each file object. */ - - -#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ -/* Setting _FS_READONLY to 1 defines read only configuration. This removes -/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, -/ f_truncate and useless f_getfree. */ - - -#define _FS_MINIMIZE 0 /* 0 to 3 */ -/* The _FS_MINIMIZE option defines minimization level to remove some functions. -/ -/ 0: Full function. -/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename -/ are removed. -/ 2: f_opendir and f_readdir are removed in addition to 1. -/ 3: f_lseek is removed in addition to 2. */ - - -#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */ -/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ - - -#define _USE_MKFS 1 /* 0:Disable or 1:Enable */ -/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ - - -#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ -/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ - - -#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ -/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ - - - -/*---------------------------------------------------------------------------/ -/ Locale and Namespace Configurations -/----------------------------------------------------------------------------*/ - -#define _CODE_PAGE 1251 -/* The _CODE_PAGE specifies the OEM code page to be used on the target system. -/ Incorrect setting of the code page can cause a file open failure. -/ -/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) -/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) -/ 949 - Korean (DBCS, OEM, Windows) -/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) -/ 1250 - Central Europe (Windows) -/ 1251 - Cyrillic (Windows) -/ 1252 - Latin 1 (Windows) -/ 1253 - Greek (Windows) -/ 1254 - Turkish (Windows) -/ 1255 - Hebrew (Windows) -/ 1256 - Arabic (Windows) -/ 1257 - Baltic (Windows) -/ 1258 - Vietnam (OEM, Windows) -/ 437 - U.S. (OEM) -/ 720 - Arabic (OEM) -/ 737 - Greek (OEM) -/ 775 - Baltic (OEM) -/ 850 - Multilingual Latin 1 (OEM) -/ 858 - Multilingual Latin 1 + Euro (OEM) -/ 852 - Latin 2 (OEM) -/ 855 - Cyrillic (OEM) -/ 866 - Russian (OEM) -/ 857 - Turkish (OEM) -/ 862 - Hebrew (OEM) -/ 874 - Thai (OEM, Windows) -/ 1 - ASCII only (Valid for non LFN cfg.) -*/ - - -#define _USE_LFN 1 /* 0 to 3 */ -#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ -/* The _USE_LFN option switches the LFN support. -/ -/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect. -/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant. -/ 2: Enable LFN with dynamic working buffer on the STACK. -/ 3: Enable LFN with dynamic working buffer on the HEAP. -/ -/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN, -/ Unicode handling functions ff_convert() and ff_wtoupper() must be added -/ to the project. When enable to use heap, memory control functions -/ ff_memalloc() and ff_memfree() must be added to the project. */ - - -#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ -/* To switch the character code set on FatFs API to Unicode, -/ enable LFN feature and set _LFN_UNICODE to 1. */ - - -#define _FS_RPATH 0 /* 0 to 2 */ -/* The _FS_RPATH option configures relative path feature. -/ -/ 0: Disable relative path feature and remove related functions. -/ 1: Enable relative path. f_chdrive() and f_chdir() are available. -/ 2: f_getcwd() is available in addition to 1. -/ -/ Note that output of the f_readdir fnction is affected by this option. */ - - - -/*---------------------------------------------------------------------------/ -/ Physical Drive Configurations -/----------------------------------------------------------------------------*/ - -#define _VOLUMES 1 -/* Number of volumes (logical drives) to be used. */ - - -#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ -/* Maximum sector size to be handled. -/ Always set 512 for memory card and hard disk but a larger value may be -/ required for on-board flash memory, floppy disk and optical disk. -/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size -/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */ - - -#define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */ -/* When set to 0, each volume is bound to the same physical drive number and -/ it can mount only first primaly partition. When it is set to 1, each volume -/ is tied to the partitions listed in VolToPart[]. */ - - -#define _USE_ERASE 1 /* 0:Disable or 1:Enable */ -/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command -/ should be added to the disk_ioctl functio. */ - - - -/*---------------------------------------------------------------------------/ -/ System Configurations -/----------------------------------------------------------------------------*/ - -#define _WORD_ACCESS 1 /* 0 or 1 */ -/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS -/ option defines which access method is used to the word data on the FAT volume. -/ -/ 0: Byte-by-byte access. -/ 1: Word access. Do not choose this unless following condition is met. -/ -/ When the byte order on the memory is big-endian or address miss-aligned word -/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. -/ If it is not the case, the value can also be set to 1 to improve the -/ performance and code size. -*/ - - -/* A header file that defines sync object types on the O/S, such as -/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */ - -#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ -#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ -#define _SYNC_t Semaphore * /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ - -/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module. -/ -/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. -/ 1: Enable reentrancy. Also user provided synchronization handlers, -/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj -/ function must be added to the project. */ - - -#define _FS_SHARE 0 /* 0:Disable or >=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 dbaa32f..0000000 --- a/fft.h +++ /dev/null @@ -1,90 +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 - -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 fft256(float array[][2], const uint8_t dir) { - const uint16_t n = 256; - const uint8_t levels = 8; // log2(n) - - const uint8_t real = dir & 1; - const uint8_t imag = ~real & 1; - uint16_t i; - uint16_t size; - - 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; - } - } - - // Cooley-Tukey decimation-in-time radix-2 FFT - for (size = 2; size <= n; size *= 2) { - uint16_t halfsize = size / 2; - uint16_t tablestep = n / size; - uint16_t i; - for (i = 0; i < n; i += size) { - uint16_t j, k; - for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) { - uint16_t l = j + halfsize; - float tpre = array[l][real] * cos(2 * VNA_PI * k / 256) + array[l][imag] * sin(2 * VNA_PI * k / 256); - float tpim = -array[l][real] * sin(2 * VNA_PI * k / 256) + array[l][imag] * cos(2 * VNA_PI * k / 256); - array[l][real] = array[j][real] - tpre; - array[l][imag] = array[j][imag] - tpim; - array[j][real] += tpre; - array[j][imag] += tpim; - } - } - if (size == n) // Prevent overflow in 'size *= 2' - break; - } -} - -static inline void fft256_forward(float array[][2]) { - fft256(array, 0); -} - -static inline void fft256_inverse(float array[][2]) { - fft256(array, 1); -} diff --git a/halconf.h b/halconf.h index 38341a0..1450b9f 100644 --- a/halconf.h +++ b/halconf.h @@ -76,14 +76,14 @@ * @brief Enables the I2C subsystem. */ #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C TRUE +#define HAL_USE_I2C FALSE #endif /** * @brief Enables the I2S subsystem. */ #if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) -#define HAL_USE_I2S TRUE +#define HAL_USE_I2S FALSE #endif /** diff --git a/main.c b/main.c index fff210d..d25530c 100644 --- a/main.c +++ b/main.c @@ -21,14 +21,25 @@ #include "ch.h" #include "hal.h" #include "usbcfg.h" +#ifdef __VNA__ #include "si5351.h" +#endif #include "nanovna.h" +#ifdef __VNA__ #include "fft.h" +#endif #include #include #include +extern uint32_t minFreq; +extern uint32_t maxFreq; +uint32_t frequencyStart; +uint32_t frequencyStop; +int32_t frequencyExtra; +#define START_MIN minFreq +#define STOP_MAX maxFreq /* * Shell settings */ @@ -69,13 +80,15 @@ static volatile vna_shellcmd_t shell_function = 0; #define ENABLE_INFO_COMMAND // Enable color command, allow change config color for traces, grid, menu #define ENABLE_COLOR_COMMAND - +#ifdef __VNA__ static void apply_error_term_at(int i); static void apply_edelay_at(int i); static void cal_interpolate(int s); +#endif static void update_frequencies(void); static void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); static bool sweep(bool break_on_operation); +#ifdef __VNA__ static void transform_domain(void); #define DRIVE_STRENGTH_AUTO (-1) @@ -85,14 +98,15 @@ static void transform_domain(void); #define cal_auto_interpolate TRUE static int8_t drive_strength = DRIVE_STRENGTH_AUTO; +#endif int8_t sweep_mode = SWEEP_ENABLE; volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags // Version text, displayed in Config->Version menu, also send by info command const char *info_about[]={ BOARD_NAME, - "2016-2020 Copyright @edy555", - "Licensed under GPL. See: https://github.com/ttrftech/NanoVNA", + "2016-2020 Copyright @Erik Kaashoek", + "Licensed under GPL. See: https://github.com/erikkaashoek/tinySA", "Version: " VERSION, "Build Time: " __DATE__ " - " __TIME__, "Kernel: " CH_KERNEL_VERSION, @@ -103,7 +117,7 @@ const char *info_about[]={ 0 // sentinel }; -static THD_WORKING_AREA(waThread1, 640); +static THD_WORKING_AREA(waThread1, 700); static THD_FUNCTION(Thread1, arg) { (void)arg; @@ -129,7 +143,9 @@ static THD_FUNCTION(Thread1, arg) // Process collected data, calculate trace coordinates and plot only if scan // completed if (sweep_mode & SWEEP_ENABLE && completed) { +#ifdef __VNA__ if ((domain_mode & DOMAIN_MODE) == DOMAIN_TIME) transform_domain(); +#endif // Prepare draw graphics, cache all lines, mark screen cells for redraw plot_into_index(measured); redraw_request |= REDRAW_CELLS | REDRAW_BATTERY; @@ -166,6 +182,7 @@ toggle_sweep(void) sweep_mode ^= SWEEP_ENABLE; } +#ifdef __VNA__ static float bessel0(float x) { @@ -261,9 +278,10 @@ transform_domain(void) } } } +#endif // Shell commands output -static int shell_printf(const char *fmt, ...) +int shell_printf(const char *fmt, ...) { va_list ap; int formatted_bytes; @@ -287,9 +305,10 @@ VNA_SHELL_FUNCTION(cmd_resume) // restore frequencies array and cal update_frequencies(); +#ifdef __VNA__ if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) cal_interpolate(lastsaveid); - +#endif resume_sweep(); } @@ -316,6 +335,7 @@ VNA_SHELL_FUNCTION(cmd_reset) ; } +#ifdef __VNA__ const int8_t gain_table[] = { 0, // 0 ~ 300MHz 40, // 300 ~ 600MHz @@ -341,9 +361,12 @@ adjust_gain(uint32_t newfreq) } return 0; } +#endif int set_frequency(uint32_t freq) { + (void) freq; +#ifdef __VNA__ int delay = adjust_gain(freq); int8_t ds = drive_strength; if (ds == DRIVE_STRENGTH_AUTO) { @@ -351,6 +374,8 @@ int set_frequency(uint32_t freq) } delay += si5351_set_frequency(freq, ds); return delay; +#endif + return 1; } // Use macro, std isdigit more big @@ -467,7 +492,7 @@ static int get_str_index(char *v, const char *list) } return -1; } - +#ifdef __VNA__ VNA_SHELL_FUNCTION(cmd_offset) { if (argc != 1) { @@ -476,6 +501,7 @@ VNA_SHELL_FUNCTION(cmd_offset) } si5351_set_frequency_offset(my_atoi(argv[0])); } +#endif VNA_SHELL_FUNCTION(cmd_freq) { @@ -490,16 +516,18 @@ VNA_SHELL_FUNCTION(cmd_freq) usage: shell_printf("usage: freq {frequency(Hz)}\r\n"); } - +#ifdef __VNA__ VNA_SHELL_FUNCTION(cmd_power) { if (argc != 1) { shell_printf("usage: power {0-3|-1}\r\n"); return; } + (void)argv; drive_strength = my_atoi(argv[0]); // set_frequency(frequency); } +#endif #ifdef ENABLE_TIME_COMMAND #if HAL_USE_RTC == FALSE @@ -528,6 +556,7 @@ VNA_SHELL_FUNCTION(cmd_dac) dacPutChannelX(&DACD2, 0, value); } +#ifdef __VNA__ VNA_SHELL_FUNCTION(cmd_threshold) { uint32_t value; @@ -539,6 +568,7 @@ VNA_SHELL_FUNCTION(cmd_threshold) value = my_atoui(argv[0]); config.harmonic_freq_threshold = value; } +#endif VNA_SHELL_FUNCTION(cmd_saveconfig) { @@ -565,6 +595,7 @@ VNA_SHELL_FUNCTION(cmd_clearconfig) "Do reset manually to take effect. Then do touch cal and save.\r\n"); } +#ifdef __VNA__ static struct { int16_t rms[2]; int16_t ave[2]; @@ -587,7 +618,9 @@ int16_t dump_selection = 0; volatile int16_t wait_count = 0; float measured[2][POINTS_COUNT][2]; - +#endif +measurement_t measured; +#ifdef __VNA__ #ifdef ENABLED_DUMP static void duplicate_buffer_to_dump(int16_t *p) @@ -637,25 +670,21 @@ static const I2SConfig i2sconfig = { 0, // i2scfgr 2 // i2spr }; +#endif +#define MAX_DATA 2 VNA_SHELL_FUNCTION(cmd_data) { int i; int sel = 0; - float (*array)[2]; if (argc == 1) sel = my_atoi(argv[0]); - if (sel == 0 || sel == 1) - array = measured[sel]; - else if (sel >= 2 && sel < 7) - array = cal_data[sel-2]; - else - goto usage; - for (i = 0; i < sweep_points; i++) - shell_printf("%f %f\r\n", array[i][0], array[i][1]); - return; -usage: + if (sel >= 0 || sel <= MAX_DATA) { + for (i = 0; i < sweep_points; i++) + shell_printf("%f %f\r\n", measured[sel][i], 0.0); + return; + } shell_printf("usage: data [array]\r\n"); } @@ -718,7 +747,7 @@ VNA_SHELL_FUNCTION(cmd_gamma) shell_printf("%d %d\r\n", gamma[0], gamma[1]); } #endif - +#ifdef __VNA__ static void (*sample_func)(float *gamma) = calculate_gamma; VNA_SHELL_FUNCTION(cmd_sample) @@ -742,19 +771,22 @@ VNA_SHELL_FUNCTION(cmd_sample) usage: shell_printf("usage: sample {%s}\r\n", cmd_sample_list); } - +#endif config_t config = { .magic = CONFIG_MAGIC, .dac_value = 1922, .grid_color = DEFAULT_GRID_COLOR, .menu_normal_color = DEFAULT_MENU_COLOR, .menu_active_color = DEFAULT_MENU_ACTIVE_COLOR, - .trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR, DEFAULT_TRACE_4_COLOR }, + .trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR}, // .touch_cal = { 693, 605, 124, 171 }, // 2.4 inch LCD panel .touch_cal = { 338, 522, 153, 192 }, // 2.8 inch LCD panel .freq_mode = FREQ_MODE_START_STOP, +#ifdef __VNA__ .harmonic_freq_threshold = 300000000, - .vbat_offset = 500 +#endif + .vbat_offset = 500, + .level_offset = 0 }; properties_t current_props; @@ -762,14 +794,13 @@ properties_t *active_props = ¤t_props; // NanoVNA Default settings static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, reserved, scale, refpos - { 1, TRC_LOGMAG, 0, 0, 10.0, NGRIDY-1 }, - { 1, TRC_LOGMAG, 1, 0, 10.0, NGRIDY-1 }, - { 1, TRC_SMITH, 0, 0, 1.0, 0 }, - { 1, TRC_PHASE, 1, 0, 90.0, NGRIDY/2 } + { 0, TRC_LOGMAG, 0, 0, 10.0, (float) NGRIDY+1 }, //Temp + { 0, TRC_LOGMAG, 1, 0, 10.0, (float) NGRIDY+1 }, //Stored + { 1, TRC_LOGMAG, 2, 0, 10.0, (float) NGRIDY+1 } //Actual }; static const marker_t def_markers[MARKERS_MAX] = { - { 1, 30, 0 }, { 0, 40, 0 }, { 0, 60, 0 }, { 0, 80, 0 } + { 1, M_REFERENCE, 30, 0 }, { 0, M_DELTA, 40, 0 }, { 0, M_DELTA, 60, 0 }, { 0, M_DELTA, 80, 0 } }; // Load propeties default settings @@ -777,21 +808,29 @@ void load_default_properties(void) { //Magic add on caldata_save //current_props.magic = CONFIG_MAGIC; - current_props._frequency0 = 50000; // start = 50kHz - current_props._frequency1 = 900000000; // end = 900MHz + current_props._frequency0 = 0; // start = 0Hz + current_props._frequency1 = 350000000; // end = 350MHz + current_props._frequency_IF= 433900000, + current_props._sweep_points = POINTS_COUNT; + #ifdef VNA__ current_props._cal_status = 0; //This data not loaded by default //current_props._frequencies[POINTS_COUNT]; //current_props._cal_data[5][POINTS_COUNT][2]; //============================================= current_props._electrical_delay = 0.0; +#endif memcpy(current_props._trace, def_trace, sizeof(def_trace)); memcpy(current_props._markers, def_markers, sizeof(def_markers)); +#ifdef __VNA__ current_props._velocity_factor = 0.7; +#endif current_props._active_marker = 0; +#ifdef __VNA__ current_props._domain_mode = 0; current_props._marker_smith_format = MS_RLC; +#endif //Checksum add on caldata_save //current_props.checksum = 0; } @@ -805,9 +844,13 @@ ensure_edit_config(void) //memcpy(¤t_props, active_props, sizeof(config_t)); active_props = ¤t_props; // move to uncal state +#ifdef __VNA__ cal_status = 0; +#endif } +#include "sa_core.c" +#ifdef __VNA__ #define DSP_START(delay) wait_count = delay; #define DSP_WAIT_READY while (wait_count) __WFI(); @@ -855,6 +898,7 @@ bool sweep(bool break_on_operation) palSetPad(GPIOC, GPIOC_LED); return true; } +#endif VNA_SHELL_FUNCTION(cmd_scan) { @@ -881,8 +925,10 @@ VNA_SHELL_FUNCTION(cmd_scan) } set_frequencies(start, stop, points); +#ifdef __VNA__ if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) cal_interpolate(lastsaveid); +#endif pause_sweep(); sweep(false); // Output data after if set (faster data recive) @@ -891,8 +937,9 @@ VNA_SHELL_FUNCTION(cmd_scan) if (mask) { for (i = 0; i < points; i++) { if (mask & 1) shell_printf("%u ", frequencies[i]); - if (mask & 2) shell_printf("%f %f ", measured[0][i][0], measured[0][i][1]); - if (mask & 4) shell_printf("%f %f ", measured[1][i][0], measured[1][i][1]); + if (mask & 2) shell_printf("%f %f ", measured[0][i]); + if (mask & 4) shell_printf("%f %f ", measured[1][i]); + if (mask & 8) shell_printf("%f %f ", measured[2][i]); shell_printf("\r\n"); } } @@ -947,6 +994,7 @@ set_frequencies(uint32_t start, uint32_t stop, uint16_t points) // disable at out of sweep range for (; i < POINTS_COUNT; i++) frequencies[i] = 0; + update_rbw(frequencies[1] - frequencies[0]); } static void @@ -968,7 +1016,9 @@ update_frequencies(void) void set_sweep_frequency(int type, uint32_t freq) { +#ifdef __VNA__ int cal_applied = cal_status & CALSTAT_APPLY; +#endif // Check frequency for out of bounds (minimum SPAN can be any value) if (type != ST_SPAN && freq < START_MIN) @@ -1032,8 +1082,10 @@ set_sweep_frequency(int type, uint32_t freq) break; } update_frequencies(); +#ifdef __VNA__ if (cal_auto_interpolate && cal_applied) cal_interpolate(lastsaveid); +#endif } uint32_t @@ -1091,7 +1143,7 @@ usage: "\tsweep {%s} {freq(Hz)}\r\n", sweep_cmd); } - +#ifdef __VNA__ static void eterm_set(int term, float re, float im) { @@ -1508,13 +1560,15 @@ VNA_SHELL_FUNCTION(cmd_recall) usage: shell_printf("recall {id}\r\n"); } +#endif static const struct { const char *name; uint16_t refpos; float scale_unit; } trace_info[] = { - { "LOGMAG", NGRIDY-1, 10.0 }, + { "LOGMAG", NGRIDY, 10.0 }, +#ifdef __VNA__ { "PHASE", NGRIDY/2, 90.0 }, { "DELAY", NGRIDY/2, 1e-9 }, { "SMITH", 0, 1.00 }, @@ -1525,12 +1579,17 @@ static const struct { { "IMAG", NGRIDY/2, 0.25 }, { "R", NGRIDY/2, 100.0 }, { "X", NGRIDY/2, 100.0 } +#endif }; +#ifdef __VNA__ static const char * const trc_channel_name[] = { "CH0", "CH1" }; - +#endif +const char * const trc_channel_name[] = { + "ACTUAL", "STORED", "COMPUTED" +}; const char *get_trace_typename(int t) { return trace_info[trace[t].type].name; @@ -1666,6 +1725,7 @@ usage: } +#ifdef __VNA__ void set_electrical_delay(float picoseconds) { if (electrical_delay != picoseconds) { @@ -1690,6 +1750,7 @@ VNA_SHELL_FUNCTION(cmd_edelay) set_electrical_delay(my_atof(argv[0])); } } +#endif VNA_SHELL_FUNCTION(cmd_marker) @@ -1775,6 +1836,7 @@ VNA_SHELL_FUNCTION(cmd_frequencies) } } +#ifdef __VNA__ static void set_domain_mode(int mode) // accept DOMAIN_FREQ or DOMAIN_TIME { @@ -1839,6 +1901,7 @@ VNA_SHELL_FUNCTION(cmd_transform) usage: shell_printf("usage: transform {%s} [...]\r\n", cmd_transform_list); } +#endif VNA_SHELL_FUNCTION(cmd_test) { @@ -1896,6 +1959,7 @@ VNA_SHELL_FUNCTION(cmd_test) } } +#ifdef __VNA__ VNA_SHELL_FUNCTION(cmd_gain) { int rvalue; @@ -1956,6 +2020,7 @@ VNA_SHELL_FUNCTION(cmd_stat) // extern int awd_count; // shell_printf("awd: %d\r\n", awd_count); } +#endif #ifndef VERSION #define VERSION "unknown" @@ -2079,6 +2144,161 @@ VNA_SHELL_FUNCTION(cmd_threads) } #endif + +extern volatile int SI4432_Sel; // currently selected SI4432 +void SI4432_Write_Byte(byte ADR, byte DATA ); +byte SI4432_Read_Byte( byte ADR ); +int VFO = 0; +int points = 101; // For 's' and 'm' commands + +VNA_SHELL_FUNCTION(cmd_v) + + +{ + if (argc != 1) { + shell_printf("%d\r\n", SI4432_Sel); + return; + } + VFO = my_atoi(argv[0]); + shell_printf("VFO %d\r\n", VFO); +} + +int xtoi(char *t) +{ + + int v=0; + while (*t) { + if ('0' <= *t && *t <= '9') + v = v*16 + *t - '0'; + else if ('a' <= *t && *t <= 'f') + v = v*16 + *t - 'a' + 10; + else if ('A' <= *t && *t <= 'F') + v = v*16 + *t - 'a' + 10; + else + return v; + t++; + } + return v; +} + +VNA_SHELL_FUNCTION(cmd_x) +{ + int rvalue; + int lvalue = 0; + if (argc != 1 && argc != 2) { + shell_printf("usage: x {addr(0-95)} [value(0-FF)]\r\n"); + return; + } + rvalue = xtoi(argv[0]); + SI4432_Sel = VFO; + if (argc == 2){ + lvalue = xtoi(argv[1]); + SI4432_Write_Byte(rvalue, lvalue); + } else { + lvalue = SI4432_Read_Byte(rvalue); + shell_printf("%x\r\n", lvalue); + } +} + +VNA_SHELL_FUNCTION(cmd_i) +{ + int rvalue; + SI4432_Init(); + shell_printf("SI4432 init done\r\n"); + if (argc == 1) { + rvalue = xtoi(argv[0]); + SetRX(rvalue); + SetMode(rvalue); + shell_printf("SI4432 mode %d set\r\n", rvalue); + } +} +VNA_SHELL_FUNCTION(cmd_o) +{ + (void) argc; + int32_t value = my_atoi(argv[0]); + if (VFO == 0) + frequency_IF = value; + setFreq(VFO, value); +} + +VNA_SHELL_FUNCTION(cmd_a) +{ + (void)argc; + int32_t value = my_atoi(argv[0]); + frequencyStart = value; +} + +VNA_SHELL_FUNCTION(cmd_b) +{ + (void)argc; + int32_t value = my_atoi(argv[0]); + frequencyStop = value; +} + +VNA_SHELL_FUNCTION(cmd_t) +{ + (void)argc; + (void)argv; +} + +VNA_SHELL_FUNCTION(cmd_e) +{ + (void)argc; + extraVFO = my_atoi(argv[0]); + if (extraVFO == -1) + extraVFO = false; + else + extraVFO = true; + + if (argc >1) + frequencyExtra = my_atoi(argv[1]); +} + +VNA_SHELL_FUNCTION(cmd_s) +{ + (void)argc; + points = my_atoi(argv[0]); +} + +VNA_SHELL_FUNCTION(cmd_m) +{ + (void)argc; + (void)argv; + pause_sweep(); + int32_t f_step = (frequencyStop-frequencyStart)/ points; + palClearPad(GPIOC, GPIOC_LED); // disable led and wait for voltage stabilization + update_rbw(f_step); + chThdSleepMilliseconds(10); + streamPut(shell_stream, '{'); + for (int i = 0; i>8) & 0xFF)); + // enable led + } + streamPut(shell_stream, '}'); + palSetPad(GPIOC, GPIOC_LED); +} + +VNA_SHELL_FUNCTION(cmd_p) +{ + (void)argc; + int p = my_atoi(argv[0]); + int a = my_atoi(argv[1]); + if (p==5) + SetAttenuation(-a); +// if (p==6) +// SetMode(a); +} + +VNA_SHELL_FUNCTION(cmd_w) +{ + (void)argc; + int p = my_atoi(argv[0]); + SetRBW(p); +} //============================================================================= VNA_SHELL_FUNCTION(cmd_help); @@ -2097,7 +2317,9 @@ static const VNAShellCommand commands[] = {"version" , cmd_version , 0}, {"reset" , cmd_reset , 0}, {"freq" , cmd_freq , CMD_WAIT_MUTEX}, +#ifdef __VNA__ {"offset" , cmd_offset , 0}, +#endif #ifdef ENABLE_TIME_COMMAND {"time" , cmd_time , 0}, #endif @@ -2109,11 +2331,13 @@ static const VNAShellCommand commands[] = {"dump" , cmd_dump , 0}, #endif {"frequencies" , cmd_frequencies , 0}, +#ifdef __VNA__ {"port" , cmd_port , 0}, {"stat" , cmd_stat , 0}, {"gain" , cmd_gain , 0}, {"power" , cmd_power , 0}, {"sample" , cmd_sample , 0}, +#endif // {"gamma" , cmd_gamma , 0}, {"scan" , cmd_scan , CMD_WAIT_MUTEX}, {"sweep" , cmd_sweep , 0}, @@ -2122,19 +2346,25 @@ static const VNAShellCommand commands[] = {"touchtest" , cmd_touchtest , CMD_WAIT_MUTEX}, {"pause" , cmd_pause , 0}, {"resume" , cmd_resume , 0}, +#ifdef __VNA__ {"cal" , cmd_cal , CMD_WAIT_MUTEX}, {"save" , cmd_save , 0}, {"recall" , cmd_recall , CMD_WAIT_MUTEX}, +#endif {"trace" , cmd_trace , 0}, {"marker" , cmd_marker , 0}, +#ifdef __VNA__ {"edelay" , cmd_edelay , 0}, +#endif {"capture" , cmd_capture , CMD_WAIT_MUTEX}, {"vbat" , cmd_vbat , 0}, #ifdef ENABLE_VBAT_OFFSET_COMMAND {"vbat_offset" , cmd_vbat_offset , 0}, #endif +#ifdef __VNA__ {"transform" , cmd_transform , 0}, {"threshold" , cmd_threshold , 0}, +#endif {"help" , cmd_help , 0}, #ifdef ENABLE_INFO_COMMAND {"info" , cmd_info , 0}, @@ -2142,6 +2372,18 @@ static const VNAShellCommand commands[] = #ifdef ENABLE_COLOR_COMMAND {"color" , cmd_color , 0}, #endif + { "x", cmd_x, 0 }, + { "i", cmd_i, 0 }, + { "v", cmd_v, 0 }, + { "a", cmd_a, 0 }, + { "b", cmd_b, 0 }, + { "t", cmd_t, 0 }, + { "e", cmd_e, 0 }, + { "s", cmd_s, 0 }, + { "m", cmd_m, 0 }, + { "p", cmd_p, 0 }, + { "w", cmd_w, 0 }, + { "o", cmd_o, 0 }, #ifdef ENABLE_THREADS_COMMAND {"threads" , cmd_threads , 0}, #endif @@ -2269,6 +2511,7 @@ THD_FUNCTION(myshellThread, p) } #endif +#ifdef __VNA__ // I2C clock bus setting: depend from STM32_I2C1SW in mcuconf.h static const I2CConfig i2ccfg = { .timingr = // TIMINGR register initialization. (use I2C timing configuration tool for STM32F3xx and STM32F0xx microcontrollers (AN4235)) @@ -2296,7 +2539,7 @@ static const I2CConfig i2ccfg = { .cr1 = 0, // CR1 register initialization. .cr2 = 0 // CR2 register initialization. }; - +#endif static DACConfig dac1cfg1 = { //init: 2047U, init: 1922U, @@ -2315,8 +2558,10 @@ int main(void) //palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); //palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); +#ifdef __VNA__ i2cStart(&I2CD1, &i2ccfg); si5351_init(); +#endif // MCO on PA8 //palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(0)); @@ -2342,19 +2587,23 @@ int main(void) /* restore config */ config_recall(); + /* restore frequencies and calibration 0 slot properties from flash memory */ caldata_recall(0); - +#ifdef __VNA__ dac1cfg1.init = config.dac_value; /* * Starting DAC1 driver, setting up the output pin as analog as suggested * by the Reference Manual. */ dacStart(&DACD2, &dac1cfg1); - +#endif + setupSA(); + sweep_points = 290; /* initial frequencies */ update_frequencies(); +#ifdef __VNA__ /* * I2S Initialize */ @@ -2363,7 +2612,8 @@ int main(void) i2sObjectInit(&I2SD2); i2sStart(&I2SD2, &i2sconfig); i2sStartExchange(&I2SD2); - +#endif + area_height = AREA_HEIGHT_NORMAL; ui_init(); //Initialize graph plotting plot_init(); diff --git a/mcuconf.h b/mcuconf.h index a1da287..e04096c 100644 --- a/mcuconf.h +++ b/mcuconf.h @@ -113,7 +113,7 @@ /* * I2C driver system settings. */ -#define STM32_I2C_USE_I2C1 TRUE +#define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C2 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 3 @@ -133,7 +133,7 @@ * I2S driver system settings. */ #define STM32_I2S_USE_SPI1 FALSE -#define STM32_I2S_USE_SPI2 TRUE +#define STM32_I2S_USE_SPI2 FALSE #define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \ STM32_I2S_MODE_RX) #define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_SLAVE | \ diff --git a/nanovna.h b/nanovna.h index d553f38..1334f7c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -22,10 +22,29 @@ // Need enable HAL_USE_SPI in halconf.h #define __USE_DISPLAY_DMA__ +#define __SA__ +//#define __SIMULATION__ +//#define __PIPELINE__ +#define __SCROLL__ /* * main.c */ +#ifdef __SA__ +#define POINTS_COUNT 290 +#define MARKER_COUNT 4 + +#define TRACE_COUNT 3 +#define TRACE_ACTUAL 2 +#define TRACE_STORED 1 +#define TRACE_TEMP 0 +#define stored_t measured[TRACE_STORED] +#define actual_t measured[TRACE_ACTUAL] +#define temp_t measured[TRACE_TEMP] +typedef float measurement_t[3][POINTS_COUNT]; +extern measurement_t measured; +#endif +#ifdef __VNA__ // Minimum frequency set #define START_MIN 50000 // Maximum frequency set @@ -81,7 +100,7 @@ extern float measured[2][POINTS_COUNT][2]; void cal_collect(int type); void cal_done(void); - +#endif #define MAX_FREQ_TYPE 5 enum stimulus_type { ST_START=0, ST_STOP, ST_CENTER, ST_SPAN, ST_CW @@ -91,15 +110,24 @@ void set_sweep_frequency(int type, uint32_t frequency); uint32_t get_sweep_frequency(int type); double my_atof(const char *p); +int shell_printf(const char *fmt, ...); void toggle_sweep(void); void load_default_properties(void); +extern float perform(bool b, int i, int32_t f, int e); +enum { + AV_OFF, AV_MIN, AV_MAX, AV_2, AV_4, AV_8 +}; +enum { + M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, +}; #define SWEEP_ENABLE 0x01 #define SWEEP_ONCE 0x02 extern int8_t sweep_mode; extern const char *info_about[]; +#ifdef __VNA__ /* * dsp.c */ @@ -121,7 +149,9 @@ void reset_dsp_accumerator(void); void calculate_gamma(float *gamma); void fetch_amplitude(float *gamma); void fetch_amplitude_ref(float *gamma); +#endif +#ifdef __VNA__ /* * tlv320aic3204.c */ @@ -130,21 +160,32 @@ extern void tlv320aic3204_init(void); extern void tlv320aic3204_set_gain(int lgain, int rgain); extern void tlv320aic3204_select(int channel); +#endif /* * plot.c */ // Offset of plot area -#define OFFSETX 10 -#define OFFSETY 0 - -// WIDTH better be n*(POINTS_COUNT-1) -#define WIDTH 300 +#define OFFSETX 25 +#define OFFSETY 0 +#define BUTTON_WIDTH 66 +#ifdef __SCROLL__ +#define HEIGHT _height +extern int _height; +#define HEIGHT_SCROLL 180 +#define HEIGHT_NOSCROLL 232 +#else // HEIGHT = 8*GRIDY #define HEIGHT 232 +// WIDTH better be n*(POINTS_COUNT-1) +#endif +#define WIDTH 290 + +#define CELLWIDTH (32) +#define CELLHEIGHT (32) //#define NGRIDY 10 -#define NGRIDY 8 +#define NGRIDY 9 #define FREQUENCIES_XPOS1 OFFSETX #define FREQUENCIES_XPOS2 200 @@ -155,7 +196,7 @@ extern void tlv320aic3204_select(int channel); #define GRIDY (HEIGHT / NGRIDY) // -#define CELLOFFSETX 5 +#define CELLOFFSETX 0 #define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH + 1 + 4) #define AREA_HEIGHT_NORMAL ( HEIGHT + 1) @@ -190,7 +231,7 @@ extern const uint16_t numfont16x22[]; #define S_OHM "\036" // trace -#define TRACES_MAX 4 +#define TRACES_MAX 3 #define MAX_TRACE_TYPE 12 enum trace_type { @@ -231,13 +272,17 @@ typedef struct config { uint16_t trace_color[TRACES_MAX]; int16_t touch_cal[4]; int8_t freq_mode; +#ifdef __VNA__ uint32_t harmonic_freq_threshold; +#endif uint16_t vbat_offset; - uint8_t _reserved[22]; + int16_t level_offset; + uint8_t _reserved[24]; uint32_t checksum; } config_t; extern config_t config; +#define settingLevelOffset config.level_offset void set_trace_type(int t, int type); void set_trace_channel(int t, int channel); @@ -247,20 +292,26 @@ float get_trace_scale(int t); float get_trace_refpos(int t); const char *get_trace_typename(int t); +#ifdef __VNA void set_electrical_delay(float picoseconds); float get_electrical_delay(void); float groupdelay_from_array(int i, float array[POINTS_COUNT][2]); - +#endif // marker +enum { + M_REFERENCE, M_NORMAL, M_DELTA +}; -#define MARKERS_MAX 4 - -typedef struct marker { +typedef struct { int8_t enabled; + int8_t mtype; int16_t index; uint32_t frequency; } marker_t; + +#define MARKERS_MAX 4 + extern int8_t previous_marker; extern int8_t marker_tracking; @@ -272,7 +323,7 @@ void redraw_frame(void); void request_to_draw_cells_behind_menu(void); void request_to_draw_cells_behind_numeric_input(void); void redraw_marker(int marker); -void plot_into_index(float measured[2][POINTS_COUNT][2]); +void plot_into_index(measurement_t measured); void force_set_markmap(void); void draw_frequencies(void); void draw_all(bool flush); @@ -306,7 +357,7 @@ extern volatile uint8_t redraw_request; #define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) ) // Define size of screen buffer in pixels (one pixel 16bit size) -#define SPI_BUFFER_SIZE 2048 +#define SPI_BUFFER_SIZE 1024 #define DEFAULT_FG_COLOR RGB565(255,255,255) #define DEFAULT_BG_COLOR RGB565( 0, 0, 0) @@ -314,13 +365,16 @@ extern volatile uint8_t redraw_request; #define DEFAULT_MENU_COLOR RGB565(255,255,255) #define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0) #define DEFAULT_MENU_ACTIVE_COLOR RGB565(180,255,180) -#define DEFAULT_TRACE_1_COLOR RGB565(255,255, 0) -#define DEFAULT_TRACE_2_COLOR RGB565( 0,255,255) -#define DEFAULT_TRACE_3_COLOR RGB565( 0,255, 0) -#define DEFAULT_TRACE_4_COLOR RGB565(255, 0,255) +#define DEFAULT_TRACE_1_COLOR RGB565(255, 0, 0) /* RGB565(255,255, 0) */ +#define DEFAULT_TRACE_2_COLOR RGB565( 0,255, 0)/* RGB565( 0,255,255) */ +#define DEFAULT_TRACE_3_COLOR RGB565(255,255, 0)/* RGB565( 0,255, 0) */ +//#define DEFAULT_TRACE_4_COLOR RGB565(255, 0,255) #define DEFAULT_NORMAL_BAT_COLOR RGB565( 31,227, 0) #define DEFAULT_LOW_BAT_COLOR RGB565(255, 0, 0) #define DEFAULT_SPEC_INPUT_COLOR RGB565(128,255,128); +#define BRIGHT_COLOR_BLUE RGB565(200,200,255) +#define BRIGHT_COLOR_RED RGB565(255,200,200) +#define BRIGHT_COLOR_GREEN RGB565(200,255,200) extern uint16_t foreground_color; extern uint16_t background_color; @@ -349,6 +403,8 @@ void show_logo(void); /* * flash.c */ + +#if 0 #define SAVEAREA_MAX 5 // Begin addr 0x08018000 #define SAVE_CONFIG_AREA_SIZE 0x00008000 @@ -360,26 +416,45 @@ void show_logo(void); #define SAVE_PROP_CONFIG_2_ADDR 0x0801b800 #define SAVE_PROP_CONFIG_3_ADDR 0x0801d000 #define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 - +#else +#define SAVEAREA_MAX 4 +// Begin addr 0x0801C000 +#define SAVE_CONFIG_AREA_SIZE 0x00004000 +// config save area +#define SAVE_CONFIG_ADDR 0x0801C000 +// properties_t save area +#define SAVE_PROP_CONFIG_0_ADDR 0x0801C800 +#define SAVE_PROP_CONFIG_1_ADDR 0x0801D000 +#define SAVE_PROP_CONFIG_2_ADDR 0x0801D800 +#define SAVE_PROP_CONFIG_3_ADDR 0x0801E000 +#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 +#endif typedef struct properties { uint32_t magic; uint32_t _frequency0; uint32_t _frequency1; uint16_t _sweep_points; +#ifdef __VNA__ uint16_t _cal_status; +#endif +#ifdef __SA__ + uint32_t _frequency_IF; //IF frequency +#endif uint32_t _frequencies[POINTS_COUNT]; +#ifdef __VNA__ float _cal_data[5][POINTS_COUNT][2]; float _electrical_delay; // picoseconds - +#endif trace_t _trace[TRACES_MAX]; marker_t _markers[MARKERS_MAX]; - float _velocity_factor; // % int8_t _active_marker; +#ifdef __VNA__ uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */ uint8_t _marker_smith_format; - uint8_t _reserved[50]; +#endif + uint8_t _reserved[2]; uint32_t checksum; } properties_t; @@ -394,26 +469,34 @@ extern properties_t current_props; #define frequency0 current_props._frequency0 #define frequency1 current_props._frequency1 #define sweep_points current_props._sweep_points +#ifdef __VNA__ #define cal_status current_props._cal_status +#endif +#ifdef __SA__ +#define frequency_IF current_props._frequency_IF +#endif #define frequencies current_props._frequencies +#ifdef __VNA__ #define cal_data active_props->_cal_data #define electrical_delay current_props._electrical_delay - +#endif #define trace current_props._trace #define markers current_props._markers #define active_marker current_props._active_marker +#ifdef __VNA__ #define domain_mode current_props._domain_mode #define velocity_factor current_props._velocity_factor #define marker_smith_format current_props._marker_smith_format +#endif #define FREQ_IS_STARTSTOP() (!(config.freq_mode&FREQ_MODE_CENTER_SPAN)) #define FREQ_IS_CENTERSPAN() (config.freq_mode&FREQ_MODE_CENTER_SPAN) #define FREQ_IS_CW() (frequency0 == frequency1) - +#ifdef __VNA__ int caldata_save(int id); int caldata_recall(int id); const properties_t *caldata_ref(int id); - +#endif int config_save(void); int config_recall(void); @@ -446,7 +529,7 @@ typedef struct uistat { int8_t digit; /* 0~5 */ int8_t digit_mode; int8_t current_trace; /* 0..3 */ - uint32_t value; // for editing at numeric input area + int32_t value; // for editing at numeric input area // uint32_t previous_value; uint8_t lever_mode; uint8_t marker_delta; @@ -484,6 +567,23 @@ int16_t adc_vbat_read(void); */ int plot_printf(char *str, int, const char *fmt, ...); #define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0) +extern int settingAttenuate; +extern int settingPowerCal; +extern int stepDelay; +extern int settingSpeed; +extern int settingMode; +void update_rbw(uint32_t delta_f); + +#define byte uint8_t +extern volatile int SI4432_Sel; // currently selected SI4432 +void SI4432_Write_Byte(byte ADR, byte DATA ); +byte SI4432_Read_Byte( byte ADR ); + +void SI4432_Init(void); +float SI4432_RSSI(uint32_t i, int s); +void SI4432_Set_Frequency ( long Freq ); +float SI4432_SET_RBW(float WISH); +void SI4432_SetReference(int freq); // Speed profile definition #define START_PROFILE systime_t time = chVTGetSystemTimeX(); @@ -491,4 +591,12 @@ int plot_printf(char *str, int, const char *fmt, ...); // Macros for convert define value to string #define STR1(x) #x #define define_to_STR(x) STR1(x) + +// sa_core.c +int GetRBW(void); +int GetStorage(void); +int GetSubtractStorage(void); +int get_waterfall(void); + + /*EOF*/ diff --git a/plot.c b/plot.c index 01b1e85..325cd7d 100644 --- a/plot.c +++ b/plot.c @@ -25,22 +25,29 @@ #include "chprintf.h" #include "nanovna.h" +#ifdef __SCROLL__ +int _height = HEIGHT_NOSCROLL; +int waterfall = false; +int fullscreen = true; +#endif static void cell_draw_marker_info(int x0, int y0); static void draw_battery_status(void); +void cell_draw_test_info(int m, int n, int w, int h); +static void frequency_string(char *buf, size_t len, int32_t freq); static int16_t grid_offset; static int16_t grid_width; int16_t area_width = AREA_WIDTH_NORMAL; -int16_t area_height = AREA_HEIGHT_NORMAL; +int16_t area_height; // initialized in main() = AREA_HEIGHT_NORMAL; // Cell render use spi buffer typedef uint16_t pixel_t; pixel_t *cell_buffer = (pixel_t *)spi_buffer; // Cell size // Depends from spi_buffer size, CELLWIDTH*CELLHEIGHT*sizeof(pixel) <= sizeof(spi_buffer) -#define CELLWIDTH (64) -#define CELLHEIGHT (32) +//#define CELLWIDTH (64) // moved to nanovna.h +//#define CELLHEIGHT (32) // Check buffer size #if CELLWIDTH*CELLHEIGHT > SPI_BUFFER_SIZE #error "Too small spi_buffer size SPI_BUFFER_SIZE < CELLWIDTH*CELLHEIGH" @@ -58,6 +65,20 @@ typedef uint16_t map_t; typedef uint32_t map_t; #endif +uint16_t marker_color[3] = +{ + RGBHEX(0xFFFFFF), + RGBHEX(0x0000FF), + RGBHEX(0x00FF00) +}; + +char marker_letter[3] = +{ + 'R', + 'N', + 'D' +}; + map_t markmap[2][MAX_MARKMAP_Y]; uint8_t current_mappage = 0; @@ -107,6 +128,7 @@ void update_grid(void) redraw_request |= REDRAW_FREQUENCY; } +#ifdef __VNA__ static inline int circle_inout(int x, int y, int r) { @@ -339,7 +361,7 @@ smith_grid3(int x, int y) return 0; } #endif - +#endif #if 0 static int rectangular_grid(int x, int y) @@ -424,9 +446,10 @@ draw_on_strut(int v0, int d, int color) static float logmag(const float *v) { - return log10f(v[0]*v[0] + v[1]*v[1]) * 10; + return v[0]; // raw data is in logmag*10 format } +#ifdef __VNA_ /* * calculate phase[-2:2] of coefficient */ @@ -529,13 +552,14 @@ gamma2reactance(const float v[2]) float d = z0 / ((1-v[0])*(1-v[0])+v[1]*v[1]); return 2*v[1] * d; } +#endif static index_t -trace_into_index(int t, int i, float array[POINTS_COUNT][2]) +trace_into_index(int t, int i, float array[POINTS_COUNT]) { int y, x; - float *coeff = array[i]; + float *coeff = &array[i]; float refpos = NGRIDY - get_trace_refpos(t); float v = refpos; float scale = 1 / get_trace_scale(t); @@ -543,7 +567,8 @@ trace_into_index(int t, int i, float array[POINTS_COUNT][2]) case TRC_LOGMAG: v-= logmag(coeff) * scale; break; - case TRC_PHASE: +#ifdef __VNA__ + case TRC_PHASE: v-= phase(coeff) * scale; break; case TRC_DELAY: @@ -572,15 +597,17 @@ trace_into_index(int t, int i, float array[POINTS_COUNT][2]) case TRC_POLAR: cartesian_scale(coeff[0], coeff[1], &x, &y, scale); goto set_index; - } +#endif + } if (v < 0) v = 0; if (v > NGRIDY) v = NGRIDY; x = (i * (WIDTH) + (sweep_points-1)/2) / (sweep_points-1) + CELLOFFSETX; y = float2int(v * GRIDY); -set_index: +// set_index: return INDEX(x, y); } +#ifdef __VNA__ static void format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) { @@ -625,7 +652,9 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency) break; } } +#endif +#ifdef __VNA__ static void trace_get_value_string(int t, char *buf, int len, float array[POINTS_COUNT][2], int i) { @@ -738,7 +767,43 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT } plot_printf(buf, len, format, v); } +#endif +static void trace_get_value_string( + int t, char *buf, int len, + int i, float coeff[POINTS_COUNT], + uint32_t freq[POINTS_COUNT], + int point_count, + int ri, int mtype) +{ + (void) t; + (void)freq; + (void) point_count; + float v; + char buf2[11]; + buf2[0]=' '; + uint32_t dfreq = 0; + float rlevel = 0; + if (mtype == M_DELTA) { + if (ri > i) { + dfreq = frequencies[ri] - frequencies[i]; + buf2[0] = '-'; + } else { + dfreq = frequencies[i] - frequencies[ri]; + buf2[0] = '+'; + } + rlevel = coeff[ri]; + } else { + dfreq = frequencies[i]; + } + frequency_string(&buf2[1], sizeof(buf2) -1, dfreq); + v = logmag(&coeff[i]); + if (v == -INFINITY) + plot_printf(buf, len, "-INF"); + else + plot_printf(buf, len, " %s %.2f", buf2, v - rlevel); +} +#ifdef __VNA__ static int trace_get_info(int t, char *buf, int len) { @@ -773,6 +838,7 @@ static float distance_of_index(int idx) ((float)(frequencies[1] - frequencies[0]) * (float)FFT_SIZE * 2.0); return distance * velocity_factor; } +#endif static inline void mark_map(int x, int y) @@ -1038,7 +1104,7 @@ markmap_marker(int marker) } } -static void +void markmap_all_markers(void) { int i; @@ -1170,7 +1236,7 @@ search_nearest_index(int x, int y, int t) } void -plot_into_index(float measured[2][POINTS_COUNT][2]) +plot_into_index(measurement_t measured) { int t, i; for (t = 0; t < TRACES_MAX; t++) { @@ -1258,6 +1324,7 @@ draw_cell(int m, int n) } } } +#ifdef __VNA__ // Smith greed line (1000 system ticks for all screen calls) if (trace_type & (1 << TRC_SMITH)) { for (y = 0; y < h; y++) @@ -1281,6 +1348,7 @@ draw_cell(int m, int n) #endif #endif // PULSE; +#endif // Draw traces (50-600 system ticks for all screen calls, depend from lines // count and size) #if 1 @@ -1335,7 +1403,8 @@ draw_cell(int m, int n) if (n == 0) cell_draw_marker_info(x0, y0); #endif -// PULSE; + cell_draw_test_info(m, n, w, h); + // PULSE; // Draw reference position (<10 system ticks for all screen calls) for (t = 0; t < TRACES_MAX; t++) { if (!trace[t].enabled) @@ -1385,6 +1454,51 @@ draw_all_cells(bool flush_markmap) // clear map for next plotting clear_markmap(); } +#ifdef __SCROLL__ + if (waterfall) { + for (m = 226; m >= HEIGHT; m -= 1) { // Scroll down + uint16_t *buf = &spi_buffer[0]; + ili9341_read_memory(5*5, m, area_width, 1, area_width, buf); + ili9341_bulk(5*5,m+1, area_width,1); + } + for (int i=0; i 255) k = 255; + volatile unsigned int r=0,g=0,b=0; + if (k < 64) { + b = 255; + g = k*2 + 128; + } else if (k < 128) { + g = 255; + b = 255 - (k-64)*2; + } else if (k < 192) { + g = 255; + r = (k-128)*2 + 128; + } else + { + g = 255 - (k-192)*2; + r = 255; + } +#endif + spi_buffer[i] = RGB565(r,g,b); + } + ili9341_bulk(5*5,HEIGHT, 290,1); + } +#endif } void @@ -1464,7 +1578,7 @@ cell_drawchar(uint8_t ch, int x, int y) return ch_size; } -static void +void cell_drawstring(char *str, int x, int y) { if (y <= -FONT_GET_HEIGHT || y >= CELLHEIGHT) @@ -1476,6 +1590,7 @@ cell_drawstring(char *str, int x, int y) } } +#ifdef __VNA__ static void cell_draw_marker_info(int x0, int y0) { @@ -1601,13 +1716,93 @@ cell_draw_marker_info(int x0, int y0) cell_drawstring(buf, xpos, ypos); } } +#endif +static void cell_draw_marker_info(int x0, int y0) +{ + char buf[25]; + int t; + int ref_marker = 0; + int j = 0; + for (int i = 0; i < MARKER_COUNT; i++) { + if (markers[i].enabled && markers[i].mtype == M_REFERENCE) { + ref_marker = i; + break; + } + } + for (int i = 0; i < MARKER_COUNT; i++) { + if (!markers[i].enabled) + continue; + int idx = markers[i].index; + int ridx = markers[ref_marker].index; + for (t = TRACE_ACTUAL; t <= TRACE_ACTUAL; t++) { // Only show info on actual trace + if (!trace[t].enabled) + continue; + int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; + int k = 0; + if (i == active_marker) + buf[k++] = '\033'; // Right arrow (?) + else + buf[k++] = ' '; + buf[k++] = i+'1'; + buf[k++] = marker_letter[markers[i].mtype]; + buf[k++] = 0; + ili9341_set_foreground(marker_color[markers[i].mtype]); + cell_drawstring(buf, xpos, ypos); + trace_get_value_string( + t, buf, sizeof buf, + idx, measured[trace[t].channel], frequencies, sweep_points, ridx, markers[i].mtype); +// cell_drawstring_7x13(w, h, buf, xpos+2*7, ypos, config.trace_color[t]); + cell_drawstring(buf, xpos+2*7, ypos); + j++; + } + } +} +static void frequency_string(char *buf, size_t len, int32_t freq) +{ + if (freq < 0) { + freq = -freq; + *buf++ = '-'; + len -= 1; + } +#ifdef __VNA__ + if (freq < 1000) { + plot_printf(buf, len, "%d Hz", (int)freq); + } else if (freq < 1000000) { + plot_printf(buf, len, "%d.%03d kHz", + (int)(freq / 1000), + (int)(freq % 1000)); + } else { + plot_printf(buf, len, "%d.%03d %03d MHz", + (int)(freq / 1000000), + (int)((freq / 1000) % 1000), + (int)(freq % 1000)); + } +#endif +#ifdef __SA__ + if (freq < 1000) { + plot_printf(buf, len, "%dHz", (int)freq); + } else if (freq < 1000000) { + plot_printf(buf, len, "%d.%03dkHz", + (int)(freq / 1000), + (int)(freq % 1000)); + } else { + plot_printf(buf, len, "%d.%03dMHz", + (int)(freq / 1000000), + (int)((freq / 1000) % 1000)); + } +#endif +} + void draw_frequencies(void) { char buf1[32]; char buf2[32]; buf2[0] = 0; +#ifdef __VNA__ if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { +#endif if (FREQ_IS_CW()) { plot_printf(buf1, sizeof(buf1), " CW %qHz", get_sweep_frequency(ST_CW)); } else if (FREQ_IS_STARTSTOP()) { @@ -1617,10 +1812,12 @@ draw_frequencies(void) plot_printf(buf1, sizeof(buf1), " CENTER %qHz", get_sweep_frequency(ST_CENTER)); plot_printf(buf2, sizeof(buf2), " SPAN %qHz", get_sweep_frequency(ST_SPAN)); } +#ifdef __VNA__ } else { plot_printf(buf1, sizeof(buf1), " START 0s"); plot_printf(buf2, sizeof(buf2), "STOP %Fs (%Fm)", time_of_index(sweep_points-1), distance_of_index(sweep_points-1)); } +#endif ili9341_set_foreground(DEFAULT_FG_COLOR); ili9341_set_background(DEFAULT_BG_COLOR); ili9341_fill(0, FREQUENCIES_YPOS, 320, FONT_GET_HEIGHT, DEFAULT_BG_COLOR); @@ -1631,7 +1828,7 @@ draw_frequencies(void) ili9341_drawstring(buf1, FREQUENCIES_XPOS1, FREQUENCIES_YPOS); ili9341_drawstring(buf2, FREQUENCIES_XPOS2, FREQUENCIES_YPOS); } - +#ifdef __VNA__ void draw_cal_status(void) { @@ -1660,7 +1857,7 @@ draw_cal_status(void) if (cal_status & calibration_text[i].mask) ili9341_drawstring(&calibration_text[i].text, x, y); } - +#endif // Draw battery level #define BATTERY_TOP_LEVEL 4100 #define BATTERY_BOTTOM_LEVEL 3100 @@ -1692,7 +1889,7 @@ static void draw_battery_status(void) // string_buf[x++] = 0b10000001; string_buf[x++] = 0b11111111; // Draw battery - blit8BitWidthBitmap(1, 1, 8, x, string_buf); + blit8BitWidthBitmap(1, 200, 8, x, string_buf); } void @@ -1711,6 +1908,25 @@ redraw_frame(void) draw_cal_status(); } +int get_waterfall(void) +{ + return(waterfall); +} + +void +toggle_waterfall(void) +{ + if (!waterfall) { + _height = HEIGHT_SCROLL; + waterfall = true; + fullscreen = false; + } else { + _height = HEIGHT_NOSCROLL; + waterfall = false; + fullscreen = true; + } + request_to_redraw_grid(); +} void plot_init(void) { diff --git a/sa_core.c b/sa_core.c new file mode 100644 index 0000000..e5d66d8 --- /dev/null +++ b/sa_core.c @@ -0,0 +1,1180 @@ +// --------------------------------------------------- + +#include "SI4432.h" // comment out for simulation + +#if 0 +//-----------------SI4432 dummy------------------ +void SI4432_Write_Byte(unsigned char ADR, unsigned char DATA ) {} +unsigned char SI4432_Read_Byte(unsigned char ADR) {return ADR;} +float SI4432_SET_RBW(float WISH) {return (WISH > 600.0?600: (WISH<3.0?3:WISH));} +void SI4432_SetReference(int p) {} +void SI4432_Set_Frequency(long f) {} +void PE4302_Write_Byte(unsigned char DATA ) {} +void PE4302_init(void) {} +#endif + +#ifdef __SIMULATION__ +unsigned long seed = 123456789; +extern float rbw; +float myfrand(void) +{ + seed = (unsigned int) (1103515245 * seed + 12345) ; + return ((float) seed) / 1000000000.0; +} +#define NOISE ((myfrand()-2) * 2) // +/- 4 dBm noise +extern int settingAttenuate; + +//#define LEVEL(i, f, v) (v * (1-(fabs(f - frequencies[i])/rbw/1000))) + +float LEVEL(uint32_t i, uint32_t f, int v) +{ + float dv; + float df = fabs((float)f - (float)i); + if (df < rbw*1000) + dv = df/(rbw*1000); + else + dv = 1 + 50*(df - rbw*1000)/(rbw*1000); + return (v - dv - settingAttenuate); +} + +float Simulated_SI4432_RSSI(uint32_t i, int s) +{ + SI4432_Sel = s; + float v = -100 + log10(rbw)*10 + NOISE; + if(s == 0) { + v = fmax(LEVEL(i,10000000,-20),v); + v = fmax(LEVEL(i,20000000,-40),v); + v = fmax(LEVEL(i,30000000,-30),v); + v = fmax(LEVEL(i,40000000,-90),v); + } else { + v = fmax(LEVEL(i,320000000,-20),v); + v = fmax(LEVEL(i,340000000,-40),v); + v = fmax(LEVEL(i,360000000,-30),v); + v = fmax(LEVEL(i,380000000,-90),v); + } + return(v); +} + +#endif +//--------------------- Frequency control ----------------------- + +int dirty = true; +int scandirty = true; + +//---------------- menu system ----------------------- + +int settingAttenuate = 0; +int settingGenerate = 0; +int settingBandwidth = 0; + +//int settingLevelOffset = 0; + +int settingRefer = 1; +int refferFreq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; +int settingSpur = 0; +int settingAverage = 0; +int settingShowStorage = 0; +int settingSubtractStorage = 0; +int settingMode = 0; +int settingDrive=0; // 0-3 , 3=+20dBm +int settingAGC = true; +int settingLNA = false; +int extraVFO = false; + +uint32_t minFreq = 0; +uint32_t maxFreq = 350000000; + +void set_refer_output(int v) +{ + settingRefer = v; + dirty = true; +} + +int get_refer_output(void) +{ + return(settingRefer); +} + +void SetGenerate(int g) +{ + settingGenerate = g; + dirty = true; +} + +int GetMode(void) +{ + return(settingMode); +} + +void SetMode(int m) +{ + settingMode = m; + switch(m) { + case M_LOW: + case M_GENLOW: + minFreq = 0; + maxFreq = 520000000; + set_sweep_frequency(ST_START, (int32_t) 0); + set_sweep_frequency(ST_STOP, (int32_t) 300000000); + break; + case M_HIGH: + case M_GENHIGH: + minFreq = 260000000; + maxFreq = 960000000; + set_sweep_frequency(ST_START, (int32_t) 300000000); + set_sweep_frequency(ST_STOP, (int32_t) 960000000); + break; + } + dirty = true; +} + + +void SetAttenuation(int a) +{ + settingAttenuate = a; + dirty = true; +} + +void SetStorage(void) +{ + for (int i=0; i -150) { + tft.fillRect(oX+100, 0, 100, 8-1, DISPLAY_BLACK); + tft.setCursor(oX + 100,0); // Start at top-left corner + tft.setTextColor(DISPLAY_WHITE); // Draw white text + tft.print("Max="); + tft.print((int)((peakLevel/ 2.0 - settingAttenuate) - 120.0)+settingLevelOffset); + tft.print("dB, "); + tft.print(peakFreq/ 1000000.0); + tft.print("MHz"); + } + + if (old_settingAverage != settingAverage || abs(old_settingSpur) != abs(settingSpur)) { + int x = tft.width() - 60; + tft.fillRect( x, 0, 60, oY-2, DISPLAY_BLACK); + tft.setTextColor(DISPLAY_WHITE); // Draw white text + if (settingAverage) { + tft.setCursor( x,0); // Start at top-left corner + tft.print("AVR:"); + tft.print(averageText[settingAverage]); + } + if (settingSpur) { + tft.setCursor(x,8); // Start at top-left corner + tft.print("SPUR:"); + tft.print("ON"); + } + old_settingAverage = settingAverage; + old_settingSpur = settingSpur; + } + + + + /* + for (int i=0; i= Y_GRID * dY) f = Y_GRID * dY-1; + if (f < 0) f = 0; + double f2 = ((actual_t[i+1] / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; + f2 = (f2 - settingMin) * Y_GRID * dY / delta; + if (f2 >= Y_GRID * dY) f2 = Y_GRID * dY-1; + if (f2 < 0) f2 = 0; + int x = i; + int Y1 = Y_GRID * dY - 1 - (int)f; + int Y2 = Y_GRID * dY - 1 - (int)f2; + tft.drawLine(x+oX, oY+Y1, x+oX+1, oY+Y2, DISPLAY_YELLOW); +// tft.drawLine(x+oX, oY+Y1+1, x+oX+1, oY+Y2, DISPLAY_YELLOW); + } + + + */ + sendDisplay(); +} + +void DisplayPoint(unsigned char *data, int i, int color) +{ + if (i == 0) + return; + int x = i-1; + int delta=settingMax - settingMin; + double f = ((data[x] / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; + f = (f - settingMin) * Y_GRID * dY / delta; + if (f >= Y_GRID * dY) f = Y_GRID * dY-1; + if (f < 0) f = 0; + double f2 = ((data[x+1] / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; + f2 = (f2 - settingMin) * Y_GRID * dY / delta; + if (f2 >= Y_GRID * dY) f2 = Y_GRID * dY-1; + if (f2 < 0) f2 = 0; + int Y1 = Y_GRID * dY - 1 - (int)f; + int Y2 = Y_GRID * dY - 1 - (int)f2; + DrawDirty(x,min(Y2,Y1)); + DrawDirty(x+1,min(Y2,Y1)); + tft.drawLine(x+oX, oY+Y1, x+oX+1, oY+Y2, color); + // tft.drawLine(x+oX, oY+Y1+1, x+oX+1, oY+Y2, DISPLAY_YELLOW); + sendDisplay(); +} + +void DisplayPeakData(void) +{ + double f = ((((float)actual_t[peakIndex]) / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; + int delta=settingMax - settingMin; + f = (f - settingMin) * Y_GRID * dY / delta; + if (f >= Y_GRID * dY) f = Y_GRID * dY-1; + if (f < 0) f = 0; + int Y1 = Y_GRID * dY - 1 - (int)f; + tft.setCursor(oX+peakIndex+5,oY+Y1); // Start at top-left corner + tft.setTextColor(DISPLAY_WHITE); // Draw white text + tft.print(peakFreq/ 1000000.0); + tft.setCursor(oX+peakIndex+5,oY+Y1+8); // Start at top-left corner + tft.print((int)((peakLevel/ 2.0 - settingAttenuate) - 120.0)+settingLevelOffset); + tft.print("dB"); + for (int x=peakIndex+5;x=0) { + SI4432_Sel = V; +#ifdef USE_SI4463 + if (SI4432_Sel == 2) { + freq = freq - 433000000; + freq = freq / 10000; //convert to 10kHz channel starting with 433MHz + // Serial.print("Set frequency Si4463 = "); + // Serial.println(freq); + Si446x_RX ((uint8_t)freq); + } + else +#endif + SI4432_Set_Frequency(freq); + } +} + +void SetSwitchTransmit(void) { + SI4432_Write_Byte(0x0b, 0x1f);// Set switch to transmit + SI4432_Write_Byte(0x0c, 0x1d); +} + +void SetSwitchReceive(void) { + SI4432_Write_Byte(0x0b, 0x1d);// Set switch to receive + SI4432_Write_Byte(0x0c, 0x1f); +} + +void SetAGCLNA(void) { + unsigned char v = 0x40; + if (settingAGC) v |= 0x20; + if (settingLNA) v |= 0x10; + SI4432_Write_Byte(0x69, v); +} + +void SetRX(int m) +{ +switch(m) { +case M_LOW: // Mixed into 0 + SI4432_Sel = 0; + SI4432_Receive(); + SetSwitchReceive(); + SetAGCLNA(); + + SI4432_Sel = 1; + SetSwitchReceive(); +// SI4432_Receive(); For noise testing only + SI4432_Transmit(settingDrive); + // SI4432_SetReference(settingRefer); + break; +case M_HIGH: // Direct into 1 + // SI4432_SetReference(-1); // Stop reference output + SI4432_Sel = 0; // both as receiver to avoid spurs + SetSwitchReceive(); + SI4432_Receive(); + + SI4432_Sel = 1; + SI4432_Receive(); + SetSwitchReceive(); + SetAGCLNA(); + + break; +case M_GENLOW: // Mixed output from 0 + SI4432_Sel = 0; + SetSwitchTransmit(); + SI4432_Transmit(settingDrive); + + SI4432_Sel = 1; + SetSwitchReceive(); + SI4432_Transmit(settingDrive); + + break; +case M_GENHIGH: // Direct output from 1 + SI4432_Sel = 0; + SI4432_Receive(); + SetSwitchReceive(); + + SI4432_Sel = 1; + SetSwitchTransmit(); + SI4432_Transmit(settingDrive); + + break; + } +} + +void update_rbw(uint32_t delta_f) +{ + vbw = (delta_f)/1000.0; + rbw = settingBandwidth; +// float old_rbw = rbw; + if (rbw == 0) + rbw = 2*vbw; + if (rbw < 2.6) + rbw = 2.6; + if (rbw > 600) + rbw = 600; + SI4432_Sel = (settingMode & 1); + rbw = SI4432_SET_RBW(rbw); + vbwSteps = ((int)(2 * vbw / rbw)); + if (vbwSteps < 1) + vbwSteps = 1; + dirty = true; +} + +float perform(bool break_on_operation, int i, int32_t f, int extraV) +{ + long local_IF = ((settingMode & 1) == 0?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); + if (i == 0) { + if (settingSpeed == 0){ + if (rbw < 10.0) + stepDelay = 2500; + else if (rbw <30.0) + stepDelay = 2000; + else if (rbw <100.0) + stepDelay = 1000; + else + stepDelay = 500; + } else + stepDelay = settingSpeed; + +// setupSA(); + + int p = settingAttenuate * 2; + PE4302_Write_Byte(p); + SetRX(settingMode); + SI4432_SetReference(settingRefer); + temppeakLevel = -150; + setFreq (0, local_IF); + if (dirty) { + scandirty = true; + dirty = false; + } + } + volatile int subSteps = ((int)(2 * vbw / rbw)); + float RSSI = -150.0; + int t = 0; + do { + int lf = (uint32_t)(f + (int)(t * 500 * rbw)); + if (extraV) + setFreq (0, local_IF + lf - refferFreq[settingRefer]); // Offset so fundamental of reffer is visible + setFreq (1, local_IF + lf); + float subRSSI = SI4432_RSSI(lf, (settingMode & 1))+settingLevelOffset+settingAttenuate; + if (RSSI < subRSSI) + RSSI = subRSSI; + t++; + if (operation_requested && break_on_operation) + subSteps = 0; // abort + } while (subSteps-- > 0); + return(RSSI); +#if 0 + temp_t[i] = RSSI; + if (settingSubtractStorage) { + RSSI = RSSI - stored_t[i] ; + } + if (scandirty || settingAverage == AV_OFF) + actual_t[i] = RSSI; + else { + switch(settingAverage) { + case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; + case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; + case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; + case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; + case AV_8: actual_t[i] = (actual_t[i]*7 + RSSI) / 8.0; break; + } + } + if (frequencies[i] > 1000000) { + if (temppeakLevel < actual_t[i]) { + temppeakIndex = i; + temppeakLevel = actual_t[i]; + } + } + if (temp_t[i] == 0) { + SI4432_Init(); + } + if (i == POINTS_COUNT -1) { + if (scandirty) { + scandirty = false; + } + peakIndex = temppeakIndex; + peakLevel = actual_t[peakIndex]; + peakFreq = frequencies[peakIndex]; + settingSpur = -settingSpur; + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; +// redraw_marker(peak_marker, FALSE); + + + } +#endif +} + +// main loop for measurement +static bool sweep(bool break_on_operation) +{ + float RSSI; + palClearPad(GPIOC, GPIOC_LED); + for (int i = 0; i < sweep_points; i++) { +again: + RSSI = perform(break_on_operation, i, frequencies[i], extraVFO); + if (settingSpur == 1) + temp_t[i] = RSSI; + else + { + if (settingSpur == -1) + RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); + temp_t[i] = RSSI; + if (settingSubtractStorage) { + RSSI = RSSI - stored_t[i] ; + } + // stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace + if (scandirty || settingAverage == AV_OFF) + actual_t[i] = RSSI; + else { + switch(settingAverage) { + case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; + case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; + case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; + case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; + case AV_8: actual_t[i] = (actual_t[i]*7 + RSSI) / 8.0; break; + } + } + if (frequencies[i] > 1000000) { + if (temppeakLevel < actual_t[i]) { + temppeakIndex = i; + temppeakLevel = actual_t[i]; + } + } + } + if (i == sweep_points -1) { + if (settingSpur == 1) { + settingSpur = -1; + i = 0; + goto again; + } + if (scandirty) { + scandirty = false; + } + peakIndex = temppeakIndex; + peakLevel = actual_t[peakIndex]; + peakFreq = frequencies[peakIndex]; + settingSpur = -settingSpur; + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; + // redraw_marker(peak_marker, FALSE); + + + } + // back to toplevel to handle ui operation + if (operation_requested && break_on_operation) + return false; + } + palSetPad(GPIOC, GPIOC_LED); + return true; +} + + +#if 0 +void PeakSearch() +{ +#define PEAKSTACK 4 +#define PEAKDISTANCE 10 + int level = 0; + int searchLeft[PEAKSTACK]; + int peakIndex[PEAKSTACK]; + int peak_marker = 0; + searchLeft[level] = true; + peakIndex[level] = markers[peak_marker].index; + level++; + searchLeft[level] = true; + int peakFrom; + int peakTo; + while (peak_marker < 4){ + if (searchLeft[level]) + { + int fromLevel = level; + while (fromLevel > 0 && searchLeft[fromLevel]) + fromLevel-- + if(fromLevel == 0) { + peakFrom = PEAKDISTANCE; + } else { + peakFrom = peakIndex[fromLevel] + PEAKDISTANCE; + } + peakTo = peakIndex[level] - PEAKDISTANCE; + } else { + int toLevel = level; + while (toLevel > 0 && !searchLeft[toLevel]) + toLevel-- + if(toLevel == 0) { + peakTo = POINTS_COUNT - 1 - PEAKDISTANCE; + } else { + peakTo = peakIndex[fromLevel] - PEAKDISTANCE; + } + peakFrom = peakIndex[level] + PEAKDISTANCE; + } + float peakMax = actual_t[peakFrom]; + int peakIndex = peakFrom; + for (int i = peakFrom; i < peakTo; i++) { + if (peakMax < actual_t[i]) { + peakMax = actual_t[i]; + peakIndex = i; + } + } + + + peakIndex = temppeakIndex; + peakLevel = actual_t[peakIndex]; + peakFreq = frequencies[peakIndex]; + settingSpur = -settingSpur; + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; +// redraw_marker(peak_marker, FALSE); + + +} + +} +#endif + +char *averageText[] = { "OFF", "MIN", "MAX", "2", "4", "8"}; +char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; +int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; + +void draw_cal_status(void) +{ +#define BLEN 10 + char buf[BLEN]; +#define YSTEP 8 + int x = 0; + int y = OFFSETY; + unsigned int color; + +#define XSTEP 40 + +// if (!sweep_enabled) +// perform(true, 0, frequencies[0], false); + + ili9341_fill(x, y, OFFSETX, HEIGHT, 0x0000); + ili9341_set_background(DEFAULT_BG_COLOR); + + int yMax = (NGRIDY - get_trace_refpos(0)) * get_trace_scale(0); + plot_printf(buf, BLEN, "%ddB", yMax); + buf[5]=0; + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_drawstring(buf, x, y); + + y += YSTEP*2; + plot_printf(buf, BLEN, "%ddB/",(int)get_trace_scale(0)); + ili9341_drawstring(buf, x, y); + + if (settingAttenuate) { + ili9341_set_foreground(BRIGHT_COLOR_GREEN); + y += YSTEP*2; + ili9341_drawstring("Attn:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "-%ddB", settingAttenuate); + buf[5]=0; + ili9341_drawstring(buf, x, y); + } + + if (settingAverage>0) { + ili9341_set_foreground(BRIGHT_COLOR_BLUE); + y += YSTEP*2; + ili9341_drawstring("Aver:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "%s",averageText[settingAverage]); + buf[5]=0; + ili9341_drawstring(buf, x, y); + } + + if (settingSpur) { + ili9341_set_foreground(BRIGHT_COLOR_BLUE); + y += YSTEP*2; + ili9341_drawstring("Spur:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "ON"); + ili9341_drawstring(buf, x, y); + } + + if (settingBandwidth) + color = BRIGHT_COLOR_GREEN; + else + color = DEFAULT_FG_COLOR; + ili9341_set_foreground(color); + + y += YSTEP*2; + ili9341_drawstring("RBW:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "%dkHz", (int)rbw); + buf[5]=0; + ili9341_drawstring(buf, x, y); + + ili9341_set_foreground(DEFAULT_FG_COLOR); + y += YSTEP*2; + ili9341_drawstring("VBW:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "%dkHz",(int)vbw); + buf[5]=0; + ili9341_drawstring(buf, x, y); + + y += YSTEP*2; + ili9341_drawstring("Scan:", x, y); + + y += YSTEP; + int32_t t = (int)((2* vbwSteps * sweep_points * ( stepDelay / 100) )) /10 * (settingSpur ? 2 : 1); // in mS + if (t>1000) + plot_printf(buf, BLEN, "%dS",(t+500)/1000); + else + plot_printf(buf, BLEN, "%dmS",t); + + buf[5]=0; + ili9341_drawstring(buf, x, y); + + + if (settingRefer >= 0) { + ili9341_set_foreground(BRIGHT_COLOR_RED); + y += YSTEP*2; + ili9341_drawstring("Ref:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "%dMHz",refMHz[settingRefer]); + buf[5]=0; + ili9341_drawstring(buf, x, y); + } + + y = HEIGHT-7 + OFFSETY; + plot_printf(buf, BLEN, "%ddB", (int)(yMax - get_trace_scale(0) * NGRIDY)); + buf[5]=0; + ili9341_set_foreground(DEFAULT_FG_COLOR); + ili9341_drawstring(buf, x, y); + +} + +// -------------------- Self testing ------------------------------------------------- + +enum { + TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT +}; + +enum { + TP_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ +}; + +#define TEST_COUNT 7 + +static const struct { + int kind; + int setup; + uint32_t center; // In MHz + int span; // In MHz + float pass; + int width; + float stop; +} test_case [TEST_COUNT] = +{// Condition Preparation Center Span Pass Width Stop + {TC_SIGNAL, TP_10MHZ, 10, 7, -30, 30, -85 }, + {TC_SIGNAL, TP_10MHZ, 20, 7, -50, 30, -90 }, + {TC_SIGNAL, TP_10MHZ, 30, 7, -40, 30, -90 }, + {TC_BELOW, TP_SILENT, 200, 100, -80, 0, 0}, + {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -30, 50, -80 }, + {TC_FLAT, TP_10MHZEXTRA, 10, 4, -35, 20, -80}, + {TC_SIGNAL, TP_30MHZ, 360, 18, -70, 20, -100 }, +}; + +enum { + TS_WAITING, TS_PASS, TS_FAIL, TS_CRITICAL +}; +static const char *(test_text [4]) = +{ + "Waiting", "Pass", "Fail", "Critical" +}; +static const char *(test_fail_cause [TEST_COUNT]); + +static int test_status[TEST_COUNT]; +static int show_test_info = FALSE; +static volatile int test_wait = false; + +static void test_acquire(int i) +{ + pause_sweep(); + if (test_case[i].center < 300) + settingMode = 0; + else + settingMode = 1; + + set_sweep_frequency(ST_CENTER, (int32_t)test_case[i].center * 1000000); + set_sweep_frequency(ST_SPAN, (int32_t)test_case[i].span * 1000000); + sweep(false); + plot_into_index(measured); + redraw_request |= REDRAW_CELLS | REDRAW_FREQUENCY; +} + +extern void cell_drawstring_5x7(int w, int h, char *str, int x, int y, uint16_t fg); +extern void cell_drawstring_7x13(int w, int h, char *str, int x, int y, uint16_t fg); + +void cell_draw_test_info(int m, int n, int w, int h) +{ +#define INFO_SPACING 13 + char buf[35]; + if (!show_test_info) + return; + for (int i = -1; i < TEST_COUNT+1; i++) { + int xpos = 25; + int ypos = 40+i*INFO_SPACING; + xpos -= m * CELLWIDTH -CELLOFFSETX; + ypos -= n * CELLHEIGHT; + unsigned int color = RGBHEX(0xFFFFFF); + if (i == -1) { + plot_printf(buf, sizeof buf, "Self test status:"); + } else if (i == TEST_COUNT) { + if (test_wait) + plot_printf(buf, sizeof buf, "Touch screen to continue"); + else + buf[0] = 0; + } else { + plot_printf(buf, sizeof buf, "Test %d: %s%s", i+1, test_fail_cause[i], test_text[test_status[i]] ); + if (test_status[i] == TS_PASS) + color = RGBHEX(0x00FF00); + else if (test_status[i] == TS_CRITICAL) + color = RGBHEX(0xFFFF00); + else if (test_status[i] == TS_FAIL) + color = RGBHEX(0xFF7F7F); + else + color = RGBHEX(0x0000FF); + } + cell_drawstring(buf, xpos, ypos, color); + } +} + +#define fabs(X) ((X)<0?-(X):(X)) + +int validate_peak_within(int i, float margin) +{ + if (fabs(peakLevel-test_case[i].pass) > margin) + return false; + return(test_case[i].center * 1000000 - 100000 < peakFreq && peakFreq < test_case[i].center * 1000000 + 100000 ); +} + +int validate_peak_below(int i, float margin) { + return(test_case[i].pass - peakLevel > margin); +} + +int validate_below(void) { + int status = TS_PASS; + for (int j = 0; j < POINTS_COUNT; j++) { + if (actual_t[j] > stored_t[j] - 5) + status = TS_CRITICAL; + else if (actual_t[j] > stored_t[j]) { + status = TS_FAIL; + break; + } + } + return(status); +} + +int validate_flatness(int i) { + volatile int j; + for (j = peakIndex; j < POINTS_COUNT; j++) { + if (actual_t[j] < peakLevel - 3) // Search right -3dB + break; + } + if (j - peakIndex < test_case[i].width) + return(TS_FAIL); + for (j = peakIndex; j > 0; j--) { + if (actual_t[j] < peakLevel - 3) // Search left -3dB + break; + } + if (peakIndex - j < test_case[i].width) + return(TS_FAIL); + return(TS_PASS); +} + +int validate_above(void) { + int status = TS_PASS; + for (int j = 0; j < POINTS_COUNT; j++) { + if (actual_t[j] < stored_t[j] + 5) + status = TS_CRITICAL; + else if (actual_t[j] < stored_t[j]) { + status = TS_FAIL; + break; + } + } + return(status); +} + + +void test_validate(int i) +{ + if (test_case[i].kind == TC_SIGNAL) { // Validate signal + if (validate_peak_within(i, 5.0)) // Validate Peak + test_status[i] = TS_PASS; + else if (validate_peak_within(i, 10.0)) + test_status[i] = TS_CRITICAL; + else + test_status[i] = TS_FAIL; + if (test_status[i] != TS_PASS) + test_fail_cause[i] = "Peak "; + if (test_status[i] == TS_PASS) { // Validate noise floor + for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) { + if (actual_t[j] > test_case[i].stop - 5) + test_status[i] = TS_CRITICAL; + else if (actual_t[j] > test_case[i].stop) { + test_status[i] = TS_FAIL; + break; + } + } + for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) { + if (actual_t[j] > test_case[i].stop - 5) + test_status[i] = TS_CRITICAL; + else if (actual_t[j] > test_case[i].stop) { + test_status[i] = TS_FAIL; + break; + } + } + if (test_status[i] != TS_PASS) + test_fail_cause[i] = "Stopband "; + } + + } else if (test_case[i].kind == TC_ABOVE) { // Validate signal above curve + for (int j = 0; j < POINTS_COUNT; j++) { + if (actual_t[j] < test_case[i].pass + 5) + test_status[i] = TS_CRITICAL; + else if (actual_t[j] < test_case[i].pass) { + test_status[i] = TS_FAIL; + break; + } + } + if (test_status[i] != TS_PASS) + test_fail_cause[i] = "Above "; + + } else if (test_case[i].kind == TC_BELOW) { // Validate signal below curve + if (validate_peak_below(i, 10.0)) + test_status[i] = TS_PASS; + else if (validate_peak_below(i, 5.0)) + test_status[i] = TS_CRITICAL; + else + test_status[i] = TS_FAIL; + if (test_status[i] != TS_PASS) + test_fail_cause[i] = "Above "; + } else if (test_case[i].kind == TC_FLAT) { // Validate passband flatness + test_status[i] = validate_flatness(i); + if (test_status[i] != TS_PASS) + test_fail_cause[i] = "Passband "; + } + + // Report status + + if (test_status[i] != TS_PASS || i == TEST_COUNT - 1) + test_wait = true; + draw_all(TRUE); + resume_sweep(); +} + +extern void menu_autosettings_cb(int item); +extern void touch_wait_release(void); + +void self_test(void) +{ + menu_autosettings_cb(0); + for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting + test_status[i] = TS_WAITING; + test_fail_cause[i] = ""; + } + show_test_info = TRUE; + for (int i=0; i < TEST_COUNT; i++) { + extraVFO = false; //Default test setup + switch(test_case[i].setup) { // Prepare test conditions + case TP_SILENT: // No input signal + set_refer_output(-1); + for (int j = 0; j < POINTS_COUNT; j++) + stored_t[j] = test_case[i].pass; + break; + case TP_10MHZEXTRA: // Swept receiver + extraVFO = true; //Sweep BPF + // Fall through intended!!!!!! + case TP_10MHZ: // 10MHz input + common: + set_refer_output(2); + int j; + for (j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) + stored_t[j] = test_case[i].stop; + for (j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) + stored_t[j] = test_case[i].stop; + for (j = POINTS_COUNT/2 - test_case[i].width; j < POINTS_COUNT/2 + test_case[i].width; j++) + stored_t[j] = test_case[i].pass; + break; + case TP_30MHZ: + set_refer_output(0); + goto common; + } + trace[TRACE_STORED].enabled = true; + set_trace_refpos(0, NGRIDY - (test_case[i].pass + 30) / get_trace_scale(0)); + set_trace_refpos(1, NGRIDY - (test_case[i].pass + 30) / get_trace_scale(0)); + set_trace_refpos(2, NGRIDY - (test_case[i].pass + 30) / get_trace_scale(0)); + draw_cal_status(); + test_acquire(i); // Acquire test + test_validate(i); // Validate test + chThdSleepMilliseconds(2000); + if (test_status[i] != TS_PASS) { + touch_wait_release(); + } + } + touch_wait_release(); + // chThdSleepMilliseconds(2000); + show_test_info = FALSE; + trace[TRACE_STORED].enabled = false; + set_trace_refpos(0, NGRIDY - (-10) / get_trace_scale(0)); + set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); + set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); + set_refer_output(0); + settingMode = 0; + draw_cal_status(); + + menu_autosettings_cb(0); +} diff --git a/si4432.c b/si4432.c new file mode 100644 index 0000000..6efbd8f --- /dev/null +++ b/si4432.c @@ -0,0 +1,371 @@ +/* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com + * All rights reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#include "ch.h" +#include "hal.h" +#include "nanovna.h" + +#include "si4432.h" + +#define CS_SI0_HIGH palSetPad(GPIOA, GPIOA_RX_SEL) +#define CS_SI1_HIGH palSetPad(GPIOA, GPIOA_LO_SEL) +#define CS_PE_HIGH palSetPad(GPIOA, GPIOA_PE_SEL) + +#define CS_SI0_LOW palClearPad(GPIOA, GPIOA_RX_SEL) +#define CS_SI1_LOW palClearPad(GPIOA, GPIOA_LO_SEL) +#define CS_PE_LOW palClearPad(GPIOA, GPIOA_PE_SEL) + +#define SPI2_CLK_HIGH palSetPad(GPIOB, GPIOB_SPI2_CLK) +#define SPI2_CLK_LOW palClearPad(GPIOB, GPIOB_SPI2_CLK) + +#define SPI2_SDI_HIGH palSetPad(GPIOB, GPIOB_SPI2_SDI) +#define SPI2_SDI_LOW palClearPad(GPIOB, GPIOB_SPI2_SDI) + +#define SPI2_SDO ((palReadPort(GPIOB) & (1< 6207) WISH=6207; // Final value in RBW_choices[] + if (WISH > 1379) dwn3 = 1 ; + for (i=3; i= 480000000) { + hbsel = 1; + Freq = Freq / 2; + } else { + hbsel = 0; + } + int sbsel = 1; + int N = Freq / 10000000; + Carrier = ( 4 * ( Freq - N * 10000000 )) / 625; + int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 ); +#if 1 + SI4432_Write_Byte ( 0x75, Freq_Band ); + SI4432_Write_Byte ( 0x76, (Carrier>>8) & 0xFF ); + SI4432_Write_Byte ( 0x77, Carrier & 0xFF ); +#else + SI4432_Write_3_Byte ( 0x75, Freq_Band, (Carrier>>8) & 0xFF, Carrier & 0xFF ); +#endif +} + +int stepDelay = 1500; +int settingSpeed = 0; + +float SI4432_RSSI(uint32_t i, int s) +{ + int RSSI_RAW; + // SEE DATASHEET PAGE 61 +#ifdef USE_SI4463 + if (SI4432_Sel == 2) { + RSSI_RAW = Si446x_getRSSI(); + } else +#endif + SI4432_Sel = s; + chThdSleepMicroseconds(stepDelay); + RSSI_RAW = (unsigned char)SI4432_Read_Byte( 0x26 ) ; + if (settingMode < 2 && RSSI_RAW == 0) + SI4432_Init(); + float dBm = 0.5 * RSSI_RAW - 120.0 ; +#ifdef __SIMULATION__ + dBm = Simulated_SI4432_RSSI(i,s); +#endif + // Serial.println(dBm,2); + return dBm ; +} + + +void SI4432_Sub_Init() +{ + SI4432_Reset(); + SI4432_Write_Byte(0x05, 0x0); + SI4432_Write_Byte(0x06, 0x0); + // Enable receiver chain +// SI4432_Write_Byte(0x07, 0x05); + // Clock Recovery Gearshift Value + SI4432_Write_Byte(0x1F, 0x00); + // IF Filter Bandwidth + SI4432_SET_RBW(10) ; +// // Register 0x75 Frequency Band Select +// byte sbsel = 1 ; // recommended setting +// byte hbsel = 0 ; // low bands +// byte fb = 19 ; // 430–439.9 MHz +// byte FBS = (sbsel << 6 ) | (hbsel << 5 ) | fb ; +// SI4432_Write_Byte(0x75, FBS) ; + SI4432_Write_Byte(0x75, 0x46) ; + // Register 0x76 Nominal Carrier Frequency + // WE USE 433.92 MHz + // Si443x-Register-Settings_RevB1.xls +// SI4432_Write_Byte(0x76, 0x62) ; + SI4432_Write_Byte(0x76, 0x00) ; + // Register 0x77 Nominal Carrier Frequency + SI4432_Write_Byte(0x77, 0x00) ; + // RX MODEM SETTINGS + SI4432_Write_Byte(0x1C, 0x81) ; + SI4432_Write_Byte(0x1D, 0x3C) ; + SI4432_Write_Byte(0x1E, 0x02) ; + SI4432_Write_Byte(0x1F, 0x03) ; + // SI4432_Write_Byte(0x20, 0x78) ; + SI4432_Write_Byte(0x21, 0x01) ; + SI4432_Write_Byte(0x22, 0x11) ; + SI4432_Write_Byte(0x23, 0x11) ; + SI4432_Write_Byte(0x24, 0x01) ; + SI4432_Write_Byte(0x25, 0x13) ; + SI4432_Write_Byte(0x2A, 0xFF) ; + SI4432_Write_Byte(0x2C, 0x28) ; + SI4432_Write_Byte(0x2D, 0x0C) ; + SI4432_Write_Byte(0x2E, 0x28) ; + + + SI4432_Write_Byte(0x69, 0x60); // AGC, no LNA, fast gain increment + + +// GPIO automatic antenna switching + SI4432_Write_Byte(0x0B, 0x12) ; // Normal + SI4432_Write_Byte(0x0C, 0x15) ; + +} + +#define V0_XTAL_CAPACITANCE 0x64 +#define V1_XTAL_CAPACITANCE 0x64 + + + +void SI4432_Init() +{ + + +//DebugLine("IO set"); + SI4432_Sel = 0; + SI4432_Sub_Init(); + + SI4432_Sel = 1; + SI4432_Sub_Init(); +//DebugLine("1 init done"); + + SI4432_Sel = 0; + SI4432_Receive();// Enable receiver chain +// SI4432_Write_Byte(0x09, V0_XTAL_CAPACITANCE);// Tune the crystal + SI4432_Set_Frequency(433700000); + SI4432_Write_Byte(0x0D, 0x1F) ; // Set GPIO2 output to ground + + + SI4432_Sel = 1; +// SI4432_Write_Byte(0x09, V1_XTAL_CAPACITANCE);// Tune the crystal + SI4432_Set_Frequency(443700000); + SI4432_Write_Byte(0x6D, 0x1C);//Set low power + SI4432_Transmit(0); + + SI4432_Write_Byte(0x0D, 0xC0) ; // Set GPIO2 maximumdrive and clock output + SI4432_Write_Byte(0x0A, 0x02) ; // Set 10MHz output +} + +void SI4432_SetReference(int freq) +{ + SI4432_Sel = 1; //Select Lo module + if (freq < 0 || freq > 7 ) { + SI4432_Write_Byte(0x0D, 0x1F) ; // Set GPIO2 to GND + } else { + SI4432_Write_Byte(0x0D, 0xC0) ; // Set GPIO2 maximumdrive and clock output + SI4432_Write_Byte(0x0A, freq & 0x07) ; // Set GPIO2 frequency + } +} + +//------------PE4302 ----------------------------------------------- + +// Comment out this define to use parallel mode PE4302 + +#define PE4302_en 10 + +void PE4302_init(void) { + CS_PE_LOW; +} + +extern void shiftOut(uint8_t val); + +void PE4302_Write_Byte(unsigned char DATA ) +{ + SPI2_CLK_LOW; + shiftOut(DATA); + CS_PE_HIGH; + CS_PE_LOW; +} + +#endif diff --git a/si4432.h b/si4432.h new file mode 100644 index 0000000..8b2774e --- /dev/null +++ b/si4432.h @@ -0,0 +1,22 @@ +#ifndef __SI4432_H__ + +#define __SI4432_H__ + +#define byte uint8_t +extern volatile int SI4432_Sel; // currently selected SI4432 +void SI4432_Write_Byte(byte ADR, byte DATA ); +byte SI4432_Read_Byte( byte ADR ); + +void SI4432_Init(void); +float SI4432_RSSI(uint32_t i, int s); +#ifdef __SIMULATION__ +float Simulated_SI4432_RSSI(uint32_t i, int s); +#endif +void SI4432_Set_Frequency ( long Freq ); +void SI4432_Transmit(int d); +void SI4432_Receive(void); +float SI4432_SET_RBW(float WISH); +void PE4302_Write_Byte(unsigned char DATA ); +void PE4302_init(void); + +#endif //__SI4432_H__ diff --git a/si5351.c b/si5351.c deleted file mode 100644 index 8f7c9c5..0000000 --- a/si5351.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com - * Modified by DiSlord dislordlive@gmail.com - * All rights reserved. - * - * This is free software; you can redistribute it and/or modify - * 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 "hal.h" -#include "nanovna.h" -#include "si5351.h" - -// Enable cache for SI5351 CLKX_CONTROL register, little speedup exchange -#define USE_CLK_CONTROL_CACHE TRUE - -// XTAL frequency on si5351 -#define XTALFREQ 26000000U -// MCLK (processor clock if set, audio codec) frequency clock -#define CLK2_FREQUENCY 8000000U - -// Fixed PLL mode multiplier (used in band 1) -#define PLL_N 32 - -// I2C address on bus (only 0x60 for Si5351A in 10-Pin MSOP) -#define SI5351_I2C_ADDR 0x60 - -static uint8_t current_band = 0; -static uint32_t current_freq = 0; -static int32_t current_offset = FREQUENCY_OFFSET; - -// Minimum value is 2, freq change apply at next dsp measure, and need skip it -#define DELAY_NORMAL 2 -// Delay for bands (depend set band 1 more fast (can change before next dsp buffer ready, need wait additional interval) -#define DELAY_BAND_1 3 -#define DELAY_BAND_2 2 -// Band changes need set delay after reset PLL -#define DELAY_BANDCHANGE_1 3 -#define DELAY_BANDCHANGE_2 3 -// Delay after set new PLL values, and send reset (on band 1 unstable if less then 900, on 4000-5000 no amplitude spike on change) -#define DELAY_RESET_PLL 5000 - -uint32_t si5351_get_frequency(void) -{ - return current_freq; -} - -void si5351_set_frequency_offset(int32_t offset) -{ - current_offset = offset; - current_freq = 0; // reset freq, for -} - -static void -si5351_bulk_write(const uint8_t *buf, int len) -{ - i2cAcquireBus(&I2CD1); - (void)i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, buf, len, NULL, 0, 1000); - i2cReleaseBus(&I2CD1); -} - -#if 0 -static bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len) -{ - i2cAcquireBus(&I2CD1); - msg_t mr = i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, ®, 1, buf, len, 1000); - i2cReleaseBus(&I2CD1); - return mr == MSG_OK; -} - -static void si5351_wait_pll_lock(void) -{ - uint8_t status; - int count = 100; - do{ - status=0xFF; - si5351_bulk_read(0, &status, 1); - if ((status & 0x60) == 0) // PLLA and PLLB locked - return; - }while (--count); -} -#endif - -static inline void -si5351_write(uint8_t reg, uint8_t dat) -{ - uint8_t buf[] = { reg, dat }; - si5351_bulk_write(buf, 2); -} - -// register addr, length, data, ... -const uint8_t si5351_configs[] = { - 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff, - 4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, - 2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF, -// All of this init code run late on sweep -#if 0 - // setup PLL (26MHz * 32 = 832MHz, 32/2-2=14) - 9, SI5351_REG_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, - 9, SI5351_REG_PLL_B, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0, - // RESET PLL - 2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B | 0x0C, // - // setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50) - 9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0, - 2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE, -#endif - 2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN), - 0 // sentinel -}; - -void -si5351_init(void) -{ - const uint8_t *p = si5351_configs; - while (*p) { - uint8_t len = *p++; - si5351_bulk_write(p, len); - p += len; - } -} - -static const uint8_t disable_output[] = { - SI5351_REG_16_CLK0_CONTROL, - SI5351_CLK_POWERDOWN, // CLK 0 - SI5351_CLK_POWERDOWN, // CLK 1 - SI5351_CLK_POWERDOWN // CLK 2 -}; - -/* Get the appropriate starting point for the PLL registers */ -static const uint8_t msreg_base[] = { - SI5351_REG_42_MULTISYNTH0, - SI5351_REG_50_MULTISYNTH1, - SI5351_REG_58_MULTISYNTH2, -}; -static const uint8_t clkctrl[] = { - SI5351_REG_16_CLK0_CONTROL, - SI5351_REG_17_CLK1_CONTROL, - SI5351_REG_18_CLK2_CONTROL -}; - -// Reset PLL need then band changes -static void si5351_reset_pll(uint8_t mask) -{ - // Writing a 1<<5 will reset PLLA, 1<<7 reset PLLB, this is a self clearing bits. - // !!! Need delay before reset PLL for apply PLL freq changes before - chThdSleepMicroseconds(DELAY_RESET_PLL); - si5351_write(SI5351_REG_177_PLL_RESET, mask | 0x0C); -} - -void si5351_disable_output(void) -{ - si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xFF); - si5351_bulk_write(disable_output, sizeof(disable_output)); - current_band = 0; -} - -void si5351_enable_output(void) -{ - si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN)); -//si5351_reset_pll(SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); - current_freq = 0; - current_band = 0; -} - -// Set PLL freq = XTALFREQ * (mult + num/denom) -static void si5351_setupPLL(uint8_t pllSource, /* SI5351_REG_PLL_A or SI5351_REG_PLL_B */ - uint32_t mult, - uint32_t num, - uint32_t denom) -{ - /* Feedback Multisynth Divider Equation - * where: a = mult, b = num and c = denom - * P1 register is an 18-bit value using following formula: - * P1[17:0] = 128 * mult + int((128*num)/denom) - 512 - * P2 register is a 20-bit value using the following formula: - * P2[19:0] = (128 * num) % denom - * P3 register is a 20-bit value using the following formula: - * P3[19:0] = denom - */ - /* Set the main PLL config registers */ - mult <<= 7; - num <<= 7; - uint32_t P1 = mult - 512; // Integer mode - uint32_t P2 = 0; - uint32_t P3 = 1; - if (num) { // Fractional mode - P1+= num / denom; - P2 = num % denom; - P3 = denom; - } - // Pll MSN(A|B) registers Datasheet - uint8_t reg[9]; - reg[0] = pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B - reg[1] = (P3 & 0x0FF00) >> 8; // MSN_P3[15: 8] - reg[2] = (P3 & 0x000FF); // MSN_P3[ 7: 0] - reg[3] = (P1 & 0x30000) >> 16; // MSN_P1[17:16] - reg[4] = (P1 & 0x0FF00) >> 8; // MSN_P1[15: 8] - reg[5] = (P1 & 0x000FF); // MSN_P1[ 7: 0] - reg[6] = ((P3 & 0xF0000) >> 12) | ((P2 & 0xF0000) >> 16); // MSN_P3[19:16] | MSN_P2[19:16] - reg[7] = (P2 & 0x0FF00) >> 8; // MSN_P2[15: 8] - reg[8] = (P2 & 0x000FF); // MSN_P2[ 7: 0] - si5351_bulk_write(reg, 9); -} - -// Set Multisynth divider = (div + num/denom) * rdiv -static void -si5351_setupMultisynth(uint8_t channel, - uint32_t div, // 4,6,8, 8+ ~ 900 - uint32_t num, - uint32_t denom, - uint32_t rdiv, // SI5351_R_DIV_1~128 - uint8_t chctrl) // SI5351_REG_16_CLKX_CONTROL settings -{ - /* Output Multisynth Divider Equations - * where: a = div, b = num and c = denom - * P1 register is an 18-bit value using following formula: - * P1[17:0] = 128 * a + int((128*b)/c) - 512 - * P2 register is a 20-bit value using the following formula: - * P2[19:0] = (128 * b) % c - * P3 register is a 20-bit value using the following formula: - * P3[19:0] = c - */ - /* Set the main PLL config registers */ - uint32_t P1 = 0; - uint32_t P2 = 0; - uint32_t P3 = 1; - if (div == 4) - rdiv|= SI5351_DIVBY4; - else { - num<<=7; - div<<=7; - P1 = div - 512; // Integer mode - if (num) { // Fractional mode - P1+= num / denom; - P2 = num % denom; - P3 = denom; - } - } - /* Set the MSx config registers */ - uint8_t reg[9]; - reg[0] = msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2 - reg[1] = (P3 & 0x0FF00)>>8; // MSx_P3[15: 8] - reg[2] = (P3 & 0x000FF); // MSx_P3[ 7: 0] - reg[3] = ((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16] - reg[4] = (P1 & 0x0FF00)>> 8; // MSx_P1[15: 8] - reg[5] = (P1 & 0x000FF); // MSx_P1[ 7: 0] - reg[6] = ((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16] - reg[7] = (P2 & 0x0FF00)>>8; // MSx_P2[15: 8] - reg[8] = (P2 & 0x000FF); // MSx_P2[ 7: 0] - si5351_bulk_write(reg, 9); - - /* Configure the clk control and enable the output */ - uint8_t dat = chctrl | SI5351_CLK_INPUT_MULTISYNTH_N; - if (num == 0) - dat |= SI5351_CLK_INTEGER_MODE; - -#if USE_CLK_CONTROL_CACHE == TRUE - // Use cache for this reg, not update if not change - static uint8_t clk_cache[3]; - if (clk_cache[channel]!=dat) { - si5351_write(clkctrl[channel], dat); - clk_cache[channel]=dat; - } -#else - si5351_write(clkctrl[channel], dat); -#endif -} - -// Find better approximate values for n/d -#define MAX_DENOMINATOR ((1 << 20) - 1) -static inline void approximate_fraction(uint32_t *n, uint32_t *d) -{ - // cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227 - uint32_t denom = *d; - if (denom > MAX_DENOMINATOR) { - uint32_t num = *n; - uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0; - while (denom != 0) { - uint32_t a = num / denom; - uint32_t b = num % denom; - uint32_t q2 = q0 + a*q1; - if (q2 > MAX_DENOMINATOR) - break; - uint32_t p2 = p0 + a*p1; - p0 = p1; q0 = q1; p1 = p2; q1 = q2; - num = denom; denom = b; - } - *n = p1; - *d = q1; - } -} - -// Setup Multisynth divider for get correct output freq if fixed PLL = pllfreq -static void -si5351_set_frequency_fixedpll(uint8_t channel, uint64_t pllfreq, uint32_t freq, uint32_t rdiv, uint8_t chctrl) -{ - uint32_t denom = freq; - uint32_t div = pllfreq / denom; // range: 8 ~ 1800 - uint32_t num = pllfreq % denom; - approximate_fraction(&num, &denom); - si5351_setupMultisynth(channel, div, num, denom, rdiv, chctrl); -} - -// Setup PLL freq if Multisynth divider fixed = div (need get output = freq/mul) -static void -si5351_setupPLL_freq(uint32_t pllSource, uint32_t freq, uint32_t div, uint32_t mul) -{ - uint32_t denom = XTALFREQ * mul; - uint64_t pllfreq = (uint64_t)freq * div; - uint32_t multi = pllfreq / denom; - uint32_t num = pllfreq % denom; - approximate_fraction(&num, &denom); - si5351_setupPLL(pllSource, multi, num, denom); -} - -#if 0 -static void -si5351_set_frequency_fixeddiv(uint8_t channel, uint32_t pll, uint32_t freq, uint32_t div, - uint8_t chctrl, uint32_t mul) -{ - si5351_setupPLL_freq(pll, freq, div, mul); - si5351_setupMultisynth(channel, div, 0, 1, SI5351_R_DIV_1, chctrl); -} - -void -si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength) -{ - if (freq <= 100000000) { - si5351_setupPLL(SI5351_PLL_B, 32, 0, 1); - si5351_set_frequency_fixedpll(channel, SI5351_PLL_B, PLLFREQ, freq, SI5351_R_DIV_1, drive_strength, 1); - } else if (freq < 150000000) { - si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 6, drive_strength, 1); - } else { - si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength, 1); - } -} -#endif - -/* - * Frequency generation divide on 3 band - * Band 1 - * 1~100MHz fixed PLL = XTALFREQ * PLL_N, fractional divider - * Band 2 - * 100~150MHz fractional PLL = 600- 900MHz, fixed divider 'fdiv = 6' - * Band 3 - * 150~300MHz fractional PLL = 600-1200MHz, fixed divider 'fdiv = 4' - * - * For FREQ_HARMONICS = 300MHz - band range is: - * +-----------------------------------------------------------------------------------------------------------------------+ - * | Band 1 | Band 2 | Band 3 | Band 2 | Band 3 | - * +-----------------------------------------------------------------------------------------------------------------------+ - * | Direct mode x1 : x1 | x3 : x5 | x5-x7 | x7-x9 | x9-x11 | - * +-----------------------------------------------------------------------------------------------------------------------+ - * | 50kHz - 100MHz | 100 - 150MHz | 150 - 300MHz | 300-450MHz | 450-900MHz | 900-1500MHz | 1500-2100MHz | 2100-2700MHz | - * +-----------------------------------------------------------------------------------------------------------------------+ - * | f = 50kHz-300MHz | f=100-150 | f=150-300 | f=150-300 | f=214-300 | f=233-300 | - * | of = 50kHz-300MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 | - * +-----------------------------------------------------------------------------------------------------------------------+ - */ -static inline uint8_t -si5351_get_band(uint32_t freq) -{ - if (freq < 100000000U) return 1; - if (freq < 150000000U) return 2; - return 3; -} - -/* - * Maximum supported frequency = FREQ_HARMONICS * 9U - * configure output as follows: - * CLK0: frequency + offset - * CLK1: frequency - * CLK2: fixed 8MHz - */ -int -si5351_set_frequency(uint32_t freq, uint8_t drive_strength) -{ - uint8_t band; - int delay = DELAY_NORMAL; - if (freq == current_freq) - return delay; - else if (current_freq > freq) // Reset band on sweep begin (if set range 150-600, fix error then 600 MHz band 2 or 3 go back) - current_band = 0; - current_freq = freq; - uint32_t ofreq = freq + current_offset; - uint32_t mul = 1, omul = 1; - uint32_t rdiv = SI5351_R_DIV_1; - uint32_t fdiv; - // Fix possible incorrect input - drive_strength&=SI5351_CLK_DRIVE_STRENGTH_MASK; - - if (freq >= config.harmonic_freq_threshold * 7U) { - mul = 9; - omul = 11; - } else if (freq >= config.harmonic_freq_threshold * 5U) { - mul = 7; - omul = 9; - } else if (freq >= config.harmonic_freq_threshold * 3U) { - mul = 5; - omul = 7; - } else if (freq >= config.harmonic_freq_threshold) { - mul = 3; - omul = 5; - } else if (freq <= 500000U) { - rdiv = SI5351_R_DIV_64; - freq<<= 6; - ofreq<<= 6; - } else if (freq <= 4000000U) { - rdiv = SI5351_R_DIV_8; - freq<<= 3; - ofreq<<= 3; - } - band = si5351_get_band(freq / mul); - switch (band) { - case 1: - // Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq = - // CLK2_FREQUENCY - if (current_band != 1) { - si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1); - si5351_set_frequency_fixedpll( - 2, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1, - SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_PLL_SELECT_A); - delay = DELAY_BANDCHANGE_1; - } else { - delay = DELAY_BAND_1; - } - // Calculate and set CH0 and CH1 divider - si5351_set_frequency_fixedpll(0, (uint64_t)omul * XTALFREQ * PLL_N, ofreq, rdiv, - drive_strength | SI5351_CLK_PLL_SELECT_A); - si5351_set_frequency_fixedpll(1, (uint64_t)mul * XTALFREQ * PLL_N, freq, rdiv, - drive_strength | SI5351_CLK_PLL_SELECT_A); - break; - case 2: // fdiv = 6 - case 3: // fdiv = 4; - fdiv = (band == 2) ? 6 : 4; - // Setup CH0 and CH1 constant fdiv divider at change - if (current_band != band) { - si5351_setupMultisynth(0, fdiv, 0, 1, SI5351_R_DIV_1, - drive_strength | SI5351_CLK_PLL_SELECT_A); - si5351_setupMultisynth(1, fdiv, 0, 1, SI5351_R_DIV_1, - drive_strength | SI5351_CLK_PLL_SELECT_B); - delay = DELAY_BANDCHANGE_2; - } else { - delay = DELAY_BAND_2; - } - // Calculate and set CH0 and CH1 PLL freq - si5351_setupPLL_freq(SI5351_REG_PLL_A, ofreq, fdiv, - omul); // set PLLA freq = (ofreq/omul)*fdiv - si5351_setupPLL_freq(SI5351_REG_PLL_B, freq, fdiv, - mul); // set PLLB freq = ( freq/ mul)*fdiv - // Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv - si5351_set_frequency_fixedpll( - 2, (uint64_t)freq * fdiv, CLK2_FREQUENCY * mul, SI5351_R_DIV_1, - SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_PLL_SELECT_B); - break; - } - if (current_band != band) { - si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B); - current_band = band; - } - return delay; -} diff --git a/si5351.h b/si5351.h deleted file mode 100644 index 315ce3c..0000000 --- a/si5351.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com - * All rights reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3 -#define SI5351_CLK0_EN (1<<0) -#define SI5351_CLK1_EN (1<<1) -#define SI5351_CLK2_EN (1<<2) - -// Reg 16-18 CLKX_CONTROL -#define SI5351_REG_16_CLK0_CONTROL 16 -#define SI5351_REG_17_CLK1_CONTROL 17 -#define SI5351_REG_18_CLK2_CONTROL 18 -#define SI5351_CLK_POWERDOWN (1<<7) -#define SI5351_CLK_INTEGER_MODE (1<<6) -#define SI5351_CLK_PLL_SELECT_A (0<<5) -#define SI5351_CLK_PLL_SELECT_B (1<<5) -#define SI5351_CLK_INVERT (1<<4) -#define SI5351_CLK_INPUT_MASK (3<<2) -#define SI5351_CLK_INPUT_XTAL (0<<2) -#define SI5351_CLK_INPUT_CLKIN (1<<2) -#define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) -#define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) -#define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) -#define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) -#define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) -#define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) -#define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) - -#define SI5351_REG_PLL_A 26 -#define SI5351_REG_PLL_B 34 - -#define SI5351_REG_42_MULTISYNTH0 42 -#define SI5351_REG_50_MULTISYNTH1 50 -#define SI5351_REG_58_MULTISYNTH2 58 -#define SI5351_DIVBY4 (3<<2) -#define SI5351_R_DIV_1 (0<<4) -#define SI5351_R_DIV_2 (1<<4) -#define SI5351_R_DIV_4 (2<<4) -#define SI5351_R_DIV_8 (3<<4) -#define SI5351_R_DIV_16 (4<<4) -#define SI5351_R_DIV_32 (5<<4) -#define SI5351_R_DIV_64 (6<<4) -#define SI5351_R_DIV_128 (7<<4) - -#define SI5351_REG_177_PLL_RESET 177 -#define SI5351_PLL_RESET_B (1<<7) -#define SI5351_PLL_RESET_A (1<<5) - -#define SI5351_REG_183_CRYSTAL_LOAD 183 -#define SI5351_CRYSTAL_LOAD_6PF (1<<6) -#define SI5351_CRYSTAL_LOAD_8PF (2<<6) -#define SI5351_CRYSTAL_LOAD_10PF (3<<6) - -void si5351_init(void); -void si5351_disable_output(void); -void si5351_enable_output(void); - -void si5351_set_frequency_offset(int32_t offset); -int si5351_set_frequency(uint32_t freq, uint8_t drive_strength); -uint32_t si5351_get_frequency(void); diff --git a/tlv320aic3204.c b/tlv320aic3204.c deleted file mode 100644 index 21fbe84..0000000 --- a/tlv320aic3204.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com - * All rights reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#include "hal.h" -#include "nanovna.h" - -#define REFCLK_8000KHZ -#define AIC3204_ADDR 0x18 - -#define wait_ms(ms) chThdSleepMilliseconds(ms) - -static const uint8_t conf_data[] = { -// reg, data, -// PLL clock config - 0x00, 0x00, /* Initialize to Page 0 */ - 0x01, 0x01, /* Initialize the device through software reset */ - 0x04, 0x43, /* PLL Clock High, MCLK, PLL */ -#ifdef REFCLK_8000KHZ - /* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */ - 0x05, 0x91, /* Power up PLL, P=1,R=1 */ - 0x06, 0x0a, /* J=10 */ - 0x07, 29, /* D=7520 = (29<<8) + 96 */ - 0x08, 96, -#endif -// Clock config, default fs=48kHz - 0x0b, 0x82, /* Power up the NDAC divider with value 2 */ - 0x0c, 0x87, /* Power up the MDAC divider with value 7 */ - 0x0d, 0x00, /* Program the OSR of DAC to 128 */ - 0x0e, 0x80, - 0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */ - //0x3c, 25, /* Set the DAC Mode to PRB_P25 */ - 0x1b, 0x0c, /* Set the BCLK,WCLK as output */ - 0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */ - 0x25, 0xee, /* DAC power up */ - - 0x12, 0x82, /* Power up the NADC divider with value 2 */ - 0x13, 0x87, /* Power up the MADC divider with value 7 */ - 0x14, 0x80, /* Program the OSR of ADC to 128 */ - 0x3d, 0x01, /* Select ADC PRB_R1 */ -// Data routing - 0x00, 0x01, /* Select Page 1 */ - 0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/ - 0x02, 0x01, /* Enable Master Analog Power Control */ - 0x7b, 0x01, /* Set the REF charging time to 40ms */ - 0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop†sound. */ - 0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */ - - 0x3d, 0x00, /* Select ADC PTM_R4 */ - 0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */ - 0x7b, 0x01, /* Set the REF charging time to 40ms */ - 0x34, 0x10, /* Route IN2L to LEFT_P with 10K */ - 0x36, 0x10, /* Route IN2R to LEFT_N with 10K */ -//0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */ -//0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */ -//0x3b, 0x00, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */ -//0x3c, 0x00, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */ -}; - -static const uint8_t conf_data_unmute[] = { -// reg, data, - 0x00, 0x00, /* Select Page 0 */ - 0x51, 0xc0, /* Power up Left and Right ADC Channels */ - 0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */ -}; - -static const uint8_t conf_data_ch3_select[] = { -// reg, data, - 0x00, 0x01, /* Select Page 1 */ - 0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */ - 0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */ -}; - -static const uint8_t conf_data_ch1_select[] = { -// reg, data, - 0x00, 0x01, /* Select Page 1 */ - 0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */ - 0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */ -}; - -static inline void -tlv320aic3204_bulk_write(const uint8_t *buf, int len) -{ - (void)i2cMasterTransmitTimeout(&I2CD1, AIC3204_ADDR, buf, len, NULL, 0, 1000); -} - -#if 0 -static int -tlv320aic3204_read(uint8_t d0) -{ - int addr = AIC3204_ADDR; - uint8_t buf[] = { d0 }; - i2cAcquireBus(&I2CD1); - i2cMasterTransmitTimeout(&I2CD1, addr, buf, 1, buf, 1, 1000); - i2cReleaseBus(&I2CD1); - return buf[0]; -} -#endif - -static void -tlv320aic3204_config(const uint8_t *data, int len) -{ - i2cAcquireBus(&I2CD1); - for (; len--; data += 2) - tlv320aic3204_bulk_write(data, 2); - i2cReleaseBus(&I2CD1); -} - -void tlv320aic3204_init(void) -{ - tlv320aic3204_config(conf_data, sizeof(conf_data)/2); - wait_ms(40); - tlv320aic3204_config(conf_data_unmute, sizeof(conf_data_unmute)/2); -} - -void tlv320aic3204_select(int channel) -{ - tlv320aic3204_config(channel ? conf_data_ch1_select : conf_data_ch3_select, sizeof(conf_data_ch3_select)/2); -} - -void tlv320aic3204_set_gain(int lgain, int rgain) -{ - uint8_t data[] = { - 0x00, 0x01, /* Select Page 1 */ - 0x3b, lgain, /* Unmute Left MICPGA, set gain */ - 0x3c, rgain, /* Unmute Right MICPGA, set gain */ - }; - tlv320aic3204_config(data, sizeof(data)/2); -} diff --git a/ui.c b/ui.c index 391af98..a75838b 100644 --- a/ui.c +++ b/ui.c @@ -52,7 +52,7 @@ uistat_t uistat = { #define BIT_DOWN1 1 #define READ_PORT() palReadPort(GPIOA) -#define BUTTON_MASK 0b1111 +#define BUTTON_MASK 0b1110 static uint16_t last_button = 0b0000; static uint32_t last_button_down_ticks; @@ -67,9 +67,11 @@ enum { UI_NORMAL, UI_MENU, UI_NUMERIC, UI_KEYPAD }; +#ifdef __VNA__ enum { KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_SCALE, KM_REFPOS, KM_EDELAY, KM_VELOCITY_FACTOR, KM_SCALEDELAY }; +#endif #define NUMINPUT_LEN 10 @@ -120,6 +122,7 @@ static void leave_ui_mode(void); static void erase_menu_buttons(void); static void ui_process_keypad(void); static void ui_process_numeric(void); +static void choose_active_marker(void); static void menu_move_back(void); static void menu_push_submenu(const menuitem_t *submenu); @@ -287,7 +290,7 @@ touch_check(void) return stat ? EVT_TOUCH_DOWN : EVT_TOUCH_NONE; } -static inline void +void touch_wait_release(void) { while (touch_check() != EVT_TOUCH_RELEASED) @@ -435,6 +438,7 @@ enum { typedef void (*menuaction_cb_t)(int item, uint8_t data); +#ifdef __VNA__ static void menu_calop_cb(int item, uint8_t data) { @@ -630,7 +634,6 @@ menu_transform_filter_cb(int item, uint8_t data) domain_mode = (domain_mode & ~TD_FUNC) | data; ui_mode_normal(); } - static void choose_active_marker(void) { @@ -647,9 +650,11 @@ static void menu_scale_cb(int item, uint8_t data) { (void)item; +#ifdef __VNA__ if (data == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { data = KM_SCALEDELAY; } +#endif if (btn_wait_release() & EVT_BUTTON_DOWN_LONG) { ui_mode_numeric(data); ui_process_numeric(); @@ -685,6 +690,7 @@ menu_stimulus_cb(int item, uint8_t data) break; } } +#endif static uint32_t get_marker_frequency(int marker) @@ -730,6 +736,7 @@ menu_marker_op_cb(int item, uint8_t data) } } break; +#ifdef __VNA__ case 4: /* MARKERS->EDELAY */ { if (uistat.current_trace == -1) @@ -739,6 +746,7 @@ menu_marker_op_cb(int item, uint8_t data) set_electrical_delay(electrical_delay + (v / 1e-12)); } break; +#endif } ui_mode_normal(); draw_cal_status(); @@ -775,7 +783,7 @@ menu_marker_search_cb(int item, uint8_t data) redraw_marker(active_marker); select_lever_mode(LM_SEARCH); } - +#ifdef __VNA__ static void menu_marker_smith_cb(int item, uint8_t data) { @@ -784,6 +792,7 @@ menu_marker_smith_cb(int item, uint8_t data) redraw_marker(active_marker); draw_menu(); } +#endif static void active_marker_select(int item) @@ -830,7 +839,7 @@ menu_marker_sel_cb(int item, uint8_t data) redraw_marker(active_marker); draw_menu(); } - +#ifdef __VNA__ static const menuitem_t menu_calop[] = { { MT_CALLBACK, CAL_OPEN, "OPEN", menu_calop_cb }, { MT_CALLBACK, CAL_SHORT, "SHORT", menu_calop_cb }, @@ -1035,6 +1044,9 @@ const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "CONFIG", menu_config }, { MT_NONE, 0, NULL, NULL } // sentinel }; +#endif + +#include "ui_sa.c" #define MENU_STACK_DEPTH_MAX 4 const menuitem_t *menu_stack[MENU_STACK_DEPTH_MAX] = { @@ -1127,7 +1139,7 @@ menu_invoke(int item) // Key x, y position (0 - 15) on screen #define KP_GET_X(posx) ((posx)*KP_WIDTH + (320-64-KP_WIDTH*4)) #define KP_GET_Y(posy) ((posy)*KP_HEIGHT + 12 ) - +#ifdef __VNA__ // Key names #define KP_0 0 #define KP_1 1 @@ -1233,6 +1245,7 @@ static const keypads_t * const keypads_mode_tbl[] = { static const char * const keypad_mode_label[] = { "START", "STOP", "CENTER", "SPAN", "CW FREQ", "SCALE", "REFPOS", "EDELAY", "VELOCITY%", "DELAY" }; +#endif static void draw_keypad(void) @@ -1315,6 +1328,7 @@ menu_is_multiline(const char *label, const char **l1, const char **l2) return TRUE; } +#ifdef __VNA__ static void menu_item_modify_attribute(const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) @@ -1384,6 +1398,12 @@ menu_item_modify_attribute(const menuitem_t *menu, int item, } } } +#endif + +#ifndef __VNA__ +extern void menu_item_modify_attribute( + const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg); +#endif static void draw_menu_buttons(const menuitem_t *menu) @@ -1482,6 +1502,7 @@ leave_ui_mode() } } +#ifdef __VNA__ static void fetch_numeric_target(void) { @@ -1528,6 +1549,7 @@ fetch_numeric_target(void) // uistat.previous_value = uistat.value; } + static void set_numeric_value(void) { @@ -1561,6 +1583,7 @@ set_numeric_value(void) break; } } +#endif static void draw_numeric_area(void) @@ -1722,7 +1745,7 @@ lever_move(int status, int mode) } #define STEPRATIO 0.2 - +#ifdef __VNA__ static void lever_edelay(int status) { @@ -1737,7 +1760,7 @@ lever_edelay(int status) } set_electrical_delay(value); } - +#endif static void ui_process_normal(void) { @@ -1758,9 +1781,11 @@ ui_process_normal(void) else lever_zoom_span(status); break; +#ifdef __VNA__ case LM_EDELAY: lever_edelay(status); break; +#endif } } } @@ -1812,6 +1837,10 @@ keypad_click(int key) } /* numeric input done */ double value = my_atof(kp_buf) * scale; +#if 1 + uistat.value = (int)value; + set_numeric_value(); +#else switch (keypad_mode) { case KM_START: set_sweep_frequency(ST_START, value); @@ -1844,7 +1873,7 @@ keypad_click(int key) set_trace_scale(uistat.current_trace, value * 1e-12); // pico second break; } - +#endif return KP_DONE; } else if (c <= 9 && kp_index < NUMINPUT_LEN) { kp_buf[kp_index++] = '0' + c; @@ -2130,11 +2159,15 @@ touch_lever_mode_select(void) return TRUE; } if (touch_y < 25) { +#ifdef __VNA__ if (touch_x < FREQUENCIES_XPOS2 && get_electrical_delay() != 0.0) { select_lever_mode(LM_EDELAY); } else { +#endif select_lever_mode(LM_MARKER); - } +#ifdef __VNA__ + } +#endif return TRUE; } return FALSE; @@ -2191,7 +2224,7 @@ static void extcb1(EXTDriver *extp, expchannel_t channel) (void)extp; (void)channel; operation_requested|=OP_LEVER; - //cur_button = READ_PORT() & BUTTON_MASK; + // cur_button = READ_PORT() & BUTTON_MASK; } static const EXTConfig extcfg = { diff --git a/ui_sa.c b/ui_sa.c new file mode 100644 index 0000000..d6adfd3 --- /dev/null +++ b/ui_sa.c @@ -0,0 +1,826 @@ + +void markmap_all_markers(void); +static void menu_marker_type_cb(int item, uint8_t data); + +void set_sweep_frequency(int type, uint32_t frequency); +uint32_t get_sweep_frequency(int type); +void clearDisplay(void); +//void ui_process_touch(void); +void SetPowerGrid(int); +void SetRefLevel(int); +void set_refer_output(int); +int get_refer_output(void); +void SetAttenuation(int); +void SetPowerLevel(int); +void SetGenerate(int); +void SetRBW(int); +void SetSpur(int); +int GetSpur(void); +void SetAverage(int); +int GetAverage(void); +void SetStorage(void); +void SetClearStorage(void); +void SetSubtractStorage(void); +void toggle_waterfall(void); +void SetMode(int); +int GetMode(void); +void AllDirty(void); +void MenuDirty(void); +void redrawHisto(void); +void self_test(void); +extern int32_t frequencyExtra; +extern int extraVFO; +extern int settingDrive; +extern int settingLNA; +extern int settingAGC; +extern int settingSpeed; +extern int stepDelay; + +enum { + KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE +}; + + +#define KP_X(x) (48*(x) + 2 + (320-BUTTON_WIDTH-192)) +#define KP_Y(y) (48*(y) + 2) + + +#define KP_PERIOD 10 +#define KP_MINUS 11 +#define KP_X1 12 +#define KP_K 13 +#define KP_M 14 +#define KP_G 15 +#define KP_BS 16 +#define KP_INF 17 +#define KP_DB 18 +#define KP_PLUSMINUS 19 +#define KP_KEYPAD 20 +#define KP_N 21 +#define KP_P 22 + + +typedef struct { + uint8_t x:4; + uint8_t y:4; + int8_t c; +} keypads_t; + +static const keypads_t *keypads; + +static uint8_t keypads_last_index; + + +static const keypads_t keypads_freq[] = { + { 1, 3, KP_PERIOD }, + { 0, 3, 0 }, + { 0, 2, 1 }, + { 1, 2, 2 }, + { 2, 2, 3 }, + { 0, 1, 4 }, + { 1, 1, 5 }, + { 2, 1, 6 }, + { 0, 0, 7 }, + { 1, 0, 8 }, + { 2, 0, 9 }, + { 3, 0, KP_G }, + { 3, 1, KP_M }, + { 3, 2, KP_K }, + { 3, 3, KP_X1 }, + { 2, 3, KP_BS }, + { 0, 0, -1 } +}; + +static const keypads_t keypads_scale[] = { + { 1, 3, KP_PERIOD }, + { 0, 3, 0 }, + { 0, 2, 1 }, + { 1, 2, 2 }, + { 2, 2, 3 }, + { 0, 1, 4 }, + { 1, 1, 5 }, + { 2, 1, 6 }, + { 0, 0, 7 }, + { 1, 0, 8 }, + { 2, 0, 9 }, + { 3, 3, KP_X1 }, + { 2, 3, KP_BS }, + { 0, 0, -1 } +}; + +static const keypads_t keypads_level[] = { + { 1, 3, KP_PERIOD }, + { 0, 3, 0 }, + { 0, 2, 1 }, + { 1, 2, 2 }, + { 2, 2, 3 }, + { 0, 1, 4 }, + { 1, 1, 5 }, + { 2, 1, 6 }, + { 0, 0, 7 }, + { 1, 0, 8 }, + { 2, 0, 9 }, + { 3, 2, KP_MINUS }, + { 3, 3, KP_X1 }, + { 2, 3, KP_BS }, + { 0, 0, -1 } +}; + + +static const keypads_t * const keypads_mode_tbl[] = { + keypads_freq, // start + keypads_freq, // stop + keypads_freq, // center + keypads_freq, // span + keypads_freq, // cw freq + keypads_level, // refpos + keypads_scale, // scale + keypads_scale, // attenuation + keypads_level, // actual power + keypads_freq, // IF + keypads_level, // sample time + keypads_scale, // drive +}; + +#ifdef __VNA__ +static const char * const keypad_mode_label[] = { + "START", "STOP", "CENTER", "SPAN", "CW FREQ", "SCALE", "REFPOS", "EDELAY", "VELOCITY%", "DELAY" +}; +#endif +#ifdef __SA__ +static const char * const keypad_mode_label[] = { + "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "ATTENUATION", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE" +}; +#endif + + +// ===[MENU CALLBACKS]========================================================= + + +int generator_enabled = false; + +static void menu_mode_cb(int item, uint8_t data) +{ + (void)data; + switch (item) { + case 4: // Change reference output + break; + default: + SetMode(item); + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); + break; + } + +} + +extern int dirty; +void menu_autosettings_cb(int item, uint8_t data) +{ + (void)item; + (void)data; + SetMode(M_LOW); +// set_sweep_frequency(ST_START, (int32_t) 0); +// set_sweep_frequency(ST_STOP, (int32_t) 300000000); + + int value = 10; // 10dB/ + set_trace_scale(0, value); + set_trace_scale(1, value); + set_trace_scale(2, value); + + value = -10; // Top at -10dB + set_trace_refpos(0, - value / get_trace_scale(0) + NGRIDY); + set_trace_refpos(1, - value / get_trace_scale(0) + NGRIDY); + set_trace_refpos(2, - value / get_trace_scale(0) + NGRIDY); + + active_marker = 0; + menu_marker_type_cb(M_REFERENCE,M_REFERENCE); + + set_refer_output(1); + SetAttenuation(0); + SetPowerLevel(100); // Reset + SetRBW(0); + dirty = true; + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); +} + +static void menu_config_cb(int item, uint8_t data) +{ + (void)data; + switch (item) { + case 0: + touch_cal_exec(); + redraw_frame(); + request_to_redraw_grid(); + draw_menu(); + break; + case 1: + touch_draw_test(); + redraw_frame(); + request_to_redraw_grid(); + draw_menu(); + break; + case 2: + menu_move_back(); + ui_mode_normal(); + self_test(); + break; + case 3: + show_version(); + redraw_frame(); + request_to_redraw_grid(); + draw_menu(); + } +} + +static void menu_dfu_cb(int item, uint8_t data) +{ + (void)data; + switch (item) { + case 0: + enter_dfu(); + } +} + +int menu_refer_value[]={-1,0,1,2,3,4,5,6}; +static void menu_refer_cb(int item, uint8_t data) +{ + (void)data; +//Serial.println(item); + set_refer_output(menu_refer_value[item]); + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); +} + +static void menu_refer_cb2(int item, uint8_t data) +{ + (void)data; +//Serial.println(item); + set_refer_output(menu_refer_value[item+5]); + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); +} + +static void menu_spur_cb(int item, uint8_t data) +{ + (void)data; + (void)item; + if (GetSpur()) + SetSpur(0); + else + SetSpur(1); // must be 0 or 1 !!!! + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); +} + +static void menu_storage_cb(int item, uint8_t data) +{ + (void)data; + switch(item) { + case 0: + SetStorage(); + break; + case 1: + SetClearStorage(); + break; + case 2: + SetSubtractStorage(); + break; + case 3: + toggle_waterfall(); + break; + } + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); +} + +static void menu_average_cb(int item, uint8_t data) +{ + (void)data; + SetAverage(item); + menu_move_back(); + ui_mode_normal(); + draw_cal_status(); +} + +static void menu_marker_type_cb(int item, uint8_t data) +{ + (void)data; + if (markers[active_marker].enabled) + { + if (item == M_REFERENCE) { + for (int i = 0; i= 10 && n < 9; n++) + x /= 10; + uistat.digit = n; + } +// uistat.previous_value = uistat.value; +} + + +static void +set_numeric_value(void) +{ + switch (keypad_mode) { + case KM_START: + set_sweep_frequency(ST_START, uistat.value); + break; + case KM_STOP: + set_sweep_frequency(ST_STOP, uistat.value); + break; + case KM_CENTER: + set_sweep_frequency(ST_CENTER, uistat.value); + break; + case KM_SPAN: + set_sweep_frequency(ST_SPAN, uistat.value); + break; + case KM_CW: + set_sweep_frequency(ST_CW, uistat.value); + break; + case KM_SCALE: + set_trace_scale(0, uistat.value / 1000.0); + set_trace_scale(1, uistat.value / 1000.0); + set_trace_scale(2, uistat.value / 1000.0); + break; + case KM_REFPOS: + set_trace_refpos(0, NGRIDY - uistat.value / get_trace_scale(0)); + set_trace_refpos(1, NGRIDY - uistat.value / get_trace_scale(0)); + set_trace_refpos(2, NGRIDY - uistat.value / get_trace_scale(0)); + break; + case KM_ATTENUATION: + SetAttenuation(uistat.value); + break; + case KM_ACTUALPOWER: + SetPowerLevel(uistat.value); + config_save(); + break; + case KM_IF: + frequency_IF = uistat.value; + config_save(); + break; + case KM_SAMPLETIME: + settingSpeed = uistat.value; + break; + case KM_DRIVE: + settingDrive = uistat.value; + break; + } +} From f2137f4f97f079479c2a2726111b996fca258263 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 23 Mar 2020 09:49:01 +0100 Subject: [PATCH 003/193] All except waterfall working --- Font7x13b.c | 3959 +++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- chconf.h | 2 +- ili9341.c | 13 +- main.c | 30 +- nanovna.h | 11 +- plot.c | 107 +- sa_core.c | 50 +- ui.c | 7 +- ui_sa.c | 3 +- 10 files changed, 4136 insertions(+), 48 deletions(-) create mode 100644 Font7x13b.c diff --git a/Font7x13b.c b/Font7x13b.c new file mode 100644 index 0000000..b3656b2 --- /dev/null +++ b/Font7x13b.c @@ -0,0 +1,3959 @@ +/* Generated by convbdf on Mon Apr 29 14:40:18 2019. */ + +/* Font information: + name: 7x13B + facename: -Misc-Fixed-Bold-R-Normal--13-120-75-75-C-70-ISO8859-2 + w x h: 7x13 + size: 127 + ascent: 11 + descent: 2 + first char: 0 (0x00) + last char: 126 (0x7e) + default char: 0 (0x00) + proportional: no + Public domain font. Share and enjoy. Copyright (c) 1996 BIZNET Poland, Inc. All Rights Reserved. +*/ + +#include + +/* Font character bitmap data. */ +const uint16_t x7x13b_bits [] = +{ + + /* Character 0 (0x00): + width 7 + +-------+ + | | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | ***** | + | | + +-------+ */ + 0x0000, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x7c00, + 0x0000, + + /* Character 1 (0x01): + width 7 + +-------+ + | | + | | + | | + | | + | | + | ** | + | **** | + |****** | + | **** | + | ** | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0xfc00, + 0x7800, + 0x3000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 2 (0x02): + width 7 + +-------+ + | | + |** ** | + | ** | + |** ** | + | ** | + |** ** | + | ** | + |** ** | + | ** | + |** ** | + | ** | + |** ** | + | | + +-------+ */ + 0x0000, + 0xcc00, + 0x3000, + 0xcc00, + 0x3000, + 0xcc00, + 0x3000, + 0xcc00, + 0x3000, + 0xcc00, + 0x3000, + 0xcc00, + 0x0000, + + /* Character 3 (0x03): + width 7 + +-------+ + | | + |** ** | + |** ** | + |***** | + |** ** | + |** ** | + | | + | **** | + | ** | + | ** | + | ** | + | ** | + | | + +-------+ */ + 0x0000, + 0xd800, + 0xd800, + 0xf800, + 0xd800, + 0xd800, + 0x0000, + 0x3c00, + 0x1800, + 0x1800, + 0x1800, + 0x1800, + 0x0000, + + /* Character 4 (0x04): + width 7 + +-------+ + | | + |**** | + |** | + |*** | + |** | + |** | + | | + | **** | + | ** | + | *** | + | ** | + | ** | + | | + +-------+ */ + 0x0000, + 0xf000, + 0xc000, + 0xe000, + 0xc000, + 0xc000, + 0x0000, + 0x3c00, + 0x3000, + 0x3800, + 0x3000, + 0x3000, + 0x0000, + + /* Character 5 (0x05): + width 7 + +-------+ + | | + | *** | + |** | + |** | + |** | + | *** | + | | + | *** | + | ** * | + | *** | + | ** * | + | ** * | + | | + +-------+ */ + 0x0000, + 0x7000, + 0xc000, + 0xc000, + 0xc000, + 0x7000, + 0x0000, + 0x3800, + 0x3400, + 0x3800, + 0x3400, + 0x3400, + 0x0000, + + /* Character 6 (0x06): + width 7 + +-------+ + | | + |** | + |** | + |** | + |** | + |**** | + | | + | **** | + | ** | + | *** | + | ** | + | ** | + | | + +-------+ */ + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xf000, + 0x0000, + 0x3c00, + 0x3000, + 0x3800, + 0x3000, + 0x3000, + 0x0000, + + /* Character 7 (0x07): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + | **** | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 8 (0x08): + width 7 + +-------+ + | | + | | + | ** | + | ** | + |****** | + |****** | + | ** | + | ** | + | | + |****** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x3000, + 0xfc00, + 0xfc00, + 0x3000, + 0x3000, + 0x0000, + 0xfc00, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 9 (0x09): + width 7 + +-------+ + | | + |** ** | + |*** ** | + |****** | + |** *** | + |** ** | + | | + | ** | + | ** | + | ** | + | ** | + | **** | + | | + +-------+ */ + 0x0000, + 0xcc00, + 0xec00, + 0xfc00, + 0xdc00, + 0xcc00, + 0x0000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3c00, + 0x0000, + + /* Character 10 (0x0a): + width 7 + +-------+ + | | + |** ** | + |** ** | + | * * | + | **** | + | ** | + | | + | **** | + | ** | + | ** | + | ** | + | ** | + | | + +-------+ */ + 0x0000, + 0xcc00, + 0xcc00, + 0x4800, + 0x7800, + 0x3000, + 0x0000, + 0x3c00, + 0x1800, + 0x1800, + 0x1800, + 0x1800, + 0x0000, + + /* Character 11 (0x0b): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |**** | + |**** | + | | + | | + | | + | | + | | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xf000, + 0xf000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 12 (0x0c): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + |**** | + |**** | + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xf000, + 0xf000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 13 (0x0d): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | *****| + | *****| + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3e00, + 0x3e00, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 14 (0x0e): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | *****| + | *****| + | | + | | + | | + | | + | | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3e00, + 0x3e00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 15 (0x0f): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |*******| + |*******| + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xfe00, + 0xfe00, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 16 (0x10): + width 7 + +-------+ + | | + | | + |*******| + |*******| + | | + | | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfe00, + 0xfe00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 17 (0x11): + width 7 + +-------+ + | | + | | + | | + | | + |*******| + |*******| + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfe00, + 0xfe00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 18 (0x12): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + |*******| + |*******| + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfe00, + 0xfe00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 19 (0x13): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | | + | | + |*******| + |*******| + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfe00, + 0xfe00, + 0x0000, + 0x0000, + 0x0000, + + /* Character 20 (0x14): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + |*******| + |*******| + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfe00, + 0xfe00, + 0x0000, + + /* Character 21 (0x15): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | *****| + | *****| + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3e00, + 0x3e00, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 22 (0x16): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |**** | + |**** | + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xf000, + 0xf000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 23 (0x17): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |*******| + |*******| + | | + | | + | | + | | + | | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xfe00, + 0xfe00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 24 (0x18): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + |*******| + |*******| + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfe00, + 0xfe00, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 25 (0x19): + width 7 + +-------+ + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + +-------+ */ + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + + /* Character 26 (0x1a): + width 7 + +-------+ + | | + | | + | | + | * | + | ** | + |****** | + |****** | + | ** | + | * | + | | + | | + | | + | | + +-------+ */ +0x0000, +0x0000, +0x0000, +0x2000, +0x6000, +0xfc00, +0xfc00, +0x6000, +0x2000, +0x0000, +0x0000, +0x0000, +0x0000, + /* Character 27 (0x1b): + width 7 + +-------+ + | | + | | + | | + | * | + | ** | + |****** | + |****** | + | ** | + | * | + | | + | | + | | + | | + +-------+ */ +0x0000, +0x0000, +0x0000, +0x1000, +0x1800, +0xfc00, +0xfc00, +0x1800, +0x1000, +0x0000, +0x0000, +0x0000, +0x0000, + + + /* Character 28 (0x1c): + width 7 + +-------+ + | | + | | + | | + | | + | | + |****** | + | ** ** | + | ** ** | + | ** ** | + |*** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfc00, + 0x6c00, + 0x6c00, + 0x6c00, + 0xec00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 29 (0x1d): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |****** | + |** | + |** | + +-------+ */ +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0xcc00, +0xcc00, +0xcc00, +0xcc00, +0xcc00, +0xfc00, +0xc000, +0xc000, + /* Character 30 (0x1e): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | * * | + | * * | + |** ** | + | | + | | + +-------+ */ +0x0000, +0x0000, +0x7800, +0xcc00, +0xcc00, +0xcc00, +0xcc00, +0xcc00, +0x4800, +0x4800, +0xcc00, +0x0000, +0x0000, + + /* Character 31 (0x1f): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + | **** | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ +0x0000, +0x0000, +0x7800, +0xcc00, +0xcc00, +0x7800, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, + + /* Character 32 (0x20): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 33 (0x21): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x0000, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + + /* Character 34 (0x22): + width 7 + +-------+ + | | + | | + | ** ** | + | ** ** | + | ** ** | + | | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x6c00, + 0x6c00, + 0x6c00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 35 (0x23): + width 7 + +-------+ + | | + | | + | * * | + | * * | + | ***** | + | ***** | + | * * | + | ***** | + | ***** | + | * * | + | * * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x2800, + 0x2800, + 0x7c00, + 0x7c00, + 0x2800, + 0x7c00, + 0x7c00, + 0x2800, + 0x2800, + 0x0000, + 0x0000, + + /* Character 36 (0x24): + width 7 + +-------+ + | | + | | + | ** | + | **** | + |* ** * | + |* ** | + | **** | + | ** * | + |* ** * | + | **** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0xb400, + 0xb000, + 0x7800, + 0x3400, + 0xb400, + 0x7800, + 0x3000, + 0x0000, + 0x0000, + + /* Character 37 (0x25): + width 7 + +-------+ + | | + | | + |*** * | + |* * ** | + |*** * | + | ** | + | ** | + | ** | + | * *** | + |** * * | + |* *** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xe400, + 0xac00, + 0xe800, + 0x1800, + 0x3000, + 0x6000, + 0x5c00, + 0xd400, + 0x9c00, + 0x0000, + 0x0000, + + /* Character 38 (0x26): + width 7 + +-------+ + | | + | | + | *** | + |** ** | + |** ** | + |** ** | + | *** | + |** * * | + |** *** | + |** ** | + | *** * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7000, + 0xd800, + 0xd800, + 0xd800, + 0x7000, + 0xd400, + 0xdc00, + 0xd800, + 0x7400, + 0x0000, + 0x0000, + + /* Character 39 (0x27): + width 7 + +-------+ + | | + | | + | *** | + | *** | + | ** | + | ** | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3800, + 0x3800, + 0x3000, + 0x6000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 40 (0x28): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x1800, + 0x3000, + 0x3000, + 0x6000, + 0x6000, + 0x6000, + 0x3000, + 0x3000, + 0x1800, + 0x0000, + 0x0000, + + /* Character 41 (0x29): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x6000, + 0x3000, + 0x3000, + 0x1800, + 0x1800, + 0x1800, + 0x3000, + 0x3000, + 0x6000, + 0x0000, + 0x0000, + + /* Character 42 (0x2a): + width 7 + +-------+ + | | + | | + | | + | | + | * * | + | ** | + |****** | + |****** | + | ** | + | * * | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x4800, + 0x3000, + 0xfc00, + 0xfc00, + 0x3000, + 0x4800, + 0x0000, + 0x0000, + 0x0000, + + /* Character 43 (0x2b): + width 7 + +-------+ + | | + | | + | | + | | + | ** | + | ** | + |****** | + |****** | + | ** | + | ** | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3000, + 0x3000, + 0xfc00, + 0xfc00, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 44 (0x2c): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | | + | | + | *** | + | *** | + | ** | + | ** | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3800, + 0x3800, + 0x3000, + 0x6000, + 0x0000, + + /* Character 45 (0x2d): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + |****** | + |****** | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfc00, + 0xfc00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 46 (0x2e): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | | + | | + | | + | ** | + | **** | + | ** | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0x3000, + 0x0000, + + /* Character 47 (0x2f): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |** | + |** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0c00, + 0x0c00, + 0x1800, + 0x1800, + 0x3000, + 0x6000, + 0x6000, + 0xc000, + 0xc000, + 0x0000, + 0x0000, + /* Character 48 (0x30): + width 7 + +-------+ + | | + | | + | ** | + | * * | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | * * | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x4800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x4800, + 0x3000, + 0x0000, + 0x0000, + + /* Character 49 (0x31): + width 7 + +-------+ + | | + | | + | ** | + | *** | + |* ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x7000, + 0xb000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 50 (0x32): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + | ** | + | *** | + | ** | + |** | + |** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0x0c00, + 0x3800, + 0x6000, + 0xc000, + 0xc000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 51 (0x33): + width 7 + +-------+ + | | + | | + |****** | + | ** | + | ** | + | ** | + | **** | + | ** | + | ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0x0c00, + 0x1800, + 0x3000, + 0x7800, + 0x0c00, + 0x0c00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 52 (0x34): + width 7 + +-------+ + | | + | | + | ** | + | *** | + | **** | + | ** ** | + |** ** | + |** ** | + |****** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0c00, + 0x1c00, + 0x3c00, + 0x6c00, + 0xcc00, + 0xcc00, + 0xfc00, + 0x0c00, + 0x0c00, + 0x0000, + 0x0000, + + /* Character 53 (0x35): + width 7 + +-------+ + | | + | | + |****** | + |** | + |** | + |***** | + |** ** | + | ** | + | ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0xc000, + 0xc000, + 0xf800, + 0xcc00, + 0x0c00, + 0x0c00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 54 (0x36): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** | + |** | + |***** | + |** ** | + |** ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xc000, + 0xc000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 55 (0x37): + width 7 + +-------+ + | | + | | + |****** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0x0c00, + 0x0c00, + 0x1800, + 0x1800, + 0x3000, + 0x3000, + 0x6000, + 0x6000, + 0x0000, + 0x0000, + + /* Character 56 (0x38): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + | **** | + |** ** | + |** ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 57 (0x39): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + | ***** | + | ** | + | ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0c00, + 0x0c00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 58 (0x3a): + width 7 + +-------+ + | | + | | + | | + | | + | ** | + | **** | + | ** | + | | + | | + | ** | + | **** | + | ** | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0x3000, + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0x3000, + 0x0000, + + /* Character 59 (0x3b): + width 7 + +-------+ + | | + | | + | | + | | + | ** | + | **** | + | ** | + | | + | *** | + | *** | + | ** | + | ** | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0x3000, + 0x0000, + 0x3800, + 0x3800, + 0x3000, + 0x6000, + 0x0000, + + /* Character 60 (0x3c): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + |** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0c00, + 0x1800, + 0x3000, + 0x6000, + 0xc000, + 0x6000, + 0x3000, + 0x1800, + 0x0c00, + 0x0000, + 0x0000, + + /* Character 61 (0x3d): + width 7 + +-------+ + | | + | | + | | + | | + | | + |****** | + | | + | | + |****** | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfc00, + 0x0000, + 0x0000, + 0xfc00, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 62 (0x3e): + width 7 + +-------+ + | | + | | + |** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc000, + 0x6000, + 0x3000, + 0x1800, + 0x0c00, + 0x1800, + 0x3000, + 0x6000, + 0xc000, + 0x0000, + 0x0000, + + /* Character 63 (0x3f): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + | ** | + | *** | + | ** | + | | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0x0c00, + 0x3800, + 0x3000, + 0x0000, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + + /* Character 64 (0x40): + width 7 + +-------+ + | | + | | + | **** | + |* ** | + |* ** | + |* **** | + |* * ** | + |* **** | + |* | + |* ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0x8c00, + 0x8c00, + 0xbc00, + 0xac00, + 0xbc00, + 0x8000, + 0x8c00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 65 (0x41): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + |****** | + |** ** | + |** ** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xfc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 66 (0x42): + width 7 + +-------+ + | | + | | + |***** | + |** ** | + |** ** | + |** ** | + |***** | + |** ** | + |** ** | + |** ** | + |***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0x0000, + 0x0000, + + /* Character 67 (0x43): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** | + |** | + |** | + |** | + |** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 68 (0x44): + width 7 + +-------+ + | | + | | + |***** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0x0000, + 0x0000, + + /* Character 69 (0x45): + width 7 + +-------+ + | | + | | + |****** | + |** | + |** | + |** | + |***** | + |** | + |** | + |** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0xc000, + 0xc000, + 0xc000, + 0xf800, + 0xc000, + 0xc000, + 0xc000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 70 (0x46): + width 7 + +-------+ + | | + | | + |****** | + |** | + |** | + |** | + |***** | + |** | + |** | + |** | + |** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0xc000, + 0xc000, + 0xc000, + 0xf800, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x0000, + + /* Character 71 (0x47): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** | + |** | + |** *** | + |** ** | + |** ** | + |** ** | + | ***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xc000, + 0xc000, + 0xdc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0000, + 0x0000, + + /* Character 72 (0x48): + width 7 + +-------+ + | | + | | + |** ** | + |** ** | + |** ** | + |** ** | + |****** | + |** ** | + |** ** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xfc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 73 (0x49): + width 7 + +-------+ + | | + | | + |****** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 74 (0x4a): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 75 (0x4b): + width 7 + +-------+ + | | + | | + |** * | + |** ** | + |** ** | + |**** | + |*** | + |**** | + |** ** | + |** ** | + |** * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc400, + 0xcc00, + 0xd800, + 0xf000, + 0xe000, + 0xf000, + 0xd800, + 0xcc00, + 0xc400, + 0x0000, + 0x0000, + + /* Character 76 (0x4c): + width 7 + +-------+ + | | + | | + |** | + |** | + |** | + |** | + |** | + |** | + |** | + |** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 77 (0x4d): + width 7 + +-------+ + | | + | | + |* * | + |** ** | + |****** | + |****** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x8400, + 0xcc00, + 0xfc00, + 0xfc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 78 (0x4e): + width 7 + +-------+ + | | + | | + |** ** | + |** ** | + |*** ** | + |*** ** | + |****** | + |** *** | + |** *** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xec00, + 0xec00, + 0xfc00, + 0xdc00, + 0xdc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 79 (0x4f): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 80 (0x50): + width 7 + +-------+ + | | + | | + |***** | + |** ** | + |** ** | + |** ** | + |***** | + |** | + |** | + |** | + |** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x0000, + + /* Character 81 (0x51): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |*** ** | + |** *** | + | **** | + | ** | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xec00, + 0xdc00, + 0x7800, + 0x0c00, + 0x0000, + + /* Character 82 (0x52): + width 7 + +-------+ + | | + | | + |***** | + |** ** | + |** ** | + |** ** | + |***** | + |**** | + |** ** | + |** ** | + |** * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0xf000, + 0xd800, + 0xcc00, + 0xc400, + 0x0000, + 0x0000, + + /* Character 83 (0x53): + width 7 + +-------+ + | | + | | + | **** | + |** ** | + |** | + |** | + | **** | + | ** | + | ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xc000, + 0xc000, + 0x7800, + 0x0c00, + 0x0c00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 84 (0x54): + width 7 + +-------+ + | | + | | + |****** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + + /* Character 85 (0x55): + width 7 + +-------+ + | | + | | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 86 (0x56): + width 7 + +-------+ + | | + | | + |** ** | + |** ** | + |** ** | + | * * | + | * * | + | **** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0x4800, + 0x4800, + 0x7800, + 0x3000, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + + /* Character 87 (0x57): + width 7 + +-------+ + | | + | | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + |****** | + |****** | + |** ** | + |* * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xfc00, + 0xfc00, + 0xcc00, + 0x8400, + 0x0000, + 0x0000, + + /* Character 88 (0x58): + width 7 + +-------+ + | | + | | + |* * | + |** ** | + | * * | + | **** | + | ** | + | **** | + | * * | + |** ** | + |* * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x8400, + 0xcc00, + 0x4800, + 0x7800, + 0x3000, + 0x7800, + 0x4800, + 0xcc00, + 0x8400, + 0x0000, + 0x0000, + + /* Character 89 (0x59): + width 7 + +-------+ + | | + | | + |** ** | + |** ** | + | **** | + | **** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0x7800, + 0x7800, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + + /* Character 90 (0x5a): + width 7 + +-------+ + | | + | | + |****** | + | ** | + | ** | + | ** | + | ** | + | ** | + |** | + |** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xfc00, + 0x0c00, + 0x0c00, + 0x1800, + 0x3000, + 0x6000, + 0xc000, + 0xc000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 91 (0x5b): + width 7 + +-------+ + | | + | | + | **** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0x6000, + 0x6000, + 0x6000, + 0x6000, + 0x6000, + 0x6000, + 0x6000, + 0x7800, + 0x0000, + 0x0000, + + /* Character 92 (0x5c): + width 7 + +-------+ + | | + | | + |** | + |** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc000, + 0xc000, + 0x6000, + 0x6000, + 0x3000, + 0x1800, + 0x1800, + 0x0c00, + 0x0c00, + 0x0000, + 0x0000, + + /* Character 93 (0x5d): + width 7 + +-------+ + | | + | | + | **** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7800, + 0x1800, + 0x1800, + 0x1800, + 0x1800, + 0x1800, + 0x1800, + 0x1800, + 0x7800, + 0x0000, + 0x0000, + + /* Character 94 (0x5e): + width 7 + +-------+ + | | + | | + | ** | + | **** | + |** ** | + |* * | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x7800, + 0xcc00, + 0x8400, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 95 (0x5f): + width 7 + +-------+ + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + |****** | + |****** | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfc00, + 0xfc00, + 0x0000, + + /* Character 96 (0x60): + width 7 + +-------+ + | | + | ** | + | ** | + | ** | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x6000, + 0x3000, + 0x1800, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 97 (0x61): + width 7 + +-------+ + | | + | | + | | + | | + | | + | **** | + | ** | + | ***** | + |** ** | + |** ** | + | ***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7800, + 0x0c00, + 0x7c00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0000, + 0x0000, + + /* Character 98 (0x62): + width 7 + +-------+ + | | + | | + |** | + |** | + |** | + |***** | + |** ** | + |** ** | + |** ** | + |** ** | + |***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0x0000, + 0x0000, + + /* Character 99 (0x63): + width 7 + +-------+ + | | + | | + | | + | | + | | + | **** | + |** ** | + |** | + |** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xc000, + 0xc000, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 100 (0x64): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ***** | + |** ** | + |** ** | + |** ** | + |** ** | + | ***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0c00, + 0x0c00, + 0x0c00, + 0x7c00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0000, + 0x0000, + + /* Character 101 (0x65): + width 7 + +-------+ + | | + | | + | | + | | + | | + | **** | + |** ** | + |****** | + |** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xfc00, + 0xc000, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 102 (0x66): + width 7 + +-------+ + | | + | | + | *** | + | ** ** | + | ** | + | ** | + |**** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3800, + 0x6c00, + 0x6000, + 0x6000, + 0xf000, + 0x6000, + 0x6000, + 0x6000, + 0x6000, + 0x0000, + 0x0000, + + /* Character 103 (0x67): + width 7 + +-------+ + | | + | | + | | + | | + | | + | *** * | + |** ** | + |** ** | + | **** | + |** | + | **** | + |** ** | + | **** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7400, + 0xcc00, + 0xcc00, + 0x7800, + 0xc000, + 0x7800, + 0xcc00, + 0x7800, + + /* Character 104 (0x68): + width 7 + +-------+ + | | + | | + |** | + |** | + |** | + |***** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 105 (0x69): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | | + | *** | + | ** | + | ** | + | ** | + | ** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x3000, + 0x0000, + 0x7000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 106 (0x6a): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |** ** | + | **** | + +-------+ */ + 0x0000, + 0x0000, + 0x0c00, + 0x0c00, + 0x0000, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0x0c00, + 0xcc00, + 0x7800, + + /* Character 107 (0x6b): + width 7 + +-------+ + | | + | | + |** | + |** | + |** | + |** ** | + |** ** | + |**** | + |**** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0xc000, + 0xc000, + 0xc000, + 0xcc00, + 0xd800, + 0xf000, + 0xf000, + 0xd800, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 108 (0x6c): + width 7 + +-------+ + | | + | | + | *** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 109 (0x6d): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |****** | + |****** | + |** ** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xd800, + 0xfc00, + 0xfc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 110 (0x6e): + width 7 + +-------+ + | | + | | + | | + | | + | | + |***** | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 111 (0x6f): + width 7 + +-------+ + | | + | | + | | + | | + | | + | **** | + |** ** | + |** ** | + |** ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 112 (0x70): + width 7 + +-------+ + | | + | | + | | + | | + | | + |***** | + |** ** | + |** ** | + |** ** | + |***** | + |** | + |** | + |** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xcc00, + 0xcc00, + 0xf800, + 0xc000, + 0xc000, + 0xc000, + + /* Character 113 (0x71): + width 7 + +-------+ + | | + | | + | | + | | + | | + | ***** | + |** ** | + |** ** | + |** ** | + | ***** | + | ** | + | ** | + | ** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7c00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0c00, + 0x0c00, + 0x0c00, + + /* Character 114 (0x72): + width 7 + +-------+ + | | + | | + | | + | | + | | + |***** | + |** ** | + |** | + |** | + |** | + |** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xf800, + 0xcc00, + 0xc000, + 0xc000, + 0xc000, + 0xc000, + 0x0000, + 0x0000, + + /* Character 115 (0x73): + width 7 + +-------+ + | | + | | + | | + | | + | | + | **** | + |** ** | + | ** | + | ** | + |** ** | + | **** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x7800, + 0xcc00, + 0x6000, + 0x1800, + 0xcc00, + 0x7800, + 0x0000, + 0x0000, + + /* Character 116 (0x74): + width 7 + +-------+ + | | + | | + | | + | ** | + | ** | + |***** | + | ** | + | ** | + | ** | + | ** ** | + | *** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x6000, + 0x6000, + 0xf800, + 0x6000, + 0x6000, + 0x6000, + 0x6c00, + 0x3800, + 0x0000, + 0x0000, + + /* Character 117 (0x75): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |** ** | + |** ** | + |** ** | + |** ** | + | ***** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0000, + 0x0000, + + /* Character 118 (0x76): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |** ** | + |** ** | + | **** | + | **** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7800, + 0x7800, + 0x3000, + 0x0000, + 0x0000, + + /* Character 119 (0x77): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |** ** | + |** ** | + |****** | + |****** | + | * * | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0xfc00, + 0xfc00, + 0x4800, + 0x0000, + 0x0000, + + /* Character 120 (0x78): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |** ** | + | **** | + | **** | + |** ** | + |** ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0x7800, + 0x7800, + 0xcc00, + 0xcc00, + 0x0000, + 0x0000, + + /* Character 121 (0x79): + width 7 + +-------+ + | | + | | + | | + | | + | | + |** ** | + |** ** | + |** ** | + |** ** | + | ***** | + | ** | + |** ** | + | **** | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xcc00, + 0xcc00, + 0xcc00, + 0xcc00, + 0x7c00, + 0x0c00, + 0xcc00, + 0x7800, + + /* Character 122 (0x7a): + width 7 + +-------+ + | | + | | + | | + | | + | | + |****** | + | ** | + | ** | + | ** | + |** | + |****** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0xfc00, + 0x0c00, + 0x1800, + 0x6000, + 0xc000, + 0xfc00, + 0x0000, + 0x0000, + + /* Character 123 (0x7b): + width 7 + +-------+ + | | + | | + | *** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | *** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3800, + 0x6000, + 0x6000, + 0x3000, + 0x6000, + 0x3000, + 0x6000, + 0x6000, + 0x3800, + 0x0000, + 0x0000, + + /* Character 124 (0x7c): + width 7 + +-------+ + | | + | | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x3000, + 0x0000, + 0x0000, + + /* Character 125 (0x7d): + width 7 + +-------+ + | | + | | + | *** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | ** | + | *** | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x7000, + 0x1800, + 0x1800, + 0x3000, + 0x1800, + 0x3000, + 0x1800, + 0x1800, + 0x7000, + 0x0000, + 0x0000, + + /* Character 126 (0x7e): + width 7 + +-------+ + | | + | | + | ** * | + |****** | + |* ** | + | | + | | + | | + | | + | | + | | + | | + | | + +-------+ */ + 0x0000, + 0x0000, + 0x6400, + 0xfc00, + 0x9800, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; + + diff --git a/Makefile b/Makefile index 7fdcd84..e16ea2e 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,7 @@ CSRC = $(STARTUPSRC) \ $(BOARDSRC) \ $(STREAMSSRC) \ usbcfg.c \ - main.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c flash.c adc.c si4432.c + main.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c flash.c adc.c si4432.c Font7x13b.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. diff --git a/chconf.h b/chconf.h index fd54b74..08860ae 100644 --- a/chconf.h +++ b/chconf.h @@ -147,7 +147,7 @@ * * @note The default is @p TRUE. */ -#define CH_CFG_USE_REGISTRY FALSE +#define CH_CFG_USE_REGISTRY TRUE /** * @brief Threads synchronization APIs. diff --git a/ili9341.c b/ili9341.c index f1e4674..a1942ab 100644 --- a/ili9341.c +++ b/ili9341.c @@ -383,7 +383,7 @@ void ili9341_bulk(int x, int y, int w, int h) SPI_WRITE_16BIT(*buf++); } } - +#else static uint8_t ssp_sendrecvdata(void) { // Start RX clock (by sending data) @@ -417,7 +417,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) } CS_HIGH; } -#else + // // Use DMA for send data // @@ -469,7 +469,7 @@ void ili9341_bulk(int x, int y, int w, int h) STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC); dmaStreamFlush(w * h); } - +#if 0 // Read DMA hangs // Copy screen data to buffer // Warning!!! buffer size must be greater then 3*len + 1 bytes void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) @@ -516,6 +516,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) } } #endif +#endif void ili9341_clear_screen(void) { @@ -567,6 +568,12 @@ static void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_ ili9341_bulk(x, y, width, height); } +int ili9341_size = 1; + +void ili9341_charsize(int s) +{ + ili9341_size = s; +} void ili9341_drawchar(uint8_t ch, int x, int y) { blit8BitWidthBitmap(x, y, FONT_GET_WIDTH(ch), FONT_GET_HEIGHT, FONT_GET_DATA(ch)); diff --git a/main.c b/main.c index d25530c..8a4007f 100644 --- a/main.c +++ b/main.c @@ -71,7 +71,7 @@ static volatile vna_shellcmd_t shell_function = 0; //#define ENABLED_DUMP // Allow get threads debug info -//#define ENABLE_THREADS_COMMAND +#define ENABLE_THREADS_COMMAND // RTC time not used //#define ENABLE_TIME_COMMAND // Enable vbat_offset command, allow change battery voltage correction in config @@ -117,7 +117,7 @@ const char *info_about[]={ 0 // sentinel }; -static THD_WORKING_AREA(waThread1, 700); +static THD_WORKING_AREA(waThread1, 750); static THD_FUNCTION(Thread1, arg) { (void)arg; @@ -786,7 +786,8 @@ config_t config = { .harmonic_freq_threshold = 300000000, #endif .vbat_offset = 500, - .level_offset = 0 + .low_level_offset = 0, + .high_level_offset = 0, }; properties_t current_props; @@ -2221,6 +2222,14 @@ VNA_SHELL_FUNCTION(cmd_o) setFreq(VFO, value); } +VNA_SHELL_FUNCTION(cmd_d) +{ + (void) argc; + int32_t a = my_atoi(argv[0]); + settingDrive = a; +} + + VNA_SHELL_FUNCTION(cmd_a) { (void)argc; @@ -2289,8 +2298,12 @@ VNA_SHELL_FUNCTION(cmd_p) int a = my_atoi(argv[1]); if (p==5) SetAttenuation(-a); -// if (p==6) -// SetMode(a); + if (p==6) + if (a != GetMode()) + SetMode(a); + if (p==1) + if (get_refer_output() != a) + set_refer_output(a); } VNA_SHELL_FUNCTION(cmd_w) @@ -2383,7 +2396,8 @@ static const VNAShellCommand commands[] = { "m", cmd_m, 0 }, { "p", cmd_p, 0 }, { "w", cmd_w, 0 }, - { "o", cmd_o, 0 }, + { "o", cmd_o, 0 }, + { "d", cmd_d, 0 }, #ifdef ENABLE_THREADS_COMMAND {"threads" , cmd_threads , 0}, #endif @@ -2539,12 +2553,12 @@ static const I2CConfig i2ccfg = { .cr1 = 0, // CR1 register initialization. .cr2 = 0 // CR2 register initialization. }; -#endif static DACConfig dac1cfg1 = { //init: 2047U, init: 1922U, datamode: DAC_DHRM_12BIT_RIGHT }; +#endif // Main thread stack size defined in makefile USE_PROCESS_STACKSIZE = 0x200 @@ -2587,9 +2601,9 @@ int main(void) /* restore config */ config_recall(); + caldata_recall(0); // must be done to setup the scanning stuff /* restore frequencies and calibration 0 slot properties from flash memory */ - caldata_recall(0); #ifdef __VNA__ dac1cfg1.init = config.dac_value; /* diff --git a/nanovna.h b/nanovna.h index 1334f7c..93398a9 100644 --- a/nanovna.h +++ b/nanovna.h @@ -210,6 +210,7 @@ extern int16_t area_height; // font extern const uint8_t x5x7_bits []; +extern const uint16_t x7x13b_bits []; #define FONT_GET_DATA(ch) (&x5x7_bits[ch*7]) #define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7)) #define FONT_MAX_WIDTH 7 @@ -276,13 +277,15 @@ typedef struct config { uint32_t harmonic_freq_threshold; #endif uint16_t vbat_offset; - int16_t level_offset; - uint8_t _reserved[24]; + int16_t low_level_offset; + int16_t high_level_offset; + uint8_t _reserved[22]; uint32_t checksum; } config_t; extern config_t config; -#define settingLevelOffset config.level_offset +//#define settingLevelOffset config.level_offset +int settingLevelOffset(void); void set_trace_type(int t, int type); void set_trace_channel(int t, int channel); @@ -492,9 +495,9 @@ extern properties_t current_props; #define FREQ_IS_STARTSTOP() (!(config.freq_mode&FREQ_MODE_CENTER_SPAN)) #define FREQ_IS_CENTERSPAN() (config.freq_mode&FREQ_MODE_CENTER_SPAN) #define FREQ_IS_CW() (frequency0 == frequency1) +int caldata_recall(int id); #ifdef __VNA__ int caldata_save(int id); -int caldata_recall(int id); const properties_t *caldata_ref(int id); #endif int config_save(void); diff --git a/plot.c b/plot.c index 325cd7d..31a7771 100644 --- a/plot.c +++ b/plot.c @@ -32,7 +32,7 @@ int fullscreen = true; #endif static void cell_draw_marker_info(int x0, int y0); static void draw_battery_status(void); -void cell_draw_test_info(int m, int n, int w, int h); +void cell_draw_test_info(int x0, int y0); static void frequency_string(char *buf, size_t len, int32_t freq); static int16_t grid_offset; @@ -85,7 +85,7 @@ uint8_t current_mappage = 0; // Trace data cache, for faster redraw cells // CELL_X[16:31] x position // CELL_Y[ 0:15] y position -typedef uint32_t index_t; +typedef uint32_t index_t; static index_t trace_index[TRACES_MAX][POINTS_COUNT]; #define INDEX(x, y) ((((index_t)x)<<16)|(((index_t)y))) @@ -1394,7 +1394,8 @@ draw_cell(int m, int n) // Check marker icon on cell if (x + MARKER_WIDTH >= 0 && x - MARKER_WIDTH < CELLWIDTH && y + MARKER_HEIGHT >= 0 && y - MARKER_HEIGHT < CELLHEIGHT) - draw_marker(x, y, config.trace_color[t], i); + draw_marker(x, y, marker_color[markers[i].mtype], i); +// draw_marker(x, y, config.trace_color[t], i); } } #endif @@ -1403,7 +1404,7 @@ draw_cell(int m, int n) if (n == 0) cell_draw_marker_info(x0, y0); #endif - cell_draw_test_info(m, n, w, h); + cell_draw_test_info(x0, y0); // PULSE; // Draw reference position (<10 system ticks for all screen calls) for (t = 0; t < TRACES_MAX; t++) { @@ -1456,7 +1457,7 @@ draw_all_cells(bool flush_markmap) } #ifdef __SCROLL__ if (waterfall) { - for (m = 226; m >= HEIGHT; m -= 1) { // Scroll down + for (m = 226; m >= HEIGHT+3; m -= 1) { // Scroll down uint16_t *buf = &spi_buffer[0]; ili9341_read_memory(5*5, m, area_width, 1, area_width, buf); ili9341_bulk(5*5,m+1, area_width,1); @@ -1496,7 +1497,7 @@ draw_all_cells(bool flush_markmap) #endif spi_buffer[i] = RGB565(r,g,b); } - ili9341_bulk(5*5,HEIGHT, 290,1); + ili9341_bulk(5*5,HEIGHT+3, 290,1); } #endif } @@ -1578,6 +1579,35 @@ cell_drawchar(uint8_t ch, int x, int y) return ch_size; } +static int +cell_drawchar_size(uint8_t ch, int x, int y, int size) +{ + uint8_t bits; + int c, r, ch_size; + const uint8_t *char_buf = FONT_GET_DATA(ch); + ch_size = FONT_GET_WIDTH(ch); + // if (y <= -FONT_GET_HEIGHT || y >= CELLHEIGHT || x <= -ch_size || x >= CELLWIDTH) + // return ch_size; + if (x <= -ch_size*size) + return ch_size*size; + for (c = 0; c < FONT_GET_HEIGHT; c++) { + for (int i=0; i < size; i++) { + bits = *char_buf; + if ((y + c*size+i) < 0 || (y + c*size+i) >= CELLHEIGHT) + continue; + for (r = 0; r < ch_size; r++) { + for (int j = 0; j < size; j++) { + if ((x+r*size + j) >= 0 && (x+r*size+j) < CELLWIDTH && (0x80 & bits)) + cell_buffer[(y+c*size+i)*CELLWIDTH + (x+r*size+j)] = foreground_color; + } + bits <<= 1; + } + } + char_buf++; + } + return ch_size*size; +} + void cell_drawstring(char *str, int x, int y) { @@ -1590,6 +1620,54 @@ cell_drawstring(char *str, int x, int y) } } +void +cell_drawstring_size(char *str, int x, int y, int size) +{ + if (y <= -FONT_GET_HEIGHT*2 || y >= CELLHEIGHT) + return; + while (*str) { + if (x >= CELLWIDTH) + return; + x += cell_drawchar_size(*str++, x, y, size); + } +} + +static int +cell_drawchar_7x13(uint8_t ch, int x, int y) +{ + uint16_t bits; + int c, r, ch_size; + ch_size = 7; + // if (y <= -FONT_GET_HEIGHT || y >= CELLHEIGHT || x <= -ch_size || x >= CELLWIDTH) + // return ch_size; + if (x <= -ch_size) + return ch_size; + for (c = 0; c < 13; c++) { + bits = x7x13b_bits[(ch * 13) + c]; + if ((y + c) < 0 || (y + c) >= CELLHEIGHT) + continue; + for (r = 0; r < ch_size; r++) { + if ((x+r) >= 0 && (x+r) < CELLWIDTH && (0x8000 & bits)) + cell_buffer[(y+c)*CELLWIDTH + (x+r)] = foreground_color; + bits <<= 1; + } + } + return ch_size; +} + + +void +cell_drawstring_7x13(char *str, int x, int y) +{ + if (y <= -13 || y >= CELLHEIGHT) + return; + while (*str) { + if (x >= CELLWIDTH) + return; + x += cell_drawchar_7x13(*str++, x, y); + } +} + #ifdef __VNA__ static void cell_draw_marker_info(int x0, int y0) @@ -1737,8 +1815,13 @@ static void cell_draw_marker_info(int x0, int y0) for (t = TRACE_ACTUAL; t <= TRACE_ACTUAL; t++) { // Only show info on actual trace if (!trace[t].enabled) continue; +#if 1 int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*(FONT_GET_HEIGHT+1) - y0; + int ypos = 1 + (j/2)*(13) - y0; +#else + int xpos = 1 + CELLOFFSETX - x0; + int ypos = 1 + j*(FONT_GET_HEIGHT*2+1) - y0; +#endif int k = 0; if (i == active_marker) buf[k++] = '\033'; // Right arrow (?) @@ -1748,12 +1831,12 @@ static void cell_draw_marker_info(int x0, int y0) buf[k++] = marker_letter[markers[i].mtype]; buf[k++] = 0; ili9341_set_foreground(marker_color[markers[i].mtype]); - cell_drawstring(buf, xpos, ypos); + cell_drawstring_7x13(buf, xpos, ypos); trace_get_value_string( t, buf, sizeof buf, idx, measured[trace[t].channel], frequencies, sweep_points, ridx, markers[i].mtype); // cell_drawstring_7x13(w, h, buf, xpos+2*7, ypos, config.trace_color[t]); - cell_drawstring(buf, xpos+2*7, ypos); + cell_drawstring_7x13(buf, xpos+4*7, ypos); j++; } } @@ -1780,14 +1863,16 @@ static void frequency_string(char *buf, size_t len, int32_t freq) } #endif #ifdef __SA__ +/* if (freq < 1000) { plot_printf(buf, len, "%dHz", (int)freq); } else if (freq < 1000000) { plot_printf(buf, len, "%d.%03dkHz", (int)(freq / 1000), (int)(freq % 1000)); - } else { - plot_printf(buf, len, "%d.%03dMHz", + } else +*/ { + plot_printf(buf, len, "%d.%03", (int)(freq / 1000000), (int)((freq / 1000) % 1000)); } diff --git a/sa_core.c b/sa_core.c index e5d66d8..d870670 100644 --- a/sa_core.c +++ b/sa_core.c @@ -82,7 +82,7 @@ int settingLNA = false; int extraVFO = false; uint32_t minFreq = 0; -uint32_t maxFreq = 350000000; +uint32_t maxFreq = 520000000; void set_refer_output(int v) { @@ -176,13 +176,26 @@ int GetSubtractStorage(void) extern float peakLevel; void SetPowerLevel(int o) { - if (o != 100) - settingLevelOffset = o - peakLevel - settingAttenuate + settingLevelOffset; - else - settingLevelOffset = 0; + if (o != 100) { + if (settingMode & 1) + config.high_level_offset = o - peakLevel - settingAttenuate + settingLevelOffset(); + else + config.low_level_offset = o - peakLevel - settingAttenuate + settingLevelOffset(); + } + else { + config.low_level_offset = 0; + config.high_level_offset = 0; + } dirty = true; } +int settingLevelOffset(void) +{ + if (settingMode & 1) + return(config.high_level_offset); + return(config.low_level_offset); +} + void SetRBW(int v) { settingBandwidth = v; @@ -594,7 +607,7 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) if (extraV) setFreq (0, local_IF + lf - refferFreq[settingRefer]); // Offset so fundamental of reffer is visible setFreq (1, local_IF + lf); - float subRSSI = SI4432_RSSI(lf, (settingMode & 1))+settingLevelOffset+settingAttenuate; + float subRSSI = SI4432_RSSI(lf, (settingMode & 1))+settingLevelOffset()+settingAttenuate; if (RSSI < subRSSI) RSSI = subRSSI; t++; @@ -957,28 +970,28 @@ static void test_acquire(int i) extern void cell_drawstring_5x7(int w, int h, char *str, int x, int y, uint16_t fg); extern void cell_drawstring_7x13(int w, int h, char *str, int x, int y, uint16_t fg); +void cell_drawstring(char *str, int x, int y); -void cell_draw_test_info(int m, int n, int w, int h) +static char self_test_status_buf[35]; +void cell_draw_test_info(int x0, int y0) { #define INFO_SPACING 13 - char buf[35]; +// char self_test_status_buf[35]; if (!show_test_info) return; for (int i = -1; i < TEST_COUNT+1; i++) { - int xpos = 25; - int ypos = 40+i*INFO_SPACING; - xpos -= m * CELLWIDTH -CELLOFFSETX; - ypos -= n * CELLHEIGHT; + int xpos = 25 - x0; + int ypos = 40+i*INFO_SPACING - y0; unsigned int color = RGBHEX(0xFFFFFF); if (i == -1) { - plot_printf(buf, sizeof buf, "Self test status:"); + plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Self test status:"); } else if (i == TEST_COUNT) { if (test_wait) - plot_printf(buf, sizeof buf, "Touch screen to continue"); + plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Touch screen to continue"); else - buf[0] = 0; + self_test_status_buf[0] = 0; } else { - plot_printf(buf, sizeof buf, "Test %d: %s%s", i+1, test_fail_cause[i], test_text[test_status[i]] ); + plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Test %d: %s%s", i+1, test_fail_cause[i], test_text[test_status[i]] ); if (test_status[i] == TS_PASS) color = RGBHEX(0x00FF00); else if (test_status[i] == TS_CRITICAL) @@ -988,7 +1001,8 @@ void cell_draw_test_info(int m, int n, int w, int h) else color = RGBHEX(0x0000FF); } - cell_drawstring(buf, xpos, ypos, color); + ili9341_set_foreground(color); + cell_drawstring(self_test_status_buf, xpos, ypos); } } @@ -1137,7 +1151,7 @@ void self_test(void) break; case TP_10MHZEXTRA: // Swept receiver extraVFO = true; //Sweep BPF - // Fall through intended!!!!!! + goto common; case TP_10MHZ: // 10MHz input common: set_refer_output(2); diff --git a/ui.c b/ui.c index a75838b..5460ebe 100644 --- a/ui.c +++ b/ui.c @@ -2208,11 +2208,16 @@ void ui_process_touch(void) touch_start_watchdog(); } +static int previous_button_state = 0; + void ui_process(void) { - if (operation_requested&OP_LEVER) + int button_state = READ_PORT() & BUTTON_MASK; + if (operation_requested&OP_LEVER || previous_button_state != button_state) { ui_process_lever(); + previous_button_state = button_state; + } if (operation_requested&OP_TOUCH) ui_process_touch(); operation_requested = OP_NONE; diff --git a/ui_sa.c b/ui_sa.c index d6adfd3..00e5aef 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -200,6 +200,7 @@ void menu_autosettings_cb(int item, uint8_t data) set_refer_output(1); SetAttenuation(0); SetPowerLevel(100); // Reset + SetClearStorage(); SetRBW(0); dirty = true; menu_move_back(); @@ -751,7 +752,7 @@ static void fetch_numeric_target(void) uistat.value = settingAttenuate; break; case KM_ACTUALPOWER: - uistat.value = settingLevelOffset; + uistat.value = settingLevelOffset(); break; case KM_IF: uistat.value = frequency_IF; From 730fd6558dc8293d78ddbd5744626c8a9e5cbcb9 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 23 Mar 2020 12:08:01 +0100 Subject: [PATCH 004/193] V0.2 pinning and power RF control --- NANOVNA_STM32_F072/board.h | 124 +++++++++++++++++++------------------ si4432.c | 51 ++++++++------- 2 files changed, 92 insertions(+), 83 deletions(-) diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index 1a43c50..2a6af10 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -47,12 +47,12 @@ /* on-board */ -#define GPIOA_PE_SEL 0 +//#define GPIO_PE_SEL 0 #define GPIOA_LEVER1 1 #define GPIOA_LEVER2 2 #define GPIOA_PUSH 3 -#define GPIOA_RX_SEL 4 -#define GPIOA_LO_SEL 5 +//#define GPIO_RX_SEL 4 +//#define GPIO_LO_SEL 5 #define GPIOA_XP 6 #define GPIOA_YP 7 #define GPIOA_MCO 8 @@ -72,12 +72,17 @@ #define GPIOB_LCD_CS 6 #define GPIOB_LCD_CD 7 #define GPIOB_I2C1_SCL 8 -#define GPIOB_I2C1_SDA 9 -#define GPIOB_SD_GP2 10 +#define GPIO_RF_PWR 9 +#define GPIO_SPI2_CLK 10 #define GPIOB_SD_CS 11 -#define GPIOB_SPI2_CLK 12 -#define GPIOB_SPI2_SDO 13 -#define GPIOB_SPI2_SDI 15 +#define GPIO_SPI2_SDO 14 +#define GPIO_SPI2_SDI 15 + +// Port C +#define GPIO_PE_SEL 13 +#define GPIO_RX_SEL 14 +#define GPIO_LO_SEL 15 + #define GPIOC_LED 13 @@ -116,12 +121,12 @@ * PA13 - SWDIO (alternate 0). * PA14 - SWCLK (alternate 0). */ -#define VAL_GPIOA_MODER (PIN_MODE_OUTPUT(GPIOA_PE_SEL) | \ +#define VAL_GPIOA_MODER (PIN_MODE_INPUT(0U) | \ PIN_MODE_INPUT(1U) | \ PIN_MODE_INPUT(2U) | \ PIN_MODE_INPUT(3U) | \ - PIN_MODE_OUTPUT(GPIOA_RX_SEL) | \ - PIN_MODE_OUTPUT(GPIOA_LO_SEL) | \ + PIN_MODE_INPUT(4U) | \ + PIN_MODE_INPUT(5U) | \ PIN_MODE_ANALOG(GPIOA_XP) | \ PIN_MODE_ANALOG(GPIOA_YP) | \ PIN_MODE_ALTERNATE(GPIOA_MCO) | \ @@ -132,7 +137,7 @@ PIN_MODE_ALTERNATE(GPIOA_JTMS) | \ PIN_MODE_ALTERNATE(GPIOA_JTCK) | \ PIN_MODE_OUTPUT(GPIOA_LCD_RESET)) -#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_PE_SEL) | \ +#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(0U) | \ PIN_OTYPE_PUSHPULL(1U) | \ PIN_OTYPE_PUSHPULL(2U) | \ PIN_OTYPE_PUSHPULL(3U) | \ @@ -148,7 +153,7 @@ PIN_OTYPE_PUSHPULL(GPIOA_JTMS) | \ PIN_OTYPE_PUSHPULL(GPIOA_JTCK) | \ PIN_OTYPE_PUSHPULL(GPIOA_LCD_RESET)) -#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_100M(GPIOA_PE_SEL) | \ +#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_2M(0) | \ PIN_OSPEED_2M(1) | \ PIN_OSPEED_2M(2) | \ PIN_OSPEED_2M(3) | \ @@ -164,7 +169,7 @@ PIN_OSPEED_100M(GPIOA_JTMS) | \ PIN_OSPEED_100M(GPIOA_JTCK) | \ PIN_OSPEED_100M(GPIOA_LCD_RESET)) -#define VAL_GPIOA_PUPDR (PIN_PUPDR_PULLDOWN(GPIOA_PE_SEL) | \ +#define VAL_GPIOA_PUPDR ( PIN_PUPDR_PULLDOWN(0) | \ PIN_PUPDR_PULLDOWN(1) | \ PIN_PUPDR_PULLDOWN(2) | \ PIN_PUPDR_PULLDOWN(3) | \ @@ -180,7 +185,7 @@ PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \ PIN_PUPDR_PULLDOWN(GPIOA_JTCK) | \ PIN_PUPDR_PULLDOWN(GPIOA_LCD_RESET)) -#define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_PE_SEL) | \ +#define VAL_GPIOA_ODR ( PIN_ODR_HIGH(0) | \ PIN_ODR_HIGH(1) | \ PIN_ODR_HIGH(2) | \ PIN_ODR_HIGH(3) | \ @@ -196,7 +201,7 @@ PIN_ODR_HIGH(GPIOA_JTMS) | \ PIN_ODR_HIGH(GPIOA_JTCK) | \ PIN_ODR_HIGH(GPIOA_LCD_RESET)) -#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PE_SEL, 0) | \ +#define VAL_GPIOA_AFRL (PIN_AFIO_AF(0, 0) | \ PIN_AFIO_AF(1, 0) | \ PIN_AFIO_AF(2, 0) | \ PIN_AFIO_AF(3, 0) | \ @@ -235,14 +240,14 @@ PIN_MODE_ALTERNATE(GPIOB_SPI_MOSI) | \ PIN_MODE_OUTPUT(6) | \ PIN_MODE_OUTPUT(7) | \ - PIN_MODE_ALTERNATE(GPIOB_I2C1_SCL) | \ - PIN_MODE_ALTERNATE(GPIOB_I2C1_SDA) | \ - PIN_MODE_OUTPUT(10) | \ + PIN_MODE_OUTPUT(8) | \ + PIN_MODE_OUTPUT(GPIO_RF_PWR) | \ + PIN_MODE_OUTPUT(GPIO_SPI2_CLK) | \ PIN_MODE_OUTPUT(11) | \ - PIN_MODE_OUTPUT(GPIOB_SPI2_CLK) | \ - PIN_MODE_INPUT(GPIOB_SPI2_SDO) | \ - PIN_MODE_ALTERNATE(14) | \ - PIN_MODE_OUTPUT(GPIOB_SPI2_SDI)) + PIN_MODE_OUTPUT(12) | \ + PIN_MODE_OUTPUT(13) | \ + PIN_MODE_INPUT(GPIO_SPI2_SDO) | \ + PIN_MODE_OUTPUT(GPIO_SPI2_SDI)) #define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(0) | \ PIN_OTYPE_PUSHPULL(1) | \ PIN_OTYPE_PUSHPULL(2) | \ @@ -251,14 +256,14 @@ PIN_OTYPE_PUSHPULL(5) | \ PIN_OTYPE_PUSHPULL(6) | \ PIN_OTYPE_PUSHPULL(7) | \ - PIN_OTYPE_PUSHPULL(GPIOB_I2C1_SCL) | \ - PIN_OTYPE_PUSHPULL(GPIOB_I2C1_SDA) | \ - PIN_OTYPE_PUSHPULL(10) | \ + PIN_OTYPE_PUSHPULL(8) | \ + PIN_OTYPE_PUSHPULL(GPIO_RF_PWR) | \ + PIN_OTYPE_PUSHPULL(GPIO_SPI2_CLK) | \ PIN_OTYPE_PUSHPULL(11) | \ - PIN_OTYPE_PUSHPULL(GPIOB_SPI2_CLK) | \ - PIN_OTYPE_PUSHPULL(GPIOB_SPI2_SDO) | \ - PIN_OTYPE_PUSHPULL(14) | \ - PIN_OTYPE_PUSHPULL(GPIOB_SPI2_SDI)) + PIN_OTYPE_PUSHPULL(12) | \ + PIN_OTYPE_PUSHPULL(13) | \ + PIN_OTYPE_PUSHPULL(GPIO_SPI2_SDO) | \ + PIN_OTYPE_PUSHPULL(GPIO_SPI2_SDI)) #define VAL_GPIOB_OSPEEDR (PIN_PUPDR_FLOATING(GPIOB_XN) | \ PIN_PUPDR_FLOATING(GPIOB_YN) | \ PIN_OSPEED_100M(2) | \ @@ -267,14 +272,14 @@ PIN_OSPEED_100M(5) | \ PIN_OSPEED_100M(6) | \ PIN_OSPEED_100M(7) | \ - PIN_OSPEED_100M(GPIOB_I2C1_SCL) | \ - PIN_OSPEED_100M(GPIOB_I2C1_SDA) | \ + PIN_OSPEED_100M(8) | \ + PIN_OSPEED_100M(9) | \ PIN_OSPEED_100M(10) | \ PIN_OSPEED_100M(11) | \ - PIN_OSPEED_100M(GPIOB_SPI2_CLK) | \ - PIN_OSPEED_100M(GPIOB_SPI2_SDO) | \ + PIN_OSPEED_100M(12) | \ + PIN_OSPEED_100M(13) | \ PIN_OSPEED_100M(14) | \ - PIN_OSPEED_100M(GPIOB_SPI2_SDI)) + PIN_OSPEED_100M(15)) #define VAL_GPIOB_PUPDR (PIN_PUPDR_PULLUP(0) | \ PIN_PUPDR_PULLUP(1) | \ PIN_PUPDR_PULLUP(2) | \ @@ -283,14 +288,14 @@ PIN_PUPDR_PULLUP(5) | \ PIN_PUPDR_PULLUP(6) | \ PIN_PUPDR_PULLUP(7) | \ - PIN_PUPDR_PULLUP(GPIOB_I2C1_SCL) | \ - PIN_PUPDR_PULLUP(GPIOB_I2C1_SDA) | \ + PIN_PUPDR_PULLUP(8) | \ + PIN_PUPDR_PULLUP(9) | \ PIN_PUPDR_PULLUP(10) | \ PIN_PUPDR_PULLUP(11) | \ - PIN_PUPDR_PULLUP(GPIOB_SPI2_CLK) | \ - PIN_PUPDR_PULLUP(GPIOB_SPI2_SDO) | \ + PIN_PUPDR_PULLUP(12) | \ + PIN_PUPDR_PULLUP(13) | \ PIN_PUPDR_PULLUP(14) | \ - PIN_PUPDR_PULLUP(GPIOB_SPI2_SDI)) + PIN_PUPDR_PULLUP(14)) #define VAL_GPIOB_ODR (PIN_ODR_HIGH(0) | \ PIN_ODR_HIGH(1) | \ PIN_ODR_HIGH(2) | \ @@ -299,14 +304,14 @@ PIN_ODR_HIGH(5) | \ PIN_ODR_HIGH(6) | \ PIN_ODR_HIGH(7) | \ - PIN_ODR_HIGH(GPIOB_I2C1_SCL) | \ - PIN_ODR_HIGH(GPIOB_I2C1_SDA) | \ + PIN_ODR_HIGH(8) | \ + PIN_ODR_HIGH(9) | \ PIN_ODR_HIGH(10) | \ PIN_ODR_HIGH(11) | \ - PIN_ODR_HIGH(GPIOB_SPI2_CLK) | \ - PIN_ODR_HIGH(GPIOB_SPI2_SDO) | \ + PIN_ODR_HIGH(12) | \ + PIN_ODR_HIGH(13) | \ PIN_ODR_HIGH(14) | \ - PIN_ODR_HIGH(GPIOB_SPI2_SDI)) + PIN_ODR_HIGH(15)) #define VAL_GPIOB_AFRL (PIN_AFIO_AF(0, 0) | \ PIN_AFIO_AF(1, 0) | \ PIN_AFIO_AF(2, 0) | \ @@ -315,20 +320,21 @@ PIN_AFIO_AF(GPIOB_SPI_MISO, 0) | \ PIN_AFIO_AF(6, 0) | \ PIN_AFIO_AF(7, 0)) -#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_I2C1_SCL, 1) | \ - PIN_AFIO_AF(GPIOB_I2C1_SDA, 1) | \ +#define VAL_GPIOB_AFRH (PIN_AFIO_AF(8, 1) | \ + PIN_AFIO_AF(9, 1) | \ PIN_AFIO_AF(10, 0) | \ PIN_AFIO_AF(11, 0) | \ - PIN_AFIO_AF(GPIOB_SPI2_CLK, 0) | \ - PIN_AFIO_AF(GPIOB_SPI2_SDO, 0) | \ + PIN_AFIO_AF(12, 0) | \ + PIN_AFIO_AF(13, 0) | \ PIN_AFIO_AF(14, 0) | \ - PIN_AFIO_AF(GPIOB_SPI2_SDI, 0)) + PIN_AFIO_AF(15, 0)) /* * GPIOC setup: * * PC13 - LED (output pushpull maximum). * PC14 - USB DISC (output pushpull maximum). */ + #define VAL_GPIOC_MODER (PIN_MODE_INPUT(0) | \ PIN_MODE_INPUT(1) | \ PIN_MODE_INPUT(2) | \ @@ -342,9 +348,9 @@ PIN_MODE_INPUT(10) | \ PIN_MODE_INPUT(11) | \ PIN_MODE_INPUT(12) | \ - PIN_MODE_OUTPUT(GPIOC_LED) | \ - PIN_MODE_INPUT(14) | \ - PIN_MODE_INPUT(15)) + PIN_MODE_OUTPUT(GPIO_PE_SEL) | \ + PIN_MODE_OUTPUT(GPIO_RX_SEL) | \ + PIN_MODE_OUTPUT(GPIO_LO_SEL)) #define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(0) | \ PIN_OTYPE_PUSHPULL(1) | \ PIN_OTYPE_PUSHPULL(2) | \ @@ -358,7 +364,7 @@ PIN_OTYPE_PUSHPULL(10) | \ PIN_OTYPE_PUSHPULL(11) | \ PIN_OTYPE_PUSHPULL(12) | \ - PIN_OTYPE_PUSHPULL(GPIOC_LED) | \ + PIN_OTYPE_PUSHPULL(13) | \ PIN_OTYPE_PUSHPULL(14) | \ PIN_OTYPE_PUSHPULL(15)) #define VAL_GPIOC_OSPEEDR (PIN_OSPEED_100M(0) | \ @@ -374,7 +380,7 @@ PIN_OSPEED_100M(10) | \ PIN_OSPEED_100M(11) | \ PIN_OSPEED_100M(12) | \ - PIN_OSPEED_100M(GPIOC_LED) | \ + PIN_OSPEED_100M(13) | \ PIN_OSPEED_100M(14) | \ PIN_OSPEED_100M(15)) #define VAL_GPIOC_PUPDR (PIN_PUPDR_PULLUP(0) | \ @@ -390,8 +396,8 @@ PIN_PUPDR_PULLUP(10) | \ PIN_PUPDR_PULLUP(11) | \ PIN_PUPDR_PULLUP(12) | \ - PIN_PUPDR_FLOATING(GPIOC_LED) | \ - PIN_PUPDR_FLOATING(14) | \ + PIN_PUPDR_PULLUP(13) | \ + PIN_PUPDR_PULLUP(14) | \ PIN_PUPDR_PULLUP(15)) #define VAL_GPIOC_ODR (PIN_ODR_HIGH(0) | \ PIN_ODR_HIGH(1) | \ @@ -406,7 +412,7 @@ PIN_ODR_HIGH(10) | \ PIN_ODR_HIGH(11) | \ PIN_ODR_HIGH(12) | \ - PIN_ODR_HIGH(GPIOC_LED) | \ + PIN_ODR_HIGH(13) | \ PIN_ODR_HIGH(14) | \ PIN_ODR_HIGH(15)) #define VAL_GPIOC_AFRL (PIN_AFIO_AF(0, 0) | \ @@ -422,7 +428,7 @@ PIN_AFIO_AF(10, 0) | \ PIN_AFIO_AF(11, 0) | \ PIN_AFIO_AF(12, 0) | \ - PIN_AFIO_AF(GPIOC_LED, 0) | \ + PIN_AFIO_AF(13, 0) | \ PIN_AFIO_AF(14, 0) | \ PIN_AFIO_AF(15, 0)) diff --git a/si4432.c b/si4432.c index 6efbd8f..9cff2fa 100644 --- a/si4432.c +++ b/si4432.c @@ -22,21 +22,24 @@ #include "si4432.h" -#define CS_SI0_HIGH palSetPad(GPIOA, GPIOA_RX_SEL) -#define CS_SI1_HIGH palSetPad(GPIOA, GPIOA_LO_SEL) -#define CS_PE_HIGH palSetPad(GPIOA, GPIOA_PE_SEL) +#define CS_SI0_HIGH palSetPad(GPIOC, GPIO_RX_SEL) +#define CS_SI1_HIGH palSetPad(GPIOC, GPIO_LO_SEL) +#define CS_PE_HIGH palSetPad(GPIOC, GPIO_PE_SEL) -#define CS_SI0_LOW palClearPad(GPIOA, GPIOA_RX_SEL) -#define CS_SI1_LOW palClearPad(GPIOA, GPIOA_LO_SEL) -#define CS_PE_LOW palClearPad(GPIOA, GPIOA_PE_SEL) +#define RF_POWER_HIGH palSetPad(GPIOC, GPIO_RF_PWR) -#define SPI2_CLK_HIGH palSetPad(GPIOB, GPIOB_SPI2_CLK) -#define SPI2_CLK_LOW palClearPad(GPIOB, GPIOB_SPI2_CLK) -#define SPI2_SDI_HIGH palSetPad(GPIOB, GPIOB_SPI2_SDI) -#define SPI2_SDI_LOW palClearPad(GPIOB, GPIOB_SPI2_SDI) +#define CS_SI0_LOW palClearPad(GPIOC, GPIO_RX_SEL) +#define CS_SI1_LOW palClearPad(GPIOC, GPIO_LO_SEL) +#define CS_PE_LOW palClearPad(GPIOC, GPIO_PE_SEL) -#define SPI2_SDO ((palReadPort(GPIOB) & (1< 6207) WISH=6207; // Final value in RBW_choices[] if (WISH > 1379) dwn3 = 1 ; @@ -231,6 +231,7 @@ int settingSpeed = 0; float SI4432_RSSI(uint32_t i, int s) { + (void) i; int RSSI_RAW; // SEE DATASHEET PAGE 61 #ifdef USE_SI4463 @@ -252,7 +253,7 @@ float SI4432_RSSI(uint32_t i, int s) } -void SI4432_Sub_Init() +void SI4432_Sub_Init(void) { SI4432_Reset(); SI4432_Write_Byte(0x05, 0x0); @@ -311,8 +312,10 @@ void SI4432_Sub_Init() void SI4432_Init() { + RF_POWER_HIGH; // Power the RF part + chThdSleepMilliseconds(25); -//DebugLine("IO set"); + //DebugLine("IO set"); SI4432_Sel = 0; SI4432_Sub_Init(); From 11052640896b130aa0aa78b3a5db42eb37a3b891 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 23 Mar 2020 19:54:28 +0100 Subject: [PATCH 005/193] Input forms working --- plot.c | 4 +- sa_core.c | 3 +- ui.c | 26 ++++++--- ui_sa.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 175 insertions(+), 15 deletions(-) diff --git a/plot.c b/plot.c index 31a7771..481c45e 100644 --- a/plot.c +++ b/plot.c @@ -33,7 +33,7 @@ int fullscreen = true; static void cell_draw_marker_info(int x0, int y0); static void draw_battery_status(void); void cell_draw_test_info(int x0, int y0); -static void frequency_string(char *buf, size_t len, int32_t freq); +void frequency_string(char *buf, size_t len, int32_t freq); static int16_t grid_offset; static int16_t grid_width; @@ -1841,7 +1841,7 @@ static void cell_draw_marker_info(int x0, int y0) } } } -static void frequency_string(char *buf, size_t len, int32_t freq) +void frequency_string(char *buf, size_t len, int32_t freq) { if (freq < 0) { freq = -freq; diff --git a/sa_core.c b/sa_core.c index d870670..18c3da8 100644 --- a/sa_core.c +++ b/sa_core.c @@ -593,7 +593,8 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) SetRX(settingMode); SI4432_SetReference(settingRefer); temppeakLevel = -150; - setFreq (0, local_IF); + if (local_IF) + setFreq (0, local_IF); if (dirty) { scandirty = true; dirty = false; diff --git a/ui.c b/ui.c index 5460ebe..da79dc3 100644 --- a/ui.c +++ b/ui.c @@ -1046,6 +1046,11 @@ const menuitem_t menu_top[] = { }; #endif + +#define MENU_BUTTON_WIDTH 60 +#define MENU_BUTTON_HEIGHT 30 +#define NUM_INPUT_HEIGHT 30 + #include "ui_sa.c" #define MENU_STACK_DEPTH_MAX 4 @@ -1083,6 +1088,10 @@ menu_push_submenu(const menuitem_t *submenu) menu_stack[menu_current_level] = submenu; ensure_selection(); erase_menu_buttons(); + if (menu_is_form(submenu)) { + redraw_frame(); + area_width = 0; + } draw_menu(); } @@ -1105,7 +1114,7 @@ menu_invoke(int item) const menuitem_t *menu = menu_stack[menu_current_level]; menu = &menu[item]; - switch (menu->type) { + switch (menu->type & 0x0f) { case MT_NONE: case MT_BLANK: case MT_CLOSE: @@ -1130,10 +1139,6 @@ menu_invoke(int item) } } -#define MENU_BUTTON_WIDTH 60 -#define MENU_BUTTON_HEIGHT 30 -#define NUM_INPUT_HEIGHT 30 - #define KP_WIDTH 48 #define KP_HEIGHT 48 // Key x, y position (0 - 15) on screen @@ -1466,7 +1471,8 @@ menu_apply_touch(void) return; } } - + if (menu_is_form(menu)) + return; touch_wait_release(); ui_mode_normal(); } @@ -2064,8 +2070,12 @@ ui_process_keypad(void) } redraw_frame(); - request_to_redraw_grid(); - ui_mode_normal(); + if (menu_is_form(menu_stack[menu_current_level])) + ui_mode_menu(); //Reactivate menu after keypad + else { + ui_mode_normal(); + request_to_redraw_grid(); + } //redraw_all(); touch_start_watchdog(); } diff --git a/ui_sa.c b/ui_sa.c index 00e5aef..8721954 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -14,10 +14,12 @@ void SetAttenuation(int); void SetPowerLevel(int); void SetGenerate(int); void SetRBW(int); +extern int settingBandwidth; void SetSpur(int); int GetSpur(void); void SetAverage(int); int GetAverage(void); +extern int settingAverage; void SetStorage(void); void SetClearStorage(void); void SetSubtractStorage(void); @@ -159,17 +161,26 @@ static const char * const keypad_mode_label[] = { int generator_enabled = false; +extern const menuitem_t menu_lowoutputmode[]; +extern const menuitem_t menu_highoutputmode[]; + static void menu_mode_cb(int item, uint8_t data) { (void)data; switch (item) { - case 4: // Change reference output + case 4: // Change reference output, should not happen!!! break; default: SetMode(item); - menu_move_back(); - ui_mode_normal(); draw_cal_status(); + if (item == 2) { // Activate menu_lowoutputmode as input form + set_sweep_frequency(ST_SPAN, 0); + menu_push_submenu(menu_lowoutputmode); + } else if (item == 3) { // Activate menu_highoutputmode as input form + set_sweep_frequency(ST_SPAN, 0); + menu_push_submenu(menu_highoutputmode); + } else + ui_mode_normal(); // Exit menu after setting the mode break; } @@ -399,6 +410,47 @@ static void menu_scale_cb(int item, uint8_t data) draw_cal_status(); } +static void menu_lowoutputmode_cb(int item, uint8_t data) +{ + int status; + int km = data; +// if (km == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { +// km = KM_SCALEDELAY; +// } + status = btn_wait_release(); + if (status & EVT_BUTTON_DOWN_LONG) { + ui_mode_numeric(km); +// ui_process_numeric(); + } else { + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; + redraw_frame(); // Remove form numbers + ui_mode_keypad(km); + ui_process_keypad(); + } + draw_cal_status(); +} + +static void menu_highoutputmode_cb(int item, uint8_t data) +{ + int status; + int km = data; +// if (km == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { +// km = KM_SCALEDELAY; +// } + status = btn_wait_release(); + if (status & EVT_BUTTON_DOWN_LONG) { + ui_mode_numeric(km); +// ui_process_numeric(); + } else { + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; + redraw_frame(); // Remove form numbers + ui_mode_keypad(km); + ui_process_keypad(); + } + draw_cal_status(); +} + + static void menu_settings_cb(int item, uint8_t data) { (void)data; @@ -465,8 +517,56 @@ static void menu_stimulus_cb(int item, uint8_t data) //static void menu_marker_sel_cb(int); //static void menu_marker_op_cb(int); +#if 0 + +#pragma pack(push, 2) +typedef struct { + uint8_t type; + int *data; + char *format; +} menuvalue_t; +#pragma pack(pop) + +enum { + MVT_INT, MVT_FLOAT, MVT_STRINGARRAY +}; +enum { +MV_AVERAGE, MV_RBW, MV_DBPER, MV_REFER, MV_POWER, MVSAMPLETIME, MV_IFFREQ +}; + +static const char *average_text[] = +{ + "OFF", "MIN HOLD", "MAX HOLD", "2", "4", "8" +}; + +static const menuvalue_t menu_value[] = { + { MVT_STRINGARRAY,&settingAverage, (char *)average_text }, + { MVT_INT, &settingBandwidth, "%dkHz" }, + { MVT_INT, &settingScale, "%ddB/" }, + { MVT_INT, &settingRefer, "%dB" }, + { MVT_INT, &settingPower, "%dB" }, + { MVT_INT, &settingSampleTime, "%dmS" }, + { MVT_INT, %setting_IF, "%dHz" }, + } +}; +#endif + // ===[MENU DEFINITION]========================================================= +const menuitem_t menu_lowoutputmode[] = { + { MT_CALLBACK, KM_CENTER, "FREQUENCY", menu_lowoutputmode_cb}, + { MT_CALLBACK, KM_ATTENUATION,"LEVEL", menu_lowoutputmode_cb}, + { MT_CANCEL, 0, S_LARROW" BACK",NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +const menuitem_t menu_highoutputmode[] = { + { MT_CALLBACK, KM_CENTER, "FREQUENCY", menu_highoutputmode_cb}, + { MT_CALLBACK, KM_DRIVE, "LEVEL", menu_highoutputmode_cb}, + { MT_CANCEL, 0, S_LARROW" BACK",NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + static const menuitem_t menu_average[] = { { MT_CALLBACK, 0, "OFF", menu_average_cb}, { MT_CALLBACK, 0, "MIN", menu_average_cb}, @@ -651,6 +751,14 @@ static const menuitem_t menu_top[] = { #define ACTIVE_COLOR RGBHEX(0x007FFF) +void frequency_string(char *buf, size_t len, int32_t freq); + +int menu_is_form(const menuitem_t *menu) +{ + return(menu == menu_lowoutputmode || + menu == menu_highoutputmode); +} + static void menu_item_modify_attribute( const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) { @@ -722,6 +830,48 @@ static void menu_item_modify_attribute( *fg = config.menu_normal_color; } } + if (ui_mode == UI_MENU && menu_is_form(menu)) { +// if (item == 0) +// redraw_frame(); + if (item <= 1) { + + area_width = 0; +// area_height = HEIGHT - 32; + int y = MENU_BUTTON_HEIGHT*item; + uint16_t bg = config.menu_normal_color; + uint16_t fg = DEFAULT_MENU_TEXT_COLOR; + // ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); + ili9341_set_foreground(fg); + ili9341_set_background(bg); + char buf[10]; + ili9341_fill(50+25, y, 170, MENU_BUTTON_HEIGHT-2, bg); + if (menu == menu_lowoutputmode) { + switch (item) { + case 0: + set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode + frequency_string(buf, sizeof buf, frequency0); + break; + case 1: + plot_printf(buf, sizeof buf, "%ddB", -10 - settingAttenuate); + break; + } + } + if (menu == menu_highoutputmode) { + switch (item) { + case 0: + set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode + frequency_string(buf, sizeof buf, frequency0); + break; + case 1: + plot_printf(buf, sizeof buf, "%ddB", -10 - settingDrive); + break; + } + } + ili9341_drawstring_size(buf, 130, y+6, 2); + } + }else{ + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; + } } static void fetch_numeric_target(void) @@ -776,7 +926,6 @@ static void fetch_numeric_target(void) // uistat.previous_value = uistat.value; } - static void set_numeric_value(void) { From 44eb6027a952d2b4f410fa50ff15ee5387615ab5 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 24 Mar 2020 09:55:25 +0100 Subject: [PATCH 006/193] No stepping during output mode --- nanovna.h | 4 +-- sa_core.c | 94 +++++++++++++++++++++++-------------------------------- si4432.c | 6 ++-- ui_sa.c | 22 ++++++++----- 4 files changed, 59 insertions(+), 67 deletions(-) diff --git a/nanovna.h b/nanovna.h index 93398a9..0984dc7 100644 --- a/nanovna.h +++ b/nanovna.h @@ -572,8 +572,8 @@ int plot_printf(char *str, int, const char *fmt, ...); #define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0) extern int settingAttenuate; extern int settingPowerCal; -extern int stepDelay; -extern int settingSpeed; +extern int settingStepDelay; +extern int actualStepDelay; extern int settingMode; void update_rbw(uint32_t delta_f); diff --git a/sa_core.c b/sa_core.c index 18c3da8..b218a64 100644 --- a/sa_core.c +++ b/sa_core.c @@ -80,6 +80,7 @@ int settingDrive=0; // 0-3 , 3=+20dBm int settingAGC = true; int settingLNA = false; int extraVFO = false; +int settingStepDelay = 0; uint32_t minFreq = 0; uint32_t maxFreq = 520000000; @@ -101,9 +102,22 @@ void SetGenerate(int g) dirty = true; } +void SetDrive(int d) +{ + settingDrive = d; + dirty = true; +} + +void SetIF(int f) +{ + frequency_IF = f; + dirty = true; +} + int GetMode(void) { return(settingMode); + dirty = true; } void SetMode(int m) @@ -141,6 +155,7 @@ void SetStorage(void) stored_t[i] = actual_t[i]; settingShowStorage = true; trace[TRACE_STORED].enabled = true; + dirty = true; } int GetStorage(void) @@ -193,6 +208,7 @@ int settingLevelOffset(void) { if (settingMode & 1) return(config.high_level_offset); + dirty = true; return(config.low_level_offset); } @@ -214,6 +230,12 @@ void SetSpur(int v) dirty = true; } +void SetStepDelay(int d) +{ + settingStepDelay = d; + dirty = true; +} + int GetSpur(void) { return(settingSpur); @@ -234,6 +256,7 @@ int GetAverage(void) void ToggleLNA(void) { settingLNA = !settingLNA; + dirty = true; } int GetLNA(void) @@ -244,6 +267,7 @@ int GetLNA(void) void ToggleAGC(void) { settingAGC = !settingAGC; + dirty = true; } int GetAGC(void) @@ -570,21 +594,23 @@ void update_rbw(uint32_t delta_f) dirty = true; } +static int old_lf = -1; + float perform(bool break_on_operation, int i, int32_t f, int extraV) { long local_IF = ((settingMode & 1) == 0?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); - if (i == 0) { - if (settingSpeed == 0){ + if (i == 0 && dirty) { + if (settingStepDelay == 0){ if (rbw < 10.0) - stepDelay = 2500; + actualStepDelay = 2500; else if (rbw <30.0) - stepDelay = 2000; + actualStepDelay = 2000; else if (rbw <100.0) - stepDelay = 1000; + actualStepDelay = 1000; else - stepDelay = 500; + actualStepDelay = 500; } else - stepDelay = settingSpeed; + actualStepDelay = settingStepDelay; // setupSA(); @@ -595,10 +621,10 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) temppeakLevel = -150; if (local_IF) setFreq (0, local_IF); - if (dirty) { +// if (dirty) { scandirty = true; dirty = false; - } +// } } volatile int subSteps = ((int)(2 * vbw / rbw)); float RSSI = -150.0; @@ -607,57 +633,17 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) int lf = (uint32_t)(f + (int)(t * 500 * rbw)); if (extraV) setFreq (0, local_IF + lf - refferFreq[settingRefer]); // Offset so fundamental of reffer is visible - setFreq (1, local_IF + lf); + if (lf != old_lf) // only set on change + setFreq (1, local_IF + lf); + old_lf = lf; float subRSSI = SI4432_RSSI(lf, (settingMode & 1))+settingLevelOffset()+settingAttenuate; if (RSSI < subRSSI) RSSI = subRSSI; t++; - if (operation_requested && break_on_operation) + if ((operation_requested && break_on_operation ) || (settingMode & 2 )) // output modes do not step. subSteps = 0; // abort } while (subSteps-- > 0); return(RSSI); -#if 0 - temp_t[i] = RSSI; - if (settingSubtractStorage) { - RSSI = RSSI - stored_t[i] ; - } - if (scandirty || settingAverage == AV_OFF) - actual_t[i] = RSSI; - else { - switch(settingAverage) { - case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; - case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; - case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; - case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; - case AV_8: actual_t[i] = (actual_t[i]*7 + RSSI) / 8.0; break; - } - } - if (frequencies[i] > 1000000) { - if (temppeakLevel < actual_t[i]) { - temppeakIndex = i; - temppeakLevel = actual_t[i]; - } - } - if (temp_t[i] == 0) { - SI4432_Init(); - } - if (i == POINTS_COUNT -1) { - if (scandirty) { - scandirty = false; - } - peakIndex = temppeakIndex; - peakLevel = actual_t[peakIndex]; - peakFreq = frequencies[peakIndex]; - settingSpur = -settingSpur; - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; -// redraw_marker(peak_marker, FALSE); - - - } -#endif } // main loop for measurement @@ -881,7 +867,7 @@ void draw_cal_status(void) ili9341_drawstring("Scan:", x, y); y += YSTEP; - int32_t t = (int)((2* vbwSteps * sweep_points * ( stepDelay / 100) )) /10 * (settingSpur ? 2 : 1); // in mS + int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 * (settingSpur ? 2 : 1); // in mS if (t>1000) plot_printf(buf, BLEN, "%dS",(t+500)/1000); else diff --git a/si4432.c b/si4432.c index 6efbd8f..f4115a6 100644 --- a/si4432.c +++ b/si4432.c @@ -226,8 +226,8 @@ void SI4432_Set_Frequency ( long Freq ) { #endif } -int stepDelay = 1500; -int settingSpeed = 0; +int actualStepDelay = 1500; + float SI4432_RSSI(uint32_t i, int s) { @@ -239,7 +239,7 @@ float SI4432_RSSI(uint32_t i, int s) } else #endif SI4432_Sel = s; - chThdSleepMicroseconds(stepDelay); + chThdSleepMicroseconds(actualStepDelay); RSSI_RAW = (unsigned char)SI4432_Read_Byte( 0x26 ) ; if (settingMode < 2 && RSSI_RAW == 0) SI4432_Init(); diff --git a/ui_sa.c b/ui_sa.c index 8721954..a009015 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -14,6 +14,9 @@ void SetAttenuation(int); void SetPowerLevel(int); void SetGenerate(int); void SetRBW(int); +void SetDrive(int d); +void SetIF(int f); +void SetStepDelay(int t); extern int settingBandwidth; void SetSpur(int); int GetSpur(void); @@ -35,8 +38,8 @@ extern int extraVFO; extern int settingDrive; extern int settingLNA; extern int settingAGC; -extern int settingSpeed; -extern int stepDelay; +// extern int settingSpeed; +extern int settingStepDelay; enum { KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE @@ -414,6 +417,7 @@ static void menu_lowoutputmode_cb(int item, uint8_t data) { int status; int km = data; + (void) item; // if (km == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { // km = KM_SCALEDELAY; // } @@ -434,6 +438,8 @@ static void menu_highoutputmode_cb(int item, uint8_t data) { int status; int km = data; + (void) item; + // if (km == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { // km = KM_SCALEDELAY; // } @@ -843,13 +849,13 @@ static void menu_item_modify_attribute( // ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); ili9341_set_foreground(fg); ili9341_set_background(bg); - char buf[10]; + char buf[15]; ili9341_fill(50+25, y, 170, MENU_BUTTON_HEIGHT-2, bg); if (menu == menu_lowoutputmode) { switch (item) { case 0: set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode - frequency_string(buf, sizeof buf, frequency0); + plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); break; case 1: plot_printf(buf, sizeof buf, "%ddB", -10 - settingAttenuate); @@ -908,7 +914,7 @@ static void fetch_numeric_target(void) uistat.value = frequency_IF; break; case KM_SAMPLETIME: - uistat.value = settingSpeed; + uistat.value = settingStepDelay; break; case KM_DRIVE: uistat.value = settingDrive; @@ -963,14 +969,14 @@ set_numeric_value(void) config_save(); break; case KM_IF: - frequency_IF = uistat.value; + SetIF(uistat.value); config_save(); break; case KM_SAMPLETIME: - settingSpeed = uistat.value; + SetStepDelay(uistat.value); break; case KM_DRIVE: - settingDrive = uistat.value; + SetDrive(uistat.value); break; } } From 9fb0638deffa3a3b98ef41c7a857b053da23efd9 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 25 Mar 2020 09:48:55 +0100 Subject: [PATCH 007/193] Full screen mode menu --- nanovna.h | 9 +++ plot.c | 35 ++++++--- sa_core.c | 56 ++++++++----- ui.c | 84 ++++++++++++++------ ui_sa.c | 229 +++++++++++++++++++++++++++++++----------------------- 5 files changed, 260 insertions(+), 153 deletions(-) diff --git a/nanovna.h b/nanovna.h index 0984dc7..3074186 100644 --- a/nanovna.h +++ b/nanovna.h @@ -122,6 +122,13 @@ enum { enum { M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, }; + +#define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH ) +#define MODE_INPUT(x) ((x) == M_LOW || (x) == M_HIGH ) +#define MODE_HIGH(x) ((x) == M_HIGH || (x) == M_GENHIGH ) +#define MODE_LOW(x) ((x) == M_LOW || (x) == M_GENLOW ) +#define MODE_SELECT(x) (MODE_HIGH(x) ? 1 : 0) + #define SWEEP_ENABLE 0x01 #define SWEEP_ONCE 0x02 extern int8_t sweep_mode; @@ -537,6 +544,7 @@ typedef struct uistat { uint8_t lever_mode; uint8_t marker_delta; uint8_t marker_tracking; + char text[20]; } uistat_t; extern uistat_t uistat; @@ -576,6 +584,7 @@ extern int settingStepDelay; extern int actualStepDelay; extern int settingMode; void update_rbw(uint32_t delta_f); +int GetActualRBW(void); #define byte uint8_t extern volatile int SI4432_Sel; // currently selected SI4432 diff --git a/plot.c b/plot.c index 481c45e..81f628a 100644 --- a/plot.c +++ b/plot.c @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com +/* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com * All rights reserved. * * This is free software; you can redistribute it and/or modify @@ -796,12 +795,19 @@ static void trace_get_value_string( } else { dfreq = frequencies[i]; } - frequency_string(&buf2[1], sizeof(buf2) -1, dfreq); + if (GetActualRBW() < 10) + plot_printf(&buf2[1], sizeof(buf2) -1, "%3.3f" , (dfreq + 500) / 1000000.0); + else if (GetActualRBW() < 100) + plot_printf(&buf2[1], sizeof(buf2) -1, "%3.2f" , (dfreq + 5000) / 1000000.0); + else + plot_printf(&buf2[1], sizeof(buf2) -1, "%3.1f" , (dfreq + 50000) / 1000000.0); + +// frequency_string(&buf2[1], sizeof(buf2) -1, dfreq); v = logmag(&coeff[i]); if (v == -INFINITY) plot_printf(buf, len, "-INF"); else - plot_printf(buf, len, " %s %.2f", buf2, v - rlevel); + plot_printf(buf, len, "%s %.1f", buf2, v - rlevel); } #ifdef __VNA__ static int @@ -1817,26 +1823,35 @@ static void cell_draw_marker_info(int x0, int y0) continue; #if 1 int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*(13) - y0; +// int ypos = 1 + (j/2)*(13) - y0; + int ypos = 1 + (j/2)*(16) - y0; #else int xpos = 1 + CELLOFFSETX - x0; int ypos = 1 + j*(FONT_GET_HEIGHT*2+1) - y0; #endif int k = 0; - if (i == active_marker) + if (i == active_marker) { +// ili9341_set_foreground(DEFAULT_BG_COLOR); +// ili9341_set_background(marker_color[markers[i].mtype]); buf[k++] = '\033'; // Right arrow (?) - else + } else { +// ili9341_set_background(DEFAULT_BG_COLOR); +// ili9341_set_foreground(marker_color[markers[i].mtype]); buf[k++] = ' '; +// buf[k++] = ' '; + } buf[k++] = i+'1'; - buf[k++] = marker_letter[markers[i].mtype]; +// buf[k++] = marker_letter[markers[i].mtype]; buf[k++] = 0; + ili9341_set_background(DEFAULT_BG_COLOR); ili9341_set_foreground(marker_color[markers[i].mtype]); cell_drawstring_7x13(buf, xpos, ypos); +// cell_drawstring_size(buf, xpos, ypos, 2); trace_get_value_string( t, buf, sizeof buf, idx, measured[trace[t].channel], frequencies, sweep_points, ridx, markers[i].mtype); -// cell_drawstring_7x13(w, h, buf, xpos+2*7, ypos, config.trace_color[t]); - cell_drawstring_7x13(buf, xpos+4*7, ypos); + cell_drawstring_7x13(buf, xpos+3*7, ypos); +// cell_drawstring_size(buf, xpos+3*7, ypos, 2); j++; } } diff --git a/sa_core.c b/sa_core.c index b218a64..0b8d107 100644 --- a/sa_core.c +++ b/sa_core.c @@ -75,12 +75,14 @@ int settingSpur = 0; int settingAverage = 0; int settingShowStorage = 0; int settingSubtractStorage = 0; -int settingMode = 0; +int settingMode = M_LOW; int settingDrive=0; // 0-3 , 3=+20dBm int settingAGC = true; int settingLNA = false; int extraVFO = false; int settingStepDelay = 0; +float rbw = 0; +float vbw = 0; uint32_t minFreq = 0; uint32_t maxFreq = 520000000; @@ -122,21 +124,31 @@ int GetMode(void) void SetMode(int m) { + if (settingMode == m) + return; settingMode = m; switch(m) { case M_LOW: + set_sweep_frequency(ST_START, (int32_t) 0); + set_sweep_frequency(ST_STOP, (int32_t) 300000000); + goto min_max_low; case M_GENLOW: + set_sweep_frequency(ST_CENTER, (int32_t) 10000000); + set_sweep_frequency(ST_SPAN, 0); + min_max_low: minFreq = 0; maxFreq = 520000000; - set_sweep_frequency(ST_START, (int32_t) 0); - set_sweep_frequency(ST_STOP, (int32_t) 300000000); break; case M_HIGH: - case M_GENHIGH: - minFreq = 260000000; - maxFreq = 960000000; set_sweep_frequency(ST_START, (int32_t) 300000000); set_sweep_frequency(ST_STOP, (int32_t) 960000000); + goto min_max_high; + case M_GENHIGH: + set_sweep_frequency(ST_CENTER, (int32_t) 300000000); + set_sweep_frequency(ST_SPAN, 0); + min_max_high: + minFreq = 240000000; + maxFreq = 960000000; break; } dirty = true; @@ -192,9 +204,9 @@ extern float peakLevel; void SetPowerLevel(int o) { if (o != 100) { - if (settingMode & 1) + if (settingMode == M_HIGH) config.high_level_offset = o - peakLevel - settingAttenuate + settingLevelOffset(); - else + else if (settingMode == M_LOW) config.low_level_offset = o - peakLevel - settingAttenuate + settingLevelOffset(); } else { @@ -206,10 +218,11 @@ void SetPowerLevel(int o) int settingLevelOffset(void) { - if (settingMode & 1) + if (settingMode == M_HIGH) return(config.high_level_offset); - dirty = true; - return(config.low_level_offset); + if (settingMode == M_LOW) + return(config.high_level_offset); + return(0); } void SetRBW(int v) @@ -224,6 +237,10 @@ int GetRBW(void) return(settingBandwidth); } +int GetActualRBW(void) +{ + return((int) rbw); +} void SetSpur(int v) { settingSpur = v; @@ -287,8 +304,6 @@ int temppeakIndex; #define BARSTART 24 -float rbw = 0; -float vbw = 0; int vbwSteps = 1; #if 0 @@ -586,7 +601,7 @@ void update_rbw(uint32_t delta_f) rbw = 2.6; if (rbw > 600) rbw = 600; - SI4432_Sel = (settingMode & 1); + SI4432_Sel = MODE_SELECT(settingMode); rbw = SI4432_SET_RBW(rbw); vbwSteps = ((int)(2 * vbw / rbw)); if (vbwSteps < 1) @@ -598,7 +613,7 @@ static int old_lf = -1; float perform(bool break_on_operation, int i, int32_t f, int extraV) { - long local_IF = ((settingMode & 1) == 0?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); + long local_IF = (MODE_LOW(settingMode)?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); if (i == 0 && dirty) { if (settingStepDelay == 0){ if (rbw < 10.0) @@ -636,11 +651,11 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) if (lf != old_lf) // only set on change setFreq (1, local_IF + lf); old_lf = lf; - float subRSSI = SI4432_RSSI(lf, (settingMode & 1))+settingLevelOffset()+settingAttenuate; + float subRSSI = SI4432_RSSI(lf, MODE_SELECT(settingMode))+settingLevelOffset()+settingAttenuate; if (RSSI < subRSSI) RSSI = subRSSI; t++; - if ((operation_requested && break_on_operation ) || (settingMode & 2 )) // output modes do not step. + if ((operation_requested && break_on_operation ) || (MODE_OUTPUT(settingMode))) // output modes do not step. subSteps = 0; // abort } while (subSteps-- > 0); return(RSSI); @@ -944,10 +959,9 @@ static void test_acquire(int i) { pause_sweep(); if (test_case[i].center < 300) - settingMode = 0; + settingMode = M_LOW; else - settingMode = 1; - + settingMode = M_HIGH; set_sweep_frequency(ST_CENTER, (int32_t)test_case[i].center * 1000000); set_sweep_frequency(ST_SPAN, (int32_t)test_case[i].span * 1000000); sweep(false); @@ -1174,7 +1188,7 @@ void self_test(void) set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); set_refer_output(0); - settingMode = 0; + settingMode = M_LOW; draw_cal_status(); menu_autosettings_cb(0); diff --git a/ui.c b/ui.c index da79dc3..615e017 100644 --- a/ui.c +++ b/ui.c @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com +/* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com * All rights reserved. * * This is free software; you can redistribute it and/or modify @@ -31,6 +30,7 @@ uistat_t uistat = { lever_mode: LM_MARKER, marker_delta: FALSE, marker_tracking : FALSE, + text : "", }; #define NO_EVENT 0 @@ -433,8 +433,11 @@ enum { MT_SUBMENU, MT_CALLBACK, MT_CANCEL, + MT_TITLE, MT_CLOSE }; +#define MT_FORM 0x80 // Or with menu type to get large button with current value +#define MT_MASK(x) (0x7F & (x)) typedef void (*menuaction_cb_t)(int item, uint8_t data); @@ -1048,6 +1051,7 @@ const menuitem_t menu_top[] = { #define MENU_BUTTON_WIDTH 60 +#define MENU_FORM_WIDTH 290 #define MENU_BUTTON_HEIGHT 30 #define NUM_INPUT_HEIGHT 30 @@ -1055,7 +1059,7 @@ const menuitem_t menu_top[] = { #define MENU_STACK_DEPTH_MAX 4 const menuitem_t *menu_stack[MENU_STACK_DEPTH_MAX] = { - menu_top, NULL, NULL, NULL + menu_mode, NULL, NULL, NULL }; static void @@ -1063,7 +1067,7 @@ ensure_selection(void) { const menuitem_t *menu = menu_stack[menu_current_level]; int i; - for (i = 0; menu[i].type != MT_NONE; i++) + for (i = 0; MT_MASK(menu[i].type) != MT_NONE; i++) ; if (selection >= i) selection = i-1; @@ -1074,20 +1078,20 @@ menu_move_back(void) { if (menu_current_level == 0) return; + erase_menu_buttons(); menu_current_level--; ensure_selection(); - erase_menu_buttons(); draw_menu(); } static void menu_push_submenu(const menuitem_t *submenu) { + erase_menu_buttons(); if (menu_current_level < MENU_STACK_DEPTH_MAX-1) menu_current_level++; menu_stack[menu_current_level] = submenu; ensure_selection(); - erase_menu_buttons(); if (menu_is_form(submenu)) { redraw_frame(); area_width = 0; @@ -1264,6 +1268,7 @@ draw_keypad(void) ili9341_set_background(bg); int x = KP_GET_X(keypads[i].x); int y = KP_GET_Y(keypads[i].y); +// ili9341_fill(x, y, KP_WIDTH, KP_HEIGHT, DEFAULT_MENU_TEXT_COLOR); // black area around button, causes flicker.... ili9341_fill(x+2, y+2, KP_WIDTH-4, KP_HEIGHT-4, bg); ili9341_drawfont(keypads[i].c, x + (KP_WIDTH - NUM_FONT_GET_WIDTH) / 2, @@ -1414,30 +1419,55 @@ static void draw_menu_buttons(const menuitem_t *menu) { int i = 0; + char text[30]; for (i = 0; i < 7; i++) { const char *l1, *l2; - if (menu[i].type == MT_NONE) + if (MT_MASK(menu[i].type) == MT_NONE) break; - if (menu[i].type == MT_BLANK) + if (MT_MASK(menu[i].type) == MT_BLANK) continue; int y = MENU_BUTTON_HEIGHT*i; - uint16_t bg = config.menu_normal_color; - uint16_t fg = DEFAULT_MENU_TEXT_COLOR; + uint16_t bg; + uint16_t fg; + if (MT_MASK(menu[i].type) == MT_TITLE) { + fg = config.menu_normal_color; + bg = DEFAULT_MENU_TEXT_COLOR; + } else { + bg = config.menu_normal_color; + fg = DEFAULT_MENU_TEXT_COLOR; + } // focus only in MENU mode but not in KEYPAD mode if (ui_mode == UI_MENU && i == selection) bg = config.menu_active_color; - ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); - - menu_item_modify_attribute(menu, i, &fg, &bg); + + uint16_t old_bg = bg; + int active_button_width; + menu_item_modify_attribute(menu, i, &fg, &bg); // before plot_printf to create status text + if (menu[i].type & MT_FORM) { + active_button_width = MENU_FORM_WIDTH; + if (MT_MASK(menu[i].type) == MT_CALLBACK) { // Only callback can have value + keypad_mode = menu[i].data; + fetch_numeric_target(); + } + plot_printf(text, sizeof text, menu[i].label, uistat.text); + } + else + active_button_width = MENU_BUTTON_WIDTH; + ili9341_fill(320-active_button_width, y, active_button_width, MENU_BUTTON_HEIGHT-2, old_bg); // Set button to unmodified background color ili9341_set_foreground(fg); ili9341_set_background(bg); + if (menu[i].type & MT_FORM) { + ili9341_fill(320-active_button_width+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); + ili9341_drawstring_size(text, 320-active_button_width+5, y+10, 2); + } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { - ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+5, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(l1, 320-MENU_BUTTON_WIDTH+5, y+7); - ili9341_drawstring(l2, 320-MENU_BUTTON_WIDTH+5, y+7+FONT_GET_HEIGHT+1); + ili9341_fill(320-active_button_width+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(l1, 320-active_button_width+5, y+7); + ili9341_drawstring(l2, 320-active_button_width+5, y+7+FONT_GET_HEIGHT+1); } else { - ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+8, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(menu[i].label, 320-MENU_BUTTON_WIDTH+5, y+10); + ili9341_fill(320-active_button_width+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(menu[i].label, 320-active_button_width+5, y+10); + } } } } @@ -1461,12 +1491,18 @@ menu_apply_touch(void) touch_position(&touch_x, &touch_y); for (i = 0; i < 7; i++) { - if (menu[i].type == MT_NONE) + if (MT_MASK(menu[i].type) == MT_NONE) break; - if (menu[i].type == MT_BLANK) + if (MT_MASK(menu[i].type == MT_BLANK) || MT_MASK(menu[i].type) == MT_TITLE) continue; int y = MENU_BUTTON_HEIGHT*i; - if (y < touch_y && touch_y < y+MENU_BUTTON_HEIGHT && 320-MENU_BUTTON_WIDTH < touch_x) { + int active_button_width; + if (menu[i].type & MT_FORM) + active_button_width = MENU_FORM_WIDTH; + else + active_button_width = MENU_BUTTON_WIDTH; + + if (y < touch_y && touch_y < y+MENU_BUTTON_HEIGHT && 320-active_button_width < touch_x) { menu_select_touch(i); return; } @@ -1486,7 +1522,8 @@ draw_menu(void) static void erase_menu_buttons(void) { - ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*7, DEFAULT_BG_COLOR); + ili9341_fill(area_width, 0, 320 - area_width, area_height, DEFAULT_BG_COLOR); +// ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*7, DEFAULT_BG_COLOR); } static void @@ -1649,7 +1686,8 @@ ui_mode_keypad(int _keypad_mode) ui_mode = UI_KEYPAD; area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; area_height = HEIGHT - 32; - draw_menu(); + if (!menu_is_form(menu_stack[menu_current_level])) + draw_menu(); draw_keypad(); draw_numeric_area_frame(); draw_numeric_input(""); diff --git a/ui_sa.c b/ui_sa.c index a009015..db92473 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -41,11 +41,14 @@ extern int settingAGC; // extern int settingSpeed; extern int settingStepDelay; + + enum { - KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE + KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE }; + #define KP_X(x) (48*(x) + 2 + (320-BUTTON_WIDTH-192)) #define KP_Y(y) (48*(y) + 2) @@ -166,27 +169,28 @@ int generator_enabled = false; extern const menuitem_t menu_lowoutputmode[]; extern const menuitem_t menu_highoutputmode[]; +extern const menuitem_t menu_top[]; static void menu_mode_cb(int item, uint8_t data) { (void)data; + SetMode(item-1); + draw_cal_status(); switch (item) { - case 4: // Change reference output, should not happen!!! - break; - default: - SetMode(item); - draw_cal_status(); - if (item == 2) { // Activate menu_lowoutputmode as input form - set_sweep_frequency(ST_SPAN, 0); - menu_push_submenu(menu_lowoutputmode); - } else if (item == 3) { // Activate menu_highoutputmode as input form - set_sweep_frequency(ST_SPAN, 0); - menu_push_submenu(menu_highoutputmode); - } else - ui_mode_normal(); // Exit menu after setting the mode + case 1: + menu_push_submenu(menu_top); + break; + case 2: + menu_push_submenu(menu_top); + break; + case 3: + menu_push_submenu(menu_lowoutputmode); + break; + case 4: + menu_push_submenu(menu_highoutputmode); break; } - + draw_cal_status(); } extern int dirty; @@ -260,24 +264,25 @@ static void menu_dfu_cb(int item, uint8_t data) } } -int menu_refer_value[]={-1,0,1,2,3,4,5,6}; -static void menu_refer_cb(int item, uint8_t data) +int menu_reffer_value[]={-1,0,1,2,3,4,5,6}; +char *menu_reffer_text[]={"OFF","30MHz","15MHz","10MHz","4MHz","3MHz","2MHz","1MHz"}; +static void menu_reffer_cb(int item, uint8_t data) { (void)data; //Serial.println(item); - set_refer_output(menu_refer_value[item]); + set_refer_output(menu_reffer_value[item]); menu_move_back(); - ui_mode_normal(); +// ui_mode_normal(); // Stay in menu mode draw_cal_status(); } -static void menu_refer_cb2(int item, uint8_t data) +static void menu_reffer_cb2(int item, uint8_t data) { (void)data; //Serial.println(item); - set_refer_output(menu_refer_value[item+5]); + set_refer_output(menu_reffer_value[item+5]); menu_move_back(); - ui_mode_normal(); + // ui_mode_normal(); // Stay in menu mode draw_cal_status(); } @@ -560,16 +565,18 @@ static const menuvalue_t menu_value[] = { // ===[MENU DEFINITION]========================================================= const menuitem_t menu_lowoutputmode[] = { - { MT_CALLBACK, KM_CENTER, "FREQUENCY", menu_lowoutputmode_cb}, - { MT_CALLBACK, KM_ATTENUATION,"LEVEL", menu_lowoutputmode_cb}, - { MT_CANCEL, 0, S_LARROW" BACK",NULL }, + { MT_FORM | MT_TITLE, 0, "LOW OUTPUT", NULL}, + { MT_FORM | MT_CALLBACK, KM_CENTER, "FREQ: %s", menu_lowoutputmode_cb}, + { MT_FORM | MT_CALLBACK, KM_ATTENUATION,"LEVEL: %s", menu_lowoutputmode_cb}, + { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; const menuitem_t menu_highoutputmode[] = { - { MT_CALLBACK, KM_CENTER, "FREQUENCY", menu_highoutputmode_cb}, - { MT_CALLBACK, KM_DRIVE, "LEVEL", menu_highoutputmode_cb}, - { MT_CANCEL, 0, S_LARROW" BACK",NULL }, + { MT_FORM | MT_TITLE, 0, "HIGH OUTPUT", NULL}, + { MT_FORM | MT_CALLBACK, KM_CENTER, "FREQ: %s", menu_highoutputmode_cb}, + { MT_FORM | MT_CALLBACK, KM_DRIVE, "LEVEL", menu_highoutputmode_cb}, + { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -615,22 +622,22 @@ static const menuitem_t menu_dBper[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_refer2[] = { - { MT_CALLBACK, 0, "3MHz" , menu_refer_cb2}, - { MT_CALLBACK, 0, "2MHz" , menu_refer_cb2}, - { MT_CALLBACK, 0, "1MHz" , menu_refer_cb2}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, +static const menuitem_t menu_reffer2[] = { + { MT_FORM | MT_CALLBACK, 0, "3MHz" , menu_reffer_cb2}, + { MT_FORM | MT_CALLBACK, 0, "2MHz" , menu_reffer_cb2}, + { MT_FORM | MT_CALLBACK, 0, "1MHz" , menu_reffer_cb2}, + { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_refer[] = { - { MT_CALLBACK, 0, "OFF" , menu_refer_cb}, - { MT_CALLBACK, 0, "30MHz", menu_refer_cb}, - { MT_CALLBACK, 0, "15MHz", menu_refer_cb}, - { MT_CALLBACK, 0, "10MHz", menu_refer_cb}, - { MT_CALLBACK, 0, "4MHz" , menu_refer_cb}, - { MT_SUBMENU, 0, S_RARROW" MORE", menu_refer2}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, +static const menuitem_t menu_reffer[] = { + { MT_FORM | MT_CALLBACK, 0, "OFF" , menu_reffer_cb}, + { MT_FORM | MT_CALLBACK, 0, "30MHz", menu_reffer_cb}, + { MT_FORM | MT_CALLBACK, 0, "15MHz", menu_reffer_cb}, + { MT_FORM | MT_CALLBACK, 0, "10MHz", menu_reffer_cb}, + { MT_FORM | MT_CALLBACK, 0, "4MHz" , menu_reffer_cb}, + { MT_FORM | MT_SUBMENU, 0, S_RARROW" MORE", menu_reffer2}, + { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -693,16 +700,6 @@ static const menuitem_t menu_dfu[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_mode[] = { - { MT_CALLBACK, 0, "\2LOW\0INPUT", menu_mode_cb}, - { MT_CALLBACK, 0, "\2HIGH\0INPUT",menu_mode_cb}, - { MT_CALLBACK, 0, "\2LOW\0OUTPUT", menu_mode_cb}, - { MT_CALLBACK, 0, "\2HIGH\0OUTPUT",menu_mode_cb}, - { MT_SUBMENU, 0, "\2REFER\0OUTPUT",menu_refer}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; - static const menuitem_t menu_settings2[] = { // { MT_CALLBACK, 0, "TRACK", menu_settings2_cb}, @@ -738,14 +735,25 @@ static const menuitem_t menu_config[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_top[] = { - { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, - { MT_SUBMENU, 0, "SCAN", menu_stimulus}, - { MT_SUBMENU, 0, "MARKER", menu_marker}, - { MT_SUBMENU, 0, "DISPLAY", menu_scale}, - { MT_SUBMENU, 0, "STORAGE", menu_storage}, - { MT_SUBMENU, 0, "MODE", menu_mode}, - { MT_SUBMENU, 0, "CONFIG", menu_config}, +static const menuitem_t menu_mode[] = { + { MT_FORM | MT_TITLE, 0, "MODE", NULL}, + { MT_FORM | MT_CALLBACK, 0, "LOW INPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK, 0, "HIGH INPUT",menu_mode_cb}, + { MT_FORM | MT_CALLBACK, 0, "LOW OUTPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK, 0, "HIGH OUTPUT",menu_mode_cb}, + { MT_FORM | MT_SUBMENU, 0, "CAL OUTPUT: %s",menu_reffer}, +// { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +const menuitem_t menu_top[] = { + { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, + { MT_SUBMENU, 0, "SCAN", menu_stimulus}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "DISPLAY", menu_scale}, + { MT_SUBMENU, 0, "STORAGE", menu_storage}, + { MT_SUBMENU, 0, "CONFIG", menu_config}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, { MT_NONE, 0, NULL, NULL } // sentinel, // MENUITEM_CLOSE, }; @@ -761,24 +769,29 @@ void frequency_string(char *buf, size_t len, int32_t freq); int menu_is_form(const menuitem_t *menu) { - return(menu == menu_lowoutputmode || - menu == menu_highoutputmode); + int i; + for (i = 0; MT_MASK(menu[i].type) != MT_NONE; i++) + if (menu[i].type & MT_FORM) + return (true); + return(false); } static void menu_item_modify_attribute( const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) { if (menu == menu_mode) { - if (item == GetMode()){ + if (item == GetMode()+1) { *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; + } else if (item == 5) { + plot_printf(uistat.text, sizeof uistat.text, menu_reffer_text[get_refer_output()+1]); } - } else if (menu == menu_refer) { + } else if (menu == menu_reffer) { if (item < 5 && item == get_refer_output() + 1){ *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } - } else if (menu == menu_refer2) { + } else if (menu == menu_reffer2) { if (item == get_refer_output() - 4){ *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; @@ -837,44 +850,46 @@ static void menu_item_modify_attribute( } } if (ui_mode == UI_MENU && menu_is_form(menu)) { -// if (item == 0) -// redraw_frame(); + // if (item == 0) + // redraw_frame(); if (item <= 1) { - area_width = 0; -// area_height = HEIGHT - 32; - int y = MENU_BUTTON_HEIGHT*item; - uint16_t bg = config.menu_normal_color; - uint16_t fg = DEFAULT_MENU_TEXT_COLOR; - // ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); - ili9341_set_foreground(fg); - ili9341_set_background(bg); - char buf[15]; - ili9341_fill(50+25, y, 170, MENU_BUTTON_HEIGHT-2, bg); - if (menu == menu_lowoutputmode) { - switch (item) { - case 0: - set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode - plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); - break; - case 1: - plot_printf(buf, sizeof buf, "%ddB", -10 - settingAttenuate); - break; - } - } - if (menu == menu_highoutputmode) { - switch (item) { - case 0: - set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode - frequency_string(buf, sizeof buf, frequency0); - break; - case 1: - plot_printf(buf, sizeof buf, "%ddB", -10 - settingDrive); - break; - } + area_width = 0; +#if 0 + // area_height = HEIGHT - 32; + int y = MENU_BUTTON_HEIGHT*item; + uint16_t bg = config.menu_normal_color; + uint16_t fg = DEFAULT_MENU_TEXT_COLOR; + // ili9341_fill(320-MENU_BUTTON_WIDTH, y, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT-2, bg); + ili9341_set_foreground(fg); + ili9341_set_background(bg); + char buf[15]; + ili9341_fill(50+25, y, 170, MENU_BUTTON_HEIGHT-2, bg); + if (menu == menu_lowoutputmode) { + switch (item) { + case 0: + set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode + plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); + break; + case 1: + plot_printf(buf, sizeof buf, "%ddB", -10 - settingAttenuate); + break; + } + } + if (menu == menu_highoutputmode) { + switch (item) { + case 0: + set_sweep_frequency(ST_SPAN, 0); // For CW sweep mode + plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); + break; + case 1: + plot_printf(buf, sizeof buf, "%ddB", -10 - settingDrive); + break; + } + } + ili9341_drawstring_size(buf, 130, y+6, 2); +#endif } - ili9341_drawstring_size(buf, 130, y+6, 2); - } }else{ area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; } @@ -885,39 +900,53 @@ static void fetch_numeric_target(void) switch (keypad_mode) { case KM_START: uistat.value = get_sweep_frequency(ST_START); + plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_STOP: uistat.value = get_sweep_frequency(ST_STOP); + plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_CENTER: uistat.value = get_sweep_frequency(ST_CENTER); + plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_SPAN: uistat.value = get_sweep_frequency(ST_SPAN); + plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_CW: uistat.value = get_sweep_frequency(ST_CW); + plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_SCALE: uistat.value = get_trace_scale(uistat.current_trace) * 1000; + plot_printf(uistat.text, sizeof uistat.text, "%ddB/", uistat.value / 1000); break; case KM_REFPOS: uistat.value = get_trace_refpos(uistat.current_trace) * 1000; + plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value / 1000); break; case KM_ATTENUATION: uistat.value = settingAttenuate; + if (GetMode() == M_GENLOW) + uistat.value += 10; // compensation for dB offset during low output mode + plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_ACTUALPOWER: uistat.value = settingLevelOffset(); + plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_IF: uistat.value = frequency_IF; + plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_SAMPLETIME: uistat.value = settingStepDelay; + plot_printf(uistat.text, sizeof uistat.text, "%3duS", uistat.value); break; case KM_DRIVE: uistat.value = settingDrive; + plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value); break; } @@ -962,6 +991,8 @@ set_numeric_value(void) set_trace_refpos(2, NGRIDY - uistat.value / get_trace_scale(0)); break; case KM_ATTENUATION: + if (GetMode() == M_GENLOW) + uistat.value -= 10; // compensation for dB offset during low output mode SetAttenuation(uistat.value); break; case KM_ACTUALPOWER: From 9c129b1310ba2bb3012d013814e9ca36604533b9 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 25 Mar 2020 14:53:12 +0100 Subject: [PATCH 008/193] Output modulation added --- nanovna.h | 4 ++ plot.c | 2 +- sa_core.c | 46 ++++++++++++++++++- ui.c | 4 ++ ui_sa.c | 129 ++++++++++++++++++++++++++++++++++++++++-------------- 5 files changed, 149 insertions(+), 36 deletions(-) diff --git a/nanovna.h b/nanovna.h index 3074186..85e05bc 100644 --- a/nanovna.h +++ b/nanovna.h @@ -123,6 +123,10 @@ enum { M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, }; +enum { + MO_NONE, MO_AM, MO_NFM, MO_WFM, +}; + #define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH ) #define MODE_INPUT(x) ((x) == M_LOW || (x) == M_HIGH ) #define MODE_HIGH(x) ((x) == M_HIGH || (x) == M_GENHIGH ) diff --git a/plot.c b/plot.c index 81f628a..f8ee6e2 100644 --- a/plot.c +++ b/plot.c @@ -1503,7 +1503,7 @@ draw_all_cells(bool flush_markmap) #endif spi_buffer[i] = RGB565(r,g,b); } - ili9341_bulk(5*5,HEIGHT+3, 290,1); + ili9341_bulk(5*5,HEIGHT+3, area_width,1); } #endif } diff --git a/sa_core.c b/sa_core.c index 0b8d107..d9813f5 100644 --- a/sa_core.c +++ b/sa_core.c @@ -64,7 +64,7 @@ int scandirty = true; //---------------- menu system ----------------------- int settingAttenuate = 0; -int settingGenerate = 0; +// int settingGenerate = 0; int settingBandwidth = 0; //int settingLevelOffset = 0; @@ -80,6 +80,7 @@ int settingDrive=0; // 0-3 , 3=+20dBm int settingAGC = true; int settingLNA = false; int extraVFO = false; +int settingModulation = MO_NONE; int settingStepDelay = 0; float rbw = 0; float vbw = 0; @@ -98,11 +99,13 @@ int get_refer_output(void) return(settingRefer); } +#if 0 void SetGenerate(int g) { settingGenerate = g; dirty = true; } +#endif void SetDrive(int d) { @@ -110,6 +113,11 @@ void SetDrive(int d) dirty = true; } +void SetModulation(int m) +{ + settingModulation = m; + dirty = true; +} void SetIF(int f) { frequency_IF = f; @@ -157,6 +165,12 @@ void SetMode(int m) void SetAttenuation(int a) { + if (a<0) + a = 0; + if (a> 31) + a=31; + if (settingAttenuate == a) + return; settingAttenuate = a; dirty = true; } @@ -610,6 +624,7 @@ void update_rbw(uint32_t delta_f) } static int old_lf = -1; +static int modulation_counter = 0; float perform(bool break_on_operation, int i, int32_t f, int extraV) { @@ -631,6 +646,16 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) int p = settingAttenuate * 2; PE4302_Write_Byte(p); + if (settingModulation == MO_NFM ) { + SI4432_Sel = 1; + SI4432_Write_Byte(0x7A, 1); // Use frequency hopping channel width for FM modulation + } else if (settingModulation == MO_WFM ) { + SI4432_Sel = 1; + SI4432_Write_Byte(0x7A, 10); // Use frequency hopping channel width for FM modulation + } else { + SI4432_Sel = 1; + SI4432_Write_Byte(0x79, 0); // IF no FM back to channel 0 + } SetRX(settingMode); SI4432_SetReference(settingRefer); temppeakLevel = -150; @@ -641,6 +666,23 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) dirty = false; // } } + if (settingModulation == MO_AM) { + int p = settingAttenuate * 2 + modulation_counter; + PE4302_Write_Byte(p); + if (modulation_counter == 3) + modulation_counter = 0; + else + modulation_counter++; + chThdSleepMicroseconds(250); + } else if (settingModulation == MO_NFM || settingModulation == MO_WFM ) { + SI4432_Sel = 1; + SI4432_Write_Byte(0x79, modulation_counter); // Use frequency hopping channel for FM modulation + if (modulation_counter == 3) + modulation_counter = 0; + else + modulation_counter++; + chThdSleepMicroseconds(250); + } volatile int subSteps = ((int)(2 * vbw / rbw)); float RSSI = -150.0; int t = 0; @@ -651,6 +693,8 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) if (lf != old_lf) // only set on change setFreq (1, local_IF + lf); old_lf = lf; + if (MODE_OUTPUT(settingMode)) + return(0); float subRSSI = SI4432_RSSI(lf, MODE_SELECT(settingMode))+settingLevelOffset()+settingAttenuate; if (RSSI < subRSSI) RSSI = subRSSI; diff --git a/ui.c b/ui.c index 615e017..73f4a48 100644 --- a/ui.c +++ b/ui.c @@ -1095,6 +1095,10 @@ menu_push_submenu(const menuitem_t *submenu) if (menu_is_form(submenu)) { redraw_frame(); area_width = 0; + } else { + redraw_frame(); + request_to_redraw_grid(); + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; } draw_menu(); } diff --git a/ui_sa.c b/ui_sa.c index db92473..2735799 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -38,13 +38,16 @@ extern int extraVFO; extern int settingDrive; extern int settingLNA; extern int settingAGC; +void SetModulation(int); +extern int settingModulation; // extern int settingSpeed; extern int settingStepDelay; enum { - KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE + KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, + KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_HIGHOUTLEVEL }; @@ -136,6 +139,7 @@ static const keypads_t keypads_level[] = { static const keypads_t * const keypads_mode_tbl[] = { + NULL, // never used keypads_freq, // start keypads_freq, // stop keypads_freq, // center @@ -148,6 +152,8 @@ static const keypads_t * const keypads_mode_tbl[] = { keypads_freq, // IF keypads_level, // sample time keypads_scale, // drive + keypads_level, // KM_LOWOUTLEVEL + keypads_level, // KM_HIGHOUTLEVEL }; #ifdef __VNA__ @@ -157,7 +163,7 @@ static const char * const keypad_mode_label[] = { #endif #ifdef __SA__ static const char * const keypad_mode_label[] = { - "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "ATTENUATION", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE" + "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "ATTENUATION", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL" }; #endif @@ -169,6 +175,7 @@ int generator_enabled = false; extern const menuitem_t menu_lowoutputmode[]; extern const menuitem_t menu_highoutputmode[]; +extern const menuitem_t menu_modulation[]; extern const menuitem_t menu_top[]; static void menu_mode_cb(int item, uint8_t data) @@ -213,15 +220,20 @@ void menu_autosettings_cb(int item, uint8_t data) set_trace_refpos(2, - value / get_trace_scale(0) + NGRIDY); active_marker = 0; - menu_marker_type_cb(M_REFERENCE,M_REFERENCE); - set_refer_output(1); + for (int i = 0; i Date: Wed, 25 Mar 2020 18:36:42 +0100 Subject: [PATCH 009/193] Capture working with DMA, waterfall still hangs --- ili9341.c | 70 ++++++++++++++++++++++++++++--------------------------- ui.c | 4 ++-- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/ili9341.c b/ili9341.c index a1942ab..0c44bf9 100644 --- a/ili9341.c +++ b/ili9341.c @@ -384,39 +384,6 @@ void ili9341_bulk(int x, int y, int w, int h) } } #else -static uint8_t ssp_sendrecvdata(void) -{ - // Start RX clock (by sending data) - SPI_WRITE_8BIT(0); - while (SPI_RX_IS_EMPTY && SPI_IS_BUSY) - ; - return SPI_READ_DATA; -} - -void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) -{ - // uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; - // uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; - uint32_t xx = __REV16(x | ((x + w - 1) << 16)); - uint32_t yy = __REV16(y | ((y + h - 1) << 16)); - send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx); - send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); - send_command(ILI9341_MEMORY_READ, 0, NULL); - - // Skip data from rx buffer - while (SPI_RX_IS_NOT_EMPTY) - (void) SPI_READ_DATA; - // require 8bit dummy clock - ssp_sendrecvdata(); - while (len-- > 0) { - // read data is always 18bit - uint8_t r = ssp_sendrecvdata(); - uint8_t g = ssp_sendrecvdata(); - uint8_t b = ssp_sendrecvdata(); - *out++ = RGB565(r, g, b); - } - CS_HIGH; -} // // Use DMA for send data @@ -469,7 +436,7 @@ void ili9341_bulk(int x, int y, int w, int h) STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC); dmaStreamFlush(w * h); } -#if 0 // Read DMA hangs +#if 1 // Read DMA hangs // Copy screen data to buffer // Warning!!! buffer size must be greater then 3*len + 1 bytes void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) @@ -515,6 +482,41 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) rgbbuf += 3; } } +#else +static uint8_t ssp_sendrecvdata(void) +{ + // Start RX clock (by sending data) + SPI_WRITE_8BIT(0); + while (SPI_RX_IS_EMPTY && SPI_IS_BUSY) + ; + return SPI_READ_DATA; +} + +void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) +{ + // uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) }; + // uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) }; + uint32_t xx = __REV16(x | ((x + w - 1) << 16)); + uint32_t yy = __REV16(y | ((y + h - 1) << 16)); + send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx); + send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy); + send_command(ILI9341_MEMORY_READ, 0, NULL); + + // Skip data from rx buffer + while (SPI_RX_IS_NOT_EMPTY) + (void) SPI_READ_DATA; + // require 8bit dummy clock + ssp_sendrecvdata(); + while (len-- > 0) { + // read data is always 18bit + uint8_t r = ssp_sendrecvdata(); + uint8_t g = ssp_sendrecvdata(); + uint8_t b = ssp_sendrecvdata(); + *out++ = RGB565(r, g, b); + } + CS_HIGH; +} + #endif #endif diff --git a/ui.c b/ui.c index 73f4a48..a9f7185 100644 --- a/ui.c +++ b/ui.c @@ -1461,8 +1461,8 @@ draw_menu_buttons(const menuitem_t *menu) ili9341_set_foreground(fg); ili9341_set_background(bg); if (menu[i].type & MT_FORM) { - ili9341_fill(320-active_button_width+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); - ili9341_drawstring_size(text, 320-active_button_width+5, y+10, 2); + ili9341_fill(320-active_button_width+3, y+6, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); + ili9341_drawstring_size(text, 320-active_button_width+5, y+8, 2); } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { ili9341_fill(320-active_button_width+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); From e0a100af56a8062f5af26c49e29acfe8561d8446 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 25 Mar 2020 19:09:09 +0100 Subject: [PATCH 010/193] Clean up code --- nanovna.h | 12 +++++++----- si4432.c | 8 +++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/nanovna.h b/nanovna.h index 85e05bc..58a6a6b 100644 --- a/nanovna.h +++ b/nanovna.h @@ -33,14 +33,18 @@ #define POINTS_COUNT 290 #define MARKER_COUNT 4 -#define TRACE_COUNT 3 +#define TRACES_MAX 3 +#define TRACE_AGE 3 #define TRACE_ACTUAL 2 #define TRACE_STORED 1 #define TRACE_TEMP 0 +// #define age_t measured[TRACE_AGE] #define stored_t measured[TRACE_STORED] #define actual_t measured[TRACE_ACTUAL] #define temp_t measured[TRACE_TEMP] -typedef float measurement_t[3][POINTS_COUNT]; + + +typedef float measurement_t[TRACES_MAX][POINTS_COUNT]; extern measurement_t measured; #endif @@ -243,8 +247,6 @@ extern const uint16_t numfont16x22[]; #define S_OHM "\036" // trace -#define TRACES_MAX 3 - #define MAX_TRACE_TYPE 12 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_OFF @@ -418,7 +420,7 @@ void show_logo(void); * flash.c */ -#if 0 +#if 1 #define SAVEAREA_MAX 5 // Begin addr 0x08018000 #define SAVE_CONFIG_AREA_SIZE 0x00008000 diff --git a/si4432.c b/si4432.c index f4115a6..96a45a5 100644 --- a/si4432.c +++ b/si4432.c @@ -132,7 +132,6 @@ void SI4432_Reset(void) { int count = 0; // always perform a system reset (don't send 0x87) -again: SI4432_Write_Byte( 0x07, 0x80); chThdSleepMilliseconds(25); // wait for chiprdy bit @@ -147,7 +146,6 @@ void SI4432_Transmit(int d) SI4432_Write_Byte(0x6D, (byte) (0x1C+d)); if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 2) return; // Already in transmit mode -again: chThdSleepMilliseconds(20); SI4432_Write_Byte( 0x07, 0x0b); chThdSleepMilliseconds(20); @@ -161,7 +159,6 @@ void SI4432_Receive(void) int count = 0; if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 1) return; // Already in receive mode -again: SI4432_Write_Byte( 0x07, 0x07); chThdSleepMilliseconds(10); while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 1) { @@ -188,7 +185,7 @@ static short RBW_choices[] = { // Each triple is: ndec, fils, WISH*10 float SI4432_SET_RBW(float w) { uint8_t dwn3=0; - uint32_t WISH = (uint32_t)(w * 10.0); + int32_t WISH = (uint32_t)(w * 10.0); uint8_t ndec, fils, i; if (WISH > 6207) WISH=6207; // Final value in RBW_choices[] if (WISH > 1379) dwn3 = 1 ; @@ -232,6 +229,7 @@ int actualStepDelay = 1500; float SI4432_RSSI(uint32_t i, int s) { int RSSI_RAW; + (void) i; // SEE DATASHEET PAGE 61 #ifdef USE_SI4463 if (SI4432_Sel == 2) { @@ -252,7 +250,7 @@ float SI4432_RSSI(uint32_t i, int s) } -void SI4432_Sub_Init() +void SI4432_Sub_Init(void) { SI4432_Reset(); SI4432_Write_Byte(0x05, 0x0); From b56af01ba2d14607517d4f2198c228d2accf73d8 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 26 Mar 2020 10:09:08 +0100 Subject: [PATCH 011/193] Cleaning up the high input menu system --- main.c | 4 +- plot.c | 3 + sa_core.c | 312 ++++++++++++++---------------------------------------- ui_sa.c | 128 ++++++++++++++-------- 4 files changed, 167 insertions(+), 280 deletions(-) diff --git a/main.c b/main.c index 8a4007f..02d8b92 100644 --- a/main.c +++ b/main.c @@ -786,8 +786,8 @@ config_t config = { .harmonic_freq_threshold = 300000000, #endif .vbat_offset = 500, - .low_level_offset = 0, - .high_level_offset = 0, + .low_level_offset = 100, // Uncalibrated + .high_level_offset = 100, // Uncalibrated }; properties_t current_props; diff --git a/plot.c b/plot.c index f8ee6e2..7cb98a6 100644 --- a/plot.c +++ b/plot.c @@ -1900,6 +1900,9 @@ draw_frequencies(void) { char buf1[32]; char buf2[32]; buf2[0] = 0; + if (MODE_OUTPUT(settingMode)) // No frequencies during output + return; + #ifdef __VNA__ if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { #endif diff --git a/sa_core.c b/sa_core.c index d9813f5..cbf5e67 100644 --- a/sa_core.c +++ b/sa_core.c @@ -69,7 +69,7 @@ int settingBandwidth = 0; //int settingLevelOffset = 0; -int settingRefer = 1; +int settingRefer = -1; // Off by default int refferFreq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; int settingSpur = 0; int settingAverage = 0; @@ -139,10 +139,13 @@ void SetMode(int m) case M_LOW: set_sweep_frequency(ST_START, (int32_t) 0); set_sweep_frequency(ST_STOP, (int32_t) 300000000); + SetRefpos(-10); goto min_max_low; case M_GENLOW: set_sweep_frequency(ST_CENTER, (int32_t) 10000000); set_sweep_frequency(ST_SPAN, 0); + settingSpur = 0; // Not for output mode + settingRefer = -1; // No refer output in output mode min_max_low: minFreq = 0; maxFreq = 520000000; @@ -150,15 +153,20 @@ void SetMode(int m) case M_HIGH: set_sweep_frequency(ST_START, (int32_t) 300000000); set_sweep_frequency(ST_STOP, (int32_t) 960000000); + SetRefpos(-30); goto min_max_high; case M_GENHIGH: set_sweep_frequency(ST_CENTER, (int32_t) 300000000); set_sweep_frequency(ST_SPAN, 0); + settingRefer = -1; // No refer output in output mode min_max_high: minFreq = 240000000; maxFreq = 960000000; + extraVFO = false; // Not possible in high mode + settingSpur = 0; // Not possible in high mode break; } + settingAttenuate = 0; dirty = true; } @@ -224,18 +232,33 @@ void SetPowerLevel(int o) config.low_level_offset = o - peakLevel - settingAttenuate + settingLevelOffset(); } else { - config.low_level_offset = 0; - config.high_level_offset = 0; + config.low_level_offset = 100; + config.high_level_offset = 100; } dirty = true; } int settingLevelOffset(void) { - if (settingMode == M_HIGH) - return(config.high_level_offset); - if (settingMode == M_LOW) + if (settingMode == M_HIGH) { + if (config.high_level_offset == 100) + return 0; return(config.high_level_offset); + } + if (settingMode == M_LOW) { + if (config.low_level_offset == 100) + return 0; + return(config.low_level_offset); + } + return(0); +} + +int level_is_calibrated(void) +{ + if (settingMode == M_HIGH && config.high_level_offset != 100) + return 1; + if (settingMode == M_LOW && config.low_level_offset != 100) + return 1; return(0); } @@ -306,6 +329,13 @@ int GetAGC(void) return(settingAGC); } +void SetRefpos(int level) +{ + set_trace_refpos(0, NGRIDY - level / get_trace_scale(0)); + set_trace_refpos(1, NGRIDY - level / get_trace_scale(0)); + set_trace_refpos(2, NGRIDY - level / get_trace_scale(0)); + dirty = true; +} //------------------------------------------ @@ -320,197 +350,6 @@ int temppeakIndex; int vbwSteps = 1; -#if 0 -int inData = 0; -unsigned long startFreq = 250000000; -unsigned long stopFreq = 300000000; -unsigned long lastFreq[6] = { 300000000, 300000000,0,0,0,0}; -int lastParameter[10]; -int parameter; -unsigned long reg = 0; -long offset=0; -long offset2=0; -static unsigned int spacing = 10000; -double delta=0.0; -int phase=0; -int deltaPhase; -int delaytime = 50; -#endif - - -#if 0 -void displayHisto () -{ - // clearDisplay(); - //int settingMax = 0; - //int settingMin = -120; - - if (old_settingMax != settingMax || old_settingMin != settingMin) { - // Display levels at left of screen - tft.fillRect(0, 0, oX-2, tft.height(), DISPLAY_BLACK); - textWhite(); - tft.setCursor(0,oY); // Start at top-left corner - tft.println(settingMax); - tft.setCursor(0,tft.height() - 16); - tft.println(settingMin); - // tft.setCursor(0,tft.height()/2); - // tft.println("dB"); - old_settingMax = settingMax; - old_settingMin = settingMin; - } - - if (old_startFreq != startFreq || old_stopFreq != stopFreq) { - // Dsiplay frequencies - // Bottom of screen - tft.fillRect(0, tft.height()-8, tft.width(), tft.height()-1, DISPLAY_BLACK); - tft.setTextColor(DISPLAY_WHITE); // Draw white text - tft.setCursor(oX+2,tft.height()-8); // Start at top-left corner - double f = (((double)(startFreq - lastFreq[0]))/ 1000000.0); - tft.print(f); - tft.print("MHz"); - tft.setCursor(tft.width() - 58,tft.height()-8); - f = (((double)(stopFreq - lastFreq[0]))/ 1000000.0); - tft.print(f); - tft.print("MHz"); - - tft.setCursor(tft.width()/2 - 80 + oX,tft.height()-8); - tft.print("center:"); - f = (double)((stopFreq/2 + startFreq/2 - lastFreq[0]) / 1000000.0); - tft.print(f); - tft.print("MHz"); - old_startFreq = startFreq; - old_stopFreq = stopFreq; - } - - // Top of screen - - if (old_settingAttenuate != settingAttenuate || old_settingPowerGrid != settingPowerGrid) { - tft.fillRect(0, 0, 8*6, oY-2, DISPLAY_BLACK); - tft.setCursor(0,0); // Start at top-left corner - tft.setTextColor(DISPLAY_WHITE); // Draw white text - tft.print("Atten:"); - tft.print(settingAttenuate); - tft.setCursor(0,8); // Start at top-left corner - tft.print(settingPowerGrid); - tft.print("dB/"); - old_settingAttenuate = settingAttenuate; - old_settingPowerGrid = settingPowerGrid; - old_rbw = -1; - } - - if (old_rbw != rbw || old_vbw != vbw) { - tft.fillRect(56, 0, 99, oY-2, DISPLAY_BLACK); - tft.setCursor(56,0); // Start at top-left corner - tft.setTextColor(DISPLAY_WHITE); // Draw white text - tft.print("RBW:"); - tft.print(rbw); - tft.print("kHz"); - tft.setCursor(56,8); // Start at top-left corner - tft.print("VBW:"); - tft.print(vbw); - tft.print("kHz"); - old_rbw = rbw; - old_vbw = vbw; - } - - if (peakLevel > -150) { - tft.fillRect(oX+100, 0, 100, 8-1, DISPLAY_BLACK); - tft.setCursor(oX + 100,0); // Start at top-left corner - tft.setTextColor(DISPLAY_WHITE); // Draw white text - tft.print("Max="); - tft.print((int)((peakLevel/ 2.0 - settingAttenuate) - 120.0)+settingLevelOffset); - tft.print("dB, "); - tft.print(peakFreq/ 1000000.0); - tft.print("MHz"); - } - - if (old_settingAverage != settingAverage || abs(old_settingSpur) != abs(settingSpur)) { - int x = tft.width() - 60; - tft.fillRect( x, 0, 60, oY-2, DISPLAY_BLACK); - tft.setTextColor(DISPLAY_WHITE); // Draw white text - if (settingAverage) { - tft.setCursor( x,0); // Start at top-left corner - tft.print("AVR:"); - tft.print(averageText[settingAverage]); - } - if (settingSpur) { - tft.setCursor(x,8); // Start at top-left corner - tft.print("SPUR:"); - tft.print("ON"); - } - old_settingAverage = settingAverage; - old_settingSpur = settingSpur; - } - - - - /* - for (int i=0; i= Y_GRID * dY) f = Y_GRID * dY-1; - if (f < 0) f = 0; - double f2 = ((actual_t[i+1] / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; - f2 = (f2 - settingMin) * Y_GRID * dY / delta; - if (f2 >= Y_GRID * dY) f2 = Y_GRID * dY-1; - if (f2 < 0) f2 = 0; - int x = i; - int Y1 = Y_GRID * dY - 1 - (int)f; - int Y2 = Y_GRID * dY - 1 - (int)f2; - tft.drawLine(x+oX, oY+Y1, x+oX+1, oY+Y2, DISPLAY_YELLOW); -// tft.drawLine(x+oX, oY+Y1+1, x+oX+1, oY+Y2, DISPLAY_YELLOW); - } - - - */ - sendDisplay(); -} - -void DisplayPoint(unsigned char *data, int i, int color) -{ - if (i == 0) - return; - int x = i-1; - int delta=settingMax - settingMin; - double f = ((data[x] / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; - f = (f - settingMin) * Y_GRID * dY / delta; - if (f >= Y_GRID * dY) f = Y_GRID * dY-1; - if (f < 0) f = 0; - double f2 = ((data[x+1] / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; - f2 = (f2 - settingMin) * Y_GRID * dY / delta; - if (f2 >= Y_GRID * dY) f2 = Y_GRID * dY-1; - if (f2 < 0) f2 = 0; - int Y1 = Y_GRID * dY - 1 - (int)f; - int Y2 = Y_GRID * dY - 1 - (int)f2; - DrawDirty(x,min(Y2,Y1)); - DrawDirty(x+1,min(Y2,Y1)); - tft.drawLine(x+oX, oY+Y1, x+oX+1, oY+Y2, color); - // tft.drawLine(x+oX, oY+Y1+1, x+oX+1, oY+Y2, DISPLAY_YELLOW); - sendDisplay(); -} - -void DisplayPeakData(void) -{ - double f = ((((float)actual_t[peakIndex]) / 2.0 - settingAttenuate) - 120.0) + settingLevelOffset; - int delta=settingMax - settingMin; - f = (f - settingMin) * Y_GRID * dY / delta; - if (f >= Y_GRID * dY) f = Y_GRID * dY-1; - if (f < 0) f = 0; - int Y1 = Y_GRID * dY - 1 - (int)f; - tft.setCursor(oX+peakIndex+5,oY+Y1); // Start at top-left corner - tft.setTextColor(DISPLAY_WHITE); // Draw white text - tft.print(peakFreq/ 1000000.0); - tft.setCursor(oX+peakIndex+5,oY+Y1+8); // Start at top-left corner - tft.print((int)((peakLevel/ 2.0 - settingAttenuate) - 120.0)+settingLevelOffset); - tft.print("dB"); - for (int x=peakIndex+5;x RSSI) actual_t[i] = RSSI; break; - case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; - case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; - case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; - case AV_8: actual_t[i] = (actual_t[i]*7 + RSSI) / 8.0; break; - } + continue; // Skip all other processing + } + if (settingSpur == -1) // Second pass + RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes + temp_t[i] = RSSI; + if (settingSubtractStorage) { + RSSI = RSSI - stored_t[i] ; + } + // stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace + if (scandirty || settingAverage == AV_OFF) + actual_t[i] = RSSI; + else { + switch(settingAverage) { + case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; + case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; + case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; + case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; + case AV_8: actual_t[i] = (actual_t[i]*7 + RSSI) / 8.0; break; } - if (frequencies[i] > 1000000) { - if (temppeakLevel < actual_t[i]) { - temppeakIndex = i; - temppeakLevel = actual_t[i]; - } + } + if (frequencies[i] > 1000000) { + if (temppeakLevel < actual_t[i]) { + temppeakIndex = i; + temppeakLevel = actual_t[i]; } } if (i == sweep_points -1) { - if (settingSpur == 1) { - settingSpur = -1; - i = 0; - goto again; - } if (scandirty) { scandirty = false; } @@ -767,6 +600,10 @@ again: if (operation_requested && break_on_operation) return false; } + if (settingSpur == 1) { + settingSpur = -1; + goto again; + } palSetPad(GPIOC, GPIOC_LED); return true; } @@ -854,13 +691,22 @@ void draw_cal_status(void) // if (!sweep_enabled) // perform(true, 0, frequencies[0], false); + ili9341_fill(x, y, OFFSETX, HEIGHT, 0x0000); + + if (MODE_OUTPUT(settingMode)) // No cal status during output + return; + ili9341_set_background(DEFAULT_BG_COLOR); int yMax = (NGRIDY - get_trace_refpos(0)) * get_trace_scale(0); plot_printf(buf, BLEN, "%ddB", yMax); buf[5]=0; - ili9341_set_foreground(DEFAULT_FG_COLOR); + if (level_is_calibrated()) + color = DEFAULT_FG_COLOR; + else + color = BRIGHT_COLOR_RED; + ili9341_set_foreground(color); ili9341_drawstring(buf, x, y); y += YSTEP*2; @@ -950,7 +796,11 @@ void draw_cal_status(void) y = HEIGHT-7 + OFFSETY; plot_printf(buf, BLEN, "%ddB", (int)(yMax - get_trace_scale(0) * NGRIDY)); buf[5]=0; - ili9341_set_foreground(DEFAULT_FG_COLOR); + if (level_is_calibrated()) + color = DEFAULT_FG_COLOR; + else + color = BRIGHT_COLOR_RED; + ili9341_set_foreground(color); ili9341_drawstring(buf, x, y); } diff --git a/ui_sa.c b/ui_sa.c index 2735799..a000baa 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -29,6 +29,7 @@ void SetSubtractStorage(void); void toggle_waterfall(void); void SetMode(int); int GetMode(void); +void SetRefpos(int); void AllDirty(void); void MenuDirty(void); void redrawHisto(void); @@ -177,6 +178,7 @@ extern const menuitem_t menu_lowoutputmode[]; extern const menuitem_t menu_highoutputmode[]; extern const menuitem_t menu_modulation[]; extern const menuitem_t menu_top[]; +extern const menuitem_t menu_tophigh[]; static void menu_mode_cb(int item, uint8_t data) { @@ -188,7 +190,7 @@ static void menu_mode_cb(int item, uint8_t data) menu_push_submenu(menu_top); break; case 2: - menu_push_submenu(menu_top); + menu_push_submenu(menu_tophigh); break; case 3: menu_push_submenu(menu_lowoutputmode); @@ -205,7 +207,7 @@ void menu_autosettings_cb(int item, uint8_t data) { (void)item; (void)data; - SetMode(M_LOW); + SetMode(GetMode()); // set_sweep_frequency(ST_START, (int32_t) 0); // set_sweep_frequency(ST_STOP, (int32_t) 300000000); @@ -428,16 +430,12 @@ static void menu_scale_cb(int item, uint8_t data) { (void)data; int status; - int km = KM_REFPOS + item; -// if (km == KM_SCALE && trace[uistat.current_trace].type == TRC_DELAY) { -// km = KM_SCALEDELAY; -// } status = btn_wait_release(); if (status & EVT_BUTTON_DOWN_LONG) { - ui_mode_numeric(km); + ui_mode_numeric(data); // ui_process_numeric(); } else { - ui_mode_keypad(km); + ui_mode_keypad(data); ui_process_keypad(); } draw_cal_status(); @@ -498,13 +496,12 @@ static void menu_settings_cb(int item, uint8_t data) { (void)data; int status; - int km = KM_ACTUALPOWER+item; status = btn_wait_release(); if (status & EVT_BUTTON_DOWN_LONG) { - ui_mode_numeric(km); + ui_mode_numeric(data); // ui_process_numeric(); } else { - ui_mode_keypad(km); + ui_mode_keypad(data); ui_process_keypad(); } draw_cal_status(); @@ -515,10 +512,10 @@ static void menu_settings2_cb(int item, uint8_t data) (void)data; switch(item) { case 0: - settingAGC = !settingAGC; + ToggleAGC(); break; case 1: - settingLNA = !settingLNA; + ToggleLNA();; break; case 2: extraVFO = !extraVFO; @@ -687,16 +684,27 @@ static const menuitem_t menu_reffer[] = { }; static const menuitem_t menu_scale[] = { - { MT_CALLBACK, 0, "\2REF\0LEVEL", menu_scale_cb}, - { MT_SUBMENU, 0, "\2SCALE/\0DIV", menu_dBper}, - { MT_CALLBACK, 0, "ATTEN", menu_scale_cb}, - { MT_SUBMENU, 0, "AVERAGE", menu_average}, - { MT_CALLBACK, 0, "\2SPUR\0REDUCT.",menu_spur_cb}, - { MT_SUBMENU, 0, "RBW", menu_rbw}, + { MT_CALLBACK, KM_REFPOS, "\2REF\0LEVEL", menu_scale_cb}, + { MT_SUBMENU, 0, "\2SCALE/\0DIV", menu_dBper}, + { MT_CALLBACK, KM_ATTENUATION, "ATTEN", menu_scale_cb}, + { MT_SUBMENU, 0, "AVERAGE", menu_average}, + { MT_CALLBACK, 0, "\2SPUR\0REDUCT.",menu_spur_cb}, + { MT_SUBMENU, 0, "RBW", menu_rbw}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_scalehigh[] = { + { MT_CALLBACK, KM_REFPOS, "\2REF\0LEVEL", menu_scale_cb}, + { MT_SUBMENU, 0, "\2SCALE/\0DIV", menu_dBper}, + { MT_SUBMENU, 0, "AVERAGE", menu_average}, + { MT_SUBMENU, 0, "RBW", menu_rbw}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; + + static const menuitem_t menu_stimulus[] = { { MT_CALLBACK, 0, "START", menu_stimulus_cb}, { MT_CALLBACK, 0, "STOP", menu_stimulus_cb}, @@ -740,14 +748,13 @@ static const menuitem_t menu_marker[] = { }; static const menuitem_t menu_dfu[] = { - { MT_CALLBACK, 0, "ENTER DFU", menu_dfu_cb}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_FORM | MT_CALLBACK, 0, "ENTER DFU", menu_dfu_cb}, + { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_settings2[] = { -// { MT_CALLBACK, 0, "TRACK", menu_settings2_cb}, { MT_CALLBACK, 0, "AGC", menu_settings2_cb}, { MT_CALLBACK, 0, "LNA", menu_settings2_cb}, { MT_CALLBACK, 0, "BPF", menu_settings2_cb}, @@ -757,36 +764,53 @@ static const menuitem_t menu_settings2[] = static const menuitem_t menu_settings[] = { - { MT_CALLBACK, 0, "\2ACTUAL\0POWER", menu_settings_cb}, - { MT_CALLBACK, 0, "\2IF\0FREQ", menu_settings_cb}, - { MT_CALLBACK, 0, "\2SAMPLE\0TIME", menu_settings_cb}, - { MT_CALLBACK, 0, "\2LO\0DRIVE", menu_settings_cb}, - { MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2}, + { MT_CALLBACK, KM_ACTUALPOWER, "\2ACTUAL\0POWER", menu_settings_cb}, + { MT_CALLBACK, KM_IF, "\2IF\0FREQ", menu_settings_cb}, + { MT_CALLBACK, KM_SAMPLETIME, "\2SAMPLE\0TIME", menu_settings_cb}, + { MT_CALLBACK, KM_DRIVE, "\2LO\0DRIVE", menu_settings_cb}, + { MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; -// { MT_SUBMENU, 0, "RBW", menu_rbw}, + +static const menuitem_t menu_settingshigh2[] = +{ + { MT_CALLBACK, 0, "AGC", menu_settings2_cb}, + { MT_CALLBACK, 0, "LNA", menu_settings2_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_settingshigh[] = +{ + { MT_CALLBACK, KM_ACTUALPOWER, "\2ACTUAL\0POWER", menu_settings_cb}, + { MT_CALLBACK, KM_SAMPLETIME, "\2SAMPLE\0TIME", menu_settings_cb}, + { MT_SUBMENU, 0, S_RARROW" MORE", menu_settingshigh2}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + static const menuitem_t menu_config[] = { - { MT_CALLBACK, 0, "\2TOUCH\0CAL", menu_config_cb}, - { MT_CALLBACK, 0, "\2TOUCH\0TEST", menu_config_cb}, - { MT_CALLBACK, 0, "\2SELF\0TEST", menu_config_cb}, - { MT_CALLBACK, 0, "VERSION", menu_config_cb}, - { MT_SUBMENU, 0, "SETTINGS", menu_settings}, + { MT_FORM | MT_CALLBACK, 0, "TOUCH CAL", menu_config_cb}, + { MT_FORM | MT_CALLBACK, 0, "TOUCH TEST", menu_config_cb}, + { MT_FORM | MT_CALLBACK, 0, "SELF TEST", menu_config_cb}, + { MT_FORM | MT_CALLBACK, 0, "VERSION", menu_config_cb}, +// { MT_SUBMENU, 0, "SETTINGS", menu_settings}, // { MT_SUBMENU, 0, "RBW", menu_rbw}, - { MT_SUBMENU, 0, S_RARROW"DFU", menu_dfu}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_FORM | MT_SUBMENU, 0, S_RARROW"DFU", menu_dfu}, + { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_mode[] = { - { MT_FORM | MT_TITLE, 0, "MODE", NULL}, - { MT_FORM | MT_CALLBACK, 0, "LOW INPUT", menu_mode_cb}, - { MT_FORM | MT_CALLBACK, 0, "HIGH INPUT",menu_mode_cb}, - { MT_FORM | MT_CALLBACK, 0, "LOW OUTPUT", menu_mode_cb}, - { MT_FORM | MT_CALLBACK, 0, "HIGH OUTPUT",menu_mode_cb}, - { MT_FORM | MT_SUBMENU, 0, "CAL OUTPUT: %s",menu_reffer}, + { MT_FORM | MT_TITLE, 0, "MODE", NULL}, + { MT_FORM | MT_CALLBACK, 0, "LOW INPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK, 0, "HIGH INPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK, 0, "LOW OUTPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK, 0, "HIGH OUTPUT", menu_mode_cb}, + { MT_FORM | MT_SUBMENU, 0, "CAL OUTPUT: %s", menu_reffer}, + { MT_FORM | MT_SUBMENU, 0, "CONFIG", menu_config}, // { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -797,7 +821,19 @@ const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "MARKER", menu_marker}, { MT_SUBMENU, 0, "DISPLAY", menu_scale}, { MT_SUBMENU, 0, "STORAGE", menu_storage}, - { MT_SUBMENU, 0, "CONFIG", menu_config}, + { MT_SUBMENU, 0, "SETTINGS", menu_settings}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, + { MT_NONE, 0, NULL, NULL } // sentinel, + // MENUITEM_CLOSE, +}; + +const menuitem_t menu_tophigh[] = { + { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, + { MT_SUBMENU, 0, "SCAN", menu_stimulus}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "DISPLAY", menu_scalehigh}, + { MT_SUBMENU, 0, "STORAGE", menu_storage}, + { MT_SUBMENU, 0, "SETTINGS", menu_settingshigh}, { MT_CANCEL, 0, S_LARROW" MODE",NULL}, { MT_NONE, 0, NULL, NULL } // sentinel, // MENUITEM_CLOSE, @@ -884,7 +920,7 @@ static void menu_item_modify_attribute( *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } - } else if (menu == menu_settings2) { + } else if (menu == menu_settings2 || menu == menu_settingshigh2) { if (item ==0 && settingAGC){ *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; @@ -893,7 +929,7 @@ static void menu_item_modify_attribute( *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } - if (item == 2 && extraVFO){ + if (item == 2 && extraVFO){ // should not happen in high mode *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } @@ -1041,9 +1077,7 @@ set_numeric_value(void) set_trace_scale(2, uistat.value / 1000.0); break; case KM_REFPOS: - set_trace_refpos(0, NGRIDY - uistat.value / get_trace_scale(0)); - set_trace_refpos(1, NGRIDY - uistat.value / get_trace_scale(0)); - set_trace_refpos(2, NGRIDY - uistat.value / get_trace_scale(0)); + SetRefpos(uistat.value); break; case KM_ATTENUATION: SetAttenuation(uistat.value); From f2b9a38e219502ec8bc0512d629764afb15c596d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 26 Mar 2020 10:36:27 +0100 Subject: [PATCH 012/193] Mode switching improved --- sa_core.c | 91 ++++++++++++++++++++++++++++++------------------------- ui_sa.c | 35 ++++++++------------- 2 files changed, 62 insertions(+), 64 deletions(-) diff --git a/sa_core.c b/sa_core.c index cbf5e67..2349e11 100644 --- a/sa_core.c +++ b/sa_core.c @@ -130,47 +130,6 @@ int GetMode(void) dirty = true; } -void SetMode(int m) -{ - if (settingMode == m) - return; - settingMode = m; - switch(m) { - case M_LOW: - set_sweep_frequency(ST_START, (int32_t) 0); - set_sweep_frequency(ST_STOP, (int32_t) 300000000); - SetRefpos(-10); - goto min_max_low; - case M_GENLOW: - set_sweep_frequency(ST_CENTER, (int32_t) 10000000); - set_sweep_frequency(ST_SPAN, 0); - settingSpur = 0; // Not for output mode - settingRefer = -1; // No refer output in output mode - min_max_low: - minFreq = 0; - maxFreq = 520000000; - break; - case M_HIGH: - set_sweep_frequency(ST_START, (int32_t) 300000000); - set_sweep_frequency(ST_STOP, (int32_t) 960000000); - SetRefpos(-30); - goto min_max_high; - case M_GENHIGH: - set_sweep_frequency(ST_CENTER, (int32_t) 300000000); - set_sweep_frequency(ST_SPAN, 0); - settingRefer = -1; // No refer output in output mode - min_max_high: - minFreq = 240000000; - maxFreq = 960000000; - extraVFO = false; // Not possible in high mode - settingSpur = 0; // Not possible in high mode - break; - } - settingAttenuate = 0; - dirty = true; -} - - void SetAttenuation(int a) { if (a<0) @@ -336,6 +295,56 @@ void SetRefpos(int level) set_trace_refpos(2, NGRIDY - level / get_trace_scale(0)); dirty = true; } + +void SetScale(int s) { + set_trace_scale(0, s); + set_trace_scale(1, s); + set_trace_scale(2, s); +} + +void SetMode(int m) +{ + if (settingMode == m) + return; + settingMode = m; + switch(m) { + case M_LOW: + set_sweep_frequency(ST_START, (int32_t) 0); + set_sweep_frequency(ST_STOP, (int32_t) 300000000); + SetRefpos(-10); + goto min_max_low; + case M_GENLOW: + set_sweep_frequency(ST_CENTER, (int32_t) 10000000); + set_sweep_frequency(ST_SPAN, 0); + settingSpur = 0; // Not for output mode + settingRefer = -1; // No refer output in output mode + min_max_low: + minFreq = 0; + maxFreq = 520000000; + break; + case M_HIGH: + set_sweep_frequency(ST_START, (int32_t) 300000000); + set_sweep_frequency(ST_STOP, (int32_t) 960000000); + SetRefpos(-30); + goto min_max_high; + case M_GENHIGH: + set_sweep_frequency(ST_CENTER, (int32_t) 300000000); + set_sweep_frequency(ST_SPAN, 0); + settingRefer = -1; // No refer output in output mode + min_max_high: + minFreq = 240000000; + maxFreq = 960000000; + extraVFO = false; // Not possible in high mode + settingSpur = 0; // Not possible in high mode + break; + } + settingAttenuate = 0; + SetRBW(0); + SetScale(10); + dirty = true; +} + + //------------------------------------------ diff --git a/ui_sa.c b/ui_sa.c index a000baa..5850067 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -30,8 +30,11 @@ void toggle_waterfall(void); void SetMode(int); int GetMode(void); void SetRefpos(int); +void SetScale(int); void AllDirty(void); void MenuDirty(void); +void ToggleLNA(void); +void ToggleAGC(void); void redrawHisto(void); void self_test(void); extern int32_t frequencyExtra; @@ -207,33 +210,21 @@ void menu_autosettings_cb(int item, uint8_t data) { (void)item; (void)data; - SetMode(GetMode()); -// set_sweep_frequency(ST_START, (int32_t) 0); -// set_sweep_frequency(ST_STOP, (int32_t) 300000000); - - int value = 10; // 10dB/ - set_trace_scale(0, value); - set_trace_scale(1, value); - set_trace_scale(2, value); - - value = -10; // Top at -10dB - set_trace_refpos(0, - value / get_trace_scale(0) + NGRIDY); - set_trace_refpos(1, - value / get_trace_scale(0) + NGRIDY); - set_trace_refpos(2, - value / get_trace_scale(0) + NGRIDY); + int current_mode = GetMode(); + SetMode(-1); // Force setmode to do something + SetMode(current_mode); active_marker = 0; - - for (int i = 0; i Date: Thu, 26 Mar 2020 13:37:54 +0100 Subject: [PATCH 013/193] 3D buttons --- nanovna.h | 2 ++ ui.c | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/nanovna.h b/nanovna.h index 58a6a6b..36a7d06 100644 --- a/nanovna.h +++ b/nanovna.h @@ -377,6 +377,8 @@ extern volatile uint8_t redraw_request; #define DEFAULT_FG_COLOR RGB565(255,255,255) #define DEFAULT_BG_COLOR RGB565( 0, 0, 0) +#define DARK_GREY RGB565(140,140,140) +#define LIGHT_GREY RGB565(220,220,220) #define DEFAULT_GRID_COLOR RGB565(128,128,128) #define DEFAULT_MENU_COLOR RGB565(255,255,255) #define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0) diff --git a/ui.c b/ui.c index a9f7185..1d13e0d 100644 --- a/ui.c +++ b/ui.c @@ -1051,7 +1051,9 @@ const menuitem_t menu_top[] = { #define MENU_BUTTON_WIDTH 60 +#define MENU_BUTTON_START (320-MENU_BUTTON_WIDTH) #define MENU_FORM_WIDTH 290 +#define MENU_FORM_START (320 - MENU_FORM_WIDTH) #define MENU_BUTTON_HEIGHT 30 #define NUM_INPUT_HEIGHT 30 @@ -1423,6 +1425,7 @@ static void draw_menu_buttons(const menuitem_t *menu) { int i = 0; + int bw = 320; char text[30]; for (i = 0; i < 7; i++) { const char *l1, *l2; @@ -1457,20 +1460,31 @@ draw_menu_buttons(const menuitem_t *menu) } else active_button_width = MENU_BUTTON_WIDTH; - ili9341_fill(320-active_button_width, y, active_button_width, MENU_BUTTON_HEIGHT-2, old_bg); // Set button to unmodified background color + ili9341_fill(bw-active_button_width, y, active_button_width, MENU_BUTTON_HEIGHT-4, old_bg); // Set button to unmodified background color + + // 3D button accent + + if (MT_MASK(menu[i].type) != MT_TITLE) { + ili9341_fill(bw-active_button_width, y, 2, MENU_BUTTON_HEIGHT-4, LIGHT_GREY); // Set button to unmodified background color + ili9341_fill(bw-active_button_width, y, active_button_width, 2, LIGHT_GREY); // Set button to unmodified background color + ili9341_fill(bw-2, y, 2, MENU_BUTTON_HEIGHT-4, DARK_GREY); // Set button to unmodified background color + ili9341_fill(bw-active_button_width, y+MENU_BUTTON_HEIGHT-4, active_button_width, 2, DARK_GREY); // Set button to unmodified background color + } + + ili9341_set_foreground(fg); ili9341_set_background(bg); if (menu[i].type & MT_FORM) { - ili9341_fill(320-active_button_width+3, y+6, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); - ili9341_drawstring_size(text, 320-active_button_width+5, y+8, 2); + ili9341_fill(bw-active_button_width+3, y+6, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); + ili9341_drawstring_size(text, bw-active_button_width+5, y+8, 2); } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { - ili9341_fill(320-active_button_width+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(l1, 320-active_button_width+5, y+7); - ili9341_drawstring(l2, 320-active_button_width+5, y+7+FONT_GET_HEIGHT+1); + ili9341_fill(bw-active_button_width+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(l1, bw-active_button_width+5, y+7); + ili9341_drawstring(l2, bw-active_button_width+5, y+7+FONT_GET_HEIGHT+1); } else { - ili9341_fill(320-active_button_width+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(menu[i].label, 320-active_button_width+5, y+10); + ili9341_fill(bw-active_button_width+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(menu[i].label, bw-active_button_width+5, y+10); } } } From 8dcf6a6b59a72c4ab032e4b3d882621dfa9c6e1a Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 27 Mar 2020 13:08:13 +0100 Subject: [PATCH 014/193] Force top level menu on screen --- nanovna.h | 1 + plot.c | 2 ++ sa_core.c | 4 +++- ui.c | 39 ++++++++++++++++++++++++++------------- ui_sa.c | 1 + 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/nanovna.h b/nanovna.h index 36a7d06..0638ad0 100644 --- a/nanovna.h +++ b/nanovna.h @@ -525,6 +525,7 @@ void clear_all_config_prop_data(void); */ extern void ui_init(void); extern void ui_process(void); +int current_menu_is_form(void); // Irq operation process set #define OP_NONE 0x00 diff --git a/plot.c b/plot.c index 7cb98a6..719a443 100644 --- a/plot.c +++ b/plot.c @@ -1902,6 +1902,8 @@ draw_frequencies(void) char buf2[32]; buf2[0] = 0; if (MODE_OUTPUT(settingMode)) // No frequencies during output return; + if (current_menu_is_form()) + return; #ifdef __VNA__ if ((domain_mode & DOMAIN_MODE) == DOMAIN_FREQ) { diff --git a/sa_core.c b/sa_core.c index 2349e11..0731ae9 100644 --- a/sa_core.c +++ b/sa_core.c @@ -75,7 +75,7 @@ int settingSpur = 0; int settingAverage = 0; int settingShowStorage = 0; int settingSubtractStorage = 0; -int settingMode = M_LOW; +int settingMode = -1; // Initialize to unknown state int settingDrive=0; // 0-3 , 3=+20dBm int settingAGC = true; int settingLNA = false; @@ -705,6 +705,8 @@ void draw_cal_status(void) if (MODE_OUTPUT(settingMode)) // No cal status during output return; + if (current_menu_is_form()) + return; ili9341_set_background(DEFAULT_BG_COLOR); diff --git a/ui.c b/ui.c index 1d13e0d..b29cf4a 100644 --- a/ui.c +++ b/ui.c @@ -1105,6 +1105,11 @@ menu_push_submenu(const menuitem_t *submenu) draw_menu(); } +int current_menu_is_form(void) +{ + return menu_is_form(menu_stack[menu_current_level]); +} + /* static void menu_move_top(void) @@ -1425,7 +1430,6 @@ static void draw_menu_buttons(const menuitem_t *menu) { int i = 0; - int bw = 320; char text[30]; for (i = 0; i < 7; i++) { const char *l1, *l2; @@ -1449,20 +1453,25 @@ draw_menu_buttons(const menuitem_t *menu) uint16_t old_bg = bg; int active_button_width; + int active_button_start; menu_item_modify_attribute(menu, i, &fg, &bg); // before plot_printf to create status text if (menu[i].type & MT_FORM) { - active_button_width = MENU_FORM_WIDTH; + active_button_start = 320 - MENU_FORM_WIDTH; + active_button_width = MENU_FORM_WIDTH - 30; // Shorten at the right if (MT_MASK(menu[i].type) == MT_CALLBACK) { // Only callback can have value keypad_mode = menu[i].data; fetch_numeric_target(); } plot_printf(text, sizeof text, menu[i].label, uistat.text); } - else + else { active_button_width = MENU_BUTTON_WIDTH; - ili9341_fill(bw-active_button_width, y, active_button_width, MENU_BUTTON_HEIGHT-4, old_bg); // Set button to unmodified background color - + active_button_start = 320 - MENU_BUTTON_WIDTH; + } + ili9341_fill(active_button_start, y, active_button_width, MENU_BUTTON_HEIGHT-4, old_bg); // Set button to unmodified background color +#if 0 // 3D button accent + int bw = 320; if (MT_MASK(menu[i].type) != MT_TITLE) { ili9341_fill(bw-active_button_width, y, 2, MENU_BUTTON_HEIGHT-4, LIGHT_GREY); // Set button to unmodified background color @@ -1470,21 +1479,21 @@ draw_menu_buttons(const menuitem_t *menu) ili9341_fill(bw-2, y, 2, MENU_BUTTON_HEIGHT-4, DARK_GREY); // Set button to unmodified background color ili9341_fill(bw-active_button_width, y+MENU_BUTTON_HEIGHT-4, active_button_width, 2, DARK_GREY); // Set button to unmodified background color } - +#endif ili9341_set_foreground(fg); ili9341_set_background(bg); if (menu[i].type & MT_FORM) { - ili9341_fill(bw-active_button_width+3, y+6, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); - ili9341_drawstring_size(text, bw-active_button_width+5, y+8, 2); + ili9341_fill(active_button_start+3, y+6, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); + ili9341_drawstring_size(text, active_button_start+5, y+8, 2); } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { - ili9341_fill(bw-active_button_width+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(l1, bw-active_button_width+5, y+7); - ili9341_drawstring(l2, bw-active_button_width+5, y+7+FONT_GET_HEIGHT+1); + ili9341_fill(active_button_start+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(l1, active_button_start+5, y+7); + ili9341_drawstring(l2, active_button_start+5, y+7+FONT_GET_HEIGHT+1); } else { - ili9341_fill(bw-active_button_width+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(menu[i].label, bw-active_button_width+5, y+10); + ili9341_fill(active_button_start+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(menu[i].label, active_button_start+5, y+10); } } } @@ -2280,6 +2289,10 @@ void ui_process(void) { int button_state = READ_PORT() & BUTTON_MASK; + if (ui_mode == UI_NORMAL && current_menu_is_form()) { // Force into menu mode + selection = -1; // hide keyboard mode selection + ui_mode_menu(); + } if (operation_requested&OP_LEVER || previous_button_state != button_state) { ui_process_lever(); previous_button_state = button_state; diff --git a/ui_sa.c b/ui_sa.c index 5850067..b5c3f18 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -846,6 +846,7 @@ int menu_is_form(const menuitem_t *menu) return(false); } + static void menu_item_modify_attribute( const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) { From bab77014585e19e13be061d1804c3999dbb298f6 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 27 Mar 2020 15:02:40 +0100 Subject: [PATCH 015/193] Large buttons and mode switching improvements --- ili9341.c | 10 ++++++++++ sa_core.c | 59 +++++++++++++++++++++++++++++++------------------------ ui.c | 14 +++++++++++++ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/ili9341.c b/ili9341.c index 0c44bf9..0cd5ad2 100644 --- a/ili9341.c +++ b/ili9341.c @@ -592,6 +592,16 @@ void ili9341_drawstring(const char *str, int x, int y) } } +void ili9341_drawstring_7x13(const char *str, int x, int y) +{ + while (*str) { + uint8_t ch = *str++; + const uint16_t *char_buf = &x7x13b_bits[(ch * 13)]; + blit16BitWidthBitmap(x, y, 7, 11, char_buf); + x += 7; + } +} + void ili9341_drawstringV(const char *str, int x, int y) { ili9341_set_rotation(DISPLAY_ROTATION_270); diff --git a/sa_core.c b/sa_core.c index 0731ae9..b7b057a 100644 --- a/sa_core.c +++ b/sa_core.c @@ -75,7 +75,7 @@ int settingSpur = 0; int settingAverage = 0; int settingShowStorage = 0; int settingSubtractStorage = 0; -int settingMode = -1; // Initialize to unknown state +int settingMode = M_LOW; int settingDrive=0; // 0-3 , 3=+20dBm int settingAGC = true; int settingLNA = false; @@ -309,31 +309,35 @@ void SetMode(int m) settingMode = m; switch(m) { case M_LOW: + minFreq = 0; + maxFreq = 520000000; set_sweep_frequency(ST_START, (int32_t) 0); set_sweep_frequency(ST_STOP, (int32_t) 300000000); SetRefpos(-10); - goto min_max_low; + settingSpur = 0; // Not for output mode + break; case M_GENLOW: + minFreq = 0; + maxFreq = 520000000; set_sweep_frequency(ST_CENTER, (int32_t) 10000000); set_sweep_frequency(ST_SPAN, 0); settingSpur = 0; // Not for output mode settingRefer = -1; // No refer output in output mode - min_max_low: - minFreq = 0; - maxFreq = 520000000; break; case M_HIGH: + minFreq = 240000000; + maxFreq = 960000000; set_sweep_frequency(ST_START, (int32_t) 300000000); set_sweep_frequency(ST_STOP, (int32_t) 960000000); SetRefpos(-30); - goto min_max_high; + goto common_high; case M_GENHIGH: + minFreq = 240000000; + maxFreq = 960000000; set_sweep_frequency(ST_CENTER, (int32_t) 300000000); set_sweep_frequency(ST_SPAN, 0); settingRefer = -1; // No refer output in output mode - min_max_high: - minFreq = 240000000; - maxFreq = 960000000; + common_high: extraVFO = false; // Not possible in high mode settingSpur = 0; // Not possible in high mode break; @@ -506,13 +510,14 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) } SetRX(settingMode); SI4432_SetReference(settingRefer); - if (local_IF) - setFreq (0, local_IF); + // if (dirty) { scandirty = true; dirty = false; // } } + if (i == 0 && ( scandirty || settingSpur) && local_IF) + setFreq (0, local_IF); if (settingModulation == MO_AM) { int p = settingAttenuate * 2 + modulation_counter; PE4302_Write_Byte(p); @@ -561,6 +566,10 @@ static bool sweep(bool break_on_operation) again: for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], extraVFO); + // back to toplevel to handle ui operation + if (operation_requested && break_on_operation) + return false; + if (settingSpur == 1) { // First pass temp_t[i] = RSSI; continue; // Skip all other processing @@ -590,29 +599,27 @@ again: } } if (i == sweep_points -1) { - if (scandirty) { - scandirty = false; - } - peakIndex = temppeakIndex; - peakLevel = actual_t[peakIndex]; - peakFreq = frequencies[peakIndex]; - settingSpur = -settingSpur; - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; - // redraw_marker(peak_marker, FALSE); } - // back to toplevel to handle ui operation - if (operation_requested && break_on_operation) - return false; } if (settingSpur == 1) { settingSpur = -1; goto again; + } else if (settingSpur == -1) + settingSpur = 1; + + if (scandirty) { + scandirty = false; } + peakIndex = temppeakIndex; + peakLevel = actual_t[peakIndex]; + peakFreq = frequencies[peakIndex]; + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; + // redraw_marker(peak_marker, FALSE); palSetPad(GPIOC, GPIOC_LED); return true; } diff --git a/ui.c b/ui.c index b29cf4a..21ce6fe 100644 --- a/ui.c +++ b/ui.c @@ -1488,12 +1488,26 @@ draw_menu_buttons(const menuitem_t *menu) ili9341_drawstring_size(text, active_button_start+5, y+8, 2); } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { +#define BIG_BUTTON_FONT 1 +#ifdef BIG_BUTTON_FONT +#undef FONT_HEIGHT +#define FONT_HEIGHT 13 + ili9341_fill(active_button_start+1, y+1, active_button_width-2, 13+13 -2, bg); + ili9341_drawstring_7x13(l1, active_button_start+2, y+1); + ili9341_drawstring_7x13(l2, active_button_start+2, y+1+13-1); +#else ili9341_fill(active_button_start+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); ili9341_drawstring(l1, active_button_start+5, y+7); ili9341_drawstring(l2, active_button_start+5, y+7+FONT_GET_HEIGHT+1); +#endif } else { +#ifdef BIG_BUTTON_FONT + ili9341_fill(active_button_start+1, y+1, active_button_width-2, 13+13 -2, bg); + ili9341_drawstring_7x13(menu[i].label, active_button_start+2, y+6); +#else ili9341_fill(active_button_start+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); ili9341_drawstring(menu[i].label, active_button_start+5, y+10); +#endif } } } From 37befeb9478aae6d01bb78a790a0ba9558ac4573 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 27 Mar 2020 19:34:57 +0100 Subject: [PATCH 016/193] Self test extended --- nanovna.h | 1 + plot.c | 25 +++++++------ sa_core.c | 102 +++++++++++++++++++++++++++++++++++++----------------- ui_sa.c | 12 +++++++ 4 files changed, 95 insertions(+), 45 deletions(-) diff --git a/nanovna.h b/nanovna.h index 0638ad0..09d2ec9 100644 --- a/nanovna.h +++ b/nanovna.h @@ -307,6 +307,7 @@ void set_trace_refpos(int t, float refpos); float get_trace_scale(int t); float get_trace_refpos(int t); const char *get_trace_typename(int t); +extern int in_selftest; #ifdef __VNA void set_electrical_delay(float picoseconds); diff --git a/plot.c b/plot.c index 719a443..f31d193 100644 --- a/plot.c +++ b/plot.c @@ -1144,9 +1144,9 @@ marker_search(void) if (uistat.current_trace == -1) return -1; - int value = CELL_Y(trace_index[uistat.current_trace][0]); + int value = CELL_Y(trace_index[TRACE_ACTUAL][0]); for (i = 0; i < sweep_points; i++) { - index_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[TRACE_ACTUAL][i]; if ((*compare)(value, CELL_Y(index))) { value = CELL_Y(index); found = i; @@ -1167,21 +1167,21 @@ marker_search_left(int from) { int i; int found = -1; - +#define MINMAX_DELTA -10 if (uistat.current_trace == -1) return -1; - int value = CELL_Y(trace_index[uistat.current_trace][from]); + int value = CELL_Y(trace_index[TRACE_ACTUAL][from]); for (i = from - 1; i >= 0; i--) { - index_t index = trace_index[uistat.current_trace][i]; - if ((*compare)(value, CELL_Y(index))) + index_t index = trace_index[TRACE_ACTUAL][i]; + if ((*compare)(value - MINMAX_DELTA, CELL_Y(index))) break; value = CELL_Y(index); } for (; i >= 0; i--) { - index_t index = trace_index[uistat.current_trace][i]; - if ((*compare)(CELL_Y(index), value)) { + index_t index = trace_index[TRACE_ACTUAL][i]; + if ((*compare)(CELL_Y(index), value + MINMAX_DELTA)) { break; } found = i; @@ -1198,17 +1198,16 @@ marker_search_right(int from) if (uistat.current_trace == -1) return -1; - - int value = CELL_Y(trace_index[uistat.current_trace][from]); + int value = CELL_Y(trace_index[TRACE_ACTUAL][from]); for (i = from + 1; i < sweep_points; i++) { - index_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[TRACE_ACTUAL][i]; if ((*compare)(value, CELL_Y(index))) break; value = CELL_Y(index); } for (; i < sweep_points; i++) { - index_t index = trace_index[uistat.current_trace][i]; + index_t index = trace_index[TRACE_ACTUAL][i]; if ((*compare)(CELL_Y(index), value)) { break; } @@ -1902,7 +1901,7 @@ draw_frequencies(void) char buf2[32]; buf2[0] = 0; if (MODE_OUTPUT(settingMode)) // No frequencies during output return; - if (current_menu_is_form()) + if (current_menu_is_form() && !in_selftest) return; #ifdef __VNA__ diff --git a/sa_core.c b/sa_core.c index b7b057a..43a06fd 100644 --- a/sa_core.c +++ b/sa_core.c @@ -84,6 +84,7 @@ int settingModulation = MO_NONE; int settingStepDelay = 0; float rbw = 0; float vbw = 0; +int in_selftest = false; uint32_t minFreq = 0; uint32_t maxFreq = 520000000; @@ -712,7 +713,7 @@ void draw_cal_status(void) if (MODE_OUTPUT(settingMode)) // No cal status during output return; - if (current_menu_is_form()) + if (current_menu_is_form() && !in_selftest) return; ili9341_set_background(DEFAULT_BG_COLOR); @@ -826,32 +827,38 @@ void draw_cal_status(void) // -------------------- Self testing ------------------------------------------------- enum { - TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT + TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT, TC_MEASURE, TC_SET, }; enum { - TP_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ + TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ, TPH_30MHZ }; -#define TEST_COUNT 7 +#define TEST_COUNT 13 static const struct { int kind; int setup; - uint32_t center; // In MHz - int span; // In MHz + float center; // In MHz + float span; // In MHz float pass; int width; float stop; } test_case [TEST_COUNT] = {// Condition Preparation Center Span Pass Width Stop - {TC_SIGNAL, TP_10MHZ, 10, 7, -30, 30, -85 }, - {TC_SIGNAL, TP_10MHZ, 20, 7, -50, 30, -90 }, - {TC_SIGNAL, TP_10MHZ, 30, 7, -40, 30, -90 }, - {TC_BELOW, TP_SILENT, 200, 100, -80, 0, 0}, - {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -30, 50, -80 }, - {TC_FLAT, TP_10MHZEXTRA, 10, 4, -35, 20, -80}, - {TC_SIGNAL, TP_30MHZ, 360, 18, -70, 20, -100 }, + {TC_BELOW, TP_SILENT, 0.001, 0.0005, -10,0, 0}, // 1 Zero Hz leakage + {TC_BELOW, TP_SILENT, 0.01, 0.01, -40, 0, 0}, // 2 Phase noise of zero Hz + {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -85 }, // 3 Measure power level and noise + {TC_SET, TP_30MHZ, 30, 7, -25, 0, 0 }, // 4 Calibrate power low mode + {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 5 Measure powerlevel and noise + {TC_SET, TPH_30MHZ, 270, 4, -50, 0, 0 }, // 6 Calibrate power high mode + {TC_SIGNAL, TP_10MHZ, 20, 7, -40, 30, -90 }, // 7 + {TC_SIGNAL, TP_10MHZ, 30, 7, -30, 30, -90 }, // 8 + {TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 9 Wide band noise floor low mode + {TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 10 Wide band noise floor high mode + {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 50, -70 }, // 11 BPF loss and stop band + {TC_FLAT, TP_10MHZEXTRA, 10, 4, -25, 20, -70}, // 12 BPF pass band flatness + {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 13 LPF cutoff }; enum { @@ -866,16 +873,19 @@ static const char *(test_fail_cause [TEST_COUNT]); static int test_status[TEST_COUNT]; static int show_test_info = FALSE; static volatile int test_wait = false; +static float test_value; static void test_acquire(int i) { pause_sweep(); +#if 0 if (test_case[i].center < 300) settingMode = M_LOW; else settingMode = M_HIGH; - set_sweep_frequency(ST_CENTER, (int32_t)test_case[i].center * 1000000); - set_sweep_frequency(ST_SPAN, (int32_t)test_case[i].span * 1000000); +#endif + set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); + set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); sweep(false); plot_into_index(measured); redraw_request |= REDRAW_CELLS | REDRAW_FREQUENCY; @@ -978,7 +988,17 @@ int validate_above(void) { void test_validate(int i) { - if (test_case[i].kind == TC_SIGNAL) { // Validate signal +// draw_all(TRUE); + SetRefpos(test_case[i].pass+10); + switch (test_case[i].kind) { + case TC_SET: + if (test_case[i].pass == 0) { + if (test_value != 0) + SetPowerLevel(test_value); + } else + SetPowerLevel(test_case[i].pass); + case TC_MEASURE: + case TC_SIGNAL: // Validate signal if (validate_peak_within(i, 5.0)) // Validate Peak test_status[i] = TS_PASS; else if (validate_peak_within(i, 10.0)) @@ -1007,8 +1027,12 @@ void test_validate(int i) if (test_status[i] != TS_PASS) test_fail_cause[i] = "Stopband "; } - - } else if (test_case[i].kind == TC_ABOVE) { // Validate signal above curve + if (test_status[i] == TS_PASS && test_case[i].kind == TC_MEASURE) + test_value = peakLevel; + else + test_value = 0; // Not valid + break; + case TC_ABOVE: // Validate signal above curve for (int j = 0; j < POINTS_COUNT; j++) { if (actual_t[j] < test_case[i].pass + 5) test_status[i] = TS_CRITICAL; @@ -1019,26 +1043,26 @@ void test_validate(int i) } if (test_status[i] != TS_PASS) test_fail_cause[i] = "Above "; - - } else if (test_case[i].kind == TC_BELOW) { // Validate signal below curve - if (validate_peak_below(i, 10.0)) - test_status[i] = TS_PASS; - else if (validate_peak_below(i, 5.0)) - test_status[i] = TS_CRITICAL; - else - test_status[i] = TS_FAIL; + break; + case TC_BELOW: // Validate signal below curve + test_status[i] = validate_below(); if (test_status[i] != TS_PASS) test_fail_cause[i] = "Above "; - } else if (test_case[i].kind == TC_FLAT) { // Validate passband flatness + break; + case TC_FLAT: // Validate passband flatness test_status[i] = validate_flatness(i); if (test_status[i] != TS_PASS) test_fail_cause[i] = "Passband "; + break; + } // Report status if (test_status[i] != TS_PASS || i == TEST_COUNT - 1) test_wait = true; +// draw_frequencies(); +// draw_cal_status(); draw_all(TRUE); resume_sweep(); } @@ -1048,6 +1072,7 @@ extern void touch_wait_release(void); void self_test(void) { + in_selftest = true; menu_autosettings_cb(0); for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting test_status[i] = TS_WAITING; @@ -1057,26 +1082,38 @@ void self_test(void) for (int i=0; i < TEST_COUNT; i++) { extraVFO = false; //Default test setup switch(test_case[i].setup) { // Prepare test conditions + case TPH_SILENT: // No input signal + SetMode(M_HIGH); case TP_SILENT: // No input signal + SetMode(M_LOW); +common_silent: set_refer_output(-1); for (int j = 0; j < POINTS_COUNT; j++) stored_t[j] = test_case[i].pass; break; case TP_10MHZEXTRA: // Swept receiver + SetMode(M_LOW); extraVFO = true; //Sweep BPF + set_refer_output(2); goto common; case TP_10MHZ: // 10MHz input - common: + SetMode(M_LOW); set_refer_output(2); - int j; - for (j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) + common: + + for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) stored_t[j] = test_case[i].stop; - for (j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) + for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) stored_t[j] = test_case[i].stop; - for (j = POINTS_COUNT/2 - test_case[i].width; j < POINTS_COUNT/2 + test_case[i].width; j++) + for (int j = POINTS_COUNT/2 - test_case[i].width; j < POINTS_COUNT/2 + test_case[i].width; j++) stored_t[j] = test_case[i].pass; break; case TP_30MHZ: + SetMode(M_LOW); + set_refer_output(0); + goto common; + case TPH_30MHZ: + SetMode(M_HIGH); set_refer_output(0); goto common; } @@ -1103,5 +1140,6 @@ void self_test(void) settingMode = M_LOW; draw_cal_status(); + in_selftest = false; menu_autosettings_cb(0); } diff --git a/ui_sa.c b/ui_sa.c index b5c3f18..1e5f44f 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -715,12 +715,24 @@ static const menuitem_t menu_marker_type[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; +const menuitem_t menu_marker_search[] = { + //{ MT_CALLBACK, "OFF", menu_marker_search_cb }, + { MT_CALLBACK, 0, "MAXIMUM", menu_marker_search_cb }, + { MT_CALLBACK, 0, "MINIMUM", menu_marker_search_cb }, + { MT_CALLBACK, 0, "\2SEARCH\0" S_LARROW" LEFT", menu_marker_search_cb }, + { MT_CALLBACK, 0, "\2SEARCH\0" S_RARROW" RIGHT", menu_marker_search_cb }, + { MT_CALLBACK, 0, "TRACKING", menu_marker_search_cb }, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + static const menuitem_t menu_marker_sel[] = { { MT_CALLBACK, 0, "MARKER 1", menu_marker_sel_cb}, { MT_CALLBACK, 0, "MARKER 2", menu_marker_sel_cb}, { MT_CALLBACK, 0, "MARKER 3", menu_marker_sel_cb}, { MT_CALLBACK, 0, "MARKER 4", menu_marker_sel_cb}, { MT_CALLBACK, 0, "ALL OFF", menu_marker_sel_cb}, + { MT_SUBMENU, 0, "\2SEARCH\0MARKER", menu_marker_search}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 39da5289b4cf113de434fc4c31a4a67a3d9ef6ba Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 28 Mar 2020 13:11:20 +0100 Subject: [PATCH 017/193] Spur avoidance table added --- main.c | 5 ++- plot.c | 2 +- sa_core.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 87 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index 02d8b92..fb246a5 100644 --- a/main.c +++ b/main.c @@ -801,7 +801,10 @@ static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, reserved, }; static const marker_t def_markers[MARKERS_MAX] = { - { 1, M_REFERENCE, 30, 0 }, { 0, M_DELTA, 40, 0 }, { 0, M_DELTA, 60, 0 }, { 0, M_DELTA, 80, 0 } + { 1, M_REFERENCE, 30, 0 }, + { 0, M_NORMAL, 40, 0 }, + { 0, M_NORMAL, 60, 0 }, + { 0, M_NORMAL, 80, 0 } }; // Load propeties default settings diff --git a/plot.c b/plot.c index f31d193..d65a34e 100644 --- a/plot.c +++ b/plot.c @@ -67,7 +67,7 @@ typedef uint32_t map_t; uint16_t marker_color[3] = { RGBHEX(0xFFFFFF), - RGBHEX(0x0000FF), + RGBHEX(0xFFFF00), RGBHEX(0x00FF00) }; diff --git a/sa_core.c b/sa_core.c index 43a06fd..28c2cec 100644 --- a/sa_core.c +++ b/sa_core.c @@ -476,12 +476,75 @@ void update_rbw(uint32_t delta_f) dirty = true; } +//static int spur_old_stepdelay = 0; +static int spur_IF = 433900000; +static int spur_alternate_IF = 433700000; +static const int spur_table[] = +{ + 470000, + 780000, + 830000, + 880000, + 949000, + 1468000, + 1830000, + 1900000, + 2840000, + 2880000, + 4780000, + 4800000, + 4880000, + 6510000 + 6860000, + 7340000, + 8100000, + 8200000, + 8880000, +// 9970000, 10MHz!!!!!! + 10870000, + 11420000, + 14880000, + 16820000, +}; + +int avoid_spur(int f) +{ + int window = ((int)rbw ) * 1000*2; + if (window < 50000) + window = 50000; + if (! settingMode == M_LOW) + return false ; + if (frequency_IF != spur_IF) + return false; + if (rbw > 300.0) + return(false); +// if (spur_old_stepdelay != 0 && actualStepDelay != spur_old_stepdelay) // restore stepdelay +// actualStepDelay = spur_old_stepdelay; + for (int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { + if (f/window == spur_table[i]/window) { +// spur_old_stepdelay = actualStepDelay; +// actualStepDelay += 4000; + return true; + } + } + return false; +} + static int old_lf = -1; static int modulation_counter = 0; +static int old_local_IF = -1; float perform(bool break_on_operation, int i, int32_t f, int extraV) { - long local_IF = (MODE_LOW(settingMode)?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); +// long local_IF = (MODE_LOW(settingMode)?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); + long local_IF; + if (MODE_HIGH(settingMode)) + local_IF = 0; + else if (avoid_spur(f)) + local_IF = spur_alternate_IF; + else + local_IF = frequency_IF; + if (i == 0 && dirty) { if (settingStepDelay == 0){ if (rbw < 10.0) @@ -517,8 +580,11 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) dirty = false; // } } - if (i == 0 && ( scandirty || settingSpur) && local_IF) +// if (i == 0 && ( scandirty || settingSpur) && local_IF) + if (local_IF && old_local_IF != local_IF) { setFreq (0, local_IF); + old_local_IF = local_IF; + } if (settingModulation == MO_AM) { int p = settingAttenuate * 2 + modulation_counter; PE4302_Write_Byte(p); @@ -564,6 +630,7 @@ static bool sweep(bool break_on_operation) float RSSI; palClearPad(GPIOC, GPIOC_LED); temppeakLevel = -150; +// spur_old_stepdelay = 0; again: for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], extraVFO); @@ -612,6 +679,7 @@ again: if (scandirty) { scandirty = false; + draw_cal_status(); } peakIndex = temppeakIndex; peakLevel = actual_t[peakIndex]; @@ -705,10 +773,6 @@ void draw_cal_status(void) #define XSTEP 40 -// if (!sweep_enabled) -// perform(true, 0, frequencies[0], false); - - ili9341_fill(x, y, OFFSETX, HEIGHT, 0x0000); if (MODE_OUTPUT(settingMode)) // No cal status during output @@ -787,6 +851,9 @@ void draw_cal_status(void) buf[5]=0; ili9341_drawstring(buf, x, y); + if (dirty) + ili9341_set_foreground(BRIGHT_COLOR_RED); + y += YSTEP*2; ili9341_drawstring("Scan:", x, y); @@ -886,6 +953,10 @@ static void test_acquire(int i) #endif set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); + SetAverage(4); + sweep(false); + sweep(false); + sweep(false); sweep(false); plot_into_index(measured); redraw_request |= REDRAW_CELLS | REDRAW_FREQUENCY; @@ -989,7 +1060,6 @@ int validate_above(void) { void test_validate(int i) { // draw_all(TRUE); - SetRefpos(test_case[i].pass+10); switch (test_case[i].kind) { case TC_SET: if (test_case[i].pass == 0) { @@ -997,8 +1067,10 @@ void test_validate(int i) SetPowerLevel(test_value); } else SetPowerLevel(test_case[i].pass); - case TC_MEASURE: + goto common; + case TC_MEASURE: case TC_SIGNAL: // Validate signal + common: if (validate_peak_within(i, 5.0)) // Validate Peak test_status[i] = TS_PASS; else if (validate_peak_within(i, 10.0)) @@ -1084,6 +1156,7 @@ void self_test(void) switch(test_case[i].setup) { // Prepare test conditions case TPH_SILENT: // No input signal SetMode(M_HIGH); + goto common_silent; case TP_SILENT: // No input signal SetMode(M_LOW); common_silent: @@ -1118,9 +1191,7 @@ common_silent: goto common; } trace[TRACE_STORED].enabled = true; - set_trace_refpos(0, NGRIDY - (test_case[i].pass + 30) / get_trace_scale(0)); - set_trace_refpos(1, NGRIDY - (test_case[i].pass + 30) / get_trace_scale(0)); - set_trace_refpos(2, NGRIDY - (test_case[i].pass + 30) / get_trace_scale(0)); + SetRefpos(test_case[i].pass+10); draw_cal_status(); test_acquire(i); // Acquire test test_validate(i); // Validate test From 8631ac14f15434c65cc6c5c0abad6f218f26cfd5 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 28 Mar 2020 19:52:49 +0100 Subject: [PATCH 018/193] Atampt to auto scaling and other UI improvements --- sa_core.c | 31 +++++++++++++++++++++++++------ ui.c | 6 +++--- ui_sa.c | 4 ++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/sa_core.c b/sa_core.c index 28c2cec..d839429 100644 --- a/sa_core.c +++ b/sa_core.c @@ -354,6 +354,7 @@ void SetMode(int m) float peakLevel; +float min_level; uint32_t peakFreq; int peakIndex; float temppeakLevel; @@ -486,15 +487,20 @@ static const int spur_table[] = 830000, 880000, 949000, + 1390000, 1468000, 1830000, 1900000, + 2770000, 2840000, 2880000, + 4710000, 4780000, 4800000, 4880000, - 6510000 + 6510000, + 6750000, + 6790000, 6860000, 7340000, 8100000, @@ -630,7 +636,8 @@ static bool sweep(bool break_on_operation) float RSSI; palClearPad(GPIOC, GPIOC_LED); temppeakLevel = -150; -// spur_old_stepdelay = 0; + float temp_min_level = 100; + // spur_old_stepdelay = 0; again: for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], extraVFO); @@ -666,10 +673,8 @@ again: temppeakLevel = actual_t[i]; } } - if (i == sweep_points -1) { - - - } + if (temp_min_level > actual_t[i]) + temp_min_level = actual_t[i]; } if (settingSpur == 1) { settingSpur = -1; @@ -684,6 +689,20 @@ again: peakIndex = temppeakIndex; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; + min_level = temp_min_level; +#if 0 // Auto ref level setting + int scale = get_trace_scale(2); + int rp = (NGRIDY - get_trace_refpos(2)) * scale; + if (scale > 0 && peakLevel > rp && peakLevel - min_level < 8 * scale ) { + SetRefpos((((int)(peakLevel/scale)) + 1) * scale); + } + if (scale > 0 && min_level < rp - 9*scale && peakLevel - min_level < 8 * scale ) { + int new_rp = (((int)((min_level + 9*scale)/scale)) - 1) * scale; + if (new_rp < rp) + SetRefpos(new_rp); + } + +#endif int peak_marker = 0; markers[peak_marker].enabled = true; markers[peak_marker].index = peakIndex; diff --git a/ui.c b/ui.c index 21ce6fe..f89aca6 100644 --- a/ui.c +++ b/ui.c @@ -1052,7 +1052,7 @@ const menuitem_t menu_top[] = { #define MENU_BUTTON_WIDTH 60 #define MENU_BUTTON_START (320-MENU_BUTTON_WIDTH) -#define MENU_FORM_WIDTH 290 +#define MENU_FORM_WIDTH 295 #define MENU_FORM_START (320 - MENU_FORM_WIDTH) #define MENU_BUTTON_HEIGHT 30 #define NUM_INPUT_HEIGHT 30 @@ -1484,8 +1484,8 @@ draw_menu_buttons(const menuitem_t *menu) ili9341_set_foreground(fg); ili9341_set_background(bg); if (menu[i].type & MT_FORM) { - ili9341_fill(active_button_start+3, y+6, active_button_width-6, 2+FONT_GET_HEIGHT*2+2, bg); - ili9341_drawstring_size(text, active_button_start+5, y+8, 2); + ili9341_fill(active_button_start+2, y+2, active_button_width-4, FONT_GET_HEIGHT*2+8, bg); + ili9341_drawstring_size(text, active_button_start+6, y+6, 2); } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { #define BIG_BUTTON_FONT 1 diff --git a/ui_sa.c b/ui_sa.c index 1e5f44f..ec10d26 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1035,7 +1035,7 @@ static void fetch_numeric_target(void) break; case KM_LOWOUTLEVEL: uistat.value = settingAttenuate; - uistat.value = -10 - uistat.value; // compensation for dB offset during low output mode + uistat.value = -5 - uistat.value; // compensation for dB offset during low output mode plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_HIGHOUTLEVEL: @@ -1099,7 +1099,7 @@ set_numeric_value(void) SetDrive(uistat.value); break; case KM_LOWOUTLEVEL: - uistat.value = -10 - uistat.value ; // compensation for dB offset during low output mode + uistat.value = -5 - uistat.value ; // compensation for dB offset during low output mode SetAttenuation(uistat.value); break; case KM_HIGHOUTLEVEL: From 6a627149d64b849dc1a68e29e66a43e48ccafc70 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 29 Mar 2020 15:51:15 +0200 Subject: [PATCH 019/193] Test and calibrate updated --- nanovna.h | 2 + plot.c | 11 +-- sa_core.c | 263 ++++++++++++++++++++++++++++++++++-------------------- si4432.c | 9 +- ui_sa.c | 109 ++++++++++------------ 5 files changed, 226 insertions(+), 168 deletions(-) diff --git a/nanovna.h b/nanovna.h index 09d2ec9..0a96e9c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -620,5 +620,7 @@ int GetStorage(void); int GetSubtractStorage(void); int get_waterfall(void); +void calibrate(void); +void reset_calibration(void); /*EOF*/ diff --git a/plot.c b/plot.c index d65a34e..23dfe61 100644 --- a/plot.c +++ b/plot.c @@ -1100,7 +1100,7 @@ markmap_marker(int marker) int t; if (!markers[marker].enabled) return; - for (t = 0; t < TRACES_MAX; t++) { + for (t = TRACE_ACTUAL; t < TRACE_ACTUAL; t++) { if (!trace[t].enabled) continue; index_t index = trace_index[t][markers[marker].index]; @@ -1390,9 +1390,10 @@ draw_cell(int m, int n) for (i = 0; i < MARKERS_MAX; i++) { if (!markers[i].enabled) continue; - for (t = 0; t < TRACES_MAX; t++) { - if (!trace[t].enabled) - continue; +// for (t = 0; t < TRACES_MAX; t++) { +// if (!trace[t].enabled) +// continue; + t = TRACE_ACTUAL; index_t index = trace_index[t][markers[i].index]; int x = CELL_X(index) - x0 - X_MARKER_OFFSET; int y = CELL_Y(index) - y0 - Y_MARKER_OFFSET; @@ -1401,7 +1402,7 @@ draw_cell(int m, int n) y + MARKER_HEIGHT >= 0 && y - MARKER_HEIGHT < CELLHEIGHT) draw_marker(x, y, marker_color[markers[i].mtype], i); // draw_marker(x, y, config.trace_color[t], i); - } +// } } #endif // Draw trace and marker info on the top (50 system ticks for all screen calls) diff --git a/sa_core.c b/sa_core.c index d839429..f091dbe 100644 --- a/sa_core.c +++ b/sa_core.c @@ -372,22 +372,14 @@ void setupSA(void) PE4302_Write_Byte(0); } +static unsigned long old_freq[2] = { 0, 0 }; void setFreq(int V, unsigned long freq) { - if (V>=0) { - SI4432_Sel = V; -#ifdef USE_SI4463 - if (SI4432_Sel == 2) { - freq = freq - 433000000; - freq = freq / 10000; //convert to 10kHz channel starting with 433MHz - // Serial.print("Set frequency Si4463 = "); - // Serial.println(freq); - Si446x_RX ((uint8_t)freq); - } - else -#endif - SI4432_Set_Frequency(freq); + SI4432_Sel = V; + if (old_freq[V] != freq) { + SI4432_Set_Frequency(freq); + old_freq[V] = freq; } } @@ -586,10 +578,8 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) dirty = false; // } } -// if (i == 0 && ( scandirty || settingSpur) && local_IF) - if (local_IF && old_local_IF != local_IF) { + if (local_IF) { setFreq (0, local_IF); - old_local_IF = local_IF; } if (settingModulation == MO_AM) { int p = settingAttenuate * 2 + modulation_counter; @@ -615,8 +605,7 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) int lf = (uint32_t)(f + (int)(t * 500 * rbw)); if (extraV) setFreq (0, local_IF + lf - refferFreq[settingRefer]); // Offset so fundamental of reffer is visible - if (lf != old_lf) // only set on change - setFreq (1, local_IF + lf); + setFreq (1, local_IF + lf); old_lf = lf; if (MODE_OUTPUT(settingMode)) return(0); @@ -913,14 +902,14 @@ void draw_cal_status(void) // -------------------- Self testing ------------------------------------------------- enum { - TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT, TC_MEASURE, TC_SET, + TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT, TC_MEASURE, TC_SET, TC_END, }; enum { TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ, TPH_30MHZ }; -#define TEST_COUNT 13 +#define TEST_COUNT 14 static const struct { int kind; @@ -934,17 +923,18 @@ static const struct { {// Condition Preparation Center Span Pass Width Stop {TC_BELOW, TP_SILENT, 0.001, 0.0005, -10,0, 0}, // 1 Zero Hz leakage {TC_BELOW, TP_SILENT, 0.01, 0.01, -40, 0, 0}, // 2 Phase noise of zero Hz - {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -85 }, // 3 Measure power level and noise - {TC_SET, TP_30MHZ, 30, 7, -25, 0, 0 }, // 4 Calibrate power low mode - {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 5 Measure powerlevel and noise - {TC_SET, TPH_30MHZ, 270, 4, -50, 0, 0 }, // 6 Calibrate power high mode - {TC_SIGNAL, TP_10MHZ, 20, 7, -40, 30, -90 }, // 7 - {TC_SIGNAL, TP_10MHZ, 30, 7, -30, 30, -90 }, // 8 - {TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 9 Wide band noise floor low mode - {TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 10 Wide band noise floor high mode - {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 50, -70 }, // 11 BPF loss and stop band - {TC_FLAT, TP_10MHZEXTRA, 10, 4, -25, 20, -70}, // 12 BPF pass band flatness - {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 13 LPF cutoff + {TC_SIGNAL, TP_10MHZ, 20, 7, -40, 30, -90 }, // 3 + {TC_SIGNAL, TP_10MHZ, 30, 7, -30, 30, -90 }, // 4 + {TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 5 Wide band noise floor low mode + {TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 6 Wide band noise floor high mode + {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 50, -70 }, // 7 BPF loss and stop band + {TC_FLAT, TP_10MHZEXTRA, 10, 4, -25, 20, -70}, // 8 BPF pass band flatness + {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 9 LPF cutoff + {TC_END, 0, 0, 0, 0, 0, 0}, + {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -85 }, // 11 Measure power level and noise + {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 13 Measure powerlevel and noise + {TC_MEASURE, TPH_30MHZ, 270, 4, -50, 30, -85 }, // 14 Calibrate power high mode + {TC_END, 0, 0, 0, 0, 0, 0}, }; enum { @@ -992,13 +982,15 @@ void cell_draw_test_info(int x0, int y0) // char self_test_status_buf[35]; if (!show_test_info) return; - for (int i = -1; i < TEST_COUNT+1; i++) { + int i = -2; + do { + i++; int xpos = 25 - x0; int ypos = 40+i*INFO_SPACING - y0; unsigned int color = RGBHEX(0xFFFFFF); if (i == -1) { plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Self test status:"); - } else if (i == TEST_COUNT) { + } else if (test_case[i].kind == TC_END) { if (test_wait) plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Touch screen to continue"); else @@ -1016,7 +1008,7 @@ void cell_draw_test_info(int x0, int y0) } ili9341_set_foreground(color); cell_drawstring(self_test_status_buf, xpos, ypos); - } + } while (test_case[i].kind != TC_END); } #define fabs(X) ((X)<0?-(X):(X)) @@ -1076,9 +1068,10 @@ int validate_above(void) { } -void test_validate(int i) +int test_validate(int i) { // draw_all(TRUE); + int current_test_status = TS_PASS; switch (test_case[i].kind) { case TC_SET: if (test_case[i].pass == 0) { @@ -1091,34 +1084,34 @@ void test_validate(int i) case TC_SIGNAL: // Validate signal common: if (validate_peak_within(i, 5.0)) // Validate Peak - test_status[i] = TS_PASS; + current_test_status = TS_PASS; else if (validate_peak_within(i, 10.0)) - test_status[i] = TS_CRITICAL; + current_test_status = TS_CRITICAL; else - test_status[i] = TS_FAIL; - if (test_status[i] != TS_PASS) + current_test_status = TS_FAIL; + if (current_test_status != TS_PASS) test_fail_cause[i] = "Peak "; - if (test_status[i] == TS_PASS) { // Validate noise floor + if (current_test_status == TS_PASS) { // Validate noise floor for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) { if (actual_t[j] > test_case[i].stop - 5) - test_status[i] = TS_CRITICAL; + current_test_status = TS_CRITICAL; else if (actual_t[j] > test_case[i].stop) { - test_status[i] = TS_FAIL; + current_test_status = TS_FAIL; break; } } for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) { if (actual_t[j] > test_case[i].stop - 5) - test_status[i] = TS_CRITICAL; + current_test_status = TS_CRITICAL; else if (actual_t[j] > test_case[i].stop) { - test_status[i] = TS_FAIL; + current_test_status = TS_FAIL; break; } } - if (test_status[i] != TS_PASS) + if (current_test_status != TS_PASS) test_fail_cause[i] = "Stopband "; } - if (test_status[i] == TS_PASS && test_case[i].kind == TC_MEASURE) + if (current_test_status == TS_PASS && test_case[i].kind == TC_MEASURE) test_value = peakLevel; else test_value = 0; // Not valid @@ -1126,23 +1119,23 @@ void test_validate(int i) case TC_ABOVE: // Validate signal above curve for (int j = 0; j < POINTS_COUNT; j++) { if (actual_t[j] < test_case[i].pass + 5) - test_status[i] = TS_CRITICAL; + current_test_status = TS_CRITICAL; else if (actual_t[j] < test_case[i].pass) { - test_status[i] = TS_FAIL; + current_test_status = TS_FAIL; break; } } - if (test_status[i] != TS_PASS) + if (current_test_status != TS_PASS) test_fail_cause[i] = "Above "; break; case TC_BELOW: // Validate signal below curve - test_status[i] = validate_below(); - if (test_status[i] != TS_PASS) + current_test_status = validate_below(); + if (current_test_status != TS_PASS) test_fail_cause[i] = "Above "; break; case TC_FLAT: // Validate passband flatness - test_status[i] = validate_flatness(i); - if (test_status[i] != TS_PASS) + current_test_status = validate_flatness(i); + if (current_test_status != TS_PASS) test_fail_cause[i] = "Passband "; break; @@ -1150,12 +1143,58 @@ void test_validate(int i) // Report status - if (test_status[i] != TS_PASS || i == TEST_COUNT - 1) + if (current_test_status != TS_PASS || test_case[i+1].kind == TC_END) test_wait = true; // draw_frequencies(); // draw_cal_status(); draw_all(TRUE); resume_sweep(); + return current_test_status; +} + +void test_prepare(int i) +{ + extraVFO = false; //Default test setup + switch(test_case[i].setup) { // Prepare test conditions + case TPH_SILENT: // No input signal + SetMode(M_HIGH); + goto common_silent; + case TP_SILENT: // No input signal + SetMode(M_LOW); +common_silent: + set_refer_output(-1); + for (int j = 0; j < POINTS_COUNT; j++) + stored_t[j] = test_case[i].pass; + break; + case TP_10MHZEXTRA: // Swept receiver + SetMode(M_LOW); + extraVFO = true; //Sweep BPF + set_refer_output(2); + goto common; + case TP_10MHZ: // 10MHz input + SetMode(M_LOW); + set_refer_output(2); + common: + + for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) + stored_t[j] = test_case[i].stop; + for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) + stored_t[j] = test_case[i].stop; + for (int j = POINTS_COUNT/2 - test_case[i].width; j < POINTS_COUNT/2 + test_case[i].width; j++) + stored_t[j] = test_case[i].pass; + break; + case TP_30MHZ: + SetMode(M_LOW); + set_refer_output(0); + goto common; + case TPH_30MHZ: + SetMode(M_HIGH); + set_refer_output(0); + goto common; + } + trace[TRACE_STORED].enabled = true; + SetRefpos(test_case[i].pass+10); + draw_cal_status(); } extern void menu_autosettings_cb(int item); @@ -1166,58 +1205,22 @@ void self_test(void) in_selftest = true; menu_autosettings_cb(0); for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting + if (test_case[i].kind == TC_END) + break; test_status[i] = TS_WAITING; test_fail_cause[i] = ""; } show_test_info = TRUE; - for (int i=0; i < TEST_COUNT; i++) { - extraVFO = false; //Default test setup - switch(test_case[i].setup) { // Prepare test conditions - case TPH_SILENT: // No input signal - SetMode(M_HIGH); - goto common_silent; - case TP_SILENT: // No input signal - SetMode(M_LOW); -common_silent: - set_refer_output(-1); - for (int j = 0; j < POINTS_COUNT; j++) - stored_t[j] = test_case[i].pass; - break; - case TP_10MHZEXTRA: // Swept receiver - SetMode(M_LOW); - extraVFO = true; //Sweep BPF - set_refer_output(2); - goto common; - case TP_10MHZ: // 10MHz input - SetMode(M_LOW); - set_refer_output(2); - common: - - for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) - stored_t[j] = test_case[i].stop; - for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) - stored_t[j] = test_case[i].stop; - for (int j = POINTS_COUNT/2 - test_case[i].width; j < POINTS_COUNT/2 + test_case[i].width; j++) - stored_t[j] = test_case[i].pass; - break; - case TP_30MHZ: - SetMode(M_LOW); - set_refer_output(0); - goto common; - case TPH_30MHZ: - SetMode(M_HIGH); - set_refer_output(0); - goto common; - } - trace[TRACE_STORED].enabled = true; - SetRefpos(test_case[i].pass+10); - draw_cal_status(); + int i=0; + while (test_case[i].kind != TC_END) { + test_prepare(i); test_acquire(i); // Acquire test - test_validate(i); // Validate test - chThdSleepMilliseconds(2000); + test_status[i] = test_validate(i); // Validate test + chThdSleepMilliseconds(1000); if (test_status[i] != TS_PASS) { touch_wait_release(); } + i++; } touch_wait_release(); // chThdSleepMilliseconds(2000); @@ -1227,9 +1230,71 @@ common_silent: set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); set_refer_output(0); - settingMode = M_LOW; + SetMode(M_LOW); + SetAverage(0); draw_cal_status(); + in_selftest = false; + menu_autosettings_cb(0); +} + +void reset_calibration(void) +{ + SetPowerLevel(100); +} +#define CALIBRATE_RBWS 5 +const int power_rbw [5] = { 100, 300, 30, 10, 3 }; + +void calibrate(void) +{ + int local_test_status; + float last_peak_level; + in_selftest = true; + SetPowerLevel(100); + menu_autosettings_cb(0); + int i = 10; // calibrate low mode power on 30 MHz; + for (int j= 0; j < CALIBRATE_RBWS; j++ ) { + SetRBW(power_rbw[j]); + test_prepare(i); + test_acquire(i); // Acquire test + local_test_status = test_validate(i); // Validate test + chThdSleepMilliseconds(1000); + if (local_test_status != TS_PASS) { + // touch_wait_release(); + } else + SetPowerLevel(-25); + } + i = 11; // Measure 270MHz in low mode + SetRBW(100); + test_prepare(i); + test_acquire(i); // Acquire test + last_peak_level = peakLevel; + local_test_status = test_validate(i); // Validate test + chThdSleepMilliseconds(1000); + + config.high_level_offset = -20; /// Preliminary setting + + i = 12; // Calibrate 270MHz in high mode + for (int j = 0; j < CALIBRATE_RBWS-1; j++) { + SetRBW(power_rbw[j]); + test_prepare(i); + test_acquire(i); // Acquire test + local_test_status = test_validate(i); // Validate test + chThdSleepMilliseconds(1000); + if (local_test_status != TS_PASS) { + touch_wait_release(); + } else + SetPowerLevel(last_peak_level); + } + touch_wait_release(); + trace[TRACE_STORED].enabled = false; + set_trace_refpos(0, NGRIDY - (-10) / get_trace_scale(0)); + set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); + set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); + set_refer_output(0); + SetMode(M_LOW); + SetAverage(0); + draw_cal_status(); in_selftest = false; menu_autosettings_cb(0); } diff --git a/si4432.c b/si4432.c index 96a45a5..cd42d04 100644 --- a/si4432.c +++ b/si4432.c @@ -133,7 +133,7 @@ void SI4432_Reset(void) int count = 0; // always perform a system reset (don't send 0x87) SI4432_Write_Byte( 0x07, 0x80); - chThdSleepMilliseconds(25); + chThdSleepMilliseconds(50); // wait for chiprdy bit while (count++ < 100 && ( SI4432_Read_Byte ( 0x04 ) & 0x02 ) == 0) { chThdSleepMilliseconds(10); @@ -146,11 +146,11 @@ void SI4432_Transmit(int d) SI4432_Write_Byte(0x6D, (byte) (0x1C+d)); if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 2) return; // Already in transmit mode - chThdSleepMilliseconds(20); + chThdSleepMilliseconds(10); SI4432_Write_Byte( 0x07, 0x0b); chThdSleepMilliseconds(20); while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 2) { - chThdSleepMilliseconds(1); + chThdSleepMilliseconds(10); } } @@ -159,8 +159,9 @@ void SI4432_Receive(void) int count = 0; if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 1) return; // Already in receive mode - SI4432_Write_Byte( 0x07, 0x07); chThdSleepMilliseconds(10); + SI4432_Write_Byte( 0x07, 0x07); + chThdSleepMilliseconds(20); while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 1) { chThdSleepMilliseconds(5); } diff --git a/ui_sa.c b/ui_sa.c index ec10d26..a985769 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -216,47 +216,63 @@ void menu_autosettings_cb(int item, uint8_t data) active_marker = 0; for (int i = 1; i Date: Sun, 29 Mar 2020 19:05:43 +0200 Subject: [PATCH 020/193] Updated stepdelay's --- sa_core.c | 33 ++++++++++++++++++++------------- si4432.c | 2 +- ui_sa.c | 6 +++--- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/sa_core.c b/sa_core.c index f091dbe..d1fa976 100644 --- a/sa_core.c +++ b/sa_core.c @@ -470,8 +470,8 @@ void update_rbw(uint32_t delta_f) } //static int spur_old_stepdelay = 0; -static int spur_IF = 433900000; -static int spur_alternate_IF = 433700000; +static const int spur_IF = 433900000; +static const int spur_alternate_IF = 433700000; static const int spur_table[] = { 470000, @@ -545,14 +545,21 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) if (i == 0 && dirty) { if (settingStepDelay == 0){ - if (rbw < 10.0) - actualStepDelay = 2500; - else if (rbw <30.0) - actualStepDelay = 2000; - else if (rbw <100.0) - actualStepDelay = 1000; - else - actualStepDelay = 500; + if (MODE_LOW(settingMode)) { + if (rbw >300.0) actualStepDelay = 400; + else if (rbw >100.0) actualStepDelay = 500; + else if (rbw > 30.0) actualStepDelay = 900; + else if (rbw > 10.0) actualStepDelay = 900; + else if (rbw > 3.0) actualStepDelay = 1000; + else actualStepDelay = 1500; + } else { + if (rbw >300.0) actualStepDelay = 900; + else if (rbw >100.0) actualStepDelay = 900; + else if (rbw > 30.0) actualStepDelay = 900; + else if (rbw > 10.0) actualStepDelay = 1800; + else if (rbw > 3.0) actualStepDelay = 6000; + else actualStepDelay = 8000; + } } else actualStepDelay = settingStepDelay; @@ -766,9 +773,9 @@ void PeakSearch() } #endif -char *averageText[] = { "OFF", "MIN", "MAX", "2", "4", "8"}; -char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; -int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; +const char *averageText[] = { "OFF", "MIN", "MAX", "2", "4", "8"}; +const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; +const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; void draw_cal_status(void) { diff --git a/si4432.c b/si4432.c index cd42d04..89c0f3a 100644 --- a/si4432.c +++ b/si4432.c @@ -172,7 +172,7 @@ void SI4432_Receive(void) // User asks for an RBW of WISH, go through table finding the last triple // for which WISH is greater than the first entry, use those values, // Return the first entry of the following triple for the RBW actually achieved -static short RBW_choices[] = { // Each triple is: ndec, fils, WISH*10 +static const short RBW_choices[] = { // Each triple is: ndec, fils, WISH*10 0, 5,1,26, 5,2,28, 5,3,31, 5,4,32, 5,5,37, 5,6,42, 5,7, 45,4,1, 49,4,2, 54,4,3, 59,4,4, 61,4,5, 72,4,6, 82,4,7, 88,3,1, 95,3,2, 106,3,3, 115,3,4, 121,3,5, 142,3,6, 162,3,7, diff --git a/ui_sa.c b/ui_sa.c index a985769..52eccee 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -298,8 +298,8 @@ static void menu_modulation_cb(int item, uint8_t data) } -int menu_reffer_value[]={-1,0,1,2,3,4,5,6}; -char *menu_reffer_text[]={"OFF","30MHz","15MHz","10MHz","4MHz","3MHz","2MHz","1MHz"}; +const int menu_reffer_value[]={-1,0,1,2,3,4,5,6}; +const char *menu_reffer_text[]={"OFF","30MHz","15MHz","10MHz","4MHz","3MHz","2MHz","1MHz"}; static void menu_reffer_cb(int item, uint8_t data) { (void)data; @@ -384,7 +384,7 @@ static void menu_marker_type_cb(int item, uint8_t data) } -int rbwsel[]={0,3,10,30,100,300}; +const int rbwsel[]={0,3,10,30,100,300}; static void menu_rbw_cb(int item, uint8_t data) { From 6c74a28458fc561776cb690052ed1839f70b1421 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 29 Mar 2020 19:27:56 +0200 Subject: [PATCH 021/193] Code cleaning --- main.c | 10 ++-- sa_core.c | 175 ++++++++++++++++++++---------------------------------- si4432.c | 57 ++++++++++++++++++ ui_sa.c | 8 +-- 4 files changed, 129 insertions(+), 121 deletions(-) diff --git a/main.c b/main.c index fb246a5..6133260 100644 --- a/main.c +++ b/main.c @@ -2256,11 +2256,11 @@ VNA_SHELL_FUNCTION(cmd_t) VNA_SHELL_FUNCTION(cmd_e) { (void)argc; - extraVFO = my_atoi(argv[0]); - if (extraVFO == -1) - extraVFO = false; + trackingVFO = my_atoi(argv[0]); + if (trackingVFO == -1) + trackingVFO = false; else - extraVFO = true; + trackingVFO = true; if (argc >1) frequencyExtra = my_atoi(argv[1]); @@ -2283,7 +2283,7 @@ VNA_SHELL_FUNCTION(cmd_m) chThdSleepMilliseconds(10); streamPut(shell_stream, '{'); for (int i = 0; i 600.0?600: (WISH<3.0?3:WISH));} -void SI4432_SetReference(int p) {} -void SI4432_Set_Frequency(long f) {} -void PE4302_Write_Byte(unsigned char DATA ) {} -void PE4302_init(void) {} -#endif - -#ifdef __SIMULATION__ -unsigned long seed = 123456789; -extern float rbw; -float myfrand(void) -{ - seed = (unsigned int) (1103515245 * seed + 12345) ; - return ((float) seed) / 1000000000.0; -} -#define NOISE ((myfrand()-2) * 2) // +/- 4 dBm noise -extern int settingAttenuate; - -//#define LEVEL(i, f, v) (v * (1-(fabs(f - frequencies[i])/rbw/1000))) - -float LEVEL(uint32_t i, uint32_t f, int v) -{ - float dv; - float df = fabs((float)f - (float)i); - if (df < rbw*1000) - dv = df/(rbw*1000); - else - dv = 1 + 50*(df - rbw*1000)/(rbw*1000); - return (v - dv - settingAttenuate); -} - -float Simulated_SI4432_RSSI(uint32_t i, int s) -{ - SI4432_Sel = s; - float v = -100 + log10(rbw)*10 + NOISE; - if(s == 0) { - v = fmax(LEVEL(i,10000000,-20),v); - v = fmax(LEVEL(i,20000000,-40),v); - v = fmax(LEVEL(i,30000000,-30),v); - v = fmax(LEVEL(i,40000000,-90),v); - } else { - v = fmax(LEVEL(i,320000000,-20),v); - v = fmax(LEVEL(i,340000000,-40),v); - v = fmax(LEVEL(i,360000000,-30),v); - v = fmax(LEVEL(i,380000000,-90),v); - } - return(v); -} +int settingMode = M_LOW; -#endif -//--------------------- Frequency control ----------------------- int dirty = true; int scandirty = true; - -//---------------- menu system ----------------------- - int settingAttenuate = 0; -// int settingGenerate = 0; -int settingBandwidth = 0; - -//int settingLevelOffset = 0; - -int settingRefer = -1; // Off by default -int refferFreq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; -int settingSpur = 0; +int settingRBW = 0; int settingAverage = 0; int settingShowStorage = 0; int settingSubtractStorage = 0; -int settingMode = M_LOW; int settingDrive=0; // 0-3 , 3=+20dBm int settingAGC = true; int settingLNA = false; -int extraVFO = false; +int trackingVFO = false; int settingModulation = MO_NONE; int settingStepDelay = 0; -float rbw = 0; -float vbw = 0; -int in_selftest = false; +float actual_rbw = 0; +float setting_vbw = 0; +int settingSpur = 0; uint32_t minFreq = 0; uint32_t maxFreq = 520000000; +int settingRefer = -1; // Off by default +const int refferFreq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; + +int in_selftest = false; + void set_refer_output(int v) { settingRefer = v; @@ -224,19 +165,19 @@ int level_is_calibrated(void) void SetRBW(int v) { - settingBandwidth = v; + settingRBW = v; update_rbw(frequencies[1] - frequencies[0]); dirty = true; } int GetRBW(void) { - return(settingBandwidth); + return(settingRBW); } int GetActualRBW(void) { - return((int) rbw); + return((int) actual_rbw); } void SetSpur(int v) { @@ -273,6 +214,17 @@ void ToggleLNA(void) dirty = true; } +void ToggleVFO(void) +{ + trackingVFO = !trackingVFO; + dirty = true; +} + +int GetExtraVFO(void) +{ + return(trackingVFO); +} + int GetLNA(void) { return(settingLNA); @@ -339,7 +291,7 @@ void SetMode(int m) set_sweep_frequency(ST_SPAN, 0); settingRefer = -1; // No refer output in output mode common_high: - extraVFO = false; // Not possible in high mode + trackingVFO = false; // Not possible in high mode settingSpur = 0; // Not possible in high mode break; } @@ -452,26 +404,26 @@ case M_GENHIGH: // Direct output from 1 void update_rbw(uint32_t delta_f) { - vbw = (delta_f)/1000.0; - rbw = settingBandwidth; -// float old_rbw = rbw; - if (rbw == 0) - rbw = 2*vbw; - if (rbw < 2.6) - rbw = 2.6; - if (rbw > 600) - rbw = 600; + setting_vbw = (delta_f)/1000.0; + actual_rbw = settingRBW; +// float old_rbw = actual_rbw; + if (actual_rbw == 0) + actual_rbw = 2*setting_vbw; + if (actual_rbw < 2.6) + actual_rbw = 2.6; + if (actual_rbw > 600) + actual_rbw = 600; SI4432_Sel = MODE_SELECT(settingMode); - rbw = SI4432_SET_RBW(rbw); - vbwSteps = ((int)(2 * vbw / rbw)); + actual_rbw = SI4432_SET_RBW(actual_rbw); + vbwSteps = ((int)(2 * setting_vbw / actual_rbw)); if (vbwSteps < 1) vbwSteps = 1; dirty = true; } //static int spur_old_stepdelay = 0; -static const int spur_IF = 433900000; -static const int spur_alternate_IF = 433700000; +static const unsigned int spur_IF = 433900000; +static const unsigned int spur_alternate_IF = 433700000; static const int spur_table[] = { 470000, @@ -507,18 +459,18 @@ static const int spur_table[] = int avoid_spur(int f) { - int window = ((int)rbw ) * 1000*2; + int window = ((int)actual_rbw ) * 1000*2; if (window < 50000) window = 50000; if (! settingMode == M_LOW) return false ; if (frequency_IF != spur_IF) return false; - if (rbw > 300.0) + if (actual_rbw > 300.0) return(false); // if (spur_old_stepdelay != 0 && actualStepDelay != spur_old_stepdelay) // restore stepdelay // actualStepDelay = spur_old_stepdelay; - for (int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { + for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { if (f/window == spur_table[i]/window) { // spur_old_stepdelay = actualStepDelay; // actualStepDelay += 4000; @@ -528,13 +480,11 @@ int avoid_spur(int f) return false; } -static int old_lf = -1; static int modulation_counter = 0; -static int old_local_IF = -1; float perform(bool break_on_operation, int i, int32_t f, int extraV) { -// long local_IF = (MODE_LOW(settingMode)?frequency_IF + (int)(rbw < 300.0?settingSpur * 1000 * rbw :0):0); +// long local_IF = (MODE_LOW(settingMode)?frequency_IF + (int)(actual_rbw < 300.0?settingSpur * 1000 * actual_rbw :0):0); long local_IF; if (MODE_HIGH(settingMode)) local_IF = 0; @@ -546,18 +496,18 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) if (i == 0 && dirty) { if (settingStepDelay == 0){ if (MODE_LOW(settingMode)) { - if (rbw >300.0) actualStepDelay = 400; - else if (rbw >100.0) actualStepDelay = 500; - else if (rbw > 30.0) actualStepDelay = 900; - else if (rbw > 10.0) actualStepDelay = 900; - else if (rbw > 3.0) actualStepDelay = 1000; + if (actual_rbw >300.0) actualStepDelay = 400; + else if (actual_rbw >100.0) actualStepDelay = 500; + else if (actual_rbw > 30.0) actualStepDelay = 900; + else if (actual_rbw > 10.0) actualStepDelay = 900; + else if (actual_rbw > 3.0) actualStepDelay = 1000; else actualStepDelay = 1500; } else { - if (rbw >300.0) actualStepDelay = 900; - else if (rbw >100.0) actualStepDelay = 900; - else if (rbw > 30.0) actualStepDelay = 900; - else if (rbw > 10.0) actualStepDelay = 1800; - else if (rbw > 3.0) actualStepDelay = 6000; + if (actual_rbw >300.0) actualStepDelay = 900; + else if (actual_rbw >100.0) actualStepDelay = 900; + else if (actual_rbw > 30.0) actualStepDelay = 900; + else if (actual_rbw > 10.0) actualStepDelay = 1800; + else if (actual_rbw > 3.0) actualStepDelay = 6000; else actualStepDelay = 8000; } } else @@ -605,15 +555,14 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) modulation_counter++; chThdSleepMicroseconds(250); } - volatile int subSteps = ((int)(2 * vbw / rbw)); + volatile int subSteps = ((int)(2 * setting_vbw / actual_rbw)); float RSSI = -150.0; int t = 0; do { - int lf = (uint32_t)(f + (int)(t * 500 * rbw)); + int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw)); if (extraV) setFreq (0, local_IF + lf - refferFreq[settingRefer]); // Offset so fundamental of reffer is visible setFreq (1, local_IF + lf); - old_lf = lf; if (MODE_OUTPUT(settingMode)) return(0); float subRSSI = SI4432_RSSI(lf, MODE_SELECT(settingMode))+settingLevelOffset()+settingAttenuate; @@ -636,7 +585,7 @@ static bool sweep(bool break_on_operation) // spur_old_stepdelay = 0; again: for (int i = 0; i < sweep_points; i++) { - RSSI = perform(break_on_operation, i, frequencies[i], extraVFO); + RSSI = perform(break_on_operation, i, frequencies[i], trackingVFO); // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; @@ -843,7 +792,7 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); } - if (settingBandwidth) + if (settingRBW) color = BRIGHT_COLOR_GREEN; else color = DEFAULT_FG_COLOR; @@ -853,7 +802,7 @@ void draw_cal_status(void) ili9341_drawstring("RBW:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "%dkHz", (int)rbw); + plot_printf(buf, BLEN, "%dkHz", (int)actual_rbw); buf[5]=0; ili9341_drawstring(buf, x, y); @@ -862,7 +811,7 @@ void draw_cal_status(void) ili9341_drawstring("VBW:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "%dkHz",(int)vbw); + plot_printf(buf, BLEN, "%dkHz",(int)setting_vbw); buf[5]=0; ili9341_drawstring(buf, x, y); @@ -1161,7 +1110,7 @@ int test_validate(int i) void test_prepare(int i) { - extraVFO = false; //Default test setup + trackingVFO = false; //Default test setup switch(test_case[i].setup) { // Prepare test conditions case TPH_SILENT: // No input signal SetMode(M_HIGH); @@ -1175,7 +1124,7 @@ common_silent: break; case TP_10MHZEXTRA: // Swept receiver SetMode(M_LOW); - extraVFO = true; //Sweep BPF + trackingVFO = true; //Sweep BPF set_refer_output(2); goto common; case TP_10MHZ: // 10MHz input @@ -1305,3 +1254,5 @@ void calibrate(void) in_selftest = false; menu_autosettings_cb(0); } + + diff --git a/si4432.c b/si4432.c index 89c0f3a..284c267 100644 --- a/si4432.c +++ b/si4432.c @@ -368,3 +368,60 @@ void PE4302_Write_Byte(unsigned char DATA ) } #endif + + + +#if 0 +//-----------------SI4432 dummy------------------ +void SI4432_Write_Byte(unsigned char ADR, unsigned char DATA ) {} +unsigned char SI4432_Read_Byte(unsigned char ADR) {return ADR;} +float SI4432_SET_RBW(float WISH) {return (WISH > 600.0?600: (WISH<3.0?3:WISH));} +void SI4432_SetReference(int p) {} +void SI4432_Set_Frequency(long f) {} +void PE4302_Write_Byte(unsigned char DATA ) {} +void PE4302_init(void) {} +#endif + +#ifdef __SIMULATION__ +unsigned long seed = 123456789; +extern float actual_rbw; +float myfrand(void) +{ + seed = (unsigned int) (1103515245 * seed + 12345) ; + return ((float) seed) / 1000000000.0; +} +#define NOISE ((myfrand()-2) * 2) // +/- 4 dBm noise +extern int settingAttenuate; + +//#define LEVEL(i, f, v) (v * (1-(fabs(f - frequencies[i])/actual_rbw/1000))) + +float LEVEL(uint32_t i, uint32_t f, int v) +{ + float dv; + float df = fabs((float)f - (float)i); + if (df < actual_rbw*1000) + dv = df/(actual_rbw*1000); + else + dv = 1 + 50*(df - actual_rbw*1000)/(actual_rbw*1000); + return (v - dv - settingAttenuate); +} + +float Simulated_SI4432_RSSI(uint32_t i, int s) +{ + SI4432_Sel = s; + float v = -100 + log10(actual_rbw)*10 + NOISE; + if(s == 0) { + v = fmax(LEVEL(i,10000000,-20),v); + v = fmax(LEVEL(i,20000000,-40),v); + v = fmax(LEVEL(i,30000000,-30),v); + v = fmax(LEVEL(i,40000000,-90),v); + } else { + v = fmax(LEVEL(i,320000000,-20),v); + v = fmax(LEVEL(i,340000000,-40),v); + v = fmax(LEVEL(i,360000000,-30),v); + v = fmax(LEVEL(i,380000000,-90),v); + } + return(v); +} + +#endif diff --git a/ui_sa.c b/ui_sa.c index 52eccee..0658067 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -17,7 +17,7 @@ void SetRBW(int); void SetDrive(int d); void SetIF(int f); void SetStepDelay(int t); -extern int settingBandwidth; +extern int settingRBW; void SetSpur(int); int GetSpur(void); void SetAverage(int); @@ -38,7 +38,7 @@ void ToggleAGC(void); void redrawHisto(void); void self_test(void); extern int32_t frequencyExtra; -extern int extraVFO; +extern int trackingVFO; extern int settingDrive; extern int settingLNA; extern int settingAGC; @@ -523,7 +523,7 @@ static void menu_settings2_cb(int item, uint8_t data) ToggleLNA();; break; case 2: - extraVFO = !extraVFO; + ToggleVFO(); break; } draw_cal_status(); @@ -920,7 +920,7 @@ static void menu_item_modify_attribute( *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } - if (item == 2 && extraVFO){ // should not happen in high mode + if (item == 2 && trackingVFO){ // should not happen in high mode *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } From 393d5680506344dcd106f180fe598748fb1ec304 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 29 Mar 2020 19:43:24 +0200 Subject: [PATCH 022/193] Update sa_core.c --- sa_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sa_core.c b/sa_core.c index 7bd5413..33231c4 100644 --- a/sa_core.c +++ b/sa_core.c @@ -21,7 +21,6 @@ int settingStepDelay = 0; float actual_rbw = 0; float setting_vbw = 0; int settingSpur = 0; - uint32_t minFreq = 0; uint32_t maxFreq = 520000000; From dea4d02631183d956ee3eed4bd3111ad4886b83a Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 30 Mar 2020 12:27:16 +0200 Subject: [PATCH 023/193] Cleanup settings --- main.c | 18 +-- nanovna.h | 16 ++- plot.c | 2 +- sa_core.c | 423 +++++++++++++++++++++++++++--------------------------- si4432.c | 4 +- ui_sa.c | 44 +++--- 6 files changed, 255 insertions(+), 252 deletions(-) diff --git a/main.c b/main.c index 6133260..07821cb 100644 --- a/main.c +++ b/main.c @@ -998,7 +998,8 @@ set_frequencies(uint32_t start, uint32_t stop, uint16_t points) // disable at out of sweep range for (; i < POINTS_COUNT; i++) frequencies[i] = 0; - update_rbw(frequencies[1] - frequencies[0]); + setting_frequency_step = delta; + update_rbw(); } static void @@ -2229,7 +2230,7 @@ VNA_SHELL_FUNCTION(cmd_d) { (void) argc; int32_t a = my_atoi(argv[0]); - settingDrive = a; + setting_drive = a; } @@ -2256,11 +2257,11 @@ VNA_SHELL_FUNCTION(cmd_t) VNA_SHELL_FUNCTION(cmd_e) { (void)argc; - trackingVFO = my_atoi(argv[0]); - if (trackingVFO == -1) - trackingVFO = false; + setting_tracking = my_atoi(argv[0]); + if (setting_tracking == -1) + setting_tracking = false; else - trackingVFO = true; + setting_tracking = true; if (argc >1) frequencyExtra = my_atoi(argv[1]); @@ -2279,11 +2280,12 @@ VNA_SHELL_FUNCTION(cmd_m) pause_sweep(); int32_t f_step = (frequencyStop-frequencyStart)/ points; palClearPad(GPIOC, GPIOC_LED); // disable led and wait for voltage stabilization - update_rbw(f_step); + setting_frequency_step = f_step; + update_rbw(); chThdSleepMilliseconds(10); streamPut(shell_stream, '{'); for (int i = 0; i 31) a=31; - if (settingAttenuate == a) + if (setting_attenuate == a) return; - settingAttenuate = a; + setting_attenuate = a; dirty = true; } @@ -87,49 +131,50 @@ void SetStorage(void) { for (int i=0; i300.0) actualStepDelay = 400; + else if (actual_rbw >100.0) actualStepDelay = 500; + else if (actual_rbw > 30.0) actualStepDelay = 900; + else if (actual_rbw > 10.0) actualStepDelay = 900; + else if (actual_rbw > 3.0) actualStepDelay = 1000; + else actualStepDelay = 1500; + } else { + if (actual_rbw >300.0) actualStepDelay = 900; + else if (actual_rbw >100.0) actualStepDelay = 900; + else if (actual_rbw > 30.0) actualStepDelay = 900; + else if (actual_rbw > 10.0) actualStepDelay = 1800; + else if (actual_rbw > 3.0) actualStepDelay = 6000; + else actualStepDelay = 8000; + } + } else + actualStepDelay = setting_step_delay; + PE4302_Write_Byte(setting_attenuate * 2); + if (setting_modulation == MO_NFM ) { + SI4432_Sel = 1; + SI4432_Write_Byte(0x7A, 1); // Use frequency hopping channel width for FM modulation + } else if (setting_modulation == MO_WFM ) { + SI4432_Sel = 1; + SI4432_Write_Byte(0x7A, 10); // Use frequency hopping channel width for FM modulation + } else { + SI4432_Sel = 1; + SI4432_Write_Byte(0x79, 0); // IF no FM back to channel 0 + } + SetRX(setting_mode); + SI4432_SetReference(setting_refer); + update_rbw(); +} //------------------------------------------ @@ -311,11 +349,6 @@ int peakIndex; float temppeakLevel; int temppeakIndex; -#define BARSTART 24 - - -int vbwSteps = 1; - void setupSA(void) { SI4432_Init(); @@ -346,8 +379,8 @@ void SetSwitchReceive(void) { void SetAGCLNA(void) { unsigned char v = 0x40; - if (settingAGC) v |= 0x20; - if (settingLNA) v |= 0x10; + if (setting_agc) v |= 0x20; + if (setting_lna) v |= 0x10; SI4432_Write_Byte(0x69, v); } @@ -363,8 +396,8 @@ case M_LOW: // Mixed into 0 SI4432_Sel = 1; SetSwitchReceive(); // SI4432_Receive(); For noise testing only - SI4432_Transmit(settingDrive); - // SI4432_SetReference(settingRefer); + SI4432_Transmit(setting_drive); + // SI4432_SetReference(setting_refer); break; case M_HIGH: // Direct into 1 // SI4432_SetReference(-1); // Stop reference output @@ -381,11 +414,11 @@ case M_HIGH: // Direct into 1 case M_GENLOW: // Mixed output from 0 SI4432_Sel = 0; SetSwitchTransmit(); - SI4432_Transmit(settingDrive); + SI4432_Transmit(setting_drive); SI4432_Sel = 1; SetSwitchReceive(); - SI4432_Transmit(settingDrive); + SI4432_Transmit(setting_drive); break; case M_GENHIGH: // Direct output from 1 @@ -395,16 +428,16 @@ case M_GENHIGH: // Direct output from 1 SI4432_Sel = 1; SetSwitchTransmit(); - SI4432_Transmit(settingDrive); + SI4432_Transmit(setting_drive); break; } } -void update_rbw(uint32_t delta_f) +void update_rbw(void) { - setting_vbw = (delta_f)/1000.0; - actual_rbw = settingRBW; + setting_vbw = (setting_frequency_step)/1000.0; + actual_rbw = setting_rbw; // float old_rbw = actual_rbw; if (actual_rbw == 0) actual_rbw = 2*setting_vbw; @@ -412,9 +445,12 @@ void update_rbw(uint32_t delta_f) actual_rbw = 2.6; if (actual_rbw > 600) actual_rbw = 600; - SI4432_Sel = MODE_SELECT(settingMode); + + SI4432_Sel = MODE_SELECT(setting_mode); actual_rbw = SI4432_SET_RBW(actual_rbw); + vbwSteps = ((int)(2 * setting_vbw / actual_rbw)); + if (vbwSteps < 1) vbwSteps = 1; dirty = true; @@ -461,14 +497,8 @@ int avoid_spur(int f) int window = ((int)actual_rbw ) * 1000*2; if (window < 50000) window = 50000; - if (! settingMode == M_LOW) - return false ; - if (frequency_IF != spur_IF) - return false; - if (actual_rbw > 300.0) + if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0) return(false); -// if (spur_old_stepdelay != 0 && actualStepDelay != spur_old_stepdelay) // restore stepdelay -// actualStepDelay = spur_old_stepdelay; for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { if (f/window == spur_table[i]/window) { // spur_old_stepdelay = actualStepDelay; @@ -481,11 +511,11 @@ int avoid_spur(int f) static int modulation_counter = 0; -float perform(bool break_on_operation, int i, int32_t f, int extraV) +float perform(bool break_on_operation, int i, int32_t f, int tracking) { -// long local_IF = (MODE_LOW(settingMode)?frequency_IF + (int)(actual_rbw < 300.0?settingSpur * 1000 * actual_rbw :0):0); +// long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0); long local_IF; - if (MODE_HIGH(settingMode)) + if (MODE_HIGH(setting_mode)) local_IF = 0; else if (avoid_spur(f)) local_IF = spur_alternate_IF; @@ -493,59 +523,22 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) local_IF = frequency_IF; if (i == 0 && dirty) { - if (settingStepDelay == 0){ - if (MODE_LOW(settingMode)) { - if (actual_rbw >300.0) actualStepDelay = 400; - else if (actual_rbw >100.0) actualStepDelay = 500; - else if (actual_rbw > 30.0) actualStepDelay = 900; - else if (actual_rbw > 10.0) actualStepDelay = 900; - else if (actual_rbw > 3.0) actualStepDelay = 1000; - else actualStepDelay = 1500; - } else { - if (actual_rbw >300.0) actualStepDelay = 900; - else if (actual_rbw >100.0) actualStepDelay = 900; - else if (actual_rbw > 30.0) actualStepDelay = 900; - else if (actual_rbw > 10.0) actualStepDelay = 1800; - else if (actual_rbw > 3.0) actualStepDelay = 6000; - else actualStepDelay = 8000; - } - } else - actualStepDelay = settingStepDelay; - -// setupSA(); - - int p = settingAttenuate * 2; - PE4302_Write_Byte(p); - if (settingModulation == MO_NFM ) { - SI4432_Sel = 1; - SI4432_Write_Byte(0x7A, 1); // Use frequency hopping channel width for FM modulation - } else if (settingModulation == MO_WFM ) { - SI4432_Sel = 1; - SI4432_Write_Byte(0x7A, 10); // Use frequency hopping channel width for FM modulation - } else { - SI4432_Sel = 1; - SI4432_Write_Byte(0x79, 0); // IF no FM back to channel 0 - } - SetRX(settingMode); - SI4432_SetReference(settingRefer); - -// if (dirty) { - scandirty = true; - dirty = false; -// } + apply_settings(); + scandirty = true; + dirty = false; } if (local_IF) { setFreq (0, local_IF); } - if (settingModulation == MO_AM) { - int p = settingAttenuate * 2 + modulation_counter; + if (setting_modulation == MO_AM) { + int p = setting_attenuate * 2 + modulation_counter; PE4302_Write_Byte(p); if (modulation_counter == 3) modulation_counter = 0; else modulation_counter++; chThdSleepMicroseconds(250); - } else if (settingModulation == MO_NFM || settingModulation == MO_WFM ) { + } else if (setting_modulation == MO_NFM || setting_modulation == MO_WFM ) { SI4432_Sel = 1; SI4432_Write_Byte(0x79, modulation_counter); // Use frequency hopping channel for FM modulation if (modulation_counter == 3) @@ -554,23 +547,22 @@ float perform(bool break_on_operation, int i, int32_t f, int extraV) modulation_counter++; chThdSleepMicroseconds(250); } - volatile int subSteps = ((int)(2 * setting_vbw / actual_rbw)); float RSSI = -150.0; int t = 0; do { int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw)); - if (extraV) - setFreq (0, local_IF + lf - refferFreq[settingRefer]); // Offset so fundamental of reffer is visible + if (tracking) + setFreq (0, local_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible setFreq (1, local_IF + lf); - if (MODE_OUTPUT(settingMode)) + if (MODE_OUTPUT(setting_mode)) return(0); - float subRSSI = SI4432_RSSI(lf, MODE_SELECT(settingMode))+settingLevelOffset()+settingAttenuate; + float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+setting_attenuate; if (RSSI < subRSSI) RSSI = subRSSI; t++; - if ((operation_requested && break_on_operation ) || (MODE_OUTPUT(settingMode))) // output modes do not step. - subSteps = 0; // abort - } while (subSteps-- > 0); + if ((operation_requested && break_on_operation ) || (MODE_OUTPUT(setting_mode))) // output modes do not step. + break; // abort + } while (t < vbwSteps); return(RSSI); } @@ -582,28 +574,28 @@ static bool sweep(bool break_on_operation) temppeakLevel = -150; float temp_min_level = 100; // spur_old_stepdelay = 0; -again: +//again: for (int i = 0; i < sweep_points; i++) { - RSSI = perform(break_on_operation, i, frequencies[i], trackingVFO); + RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking); // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; - if (settingSpur == 1) { // First pass - temp_t[i] = RSSI; - continue; // Skip all other processing - } - if (settingSpur == -1) // Second pass - RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes +// if (setting_spur == 1) { // First pass +// temp_t[i] = RSSI; +// continue; // Skip all other processing +// } +// if (setting_spur == -1) // Second pass +// RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes temp_t[i] = RSSI; - if (settingSubtractStorage) { + if (setting_subtract_stored) { RSSI = RSSI - stored_t[i] ; } // stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace - if (scandirty || settingAverage == AV_OFF) + if (scandirty || setting_average == AV_OFF) actual_t[i] = RSSI; else { - switch(settingAverage) { + switch(setting_average) { case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; @@ -620,11 +612,11 @@ again: if (temp_min_level > actual_t[i]) temp_min_level = actual_t[i]; } - if (settingSpur == 1) { - settingSpur = -1; - goto again; - } else if (settingSpur == -1) - settingSpur = 1; +// if (setting_spur == 1) { +// setting_spur = -1; +// goto again; +// } else if (setting_spur == -1) +// setting_spur = 1; if (scandirty) { scandirty = false; @@ -708,7 +700,7 @@ void PeakSearch() peakIndex = temppeakIndex; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; - settingSpur = -settingSpur; + setting_spur = -setting_spur; int peak_marker = 0; markers[peak_marker].enabled = true; markers[peak_marker].index = peakIndex; @@ -738,7 +730,7 @@ void draw_cal_status(void) ili9341_fill(x, y, OFFSETX, HEIGHT, 0x0000); - if (MODE_OUTPUT(settingMode)) // No cal status during output + if (MODE_OUTPUT(setting_mode)) // No cal status during output return; if (current_menu_is_form() && !in_selftest) return; @@ -759,29 +751,29 @@ void draw_cal_status(void) plot_printf(buf, BLEN, "%ddB/",(int)get_trace_scale(0)); ili9341_drawstring(buf, x, y); - if (settingAttenuate) { + if (setting_attenuate) { ili9341_set_foreground(BRIGHT_COLOR_GREEN); y += YSTEP*2; ili9341_drawstring("Attn:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "-%ddB", settingAttenuate); + plot_printf(buf, BLEN, "-%ddB", setting_attenuate); buf[5]=0; ili9341_drawstring(buf, x, y); } - if (settingAverage>0) { + if (setting_average>0) { ili9341_set_foreground(BRIGHT_COLOR_BLUE); y += YSTEP*2; ili9341_drawstring("Aver:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "%s",averageText[settingAverage]); + plot_printf(buf, BLEN, "%s",averageText[setting_average]); buf[5]=0; ili9341_drawstring(buf, x, y); } - - if (settingSpur) { +#if 0 + if (setting_spur) { ili9341_set_foreground(BRIGHT_COLOR_BLUE); y += YSTEP*2; ili9341_drawstring("Spur:", x, y); @@ -790,8 +782,9 @@ void draw_cal_status(void) plot_printf(buf, BLEN, "ON"); ili9341_drawstring(buf, x, y); } +#endif - if (settingRBW) + if (setting_rbw) color = BRIGHT_COLOR_GREEN; else color = DEFAULT_FG_COLOR; @@ -821,7 +814,7 @@ void draw_cal_status(void) ili9341_drawstring("Scan:", x, y); y += YSTEP; - int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 * (settingSpur ? 2 : 1); // in mS + int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 /* * (setting_spur ? 2 : 1) */; // in mS if (t>1000) plot_printf(buf, BLEN, "%dS",(t+500)/1000); else @@ -831,13 +824,13 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); - if (settingRefer >= 0) { + if (setting_refer >= 0) { ili9341_set_foreground(BRIGHT_COLOR_RED); y += YSTEP*2; ili9341_drawstring("Ref:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "%dMHz",refMHz[settingRefer]); + plot_printf(buf, BLEN, "%dMHz",reffer_freq[setting_refer]/1000000); buf[5]=0; ili9341_drawstring(buf, x, y); } @@ -911,9 +904,9 @@ static void test_acquire(int i) pause_sweep(); #if 0 if (test_case[i].center < 300) - settingMode = M_LOW; + setting_mode = M_LOW; else - settingMode = M_HIGH; + setting_mode = M_HIGH; #endif set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); @@ -1109,7 +1102,7 @@ int test_validate(int i) void test_prepare(int i) { - trackingVFO = false; //Default test setup + setting_tracking = false; //Default test setup switch(test_case[i].setup) { // Prepare test conditions case TPH_SILENT: // No input signal SetMode(M_HIGH); @@ -1123,7 +1116,7 @@ common_silent: break; case TP_10MHZEXTRA: // Swept receiver SetMode(M_LOW); - trackingVFO = true; //Sweep BPF + setting_tracking = true; //Sweep BPF set_refer_output(2); goto common; case TP_10MHZ: // 10MHz input diff --git a/si4432.c b/si4432.c index 284c267..0f56863 100644 --- a/si4432.c +++ b/si4432.c @@ -240,8 +240,8 @@ float SI4432_RSSI(uint32_t i, int s) SI4432_Sel = s; chThdSleepMicroseconds(actualStepDelay); RSSI_RAW = (unsigned char)SI4432_Read_Byte( 0x26 ) ; - if (settingMode < 2 && RSSI_RAW == 0) - SI4432_Init(); + // if (MODE_INPUT(setting_mode) && RSSI_RAW == 0) + // SI4432_Init(); float dBm = 0.5 * RSSI_RAW - 120.0 ; #ifdef __SIMULATION__ dBm = Simulated_SI4432_RSSI(i,s); diff --git a/ui_sa.c b/ui_sa.c index 0658067..e7b3c0d 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -17,12 +17,12 @@ void SetRBW(int); void SetDrive(int d); void SetIF(int f); void SetStepDelay(int t); -extern int settingRBW; +extern int setting_rbw; void SetSpur(int); int GetSpur(void); void SetAverage(int); int GetAverage(void); -extern int settingAverage; +extern int setting_average; void SetStorage(void); void SetClearStorage(void); void SetSubtractStorage(void); @@ -38,14 +38,14 @@ void ToggleAGC(void); void redrawHisto(void); void self_test(void); extern int32_t frequencyExtra; -extern int trackingVFO; -extern int settingDrive; -extern int settingLNA; -extern int settingAGC; +extern int setting_tracking; +extern int setting_drive; +extern int setting_lna; +extern int setting_agc; void SetModulation(int); -extern int settingModulation; +extern int setting_modulation; // extern int settingSpeed; -extern int settingStepDelay; +extern int setting_step_delay; @@ -324,6 +324,7 @@ static void menu_spur_cb(int item, uint8_t data) { (void)data; (void)item; +#if 0 if (GetSpur()) SetSpur(0); else @@ -331,6 +332,7 @@ static void menu_spur_cb(int item, uint8_t data) // menu_move_back(); ui_mode_normal(); draw_cal_status(); +#endif } static void menu_storage_cb(int item, uint8_t data) @@ -523,7 +525,7 @@ static void menu_settings2_cb(int item, uint8_t data) ToggleLNA();; break; case 2: - ToggleVFO(); + toggle_tracking(); break; } draw_cal_status(); @@ -860,7 +862,7 @@ static void menu_item_modify_attribute( } } else if (menu == menu_lowoutputmode || menu == menu_highoutputmode) { if (item == 3) { - plot_printf(uistat.text, sizeof uistat.text, menu_modulation_text[settingModulation]); + plot_printf(uistat.text, sizeof uistat.text, menu_modulation_text[setting_modulation]); } } else if (menu == menu_reffer) { if (item < 5 && item == get_refer_output() + 1){ @@ -878,10 +880,12 @@ static void menu_item_modify_attribute( *fg = config.menu_normal_color; } } else if (menu == menu_scale) { +#if 0 if (item == 4 /* Spur reduction */ && GetSpur()) { *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } +#endif } else if (menu == menu_average) { if (item == GetAverage()){ *bg = DEFAULT_MENU_TEXT_COLOR; @@ -912,15 +916,15 @@ static void menu_item_modify_attribute( *fg = config.menu_normal_color; } } else if (menu == menu_settings2 || menu == menu_settingshigh2) { - if (item ==0 && settingAGC){ + if (item ==0 && setting_agc){ *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } - if (item == 1 && settingLNA){ + if (item == 1 && setting_lna){ *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } - if (item == 2 && trackingVFO){ // should not happen in high mode + if (item == 2 && setting_tracking){ // should not happen in high mode *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } @@ -948,7 +952,7 @@ static void menu_item_modify_attribute( plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); break; case 1: - plot_printf(buf, sizeof buf, "%ddB", -10 - settingAttenuate); + plot_printf(buf, sizeof buf, "%ddB", -10 - setting_attenuate); break; } } @@ -959,7 +963,7 @@ static void menu_item_modify_attribute( plot_printf(buf, sizeof buf, "%3.3fMHz", frequency0 / 1000000.0); break; case 1: - plot_printf(buf, sizeof buf, "%ddB", -10 - settingDrive); + plot_printf(buf, sizeof buf, "%ddB", -10 - setting_drive); break; } } @@ -1003,7 +1007,7 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value / 1000); break; case KM_ATTENUATION: - uistat.value = settingAttenuate; + uistat.value = setting_attenuate; plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_ACTUALPOWER: @@ -1015,20 +1019,20 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_SAMPLETIME: - uistat.value = settingStepDelay; + uistat.value = setting_step_delay; plot_printf(uistat.text, sizeof uistat.text, "%3duS", uistat.value); break; case KM_DRIVE: - uistat.value = settingDrive; + uistat.value = setting_drive; plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value); break; case KM_LOWOUTLEVEL: - uistat.value = settingAttenuate; + uistat.value = setting_attenuate; uistat.value = -5 - uistat.value; // compensation for dB offset during low output mode plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_HIGHOUTLEVEL: - uistat.value = settingDrive*5 + 5; + uistat.value = setting_drive*5 + 5; plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value); break; } From 0d3152c984bf60cc01567fbe4af7e75e7060fb64 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 30 Mar 2020 13:05:51 +0200 Subject: [PATCH 024/193] Show active mode --- sa_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sa_core.c b/sa_core.c index 2370045..b279e35 100644 --- a/sa_core.c +++ b/sa_core.c @@ -835,6 +835,14 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); } + ili9341_set_foreground(BRIGHT_COLOR_GREEN); + y += YSTEP*2; + if (MODE_LOW(setting_mode)) + ili9341_drawstring_7x13("M:L", x, y); + else + ili9341_drawstring_7x13("M:H", x, y); + + y = HEIGHT-7 + OFFSETY; plot_printf(buf, BLEN, "%ddB", (int)(yMax - get_trace_scale(0) * NGRIDY)); buf[5]=0; From 4b5e4dffdfe0d5f81b1b4de44022e4c9cf926569 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 30 Mar 2020 15:11:32 +0200 Subject: [PATCH 025/193] Small speed improvements --- Makefile | 4 ++-- nanovna.h | 2 +- sa_core.c | 3 +++ si4432.c | 6 ++++-- ui_sa.c | 4 ++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index e16ea2e..341524d 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ # Compiler options here. ifeq ($(USE_OPT),) -# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage - USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/nanovna.h b/nanovna.h index 2c342fc..8dbdef0 100644 --- a/nanovna.h +++ b/nanovna.h @@ -610,7 +610,7 @@ void SI4432_SetReference(int freq); // Speed profile definition #define START_PROFILE systime_t time = chVTGetSystemTimeX(); -#define STOP_PROFILE {char string_buf[12];plot_printf(string_buf, sizeof string_buf, "T:%06d", chVTGetSystemTimeX() - time);ili9341_drawstringV(string_buf, 1, 60);} +#define STOP_PROFILE {char string_buf[12];plot_printf(string_buf, sizeof string_buf, "T:%06d", chVTGetSystemTimeX() - time);ili9341_drawstringV(string_buf, 1, 180);} // Macros for convert define value to string #define STR1(x) #x #define define_to_STR(x) STR1(x) diff --git a/sa_core.c b/sa_core.c index b279e35..a4720aa 100644 --- a/sa_core.c +++ b/sa_core.c @@ -577,6 +577,8 @@ static bool sweep(bool break_on_operation) //again: for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking); + +//START_PROFILE // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; @@ -611,6 +613,7 @@ static bool sweep(bool break_on_operation) } if (temp_min_level > actual_t[i]) temp_min_level = actual_t[i]; +//STOP_PROFILE } // if (setting_spur == 1) { // setting_spur = -1; diff --git a/si4432.c b/si4432.c index 0f56863..a9ae215 100644 --- a/si4432.c +++ b/si4432.c @@ -215,7 +215,7 @@ void SI4432_Set_Frequency ( long Freq ) { int N = Freq / 10000000; Carrier = ( 4 * ( Freq - N * 10000000 )) / 625; int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 ); -#if 1 +#if 0 SI4432_Write_Byte ( 0x75, Freq_Band ); SI4432_Write_Byte ( 0x76, (Carrier>>8) & 0xFF ); SI4432_Write_Byte ( 0x77, Carrier & 0xFF ); @@ -237,15 +237,17 @@ float SI4432_RSSI(uint32_t i, int s) RSSI_RAW = Si446x_getRSSI(); } else #endif +//START_PROFILE SI4432_Sel = s; chThdSleepMicroseconds(actualStepDelay); RSSI_RAW = (unsigned char)SI4432_Read_Byte( 0x26 ) ; // if (MODE_INPUT(setting_mode) && RSSI_RAW == 0) // SI4432_Init(); - float dBm = 0.5 * RSSI_RAW - 120.0 ; + float dBm = (RSSI_RAW-240)/2.0; #ifdef __SIMULATION__ dBm = Simulated_SI4432_RSSI(i,s); #endif +//STOP_PROFILE // Serial.println(dBm,2); return dBm ; } diff --git a/ui_sa.c b/ui_sa.c index e7b3c0d..d9d5eb6 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -187,7 +187,7 @@ static void menu_mode_cb(int item, uint8_t data) { (void)data; SetMode(item-1); - draw_cal_status(); +// draw_cal_status(); switch (item) { case 1: menu_push_submenu(menu_top); @@ -202,7 +202,7 @@ static void menu_mode_cb(int item, uint8_t data) menu_push_submenu(menu_highoutputmode); break; } - draw_cal_status(); +// draw_cal_status(); } extern int dirty; From f0f6004bac4378b8aa61dc0bc651f8e1a2e3adb5 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 30 Mar 2020 16:38:57 +0200 Subject: [PATCH 026/193] Added MAX_DECAY average --- Makefile | 4 ++-- nanovna.h | 2 +- sa_core.c | 27 ++++++++++++++++++++------- ui_sa.c | 10 +++++----- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 341524d..e16ea2e 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage -# USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/nanovna.h b/nanovna.h index 8dbdef0..fd0eefc 100644 --- a/nanovna.h +++ b/nanovna.h @@ -121,7 +121,7 @@ void load_default_properties(void); extern float perform(bool b, int i, int32_t f, int e); enum { - AV_OFF, AV_MIN, AV_MAX, AV_2, AV_4, AV_8 + AV_OFF, AV_MIN, AV_MAX_HOLD, AV_MAX_DECAY, AV_4, AV_16 }; enum { M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, diff --git a/sa_core.c b/sa_core.c index a4720aa..646bf2e 100644 --- a/sa_core.c +++ b/sa_core.c @@ -511,6 +511,8 @@ int avoid_spur(int f) static int modulation_counter = 0; +char age[POINTS_COUNT]; + float perform(bool break_on_operation, int i, int32_t f, int tracking) { // long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0); @@ -594,15 +596,26 @@ static bool sweep(bool break_on_operation) RSSI = RSSI - stored_t[i] ; } // stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace - if (scandirty || setting_average == AV_OFF) + if (scandirty || setting_average == AV_OFF) { actual_t[i] = RSSI; - else { + age[i] = 0; + } else { switch(setting_average) { - case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; - case AV_MAX: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; - case AV_2: actual_t[i] = (actual_t[i] + RSSI) / 2.0; break; - case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; - case AV_8: actual_t[i] = (actual_t[i]*7 + RSSI) / 8.0; break; + case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; + case AV_MAX_HOLD: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; + case AV_MAX_DECAY: + if (actual_t[i] < RSSI) { + actual_t[i] = RSSI; + age[i] = 0; + } else { + if (age[i] > 20) + actual_t[i] -= 0.5; + else + age[i] += 1; + } + break; + case AV_4: actual_t[i] = (actual_t[i] + RSSI) / 4.0; break; + case AV_16: actual_t[i] = (actual_t[i]*3 + RSSI) / 16.0; break; } } if (frequencies[i] > 1000000) { diff --git a/ui_sa.c b/ui_sa.c index d9d5eb6..d997f30 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -593,12 +593,12 @@ const menuitem_t menu_highoutputmode[] = { }; static const menuitem_t menu_average[] = { - { MT_CALLBACK, 0, "OFF", menu_average_cb}, - { MT_CALLBACK, 0, "MIN", menu_average_cb}, - { MT_CALLBACK, 0, "MAX", menu_average_cb}, - { MT_CALLBACK, 0, " 2 ", menu_average_cb}, + { MT_CALLBACK, 0, " OFF", menu_average_cb}, + { MT_CALLBACK, 0, "\2 MIN\0 HOLD", menu_average_cb}, + { MT_CALLBACK, 0, "\2 MAX\0 HOLD", menu_average_cb}, + { MT_CALLBACK, 0, "\2 MAX\0 DECAY", menu_average_cb}, { MT_CALLBACK, 0, " 4 ", menu_average_cb}, - { MT_CALLBACK, 0, " 8 ", menu_average_cb}, + { MT_CALLBACK, 0, " 16 ", menu_average_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 4683b88d0c7b2507666465292df761c90222275c Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 31 Mar 2020 11:07:43 +0200 Subject: [PATCH 027/193] Menu update --- main.c | 4 +- ui.c | 38 ++++-- ui_sa.c | 408 +++++++++++++++++++++----------------------------------- 3 files changed, 187 insertions(+), 263 deletions(-) diff --git a/main.c b/main.c index 424b80c..460245e 100644 --- a/main.c +++ b/main.c @@ -117,7 +117,7 @@ const char *info_about[]={ 0 // sentinel }; -static THD_WORKING_AREA(waThread1, 750); +static THD_WORKING_AREA(waThread1, 730); static THD_FUNCTION(Thread1, arg) { (void)arg; @@ -2140,7 +2140,7 @@ VNA_SHELL_FUNCTION(cmd_threads) thread_t *tp; (void)argc; (void)argv; - shell_printf("stklimit| stack|stk free| addr|refs|prio| state| name"VNA_SHELL_NEWLINE_STR); + shell_printf("stklimit| |stk free| addr|refs|prio| state| name"VNA_SHELL_NEWLINE_STR); tp = chRegFirstThread(); do { uint32_t max_stack_use = 0U; diff --git a/ui.c b/ui.c index 544d47b..82f58c3 100644 --- a/ui.c +++ b/ui.c @@ -434,10 +434,13 @@ enum { MT_CALLBACK, MT_CANCEL, MT_TITLE, - MT_CLOSE + MT_CLOSE, + MT_KEYPAD }; -#define MT_FORM 0x80 // Or with menu type to get large button with current value -#define MT_MASK(x) (0x7F & (x)) +#define MT_FORM 0x80 // Or with menu type to get large button with current value +#define MT_BACK 0x40 +#define MT_LEAVE 0x20 +#define MT_MASK(x) (0xF & (x)) typedef void (*menuaction_cb_t)(int item, uint8_t data); @@ -767,15 +770,15 @@ menu_marker_op_cb(int item, uint8_t data) static void menu_marker_search_cb(int item, uint8_t data) { - (void)data; + (void)item; int i = -1; if (active_marker == -1) return; - switch (item) { + switch (data) { case 0: /* maximum */ case 1: /* minimum */ - set_marker_search(item); + set_marker_search(data); i = marker_search(); break; case 2: /* search Left */ @@ -1145,10 +1148,11 @@ menu_move_top(void) static void menu_invoke(int item) { + int status; const menuitem_t *menu = menu_stack[menu_current_level]; menu = &menu[item]; - switch (menu->type & 0x0f) { + switch (MT_MASK(menu->type)) { case MT_NONE: case MT_BLANK: case MT_CLOSE: @@ -1164,12 +1168,30 @@ menu_invoke(int item) if (cb == NULL) return; (*cb)(item, menu->data); + if (!(menu->type & MT_FORM)) + draw_cal_status(); break; } case MT_SUBMENU: menu_push_submenu((const menuitem_t*)menu->reference); break; + + case MT_KEYPAD: + status = btn_wait_release(); + if (status & EVT_BUTTON_DOWN_LONG) { + ui_mode_numeric(menu->data); + // ui_process_numeric(); + } else { + if (menu->type & MT_FORM) { + area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; + redraw_frame(); // Remove form numbers + } + ui_mode_keypad(menu->data); + ui_process_keypad(); + } + draw_cal_status(); + break; } } @@ -1482,7 +1504,7 @@ draw_menu_buttons(const menuitem_t *menu) if (menu[i].type & MT_FORM) { active_button_start = 320 - MENU_FORM_WIDTH; active_button_width = MENU_FORM_WIDTH - 30; // Shorten at the right - if (MT_MASK(menu[i].type) == MT_CALLBACK) { // Only callback can have value + if (MT_MASK(menu[i].type) == MT_KEYPAD) { // Only keypad retrieves value keypad_mode = menu[i].data; fetch_numeric_target(); } diff --git a/ui_sa.c b/ui_sa.c index d997f30..7d479e8 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -228,7 +228,7 @@ void menu_autosettings_cb(int item, uint8_t data) dirty = true; // menu_move_back(); // stay in input menu ui_mode_normal(); - draw_cal_status(); +// draw_cal_status(); } static void menu_calibrate_cb(int item, uint8_t data) @@ -285,16 +285,18 @@ static void menu_dfu_cb(int item, uint8_t data) } } -int menu_modulation_value[]={0, MO_NONE,MO_AM, MO_NFM, MO_WFM}; -char *menu_modulation_text[]={"NONE","AM","NARROW FM","WIDE FM"}; + +const int menu_modulation_value[]={MO_NONE,MO_AM, MO_NFM, MO_WFM}; +const char *menu_modulation_text[]={"NONE","AM","NARROW FM","WIDE FM"}; + static void menu_modulation_cb(int item, uint8_t data) { - (void)data; + (void)item; //Serial.println(item); - SetModulation(menu_modulation_value[item]); + SetModulation(menu_modulation_value[data]); menu_move_back(); // ui_mode_normal(); // Stay in menu mode - draw_cal_status(); +// draw_cal_status(); } @@ -302,24 +304,29 @@ const int menu_reffer_value[]={-1,0,1,2,3,4,5,6}; const char *menu_reffer_text[]={"OFF","30MHz","15MHz","10MHz","4MHz","3MHz","2MHz","1MHz"}; static void menu_reffer_cb(int item, uint8_t data) { - (void)data; + (void)item; //Serial.println(item); - set_refer_output(menu_reffer_value[item]); + set_refer_output(menu_reffer_value[data]); menu_move_back(); // ui_mode_normal(); // Stay in menu mode - draw_cal_status(); +// draw_cal_status(); } -static void menu_reffer_cb2(int item, uint8_t data) +const int menu_drive_value[]={5,10,15,20}; +const char *menu_drive_text[]={"5dBm","10dBm","15dBm","20dBm"}; +static void menu_drive_cb(int item, uint8_t data) { - (void)data; + (void)item; //Serial.println(item); - set_refer_output(menu_reffer_value[item+5]); + SetDrive(data); menu_move_back(); - // ui_mode_normal(); // Stay in menu mode - draw_cal_status(); +// ui_mode_normal(); +// draw_cal_status(); } + + + static void menu_spur_cb(int item, uint8_t data) { (void)data; @@ -337,8 +344,8 @@ static void menu_spur_cb(int item, uint8_t data) static void menu_storage_cb(int item, uint8_t data) { - (void)data; - switch(item) { + (void)item; + switch(data) { case 0: SetStorage(); break; @@ -354,7 +361,7 @@ static void menu_storage_cb(int item, uint8_t data) } menu_move_back(); ui_mode_normal(); - draw_cal_status(); +// draw_cal_status(); } static void menu_average_cb(int item, uint8_t data) @@ -368,16 +375,16 @@ static void menu_average_cb(int item, uint8_t data) static void menu_marker_type_cb(int item, uint8_t data) { - (void)data; + (void)item; if (markers[active_marker].enabled) { - if (item == M_REFERENCE) { + if (data == M_REFERENCE) { for (int i = 0; i Date: Tue, 31 Mar 2020 12:28:17 +0200 Subject: [PATCH 028/193] Small memory optim --- STM32F072xB.ld | 4 ++-- nanovna.h | 14 +++++++------- ui_sa.c | 49 +++++++++++++++++-------------------------------- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/STM32F072xB.ld b/STM32F072xB.ld index 577e87f..b1f2ea2 100644 --- a/STM32F072xB.ld +++ b/STM32F072xB.ld @@ -19,14 +19,14 @@ */ MEMORY { - flash0 : org = 0x08000000, len = 96k + flash0 : org = 0x08000000, len = 104k 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 + flash7 : org = 0x0801C000, len = 16k ram0 : org = 0x20000000, len = 16k ram1 : org = 0x00000000, len = 0 ram2 : org = 0x00000000, len = 0 diff --git a/nanovna.h b/nanovna.h index 276df10..fd34c62 100644 --- a/nanovna.h +++ b/nanovna.h @@ -427,15 +427,15 @@ void show_logo(void); #if 1 #define SAVEAREA_MAX 5 // Begin addr 0x08018000 -#define SAVE_CONFIG_AREA_SIZE 0x00008000 +#define SAVE_CONFIG_AREA_SIZE 0x00000800 // config save area -#define SAVE_CONFIG_ADDR 0x08018000 +#define SAVE_CONFIG_ADDR 0x0801C000 // properties_t save area -#define SAVE_PROP_CONFIG_0_ADDR 0x08018800 -#define SAVE_PROP_CONFIG_1_ADDR 0x0801a000 -#define SAVE_PROP_CONFIG_2_ADDR 0x0801b800 -#define SAVE_PROP_CONFIG_3_ADDR 0x0801d000 -#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 +#define SAVE_PROP_CONFIG_0_ADDR 0x0801C800 +#define SAVE_PROP_CONFIG_1_ADDR 0x0801D000 +#define SAVE_PROP_CONFIG_2_ADDR 0x0801D800 +#define SAVE_PROP_CONFIG_3_ADDR 0x0801E000 +#define SAVE_PROP_CONFIG_4_ADDR 0x0801E800 #else #define SAVEAREA_MAX 4 // Begin addr 0x0801C000 diff --git a/ui_sa.c b/ui_sa.c index 7d479e8..1b3d87a 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -780,8 +780,7 @@ static void menu_item_modify_attribute( int mark = false; if (menu == menu_mode) { if (item == GetMode()+1) { - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } else if (item == 5) { plot_printf(uistat.text, sizeof uistat.text, menu_reffer_text[get_refer_output()+1]); } @@ -793,73 +792,59 @@ static void menu_item_modify_attribute( } } else if (menu == menu_reffer) { if (item < 5 && item == get_refer_output() + 1){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; - } + mark = true; + } } else if (menu == menu_reffer2) { if (item == get_refer_output() - 4){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_stimulus) { if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_ENABLE)) { - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_scale) { #if 0 if (item == 4 /* Spur reduction */ && GetSpur()) { - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; - } + mark = true; + } #endif } else if (menu == menu_average) { if (item == GetAverage()){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_dBper) { if (menu_dBper_value[item] == get_trace_scale(1)){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_rbw) { if (rbwsel[item] == GetRBW()){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_drive || menu == menu_drive_wide) { if (item == setting_drive){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_storage) { if (item ==0 && GetStorage()){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } if (item == 2 && GetSubtractStorage()){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } if (item == 3 && get_waterfall()){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } else if (menu == menu_settings2 || menu == menu_settingshigh2) { if (item ==0 && setting_agc){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } if (item == 1 && setting_lna){ - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } if (item == 2 && setting_tracking){ // should not happen in high mode - *bg = DEFAULT_MENU_TEXT_COLOR; - *fg = config.menu_normal_color; + mark = true; } } if (mark) { From c40a01f22a08163ce85c3a27d6305b3a24a7ec5d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 1 Apr 2020 07:57:55 +0200 Subject: [PATCH 029/193] Large value text --- ui.c | 10 +++++++- ui_sa.c | 80 +++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/ui.c b/ui.c index 82f58c3..0f7de2f 100644 --- a/ui.c +++ b/ui.c @@ -1328,14 +1328,22 @@ draw_keypad(void) i++; } } +static int +menu_is_multiline(const char *label, const char **l1, const char **l2); static void draw_numeric_area_frame(void) { + char *l1; + char *l2; ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, config.menu_normal_color); ili9341_set_foreground(DEFAULT_MENU_TEXT_COLOR); ili9341_set_background(config.menu_normal_color); - ili9341_drawstring(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); + if (menu_is_multiline(keypad_mode_label[keypad_mode], &l1, &l2)) { + ili9341_drawstring_7x13(l1, 10, 240-NUM_INPUT_HEIGHT+1); + ili9341_drawstring_7x13(l2, 10, 240-NUM_INPUT_HEIGHT/2 + 1); + } else + ili9341_drawstring_7x13(keypad_mode_label[keypad_mode], 10, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); //ili9341_drawfont(KP_KEYPAD, 300, 216); } diff --git a/ui_sa.c b/ui_sa.c index 1b3d87a..319b4ea 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -167,7 +167,7 @@ static const char * const keypad_mode_label[] = { #endif #ifdef __SA__ static const char * const keypad_mode_label[] = { - "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "ATTENUATION", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL" + "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL" }; #endif @@ -326,12 +326,12 @@ static void menu_drive_cb(int item, uint8_t data) +#if 0 static void menu_spur_cb(int item, uint8_t data) { (void)data; (void)item; -#if 0 if (GetSpur()) SetSpur(0); else @@ -339,8 +339,8 @@ static void menu_spur_cb(int item, uint8_t data) // menu_move_back(); ui_mode_normal(); draw_cal_status(); -#endif } +#endif static void menu_storage_cb(int item, uint8_t data) { @@ -527,7 +527,7 @@ static const menuitem_t menu_average[] = { { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; - +#if 0 static const menuitem_t menu_storage[] = { { MT_CALLBACK, 0, "STORE", menu_storage_cb}, { MT_CALLBACK, 1, "CLEAR", menu_storage_cb}, @@ -536,6 +536,7 @@ static const menuitem_t menu_storage[] = { { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; +#endif static const menuitem_t menu_rbw[] = { { MT_CALLBACK, 0, " AUTO", menu_rbw_cb}, @@ -578,6 +579,36 @@ static const menuitem_t menu_reffer[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_acquire[] = { + { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, + { MT_KEYPAD, KM_ATTENUATION, "ATTEN", NULL}, + { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_SUBMENU,0, "AVERAGE", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_acquirehigh[] = { + { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, + { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_SUBMENU,0, "AVERAGE", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + + +static const menuitem_t menu_display[] = { + { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, + { MT_SUBMENU,0, "\2SCALE/\0DIV", menu_dBper}, + { MT_CALLBACK, 0, "STORE", menu_storage_cb}, + { MT_CALLBACK, 1, "CLEAR", menu_storage_cb}, + { MT_CALLBACK, 2, "SUBTRACT", menu_storage_cb}, + { MT_CALLBACK, 3, "WATERFALL",menu_storage_cb}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +#if 0 static const menuitem_t menu_scale[] = { { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, { MT_SUBMENU,0, "\2SCALE/\0DIV", menu_dBper}, @@ -598,7 +629,7 @@ static const menuitem_t menu_scalehigh[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; - +#endif static const menuitem_t menu_stimulus[8] = { { MT_KEYPAD, KM_START, "START", NULL}, @@ -730,7 +761,30 @@ static const menuitem_t menu_mode[] = { // { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; +#if 1 +const menuitem_t menu_top[] = { + { MT_SUBMENU, 0, "ACQUIRE", menu_acquire}, + { MT_SUBMENU, 0, "SCAN", menu_stimulus}, + { MT_SUBMENU, 0, "DISPLAY", menu_display}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "SETTINGS", menu_settings}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, + { MT_NONE, 0, NULL, NULL } // sentinel, + // MENUITEM_CLOSE, +}; +const menuitem_t menu_tophigh[] = +{ + { MT_SUBMENU, 0, "ACQUIRE", menu_acquirehigh}, + { MT_SUBMENU, 0, "SCAN", menu_stimulus}, + { MT_SUBMENU, 0, "DISPLAY", menu_display}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "SETTINGS", menu_settings}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, + { MT_NONE, 0, NULL, NULL } // sentinel, + // MENUITEM_CLOSE, +}; +#else const menuitem_t menu_top[] = { { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, { MT_SUBMENU, 0, "SCAN", menu_stimulus}, @@ -754,7 +808,7 @@ const menuitem_t menu_tophigh[] = { { MT_NONE, 0, NULL, NULL } // sentinel, // MENUITEM_CLOSE, }; - +#endif // ===[MENU DEFINITION END]====================================================== #undef BOARD_NAME @@ -802,12 +856,6 @@ static void menu_item_modify_attribute( if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_ENABLE)) { mark = true; } - } else if (menu == menu_scale) { -#if 0 - if (item == 4 /* Spur reduction */ && GetSpur()) { - mark = true; - } -#endif } else if (menu == menu_average) { if (item == GetAverage()){ mark = true; @@ -826,14 +874,14 @@ static void menu_item_modify_attribute( mark = true; } - } else if (menu == menu_storage) { - if (item ==0 && GetStorage()){ + } else if (menu == menu_display) { + if (item ==2 && GetStorage()){ mark = true; } - if (item == 2 && GetSubtractStorage()){ + if (item == 4 && GetSubtractStorage()){ mark = true; } - if (item == 3 && get_waterfall()){ + if (item == 5 && get_waterfall()){ mark = true; } } else if (menu == menu_settings2 || menu == menu_settingshigh2) { From 0a03ff0a2ff5e8dd216a49e638d3089a411eac8e Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 1 Apr 2020 11:07:18 +0200 Subject: [PATCH 030/193] Added full marker tracking --- ili9341.c | 4 +- main.c | 8 +-- nanovna.h | 11 +++- sa_core.c | 155 +++++++++++++++++++++++++++++------------------------- ui.c | 10 ++-- ui_sa.c | 18 +++++-- 6 files changed, 120 insertions(+), 86 deletions(-) diff --git a/ili9341.c b/ili9341.c index 0cd5ad2..f423b19 100644 --- a/ili9341.c +++ b/ili9341.c @@ -524,7 +524,7 @@ void ili9341_clear_screen(void) { ili9341_fill(0, 0, ILI9341_WIDTH, ILI9341_HEIGHT, background_color); } - +#if 0 void ili9341_set_foreground(uint16_t fg) { foreground_color = fg; @@ -534,7 +534,7 @@ void ili9341_set_background(uint16_t bg) { background_color = bg; } - +#endif void ili9341_set_rotation(uint8_t r) { // static const uint8_t rotation_const[]={DISPLAY_ROTATION_0, DISPLAY_ROTATION_90, diff --git a/main.c b/main.c index 460245e..51a7e6e 100644 --- a/main.c +++ b/main.c @@ -813,10 +813,10 @@ static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, reserved, }; static const marker_t def_markers[MARKERS_MAX] = { - { 1, M_REFERENCE, 30, 0 }, - { 0, M_NORMAL, 40, 0 }, - { 0, M_NORMAL, 60, 0 }, - { 0, M_NORMAL, 80, 0 } + { M_TRACKING_ENABLED, M_REFERENCE, 30, 0 }, + { M_DISABLED, M_NORMAL, 40, 0 }, + { M_DISABLED, M_NORMAL, 60, 0 }, + { M_DISABLED, M_NORMAL, 80, 0 } }; // Load propeties default settings diff --git a/nanovna.h b/nanovna.h index fd34c62..a299dd5 100644 --- a/nanovna.h +++ b/nanovna.h @@ -316,7 +316,11 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]); #endif // marker enum { - M_REFERENCE, M_NORMAL, M_DELTA + M_REFERENCE, M_NORMAL, M_DELTA, M_TRACKING +}; + +enum { + M_DISABLED, M_ENABLED, M_TRACKING_ENABLED }; typedef struct { @@ -404,8 +408,13 @@ void ili9341_init(void); void ili9341_test(int mode); void ili9341_bulk(int x, int y, int w, int h); void ili9341_fill(int x, int y, int w, int h, int color); +#if 0 void ili9341_set_foreground(uint16_t fg); void ili9341_set_background(uint16_t fg); +#else +#define ili9341_set_foreground(fg) { foreground_color = fg; } +#define ili9341_set_background(bg) { background_color = bg;} +#endif void ili9341_clear_screen(void); void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap); void ili9341_drawchar(uint8_t ch, int x, int y); diff --git a/sa_core.c b/sa_core.c index 646bf2e..799002d 100644 --- a/sa_core.c +++ b/sa_core.c @@ -568,10 +568,16 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) return(RSSI); } +#define MAX_MAX 4 +#define MAX_NOISE 20 // 10dB +int16_t max_index[MAX_MAX]; +int16_t cur_max = 0; + // main loop for measurement static bool sweep(bool break_on_operation) { float RSSI; + int16_t downslope = true; palClearPad(GPIOC, GPIOC_LED); temppeakLevel = -150; float temp_min_level = 100; @@ -580,7 +586,6 @@ static bool sweep(bool break_on_operation) for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking); -//START_PROFILE // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; @@ -618,6 +623,54 @@ static bool sweep(bool break_on_operation) case AV_16: actual_t[i] = (actual_t[i]*3 + RSSI) / 16.0; break; } } +#if 1 +// START_PROFILE + if (i == 0) { + cur_max = 0; // Always at least one maximum + temppeakIndex = 0; + temppeakLevel = actual_t[i]; + max_index[i] = 0; + downslope = true; + } + if (downslope) { + if (temppeakLevel > actual_t[i]) { // Follow down + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + } else if (temppeakLevel + MAX_NOISE < actual_t[i]) { // Local minimum found + temppeakIndex = i; // This is now the latest maximum + temppeakLevel = actual_t[i]; + downslope = false; + } + } else { + if (temppeakLevel < actual_t[i]) { // Follow up + temppeakIndex = i; + temppeakLevel = actual_t[i]; + } else if (temppeakLevel - MAX_NOISE > actual_t[i]) { // Local max found + + int j = 0; // Insertion index + while (j= temppeakLevel) // Find where to insert + j++; + if (j < MAX_MAX) { // Larger then one of the previous found + int k = MAX_MAX-1; + while (k > j) { // Shift to make room for max + max_index[k] = max_index[k-1]; +// maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging + k--; + } + max_index[j] = temppeakIndex; +// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging + if (cur_max < MAX_MAX) { + cur_max++; + } +//STOP_PROFILE + } + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + + downslope = true; + } + } +#else if (frequencies[i] > 1000000) { if (temppeakLevel < actual_t[i]) { temppeakIndex = i; @@ -626,7 +679,7 @@ static bool sweep(bool break_on_operation) } if (temp_min_level > actual_t[i]) temp_min_level = actual_t[i]; -//STOP_PROFILE +#endif } // if (setting_spur == 1) { // setting_spur = -1; @@ -638,9 +691,37 @@ static bool sweep(bool break_on_operation) scandirty = false; draw_cal_status(); } - peakIndex = temppeakIndex; +#if 1 + int i = 0; + int m = 0; + while (i < cur_max) { // For all maxima found + while (m < MARKERS_MAX) { + if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found + markers[m].index = max_index[i]; + markers[m].frequency = frequencies[markers[m].index]; + m++; + break; // Next maximum + } + m++; // Try next marker + } + i++; + } + while (m < MARKERS_MAX) { + if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found + markers[m].index = 0; // Enabled but no max + markers[m].frequency = frequencies[markers[m].index]; + } + m++; // Try next marker + } + peakIndex = max_index[0]; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; +#else + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; +#endif min_level = temp_min_level; #if 0 // Auto ref level setting int scale = get_trace_scale(2); @@ -655,80 +736,12 @@ static bool sweep(bool break_on_operation) } #endif - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; // redraw_marker(peak_marker, FALSE); palSetPad(GPIOC, GPIOC_LED); return true; } -#if 0 -void PeakSearch() -{ -#define PEAKSTACK 4 -#define PEAKDISTANCE 10 - int level = 0; - int searchLeft[PEAKSTACK]; - int peakIndex[PEAKSTACK]; - int peak_marker = 0; - searchLeft[level] = true; - peakIndex[level] = markers[peak_marker].index; - level++; - searchLeft[level] = true; - int peakFrom; - int peakTo; - while (peak_marker < 4){ - if (searchLeft[level]) - { - int fromLevel = level; - while (fromLevel > 0 && searchLeft[fromLevel]) - fromLevel-- - if(fromLevel == 0) { - peakFrom = PEAKDISTANCE; - } else { - peakFrom = peakIndex[fromLevel] + PEAKDISTANCE; - } - peakTo = peakIndex[level] - PEAKDISTANCE; - } else { - int toLevel = level; - while (toLevel > 0 && !searchLeft[toLevel]) - toLevel-- - if(toLevel == 0) { - peakTo = POINTS_COUNT - 1 - PEAKDISTANCE; - } else { - peakTo = peakIndex[fromLevel] - PEAKDISTANCE; - } - peakFrom = peakIndex[level] + PEAKDISTANCE; - } - float peakMax = actual_t[peakFrom]; - int peakIndex = peakFrom; - for (int i = peakFrom; i < peakTo; i++) { - if (peakMax < actual_t[i]) { - peakMax = actual_t[i]; - peakIndex = i; - } - } - - - peakIndex = temppeakIndex; - peakLevel = actual_t[peakIndex]; - peakFreq = frequencies[peakIndex]; - setting_spur = -setting_spur; - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; -// redraw_marker(peak_marker, FALSE); - - -} - -} -#endif - const char *averageText[] = { "OFF", "MIN", "MAX", "2", "4", "8"}; const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; diff --git a/ui.c b/ui.c index 0f7de2f..3b9f54b 100644 --- a/ui.c +++ b/ui.c @@ -833,18 +833,18 @@ menu_marker_sel_cb(int item, uint8_t data) if (markers[item].enabled) { if (item == active_marker) { // disable if active trace is selected - markers[item].enabled = FALSE; + markers[item].enabled = M_DISABLED; active_marker_select(-1); } else { active_marker_select(item); } } else { - markers[item].enabled = TRUE; + markers[item].enabled = M_TRACKING_ENABLED; // default tracking enabled active_marker_select(item); } } else if (item == 4) { /* all off */ for (t = 0; t < MARKERS_MAX; t++) - markers[t].enabled = FALSE; + markers[t].enabled = M_DISABLED; previous_marker = -1; active_marker = -1; } else if (item == 5) { /* marker delta */ @@ -1334,8 +1334,8 @@ menu_is_multiline(const char *label, const char **l1, const char **l2); static void draw_numeric_area_frame(void) { - char *l1; - char *l2; + const char *l1; + const char *l2; ili9341_fill(0, 240-NUM_INPUT_HEIGHT, 320, NUM_INPUT_HEIGHT, config.menu_normal_color); ili9341_set_foreground(DEFAULT_MENU_TEXT_COLOR); ili9341_set_background(config.menu_normal_color); diff --git a/ui_sa.c b/ui_sa.c index 319b4ea..81631a0 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -216,9 +216,9 @@ void menu_autosettings_cb(int item, uint8_t data) active_marker = 0; for (int i = 1; i= 0 && markers[active_marker].enabled) { + if (item == 3 && markers[active_marker].enabled == M_TRACKING_ENABLED) + mark = true; + else if (item == markers[active_marker].mtype) + mark = true; } if (mark) { *bg = DEFAULT_MENU_TEXT_COLOR; From a121457164da3e21902cbd68ab602cee85a9b910 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 1 Apr 2020 11:24:37 +0200 Subject: [PATCH 031/193] Show active markers in menu --- ui_sa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui_sa.c b/ui_sa.c index 81631a0..2ddc17d 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -906,6 +906,9 @@ static void menu_item_modify_attribute( mark = true; else if (item == markers[active_marker].mtype) mark = true; + } else if (menu == menu_marker_sel) { + if (item < MARKERS_MAX && markers[item].enabled) + mark = true; } if (mark) { *bg = DEFAULT_MENU_TEXT_COLOR; From 0575aed87bca44d4ebde5558a49565db03ccef33 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 1 Apr 2020 14:33:01 +0200 Subject: [PATCH 032/193] First measurement function --- sa_core.c | 4 ++-- ui_sa.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/sa_core.c b/sa_core.c index 799002d..3c370ea 100644 --- a/sa_core.c +++ b/sa_core.c @@ -458,7 +458,7 @@ void update_rbw(void) //static int spur_old_stepdelay = 0; static const unsigned int spur_IF = 433900000; -static const unsigned int spur_alternate_IF = 433700000; +static const unsigned int spur_alternate_IF = 434100000; static const int spur_table[] = { 470000, @@ -569,7 +569,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) } #define MAX_MAX 4 -#define MAX_NOISE 20 // 10dB +#define MAX_NOISE 10 // 10dB int16_t max_index[MAX_MAX]; int16_t cur_max = 0; diff --git a/ui_sa.c b/ui_sa.c index 2ddc17d..7f0a67e 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -342,6 +342,34 @@ static void menu_spur_cb(int item, uint8_t data) } #endif +static void menu_measure_cb(int item, uint8_t data) +{ + (void)item; + switch(data) { + case 0: // IMD + for (int i = 0; i< MARKERS_MAX; i++) { + markers[i].enabled = M_TRACKING_ENABLED; + markers[i].mtype = M_DELTA; + } + markers[0].mtype = M_REFERENCE; + break; + case 1: + for (int i = 0; i< MARKERS_MAX; i++) { + markers[i].enabled = M_TRACKING_ENABLED; + markers[i].mtype = M_DELTA; + } + markers[0].mtype = M_REFERENCE; + break; + case 2: + break; + case 3: + break; + } + menu_move_back(); + ui_mode_normal(); +// draw_cal_status(); +} + static void menu_storage_cb(int item, uint8_t data) { (void)item; @@ -717,6 +745,12 @@ static const menuitem_t menu_settings[] = { MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_measure[] = { + { MT_CALLBACK, 0, "IMD", menu_measure_cb}, + { MT_CALLBACK, 1, "IIP3", menu_measure_cb}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; static const menuitem_t menu_settingshigh2[] = { @@ -774,6 +808,7 @@ const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "SCAN", menu_stimulus}, { MT_SUBMENU, 0, "DISPLAY", menu_display}, { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "MEASURE", menu_measure}, { MT_SUBMENU, 0, "SETTINGS", menu_settings}, { MT_CANCEL, 0, S_LARROW" MODE",NULL}, { MT_NONE, 0, NULL, NULL } // sentinel, @@ -786,6 +821,7 @@ const menuitem_t menu_tophigh[] = { MT_SUBMENU, 0, "SCAN", menu_stimulus}, { MT_SUBMENU, 0, "DISPLAY", menu_display}, { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "MEASURE", menu_measure}, { MT_SUBMENU, 0, "SETTINGS", menu_settings}, { MT_CANCEL, 0, S_LARROW" MODE",NULL}, { MT_NONE, 0, NULL, NULL } // sentinel, From bd50a9d3e5e8e33d6b56012728979b9497c8cfbd Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 1 Apr 2020 18:53:12 +0200 Subject: [PATCH 033/193] Small bug fixes --- nanovna.h | 4 ++-- plot.c | 8 ++++---- ui.c | 6 ++++-- ui_sa.c | 8 ++++++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/nanovna.h b/nanovna.h index a299dd5..82d5efa 100644 --- a/nanovna.h +++ b/nanovna.h @@ -199,8 +199,8 @@ extern int _height; #define CELLWIDTH (32) #define CELLHEIGHT (32) -//#define NGRIDY 10 -#define NGRIDY 9 +#define NGRIDY 10 +//#define NGRIDY 9 #define FREQUENCIES_XPOS1 OFFSETX #define FREQUENCIES_XPOS2 200 diff --git a/plot.c b/plot.c index 56748a3..a6e4bad 100644 --- a/plot.c +++ b/plot.c @@ -1465,10 +1465,10 @@ draw_all_cells(bool flush_markmap) if (waterfall) { for (m = 226; m >= HEIGHT+3; m -= 1) { // Scroll down uint16_t *buf = &spi_buffer[0]; - ili9341_read_memory(5*5, m, area_width, 1, area_width, buf); - ili9341_bulk(5*5,m+1, area_width,1); + ili9341_read_memory(5*5, m, 290, 1, 290, buf); + ili9341_bulk(5*5,m+1, 290,1); } - for (int i=0; i= i) selection = i-1; @@ -1767,7 +1767,7 @@ ui_mode_numeric(int _keypad_mode) static void ui_mode_keypad(int _keypad_mode) { - if (ui_mode == UI_KEYPAD) + if (ui_mode == UI_KEYPAD && keypad_mode == _keypad_mode ) return; // keypads array @@ -2337,6 +2337,7 @@ void ui_process_touch(void) // switch menu mode after release touch_wait_release(); selection = -1; // hide keyboard mode selection + ensure_selection(); ui_mode_menu(); break; case UI_MENU: @@ -2359,6 +2360,7 @@ ui_process(void) int button_state = READ_PORT() & BUTTON_MASK; if (ui_mode == UI_NORMAL && current_menu_is_form()) { // Force into menu mode selection = -1; // hide keyboard mode selection + ensure_selection(); ui_mode_menu(); } if (operation_requested&OP_LEVER || previous_button_state != button_state) { diff --git a/ui_sa.c b/ui_sa.c index 7f0a67e..58875ca 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -352,6 +352,10 @@ static void menu_measure_cb(int item, uint8_t data) markers[i].mtype = M_DELTA; } markers[0].mtype = M_REFERENCE; + ui_mode_keypad(KM_CENTER); + ui_process_keypad(); + set_sweep_frequency(ST_START, 0); + set_sweep_frequency(ST_STOP, uistat.value*5); break; case 1: for (int i = 0; i< MARKERS_MAX; i++) { @@ -359,6 +363,10 @@ static void menu_measure_cb(int item, uint8_t data) markers[i].mtype = M_DELTA; } markers[0].mtype = M_REFERENCE; + ui_mode_keypad(KM_CENTER); + ui_process_keypad(); + ui_mode_keypad(KM_SPAN); + ui_process_keypad(); break; case 2: break; From ca687ea11be15a8f334df717cba3d540adbac010 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 2 Apr 2020 08:52:04 +0200 Subject: [PATCH 034/193] Intermediate commit on UI change --- nanovna.h | 4 ++-- sa_core.c | 2 +- ui.c | 24 +++++++++++++++--------- ui_sa.c | 22 +++++++++++----------- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/nanovna.h b/nanovna.h index 82d5efa..a299dd5 100644 --- a/nanovna.h +++ b/nanovna.h @@ -199,8 +199,8 @@ extern int _height; #define CELLWIDTH (32) #define CELLHEIGHT (32) -#define NGRIDY 10 -//#define NGRIDY 9 +//#define NGRIDY 10 +#define NGRIDY 9 #define FREQUENCIES_XPOS1 OFFSETX #define FREQUENCIES_XPOS2 200 diff --git a/sa_core.c b/sa_core.c index 3c370ea..2396f5c 100644 --- a/sa_core.c +++ b/sa_core.c @@ -742,7 +742,7 @@ static bool sweep(bool break_on_operation) } -const char *averageText[] = { "OFF", "MIN", "MAX", "2", "4", "8"}; +const char *averageText[] = { "OFF", "MIN", "MAX", "MAXD", "4", "16"}; const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; diff --git a/ui.c b/ui.c index 6fc675c..2542794 100644 --- a/ui.c +++ b/ui.c @@ -1090,8 +1090,12 @@ static void ensure_selection(void) { const menuitem_t *menu = menu_stack[menu_current_level]; - int i; - for (i = 0; MT_MASK(menu[i].type) != MT_NONE && MT_MASK(menu[i].type) != MT_TITLE ; i++) + int i=0; + if (MT_MASK(menu[0].type) == MT_TITLE && selection == 0) { + selection = 1; + return; + } + for (i = 0; MT_MASK(menu[i].type) != MT_NONE ; i++) ; if (selection >= i) selection = i-1; @@ -1943,13 +1947,14 @@ ui_process_menu(void) // close menu if next item is sentinel if (menu_stack[menu_current_level][selection+1].type == MT_NONE) goto menuclose; - selection++; + if (!(menu_stack[menu_current_level][selection+1].type == MT_FORM | MT_NONE)) + selection++; } if (status & EVT_DOWN) { - if (selection == 0) - goto menuclose; - selection--; + if (! ( selection == 0 && menu_stack[menu_current_level][0].type & MT_FORM)) + selection--; } + ensure_selection(); draw_menu(); status = btn_wait_release(); } while (status != 0); @@ -2203,9 +2208,11 @@ ui_process_keypad(void) } redraw_frame(); - if (menu_is_form(menu_stack[menu_current_level])) + if (menu_is_form(menu_stack[menu_current_level])) { ui_mode_menu(); //Reactivate menu after keypad - else { + selection = 0; + ensure_selection(); + } else { ui_mode_normal(); request_to_redraw_grid(); } @@ -2360,7 +2367,6 @@ ui_process(void) int button_state = READ_PORT() & BUTTON_MASK; if (ui_mode == UI_NORMAL && current_menu_is_form()) { // Force into menu mode selection = -1; // hide keyboard mode selection - ensure_selection(); ui_mode_menu(); } if (operation_requested&OP_LEVER || previous_button_state != button_state) { diff --git a/ui_sa.c b/ui_sa.c index 58875ca..b67489e 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -528,7 +528,7 @@ static const menuitem_t menu_drive_wide[] = { { MT_FORM | MT_CALLBACK, 2, " 15dBm", menu_drive_cb}, { MT_FORM | MT_CALLBACK, 3, " 20dBm", menu_drive_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; const menuitem_t menu_modulation[] = { @@ -538,7 +538,7 @@ const menuitem_t menu_modulation[] = { { MT_FORM | MT_CALLBACK, 2, "NARROW FM", menu_modulation_cb}, { MT_FORM | MT_CALLBACK, 3, "WIDE FM", menu_modulation_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; const menuitem_t menu_lowoutputmode[] = { @@ -547,7 +547,7 @@ const menuitem_t menu_lowoutputmode[] = { { MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", NULL}, { MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; const menuitem_t menu_highoutputmode[] = { @@ -556,7 +556,7 @@ const menuitem_t menu_highoutputmode[] = { { MT_FORM | MT_SUBMENU, 0, "LEVEL: %s", menu_drive_wide}, { MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_average[] = { @@ -607,7 +607,7 @@ static const menuitem_t menu_reffer2[] = { { MT_FORM | MT_CALLBACK, 6, "2MHz" , menu_reffer_cb}, { MT_FORM | MT_CALLBACK, 7, "1MHz" , menu_reffer_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_reffer[] = { @@ -618,7 +618,7 @@ static const menuitem_t menu_reffer[] = { { MT_FORM | MT_CALLBACK, 4, "4MHz" , menu_reffer_cb}, { MT_FORM | MT_SUBMENU, 0, S_RARROW" MORE", menu_reffer2}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_acquire[] = { @@ -627,7 +627,7 @@ static const menuitem_t menu_acquire[] = { { MT_SUBMENU,0, "RBW", menu_rbw}, { MT_SUBMENU,0, "AVERAGE", menu_average}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_acquirehigh[] = { @@ -730,7 +730,7 @@ static const menuitem_t menu_marker[] = { static const menuitem_t menu_dfu[] = { { MT_FORM | MT_CALLBACK, 0, "ENTER DFU", menu_dfu_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_settings2[] = @@ -783,7 +783,7 @@ static const menuitem_t menu_calibrate[] = { MT_FORM | MT_CALLBACK, 0, "CALIBRATE", menu_calibrate_cb}, { MT_FORM | MT_CALLBACK, 0, "RESET CALBRATION", menu_calibrate_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_config[] = { @@ -796,7 +796,7 @@ static const menuitem_t menu_config[] = { // { MT_SUBMENU, 0, "RBW", menu_rbw}, { MT_FORM | MT_SUBMENU, 0, S_RARROW"DFU", menu_dfu}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_mode[] = { @@ -808,7 +808,7 @@ static const menuitem_t menu_mode[] = { { MT_FORM | MT_SUBMENU, 0, "CAL OUTPUT: %s", menu_reffer}, { MT_FORM | MT_SUBMENU, 0, "CONFIG", menu_config}, // { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; #if 1 const menuitem_t menu_top[] = { From 62e0120f221f21f8dfe6c656a61e93b3774723e5 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 2 Apr 2020 13:34:10 +0200 Subject: [PATCH 035/193] Measurements working --- nanovna.h | 6 +++ plot.c | 32 +++++++++++++-- sa_core.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++----- ui.c | 13 +++++- ui_sa.c | 91 ++++++++++++++++++++++++++---------------- 5 files changed, 208 insertions(+), 50 deletions(-) diff --git a/nanovna.h b/nanovna.h index a299dd5..c8f8da2 100644 --- a/nanovna.h +++ b/nanovna.h @@ -638,4 +638,10 @@ void SetRefpos(int); void SetScale(int); void SetRBW(int); void SetRX(int); +extern int setting_measurement; + +enum { + M_OFF, M_IMD, M_OIP3 +}; + /*EOF*/ diff --git a/plot.c b/plot.c index a6e4bad..1a8ef2b 100644 --- a/plot.c +++ b/plot.c @@ -1,5 +1,4 @@ -/* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com - * All rights reserved. +/* 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 @@ -1100,7 +1099,7 @@ markmap_marker(int marker) int t; if (!markers[marker].enabled) return; - for (t = TRACE_ACTUAL; t < TRACE_ACTUAL; t++) { + for (t = TRACE_ACTUAL; t <= TRACE_ACTUAL; t++) { if (!trace[t].enabled) continue; index_t index = trace_index[t][markers[marker].index]; @@ -1398,10 +1397,18 @@ draw_cell(int m, int n) int x = CELL_X(index) - x0 - X_MARKER_OFFSET; int y = CELL_Y(index) - y0 - Y_MARKER_OFFSET; // Check marker icon on cell +#if 1 + + if (x + MARKER_WIDTH >= 0 && x < CELLWIDTH && + y + MARKER_HEIGHT >= 0 && y < CELLHEIGHT) + draw_marker(x, y, marker_color[markers[i].mtype], i); +#else + if (x + MARKER_WIDTH >= 0 && x - MARKER_WIDTH < CELLWIDTH && y + MARKER_HEIGHT >= 0 && y - MARKER_HEIGHT < CELLHEIGHT) draw_marker(x, y, marker_color[markers[i].mtype], i); -// draw_marker(x, y, config.trace_color[t], i); +#endif + // draw_marker(x, y, config.trace_color[t], i); // } } #endif @@ -1814,6 +1821,23 @@ static void cell_draw_marker_info(int x0, int y0) } } for (int i = 0; i < MARKER_COUNT; i++) { + if (i >= 2 && setting_measurement == M_OIP3 && markers[2].enabled && markers[3].enabled) { + float il = logmag(&(actual_t[markers[2].index])); + float ir = logmag(&(actual_t[markers[3].index])); + float sl = logmag(&(actual_t[markers[0].index])); + float sr = logmag(&(actual_t[markers[1].index])); + sl = (sl + sr)/2; + il = (il + ir)/2; + + il = sl+ (sl - il)/2; + plot_printf(buf, sizeof buf, "OIP3: %4.1fdB", il); + j = 2; + int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(16) - y0; + + cell_drawstring_7x13(buf, xpos, ypos); + break; + } if (!markers[i].enabled) continue; int idx = markers[i].index; diff --git a/sa_core.c b/sa_core.c index 2396f5c..08c945e 100644 --- a/sa_core.c +++ b/sa_core.c @@ -19,8 +19,11 @@ int setting_tracking = false; int setting_modulation = MO_NONE; int setting_step_delay = 0; int setting_frequency_step; +int setting_decay; +int setting_noise; float actual_rbw = 0; float setting_vbw = 0; +int setting_measurement; int vbwSteps = 1; @@ -48,6 +51,9 @@ void reset_settings(int m) setting_modulation = MO_NONE; setting_step_delay = 0; setting_vbw = 0; + setting_decay=20; + setting_noise=20; + setting_measurement = M_OFF; // setting_spur = 0; switch(m) { case M_LOW: @@ -92,6 +98,27 @@ int get_refer_output(void) return(setting_refer); } +void set_decay(int d) +{ + if (d < 0 || d > 200) + return; + setting_decay = d; + dirty = true; +} + +void set_noise(int d) +{ + if (d < 5 || d > 200) + return; + setting_noise = d; + dirty = true; +} + +void set_measurement(int m) +{ + setting_measurement = m; + dirty = true; +} void SetDrive(int d) { setting_drive = d; @@ -455,6 +482,64 @@ void update_rbw(void) vbwSteps = 1; dirty = true; } +#define MAX_MAX 4 +int +search_maximum(int m, int center, int span) +{ + int from = center - span/2; + int found = false; + int to = center + span/2; + int cur_max = 0; // Always at least one maximum + int max_index[4]; + temppeakIndex = 0; + temppeakLevel = actual_t[from]; + max_index[cur_max] = from; + int downslope = true; + + for (int i = from; i <= to; i++) { + if (downslope) { + if (temppeakLevel > actual_t[i]) { // Follow down + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + } else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found + temppeakIndex = i; // This is now the latest maximum + temppeakLevel = actual_t[i]; + downslope = false; + } + } else { + if (temppeakLevel < actual_t[i]) { // Follow up + temppeakIndex = i; + temppeakLevel = actual_t[i]; + } else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found + + found = true; + int j = 0; // Insertion index + while (j= temppeakLevel) // Find where to insert + j++; + if (j < MAX_MAX) { // Larger then one of the previous found + int k = MAX_MAX-1; + while (k > j) { // Shift to make room for max + max_index[k] = max_index[k-1]; + // maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging + k--; + } + max_index[j] = temppeakIndex; + // maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging + if (cur_max < MAX_MAX) { + cur_max++; + } + //STOP_PROFILE + } + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + + downslope = true; + } + } + } + markers[m].index = max_index[0]; + return found; +} //static int spur_old_stepdelay = 0; static const unsigned int spur_IF = 433900000; @@ -569,7 +654,6 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) } #define MAX_MAX 4 -#define MAX_NOISE 10 // 10dB int16_t max_index[MAX_MAX]; int16_t cur_max = 0; @@ -613,14 +697,14 @@ static bool sweep(bool break_on_operation) actual_t[i] = RSSI; age[i] = 0; } else { - if (age[i] > 20) + if (age[i] > setting_decay) actual_t[i] -= 0.5; else age[i] += 1; } break; - case AV_4: actual_t[i] = (actual_t[i] + RSSI) / 4.0; break; - case AV_16: actual_t[i] = (actual_t[i]*3 + RSSI) / 16.0; break; + case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; + case AV_16: actual_t[i] = (actual_t[i]*15 + RSSI) / 16.0; break; } } #if 1 @@ -629,14 +713,14 @@ static bool sweep(bool break_on_operation) cur_max = 0; // Always at least one maximum temppeakIndex = 0; temppeakLevel = actual_t[i]; - max_index[i] = 0; + max_index[0] = 0; downslope = true; } if (downslope) { if (temppeakLevel > actual_t[i]) { // Follow down temppeakIndex = i; // Latest minimum temppeakLevel = actual_t[i]; - } else if (temppeakLevel + MAX_NOISE < actual_t[i]) { // Local minimum found + } else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found temppeakIndex = i; // This is now the latest maximum temppeakLevel = actual_t[i]; downslope = false; @@ -645,7 +729,7 @@ static bool sweep(bool break_on_operation) if (temppeakLevel < actual_t[i]) { // Follow up temppeakIndex = i; temppeakLevel = actual_t[i]; - } else if (temppeakLevel - MAX_NOISE > actual_t[i]) { // Local max found + } else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found int j = 0; // Insertion index while (j= temppeakLevel) // Find where to insert @@ -713,6 +797,20 @@ static bool sweep(bool break_on_operation) } m++; // Try next marker } + if (setting_measurement == M_IMD && markers[0].index > 10) { + markers[1].enabled = search_maximum(1, markers[0].index*2, 8); + markers[2].enabled = search_maximum(2, markers[0].index*3, 12); + markers[3].enabled = search_maximum(3, markers[0].index*4, 16); + } else if (setting_measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) { + int l = markers[0].index; + int r = markers[1].index; + if (r < l) { + l = markers[1].index; + r = markers[0].index; + } + markers[2].enabled = search_maximum(2, l - (r-l), 10); + markers[3].enabled = search_maximum(3, r + (r-l), 10); + } peakIndex = max_index[0]; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; @@ -742,7 +840,7 @@ static bool sweep(bool break_on_operation) } -const char *averageText[] = { "OFF", "MIN", "MAX", "MAXD", "4", "16"}; +const char *averageText[] = { "OFF", "MIN", "MAX", "MAXD", " A 4", "A 16"}; const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; @@ -794,7 +892,7 @@ void draw_cal_status(void) if (setting_average>0) { ili9341_set_foreground(BRIGHT_COLOR_BLUE); y += YSTEP*2; - ili9341_drawstring("Aver:", x, y); + ili9341_drawstring("Calc:", x, y); y += YSTEP; plot_printf(buf, BLEN, "%s",averageText[setting_average]); diff --git a/ui.c b/ui.c index 2542794..a7822e3 100644 --- a/ui.c +++ b/ui.c @@ -1108,6 +1108,8 @@ menu_move_back(void) return; erase_menu_buttons(); menu_current_level--; + if (selection >= 0) + selection = 0; ensure_selection(); draw_menu(); } @@ -1119,6 +1121,8 @@ menu_push_submenu(const menuitem_t *submenu) if (menu_current_level < MENU_STACK_DEPTH_MAX-1) menu_current_level++; menu_stack[menu_current_level] = submenu; + if (selection >= 0) + selection = 0; ensure_selection(); if (menu_is_form(submenu)) { redraw_frame(); @@ -1940,6 +1944,10 @@ ui_process_menu(void) int status = btn_check(); if (status != 0) { if (status & EVT_BUTTON_SINGLE_CLICK) { + if (selection == -1) { + selection = 0; + goto activate; + } menu_invoke(selection); } else { do { @@ -1947,13 +1955,14 @@ ui_process_menu(void) // close menu if next item is sentinel if (menu_stack[menu_current_level][selection+1].type == MT_NONE) goto menuclose; - if (!(menu_stack[menu_current_level][selection+1].type == MT_FORM | MT_NONE)) + if (!(menu_stack[menu_current_level][selection+1].type == (MT_FORM | MT_NONE))) selection++; } if (status & EVT_DOWN) { if (! ( selection == 0 && menu_stack[menu_current_level][0].type & MT_FORM)) selection--; } +activate: ensure_selection(); draw_menu(); status = btn_wait_release(); @@ -2210,7 +2219,7 @@ ui_process_keypad(void) redraw_frame(); if (menu_is_form(menu_stack[menu_current_level])) { ui_mode_menu(); //Reactivate menu after keypad - selection = 0; + selection = -1; ensure_selection(); } else { ui_mode_normal(); diff --git a/ui_sa.c b/ui_sa.c index b67489e..6c66358 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -5,6 +5,7 @@ static void menu_marker_type_cb(int item, uint8_t data); void set_sweep_frequency(int type, uint32_t frequency); uint32_t get_sweep_frequency(int type); void clearDisplay(void); +void reset_settings(int); //void ui_process_touch(void); void SetPowerGrid(int); void SetRefLevel(int); @@ -37,13 +38,18 @@ void ToggleLNA(void); void ToggleAGC(void); void redrawHisto(void); void self_test(void); +void set_decay(int); +void set_noise(int); extern int32_t frequencyExtra; extern int setting_tracking; extern int setting_drive; extern int setting_lna; extern int setting_agc; +extern int setting_decay; +extern int setting_noise; void SetModulation(int); extern int setting_modulation; +void set_measurement(int); // extern int settingSpeed; extern int setting_step_delay; @@ -51,7 +57,7 @@ extern int setting_step_delay; enum { KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, - KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_HIGHOUTLEVEL + KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE }; @@ -157,7 +163,8 @@ static const keypads_t * const keypads_mode_tbl[] = { keypads_level, // sample time keypads_scale, // drive keypads_level, // KM_LOWOUTLEVEL - keypads_level, // KM_HIGHOUTLEVEL + keypads_level, // KM_DECAY + keypads_level, // KM_NOISE }; #ifdef __VNA__ @@ -167,7 +174,7 @@ static const char * const keypad_mode_label[] = { #endif #ifdef __SA__ static const char * const keypad_mode_label[] = { - "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL" + "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL", "LEVEL" }; #endif @@ -210,9 +217,7 @@ void menu_autosettings_cb(int item, uint8_t data) { (void)item; (void)data; - int current_mode = GetMode(); - SetMode(-1); // Force setmode to do something - SetMode(current_mode); + reset_settings(GetMode()); active_marker = 0; for (int i = 1; i Date: Fri, 3 Apr 2020 12:54:49 +0200 Subject: [PATCH 036/193] Increase output power selectable range --- sa_core.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------ ui_sa.c | 30 ++++++++++++---------- 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/sa_core.c b/sa_core.c index 08c945e..997d4e6 100644 --- a/sa_core.c +++ b/sa_core.c @@ -8,6 +8,7 @@ int setting_mode = M_LOW; int dirty = true; int scandirty = true; int setting_attenuate = 0; +int setting_step_atten; int setting_rbw = 0; int setting_average = 0; int setting_show_stored = 0; @@ -40,6 +41,7 @@ void reset_settings(int m) { setting_mode = m; setting_attenuate = 0; + setting_step_atten = 0; setting_rbw = 0; setting_average = 0; setting_show_stored = 0; @@ -64,6 +66,7 @@ void reset_settings(int m) SetRefpos(-10); break; case M_GENLOW: + setting_drive=1; // 0-3 , 3=+20dBm minFreq = 0; maxFreq = 520000000; set_sweep_frequency(ST_CENTER, (int32_t) 10000000); @@ -121,7 +124,14 @@ void set_measurement(int m) } void SetDrive(int d) { - setting_drive = d; + setting_drive = (d & 3); + if (setting_mode == M_GENHIGH) { + if (!(d & 4)) + setting_step_atten = 1; + else + setting_step_atten = 0; + setting_drive = d; + } dirty = true; } @@ -142,14 +152,55 @@ int GetMode(void) dirty = true; } + +#define POWER_STEP 0 // Should be 5 dB but appearently it is lower +#define POWER_OFFSET 2 +#define SWITCH_ATTENUATION 29 + +int GetAttenuation(void) +{ + if (setting_mode == M_GENLOW) { + if (setting_step_atten) + return ( - (POWER_OFFSET + setting_attenuate - (setting_step_atten-1)*POWER_STEP + SWITCH_ATTENUATION)); + else + return ( -(POWER_OFFSET + setting_attenuate)); + } + return(setting_attenuate); +} + + void SetAttenuation(int a) { + a = a + POWER_OFFSET; + if (setting_mode == M_GENLOW) { + if( a > - SWITCH_ATTENUATION + 3*POWER_STEP) { + setting_step_atten = 0; + } else { + a = a + SWITCH_ATTENUATION; +#if 0 + if (a >= 2 * POWER_STEP) { + setting_step_atten = 3; // Max drive + a = a - 2 * POWER_STEP; + } else if (a >= POWER_STEP ) { + setting_step_atten = 2; // Max drive + a = a - POWER_STEP; + } else { + setting_step_atten = 1; + } +#else + setting_step_atten = 1; // drive level is unpredictable +#endif + } + a = -a; + } else { + setting_step_atten = 0; + } if (a<0) - a = 0; + a = 0; if (a> 31) a=31; - if (setting_attenuate == a) - return; +// if (setting_attenuate == a) +// return; setting_attenuate = a; dirty = true; } @@ -440,8 +491,13 @@ case M_HIGH: // Direct into 1 break; case M_GENLOW: // Mixed output from 0 SI4432_Sel = 0; - SetSwitchTransmit(); - SI4432_Transmit(setting_drive); + if (setting_step_atten) { + SetSwitchReceive(); + SI4432_Transmit(setting_step_atten-1); + } else { + SetSwitchTransmit(); + SI4432_Transmit(0); // To prevent damage to the BPF always set low drive + } SI4432_Sel = 1; SetSwitchReceive(); @@ -454,8 +510,12 @@ case M_GENHIGH: // Direct output from 1 SetSwitchReceive(); SI4432_Sel = 1; - SetSwitchTransmit(); - SI4432_Transmit(setting_drive); + if (setting_step_atten) { + SetSwitchReceive(); + } else { + SetSwitchTransmit(); + } + SI4432_Transmit(setting_drive & 3); break; } diff --git a/ui_sa.c b/ui_sa.c index 6c66358..bf90342 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -12,6 +12,7 @@ void SetRefLevel(int); void set_refer_output(int); int get_refer_output(void); void SetAttenuation(int); +int GetAttenuation(void); void SetPowerLevel(int); void SetGenerate(int); void SetRBW(int); @@ -317,8 +318,9 @@ static void menu_reffer_cb(int item, uint8_t data) // draw_cal_status(); } -const int menu_drive_value[]={5,10,15,20}; -const char *menu_drive_text[]={"5dBm","10dBm","15dBm","20dBm"}; +//const int menu_drive_value[]={5,10,15,20}; +const char *menu_drive_text[]={"-15dBm","-10dBm","-5dBm","0dBm","5dBm","10dBm","15dBm","20dBm"}; + static void menu_drive_cb(int item, uint8_t data) { (void)item; @@ -524,19 +526,21 @@ static void menu_pause_cb(int item, uint8_t data) // ===[MENU DEFINITION]========================================================= static const menuitem_t menu_drive[] = { - { MT_CALLBACK, 0, " 5dBm", menu_drive_cb}, - { MT_CALLBACK, 1, " 10dBm", menu_drive_cb}, - { MT_CALLBACK, 2, " 15dBm", menu_drive_cb}, { MT_CALLBACK, 3, " 20dBm", menu_drive_cb}, + { MT_CALLBACK, 2, " 15dBm", menu_drive_cb}, + { MT_CALLBACK, 1, " 10dBm", menu_drive_cb}, + { MT_CALLBACK, 0, " 5dBm", menu_drive_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_drive_wide[] = { - { MT_FORM | MT_CALLBACK, 0, " 5dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 1, " 10dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 2, " 15dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 3, " 20dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 6, " 15dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 5, " 10dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 4, " 5dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 2, " -5dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 1, "-10dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 0, "-15dBm", menu_drive_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -936,7 +940,7 @@ static void menu_item_modify_attribute( } } else if (menu == menu_drive || menu == menu_drive_wide) { - if (item == setting_drive){ + if (menu[item].data == setting_drive){ mark = true; } @@ -1016,7 +1020,7 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value / 1000); break; case KM_ATTENUATION: - uistat.value = setting_attenuate; + uistat.value = GetAttenuation(); plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_ACTUALPOWER: @@ -1036,8 +1040,7 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value); break; case KM_LOWOUTLEVEL: - uistat.value = setting_attenuate; - uistat.value = -5 - uistat.value; // compensation for dB offset during low output mode + uistat.value = GetAttenuation(); // compensation for dB offset during low output mode plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_DECAY: @@ -1105,7 +1108,6 @@ set_numeric_value(void) SetDrive(uistat.value); break; case KM_LOWOUTLEVEL: - uistat.value = -5 - uistat.value ; // compensation for dB offset during low output mode SetAttenuation(uistat.value); break; case KM_DECAY: From 766eecc0571bcc54cf22f3ed28915eb4e0533ce4 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 4 Apr 2020 09:10:16 +0200 Subject: [PATCH 037/193] Attenuator timing and PE4302 shift error corrected --- sa_core.c | 2 +- si4432.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sa_core.c b/sa_core.c index 997d4e6..7f87134 100644 --- a/sa_core.c +++ b/sa_core.c @@ -171,8 +171,8 @@ int GetAttenuation(void) void SetAttenuation(int a) { - a = a + POWER_OFFSET; if (setting_mode == M_GENLOW) { + a = a + POWER_OFFSET; if( a > - SWITCH_ATTENUATION + 3*POWER_STEP) { setting_step_atten = 0; } else { diff --git a/si4432.c b/si4432.c index a9ae215..12e8890 100644 --- a/si4432.c +++ b/si4432.c @@ -359,14 +359,38 @@ void PE4302_init(void) { CS_PE_LOW; } -extern void shiftOut(uint8_t val); +#define PE4302_DELAY 100 + +void PE4302_shiftOut(uint8_t val) +{ + uint8_t i; + SI4432_log(SI4432_Sel); + SI4432_log(val); + for (i = 0; i < 8; i++) { + if (val & (1 << (7 - i))) + SPI2_SDI_HIGH; + else + SPI2_SDI_LOW; + chThdSleepMicroseconds(PE4302_DELAY); + SPI2_CLK_HIGH; + chThdSleepMicroseconds(PE4302_DELAY); + SPI2_CLK_LOW; + chThdSleepMicroseconds(PE4302_DELAY); + } +} void PE4302_Write_Byte(unsigned char DATA ) { + chThdSleepMicroseconds(PE4302_DELAY); SPI2_CLK_LOW; - shiftOut(DATA); + chThdSleepMicroseconds(PE4302_DELAY); + PE4302_shiftOut(DATA); + chThdSleepMicroseconds(PE4302_DELAY); CS_PE_HIGH; + chThdSleepMicroseconds(PE4302_DELAY); CS_PE_LOW; + chThdSleepMicroseconds(PE4302_DELAY); + } #endif From b7d2d87825e85d8aa63f67339a1f21ecdff765f1 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 5 Apr 2020 09:54:33 +0200 Subject: [PATCH 038/193] Corrected the attenuator error --- NANOVNA_STM32_F072/board.h | 2 +- main.c | 20 ++++++++++---------- sa_core.c | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index 2a6af10..3d4beee 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -84,7 +84,7 @@ #define GPIO_LO_SEL 15 -#define GPIOC_LED 13 +#define GPIOB_LED 11 #define GPIOF_OSC_IN 0 #define GPIOF_OSC_OUT 1 diff --git a/main.c b/main.c index 51a7e6e..b5adc95 100644 --- a/main.c +++ b/main.c @@ -877,7 +877,7 @@ bool sweep(bool break_on_operation) { int i, delay; // blink LED while scanning - palClearPad(GPIOC, GPIOC_LED); + palClearPad(GPIOB, GPIOB_LED); // Power stabilization after LED off, also align timings on i == 0 for (i = 0; i < sweep_points; i++) { // 5300 if (frequencies[i] == 0) break; @@ -911,7 +911,7 @@ bool sweep(bool break_on_operation) return false; } // blink LED while scanning - palSetPad(GPIOC, GPIOC_LED); + palSetPad(GPIOB, GPIOB_LED); return true; } #endif @@ -1928,14 +1928,14 @@ VNA_SHELL_FUNCTION(cmd_test) #if 0 int i; for (i = 0; i < 100; i++) { - palClearPad(GPIOC, GPIOC_LED); + palClearPad(GPIOB, GPIOB_LED); set_frequency(10000000); - palSetPad(GPIOC, GPIOC_LED); + palSetPad(GPIOB, GPIOB_LED); chThdSleepMilliseconds(50); - palClearPad(GPIOC, GPIOC_LED); + palClearPad(GPIOB, GPIOB_LED); set_frequency(90000000); - palSetPad(GPIOC, GPIOC_LED); + palSetPad(GPIOB, GPIOB_LED); chThdSleepMilliseconds(50); } #endif @@ -1947,9 +1947,9 @@ VNA_SHELL_FUNCTION(cmd_test) mode = my_atoi(argv[0]); for (i = 0; i < 20; i++) { - palClearPad(GPIOC, GPIOC_LED); + palClearPad(GPIOB, GPIOB_LED); ili9341_test(mode); - palSetPad(GPIOC, GPIOC_LED); + palSetPad(GPIOB, GPIOB_LED); chThdSleepMilliseconds(50); } #endif @@ -2291,7 +2291,7 @@ VNA_SHELL_FUNCTION(cmd_m) (void)argv; pause_sweep(); int32_t f_step = (frequencyStop-frequencyStart)/ points; - palClearPad(GPIOC, GPIOC_LED); // disable led and wait for voltage stabilization + palClearPad(GPIOB, GPIOB_LED); // disable led and wait for voltage stabilization setting_frequency_step = f_step; update_rbw(); chThdSleepMilliseconds(10); @@ -2305,7 +2305,7 @@ VNA_SHELL_FUNCTION(cmd_m) // enable led } streamPut(shell_stream, '}'); - palSetPad(GPIOC, GPIOC_LED); + palSetPad(GPIOB, GPIOB_LED); } VNA_SHELL_FUNCTION(cmd_p) diff --git a/sa_core.c b/sa_core.c index 7f87134..9a9d4e5 100644 --- a/sa_core.c +++ b/sa_core.c @@ -722,7 +722,7 @@ static bool sweep(bool break_on_operation) { float RSSI; int16_t downslope = true; - palClearPad(GPIOC, GPIOC_LED); + palClearPad(GPIOB, GPIOB_LED); temppeakLevel = -150; float temp_min_level = 100; // spur_old_stepdelay = 0; @@ -895,7 +895,7 @@ static bool sweep(bool break_on_operation) #endif // redraw_marker(peak_marker, FALSE); - palSetPad(GPIOC, GPIOC_LED); + palSetPad(GPIOB, GPIOB_LED); return true; } From 0cc0dacd55540f98ef37107eb2cb8ac7c95b421a Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 5 Apr 2020 11:05:08 +0200 Subject: [PATCH 039/193] Adapted the IF to avoid the side lobe. SPur table TODO --- sa_core.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/sa_core.c b/sa_core.c index 9a9d4e5..46fb8d8 100644 --- a/sa_core.c +++ b/sa_core.c @@ -602,39 +602,11 @@ search_maximum(int m, int center, int span) } //static int spur_old_stepdelay = 0; -static const unsigned int spur_IF = 433900000; -static const unsigned int spur_alternate_IF = 434100000; +static const unsigned int spur_IF = 433800000; +static const unsigned int spur_alternate_IF = 433600000; static const int spur_table[] = { 470000, - 780000, - 830000, - 880000, - 949000, - 1390000, - 1468000, - 1830000, - 1900000, - 2770000, - 2840000, - 2880000, - 4710000, - 4780000, - 4800000, - 4880000, - 6510000, - 6750000, - 6790000, - 6860000, - 7340000, - 8100000, - 8200000, - 8880000, -// 9970000, 10MHz!!!!!! - 10870000, - 11420000, - 14880000, - 16820000, }; int avoid_spur(int f) @@ -642,7 +614,7 @@ int avoid_spur(int f) int window = ((int)actual_rbw ) * 1000*2; if (window < 50000) window = 50000; - if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0) + if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw >= 300.0) return(false); for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { if (f/window == spur_table[i]/window) { From 8c8bd14d4d9bdc450f12cc2b4f5c1f596999e82c Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 5 Apr 2020 12:56:44 +0200 Subject: [PATCH 040/193] Increase mixer drive to compensate for 3dB pad --- sa_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sa_core.c b/sa_core.c index 46fb8d8..fe1942c 100644 --- a/sa_core.c +++ b/sa_core.c @@ -46,7 +46,7 @@ void reset_settings(int m) setting_average = 0; setting_show_stored = 0; setting_subtract_stored = 0; - setting_drive=0; // 0-3 , 3=+20dBm + setting_drive=1; // 0-3 , 3=+20dBm setting_agc = true; setting_lna = false; setting_tracking = false; @@ -66,7 +66,6 @@ void reset_settings(int m) SetRefpos(-10); break; case M_GENLOW: - setting_drive=1; // 0-3 , 3=+20dBm minFreq = 0; maxFreq = 520000000; set_sweep_frequency(ST_CENTER, (int32_t) 10000000); From 1dccb2f8945947545013eaa4dfb3eb109dd07002 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 5 Apr 2020 14:46:53 +0200 Subject: [PATCH 041/193] Add self test message --- plot.c | 9 +++++++++ sa_core.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/plot.c b/plot.c index 1a8ef2b..045fcff 100644 --- a/plot.c +++ b/plot.c @@ -1838,6 +1838,15 @@ static void cell_draw_marker_info(int x0, int y0) cell_drawstring_7x13(buf, xpos, ypos); break; } + if (i >= 2 && in_selftest) { + plot_printf(buf, sizeof buf, "DO NOT SWITCH OFF!!"); + j = 2; + int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(16) - y0; + + cell_drawstring_7x13(buf, xpos, ypos); + break; + } if (!markers[i].enabled) continue; int idx = markers[i].index; diff --git a/sa_core.c b/sa_core.c index fe1942c..5c5fde2 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1100,7 +1100,7 @@ void cell_draw_test_info(int x0, int y0) do { i++; int xpos = 25 - x0; - int ypos = 40+i*INFO_SPACING - y0; + int ypos = 50+i*INFO_SPACING - y0; unsigned int color = RGBHEX(0xFFFFFF); if (i == -1) { plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Self test status:"); From 7d6476651340ec77d45082f5b4e1494dd3e0bc53 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 5 Apr 2020 19:37:35 +0200 Subject: [PATCH 042/193] Optimize stack usage by shifting test and calibrate to lowest level --- main.c | 6 +++++- nanovna.h | 3 +++ plot.c | 9 +++++++++ sa_core.c | 51 +++++++++++++++++++++++++++++---------------------- ui.c | 17 +++++++++++++++++ ui_sa.c | 4 ++-- 6 files changed, 65 insertions(+), 25 deletions(-) diff --git a/main.c b/main.c index 51a7e6e..a0fd3ae 100644 --- a/main.c +++ b/main.c @@ -117,7 +117,7 @@ const char *info_about[]={ 0 // sentinel }; -static THD_WORKING_AREA(waThread1, 730); +static THD_WORKING_AREA(waThread1, 900); static THD_FUNCTION(Thread1, arg) { (void)arg; @@ -128,6 +128,10 @@ static THD_FUNCTION(Thread1, arg) if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) { completed = sweep(true); sweep_mode&=~SWEEP_ONCE; + } else if (sweep_mode & SWEEP_SELFTEST) { + self_test(); // call from lowest level to save stack space + } else if (sweep_mode & SWEEP_CALIBRATE) { + calibrate(); // call from lowest level to save stack space } else { __WFI(); } diff --git a/nanovna.h b/nanovna.h index c8f8da2..469ad6b 100644 --- a/nanovna.h +++ b/nanovna.h @@ -139,6 +139,9 @@ enum { #define SWEEP_ENABLE 0x01 #define SWEEP_ONCE 0x02 +#define SWEEP_CALIBRATE 0x04 +#define SWEEP_SELFTEST 0x08 + extern int8_t sweep_mode; extern const char *info_about[]; diff --git a/plot.c b/plot.c index 1a8ef2b..045fcff 100644 --- a/plot.c +++ b/plot.c @@ -1838,6 +1838,15 @@ static void cell_draw_marker_info(int x0, int y0) cell_drawstring_7x13(buf, xpos, ypos); break; } + if (i >= 2 && in_selftest) { + plot_printf(buf, sizeof buf, "DO NOT SWITCH OFF!!"); + j = 2; + int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; + int ypos = 1 + (j/2)*(16) - y0; + + cell_drawstring_7x13(buf, xpos, ypos); + break; + } if (!markers[i].enabled) continue; int idx = markers[i].index; diff --git a/sa_core.c b/sa_core.c index 7f87134..2f9bbe2 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1074,7 +1074,7 @@ static const struct { {TC_FLAT, TP_10MHZEXTRA, 10, 4, -25, 20, -70}, // 8 BPF pass band flatness {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 9 LPF cutoff {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -85 }, // 11 Measure power level and noise + {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -80 }, // 11 Measure power level and noise {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 13 Measure powerlevel and noise {TC_MEASURE, TPH_30MHZ, 270, 4, -50, 30, -85 }, // 14 Calibrate power high mode {TC_END, 0, 0, 0, 0, 0, 0}, @@ -1129,7 +1129,7 @@ void cell_draw_test_info(int x0, int y0) do { i++; int xpos = 25 - x0; - int ypos = 40+i*INFO_SPACING - y0; + int ypos = 50+i*INFO_SPACING - y0; unsigned int color = RGBHEX(0xFFFFFF); if (i == -1) { plot_printf(self_test_status_buf, sizeof self_test_status_buf, "Self test status:"); @@ -1341,7 +1341,6 @@ common_silent: } extern void menu_autosettings_cb(int item); -extern void touch_wait_release(void); void self_test(void) { @@ -1359,25 +1358,25 @@ void self_test(void) test_prepare(i); test_acquire(i); // Acquire test test_status[i] = test_validate(i); // Validate test - chThdSleepMilliseconds(1000); if (test_status[i] != TS_PASS) { - touch_wait_release(); + wait_user(); } i++; } - touch_wait_release(); - // chThdSleepMilliseconds(2000); + ili9341_set_foreground(BRIGHT_COLOR_GREEN); + ili9341_drawstring_7x13("Self test complete", 30, 120); + ili9341_drawstring_7x13("Touch screen to continue", 30, 140); + wait_user(); + + sweep_mode = SWEEP_ENABLE; show_test_info = FALSE; trace[TRACE_STORED].enabled = false; set_trace_refpos(0, NGRIDY - (-10) / get_trace_scale(0)); set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); set_refer_output(0); - SetMode(M_LOW); - SetAverage(0); - draw_cal_status(); + reset_settings(M_LOW); in_selftest = false; - menu_autosettings_cb(0); } void reset_calibration(void) @@ -1394,18 +1393,21 @@ void calibrate(void) float last_peak_level; in_selftest = true; SetPowerLevel(100); - menu_autosettings_cb(0); + reset_settings(M_LOW); int i = 10; // calibrate low mode power on 30 MHz; for (int j= 0; j < CALIBRATE_RBWS; j++ ) { SetRBW(power_rbw[j]); test_prepare(i); test_acquire(i); // Acquire test local_test_status = test_validate(i); // Validate test - chThdSleepMilliseconds(1000); +// chThdSleepMilliseconds(1000); if (local_test_status != TS_PASS) { - // touch_wait_release(); + ili9341_set_foreground(BRIGHT_COLOR_RED); + ili9341_drawstring_7x13("Calibration failed", 30, 120); + goto quit; } else SetPowerLevel(-25); + goto done; } i = 11; // Measure 270MHz in low mode SetRBW(100); @@ -1423,23 +1425,28 @@ void calibrate(void) test_prepare(i); test_acquire(i); // Acquire test local_test_status = test_validate(i); // Validate test - chThdSleepMilliseconds(1000); if (local_test_status != TS_PASS) { - touch_wait_release(); + ili9341_set_foreground(BRIGHT_COLOR_RED); + ili9341_drawstring_7x13("Calibration failed", 30, 120); + goto quit; } else SetPowerLevel(last_peak_level); } - touch_wait_release(); +done: + ili9341_set_foreground(BRIGHT_COLOR_GREEN); + ili9341_drawstring_7x13("Calibration complete", 30, 120); +quit: + ili9341_drawstring_7x13("Touch screen to continue", 30, 140); + wait_user(); + + in_selftest = false; + sweep_mode = SWEEP_ENABLE; trace[TRACE_STORED].enabled = false; set_trace_refpos(0, NGRIDY - (-10) / get_trace_scale(0)); set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); set_refer_output(0); - SetMode(M_LOW); - SetAverage(0); - draw_cal_status(); - in_selftest = false; - menu_autosettings_cb(0); + reset_settings(M_LOW); } diff --git a/ui.c b/ui.c index a7822e3..01467da 100644 --- a/ui.c +++ b/ui.c @@ -2469,3 +2469,20 @@ ui_init() touch_start_watchdog(); } + +void wait_user(void) +{ + adc_stop(); + touch_wait_release(); +#if 0 + operation_requested = OP_NONE; + while (true) { + if (operation_requested & OP_TOUCH) + break; + if (operation_requested & OP_LEVER) + break; + } +#endif + touch_start_watchdog(); +} + diff --git a/ui_sa.c b/ui_sa.c index bf90342..6b06b7a 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -242,7 +242,7 @@ static void menu_calibrate_cb(int item, uint8_t data) (void)data; switch (item) { case 1: - calibrate(); + sweep_mode = SWEEP_CALIBRATE; menu_move_back(); ui_mode_normal(); break; @@ -272,7 +272,7 @@ static void menu_config_cb(int item, uint8_t data) case 2: menu_move_back(); ui_mode_normal(); - self_test(); + sweep_mode = SWEEP_SELFTEST; break; case 4: show_version(); From 85e17da3bf144d76163e733baaa1310a11d24024 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 10:15:13 +0200 Subject: [PATCH 043/193] RBW power calibration table added and calibration completed --- nanovna.h | 3 +++ sa_core.c | 33 ++++++++++++++++----------------- si4432.c | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/nanovna.h b/nanovna.h index 469ad6b..d5ff1e4 100644 --- a/nanovna.h +++ b/nanovna.h @@ -642,6 +642,9 @@ void SetScale(int); void SetRBW(int); void SetRX(int); extern int setting_measurement; +void self_test(void); +void wait_user(void); +void calibrate(void); enum { M_OFF, M_IMD, M_OIP3 diff --git a/sa_core.c b/sa_core.c index 2f9bbe2..495ff13 100644 --- a/sa_core.c +++ b/sa_core.c @@ -13,7 +13,7 @@ int setting_rbw = 0; int setting_average = 0; int setting_show_stored = 0; int setting_subtract_stored = 0; -int setting_drive=0; // 0-3 , 3=+20dBm +int setting_drive=1; // 0-3 , 3=+20dBm int setting_agc = true; int setting_lna = false; int setting_tracking = false; @@ -24,6 +24,7 @@ int setting_decay; int setting_noise; float actual_rbw = 0; float setting_vbw = 0; + int setting_measurement; int vbwSteps = 1; @@ -55,6 +56,9 @@ void reset_settings(int m) setting_vbw = 0; setting_decay=20; setting_noise=20; + trace[TRACE_STORED].enabled = false; + trace[TRACE_TEMP].enabled = false; + setting_measurement = M_OFF; // setting_spur = 0; switch(m) { @@ -1076,7 +1080,7 @@ static const struct { {TC_END, 0, 0, 0, 0, 0, 0}, {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -80 }, // 11 Measure power level and noise {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 13 Measure powerlevel and noise - {TC_MEASURE, TPH_30MHZ, 270, 4, -50, 30, -85 }, // 14 Calibrate power high mode + {TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 14 Calibrate power high mode {TC_END, 0, 0, 0, 0, 0, 0}, }; @@ -1367,13 +1371,10 @@ void self_test(void) ili9341_drawstring_7x13("Self test complete", 30, 120); ili9341_drawstring_7x13("Touch screen to continue", 30, 140); wait_user(); + ili9341_clear_screen(); sweep_mode = SWEEP_ENABLE; show_test_info = FALSE; - trace[TRACE_STORED].enabled = false; - set_trace_refpos(0, NGRIDY - (-10) / get_trace_scale(0)); - set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); - set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); set_refer_output(0); reset_settings(M_LOW); in_selftest = false; @@ -1384,7 +1385,7 @@ void reset_calibration(void) SetPowerLevel(100); } -#define CALIBRATE_RBWS 5 +#define CALIBRATE_RBWS 1 const int power_rbw [5] = { 100, 300, 30, 10, 3 }; void calibrate(void) @@ -1405,9 +1406,10 @@ void calibrate(void) ili9341_set_foreground(BRIGHT_COLOR_RED); ili9341_drawstring_7x13("Calibration failed", 30, 120); goto quit; - } else - SetPowerLevel(-25); - goto done; + } else { + SetPowerLevel(-23); + chThdSleepMilliseconds(1000); + } } i = 11; // Measure 270MHz in low mode SetRBW(100); @@ -1417,10 +1419,10 @@ void calibrate(void) local_test_status = test_validate(i); // Validate test chThdSleepMilliseconds(1000); - config.high_level_offset = -20; /// Preliminary setting + config.high_level_offset = 0; /// Preliminary setting i = 12; // Calibrate 270MHz in high mode - for (int j = 0; j < CALIBRATE_RBWS-1; j++) { + for (int j = 0; j < CALIBRATE_RBWS; j++) { SetRBW(power_rbw[j]); test_prepare(i); test_acquire(i); // Acquire test @@ -1431,20 +1433,17 @@ void calibrate(void) goto quit; } else SetPowerLevel(last_peak_level); + chThdSleepMilliseconds(1000); } -done: ili9341_set_foreground(BRIGHT_COLOR_GREEN); ili9341_drawstring_7x13("Calibration complete", 30, 120); quit: ili9341_drawstring_7x13("Touch screen to continue", 30, 140); wait_user(); + ili9341_clear_screen(); in_selftest = false; sweep_mode = SWEEP_ENABLE; - trace[TRACE_STORED].enabled = false; - set_trace_refpos(0, NGRIDY - (-10) / get_trace_scale(0)); - set_trace_refpos(1, NGRIDY - (-10) / get_trace_scale(0)); - set_trace_refpos(2, NGRIDY - (-10) / get_trace_scale(0)); set_refer_output(0); reset_settings(M_LOW); } diff --git a/si4432.c b/si4432.c index 12e8890..0042f32 100644 --- a/si4432.c +++ b/si4432.c @@ -168,39 +168,49 @@ void SI4432_Receive(void) } -// First entry of each triple is RBW in khz times 10, so 377 = 37.7khz // User asks for an RBW of WISH, go through table finding the last triple // for which WISH is greater than the first entry, use those values, // Return the first entry of the following triple for the RBW actually achieved -static const short RBW_choices[] = { // Each triple is: ndec, fils, WISH*10 - 0, 5,1,26, 5,2,28, 5,3,31, 5,4,32, 5,5,37, 5,6,42, 5,7, - 45,4,1, 49,4,2, 54,4,3, 59,4,4, 61,4,5, 72,4,6, 82,4,7, - 88,3,1, 95,3,2, 106,3,3, 115,3,4, 121,3,5, 142,3,6, 162,3,7, - 175,2,1, 189,2,2, 210,2,3, 227,2,4, 240,2,5, 282,2,6, 322,2,7, - 347,1,1, 377,1,2, 417,1,3, 452,1,4, 479,1,5, 562,1,6, 641,1,7, - 692,0,1, 752,0,2, 832,0,3, 900,0,4, 953,0,5, 1121,0,6, 1279,0,7, - 1379,1,4, 1428,1,5, 1678,1,9, 1811,0,15, 1915,0,1, 2251,0,2, 2488,0,3, - 2693,0,4, 2849,0,8, 3355,0,9, 3618,0,10, 4202,0,11, 4684,0,12, 5188,0,13, - 5770,0,14, 6207 +static const short RBW_choices[] = { // Each quadrupple is: ndec, fils, WISH*10, corr*10 + 5,1,26,5, 5,2,28,5, 5,3,31,5, 5,4,32,5, 5,5,37,5, 5,6,42,5, + 5,7,45,5, 4,1,49,5, + 4,2,54,5, 4,3,59,5, 4,4,61,5, 4,5,72,5, 4,6,82,5, 4,7,88,5, + 3,1,95,5, 3,2,106,5, 3,3,115,5, 3,4,121,5, 3,5,142,5, 3,6,162,5, + 3,7,175,5, 2,1,189,5, 2,2,210,5, 2,3,227,5, 2,4,240,5, 2,5,282,5, + 2,6,322,5, 2,7,347,5, 1,1,377,5, 1,2,417,5, 1,3,452,5, 1,4,479,5, + 1,5,562,5, 1,6,641,5, 1,7,692,5, 0,1,752,5, 0,2,832,5, 0,3,900,5, + 0,4,953,5, 0,5,1121,5, 0,6,1279,5, 0,7,1379,5, 1,4,1428,5, 1,5,1678,5, + 1,9,1811,5, 0,15,1915,5, 0,1,2251,5, 0,2,2488,5, 0,3,2693,5, + 0,4,2849,5, 0,8,3355,5, 0,9,3618,5, 0,10,4202,5, 0,11,4684,5, 0,12,5188,5, + 0,13,5770,5, 0,14,6207,5 }; +static float SI4432_RSSI_correction = 0; + float SI4432_SET_RBW(float w) { uint8_t dwn3=0; int32_t WISH = (uint32_t)(w * 10.0); uint8_t ndec, fils, i; if (WISH > 6207) WISH=6207; // Final value in RBW_choices[] if (WISH > 1379) dwn3 = 1 ; - for (i=3; i= (sizeof RBW_choices) / 2 ) + return 0; + return(RBW_choices[i*4-1]); +} void SI4432_Set_Frequency ( long Freq ) { int hbsel; From 6a4daa8c941e87f24dd1dccd5da00e64a7558614 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 13:27:47 +0200 Subject: [PATCH 044/193] Lock DMA stuff to prevent deadlock --- ili9341.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ili9341.c b/ili9341.c index f423b19..61cb305 100644 --- a/ili9341.c +++ b/ili9341.c @@ -452,6 +452,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) // Skip SPI rx buffer while (SPI_RX_IS_NOT_EMPTY) (void)SPI_READ_DATA; // Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit) + chSysLock(); dmaStreamSetMemory0(dmarx, rgbbuf); dmaStreamSetTransactionSize(dmarx, data_size); dmaStreamSetMode(dmarx, rxdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | @@ -467,6 +468,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) // Wait DMA completion dmaWaitCompletion(dmatx); dmaWaitCompletion(dmarx); + chSysUnlock(); CS_HIGH; // Parce recived data From 92119ca10163482b652f192ad071f8858195f5f5 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 14:14:10 +0200 Subject: [PATCH 045/193] High outputlevels and waterfall fix --- ili9341.c | 10 ++++++++++ plot.c | 8 +++++--- ui_sa.c | 32 +++++++++++++++++++++----------- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/ili9341.c b/ili9341.c index 61cb305..7417ef7 100644 --- a/ili9341.c +++ b/ili9341.c @@ -467,7 +467,17 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) dmaStreamEnable(dmarx); // Wait DMA completion dmaWaitCompletion(dmatx); +#if 1 + int count = 0; + while ((dmarx)->channel->CNDTR > 0U) { + chThdSleepMicroseconds(100); + if (count++ > 10) + break; + } + dmaStreamDisable(dmarx); +#else dmaWaitCompletion(dmarx); +#endif; chSysUnlock(); CS_HIGH; diff --git a/plot.c b/plot.c index 045fcff..555d553 100644 --- a/plot.c +++ b/plot.c @@ -1469,11 +1469,13 @@ draw_all_cells(bool flush_markmap) clear_markmap(); } #ifdef __SCROLL__ + int w = area_width - 5; + if (w < 5) w = 5; if (waterfall) { for (m = 226; m >= HEIGHT+3; m -= 1) { // Scroll down uint16_t *buf = &spi_buffer[0]; - ili9341_read_memory(5*5, m, 290, 1, 290, buf); - ili9341_bulk(5*5,m+1, 290,1); + ili9341_read_memory(5*5, m, w, 1, w, buf); + ili9341_bulk(5*5,m+1, w,1); } for (int i=0; i<290; i++) { // Add new topline #if 0 @@ -1510,7 +1512,7 @@ draw_all_cells(bool flush_markmap) #endif spi_buffer[i] = RGB565(r,g,b); } - ili9341_bulk(5*5,HEIGHT+3, 290,1); + ili9341_bulk(5*5,HEIGHT+3, w,1); } #endif } diff --git a/ui_sa.c b/ui_sa.c index 6b06b7a..b417646 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -318,9 +318,6 @@ static void menu_reffer_cb(int item, uint8_t data) // draw_cal_status(); } -//const int menu_drive_value[]={5,10,15,20}; -const char *menu_drive_text[]={"-15dBm","-10dBm","-5dBm","0dBm","5dBm","10dBm","15dBm","20dBm"}; - static void menu_drive_cb(int item, uint8_t data) { (void)item; @@ -523,6 +520,11 @@ static void menu_pause_cb(int item, uint8_t data) // draw_cal_status(); } +//const int menu_drive_value[]={5,10,15,20}; +const char *menu_drive_text[]={"-24dBm","-20dBm","-16dBm","-12dBm"," 6dBm"," 10dBm"," 14dBm"," 18dBm"}; + + + // ===[MENU DEFINITION]========================================================= static const menuitem_t menu_drive[] = { @@ -530,18 +532,26 @@ static const menuitem_t menu_drive[] = { { MT_CALLBACK, 2, " 15dBm", menu_drive_cb}, { MT_CALLBACK, 1, " 10dBm", menu_drive_cb}, { MT_CALLBACK, 0, " 5dBm", menu_drive_cb}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_drive_wide2[] = { + { MT_FORM | MT_CALLBACK, 2, "-16dBm", menu_drive_cb }, + { MT_FORM | MT_CALLBACK, 1, "-20dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 0, "-24dBm", menu_drive_cb}, + { MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL }, + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel +}; + static const menuitem_t menu_drive_wide[] = { - { MT_FORM | MT_CALLBACK, 6, " 15dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 7, " 18dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 6, " 14dBm", menu_drive_cb}, { MT_FORM | MT_CALLBACK, 5, " 10dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 4, " 5dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 2, " -5dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 1, "-10dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 0, "-15dBm", menu_drive_cb}, - { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_FORM | MT_CALLBACK, 4, " 6dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 3, "-12dBm", menu_drive_cb}, + { MT_FORM | MT_SUBMENU, 255, S_RARROW" MORE", menu_drive_wide2}, + { MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -939,7 +949,7 @@ static void menu_item_modify_attribute( mark = true; } - } else if (menu == menu_drive || menu == menu_drive_wide) { + } else if (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2) { if (menu[item].data == setting_drive){ mark = true; } From 01a665f306966343a63eca479ffdbe7251b321ac Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 15:55:56 +0200 Subject: [PATCH 046/193] Powerlevels, spur table and marker menu update --- sa_core.c | 29 +++++++++++++++++++++++------ ui.c | 4 ++++ ui_sa.c | 6 +++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/sa_core.c b/sa_core.c index 495ff13..a75253b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -606,12 +606,28 @@ search_maximum(int m, int center, int span) } //static int spur_old_stepdelay = 0; -static const unsigned int spur_IF = 433900000; -static const unsigned int spur_alternate_IF = 434100000; +static const unsigned int spur_IF = 433800000; +static const unsigned int spur_alternate_IF = 434000000; static const int spur_table[] = { - 470000, - 780000, + 870000, + 970000, + 1460000, + 1610000, + 1840000, + 2840000, + 2890000, + 2970000, + 4780000, + 4810000, + 4850000, + 4880000, + 8100000, + 8140000, + 10870000, + 14880000, +#ifdef IF_AT_4339 + 780000, 830000, 880000, 949000, @@ -639,13 +655,14 @@ static const int spur_table[] = 11420000, 14880000, 16820000, +#endif }; int avoid_spur(int f) { int window = ((int)actual_rbw ) * 1000*2; - if (window < 50000) - window = 50000; +// if (window < 50000) +// window = 50000; if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0) return(false); for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { diff --git a/ui.c b/ui.c index 01467da..874a530 100644 --- a/ui.c +++ b/ui.c @@ -126,6 +126,7 @@ static void choose_active_marker(void); static void menu_move_back(void); static void menu_push_submenu(const menuitem_t *submenu); +static const menuitem_t menu_marker_type[]; static int btn_check(void) { @@ -842,6 +843,9 @@ menu_marker_sel_cb(int item, uint8_t data) markers[item].enabled = M_TRACKING_ENABLED; // default tracking enabled active_marker_select(item); } + if (markers[item].enabled) + menu_push_submenu(menu_marker_type); + } else if (item == 4) { /* all off */ for (t = 0; t < MARKERS_MAX; t++) markers[t].enabled = M_DISABLED; diff --git a/ui_sa.c b/ui_sa.c index b417646..c509c52 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -529,9 +529,9 @@ const char *menu_drive_text[]={"-24dBm","-20dBm","-16dBm","-12dBm"," 6dBm"," 10 static const menuitem_t menu_drive[] = { { MT_CALLBACK, 3, " 20dBm", menu_drive_cb}, - { MT_CALLBACK, 2, " 15dBm", menu_drive_cb}, - { MT_CALLBACK, 1, " 10dBm", menu_drive_cb}, - { MT_CALLBACK, 0, " 5dBm", menu_drive_cb}, + { MT_CALLBACK, 2, " 16dBm", menu_drive_cb}, + { MT_CALLBACK, 1, " 12dBm", menu_drive_cb}, + { MT_CALLBACK, 0, " 8dBm", menu_drive_cb}, { MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 495063f5bf273d7ff0d0a76327e0dfbdba07cde9 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 19:19:23 +0200 Subject: [PATCH 047/193] First experiment with span in output mode --- main.c | 6 +- sa_core.c | 241 ++++++++++++++++++++++++++++-------------------------- si4432.c | 18 +++- ui_sa.c | 2 + 4 files changed, 149 insertions(+), 118 deletions(-) diff --git a/main.c b/main.c index a0fd3ae..f9d28d7 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,4 @@ /* - * Copyright (c) 2016-2017, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com * All rights reserved. * * This is free software; you can redistribute it and/or modify @@ -116,7 +115,7 @@ const char *info_about[]={ "Platform: " PLATFORM_NAME, 0 // sentinel }; - +extern int dirty; static THD_WORKING_AREA(waThread1, 900); static THD_FUNCTION(Thread1, arg) { @@ -126,7 +125,8 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) { - completed = sweep(true); + if (dirty) + completed = sweep(true); sweep_mode&=~SWEEP_ONCE; } else if (sweep_mode & SWEEP_SELFTEST) { self_test(); // call from lowest level to save stack space diff --git a/sa_core.c b/sa_core.c index a75253b..649f75b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -444,6 +444,10 @@ void setFreq(int V, unsigned long freq) { SI4432_Sel = V; if (old_freq[V] != freq) { + if (V == 0) { + V = -V; + V = -V; + } SI4432_Set_Frequency(freq); old_freq[V] = freq; } @@ -685,7 +689,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) long local_IF; if (MODE_HIGH(setting_mode)) local_IF = 0; - else if (avoid_spur(f)) + else if (setting_mode == M_LOW && avoid_spur(f)) local_IF = spur_alternate_IF; else local_IF = frequency_IF; @@ -698,7 +702,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) if (local_IF) { setFreq (0, local_IF); } - if (setting_modulation == MO_AM) { + if (MODE_OUTPUT(setting_mode) && setting_modulation == MO_AM) { int p = setting_attenuate * 2 + modulation_counter; PE4302_Write_Byte(p); if (modulation_counter == 3) @@ -706,7 +710,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) else modulation_counter++; chThdSleepMicroseconds(250); - } else if (setting_modulation == MO_NFM || setting_modulation == MO_WFM ) { + } else if (MODE_OUTPUT(setting_mode) && (setting_modulation == MO_NFM || setting_modulation == MO_WFM )) { SI4432_Sel = 1; SI4432_Write_Byte(0x79, modulation_counter); // Use frequency hopping channel for FM modulation if (modulation_counter == 3) @@ -719,16 +723,22 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) int t = 0; do { int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw)); - if (tracking) + if (MODE_INPUT(setting_mode) && tracking) setFreq (0, local_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible +#if 0 + if (lf >11000000 || lf < 9000000) { + lf = lf; + break; + } +#endif setFreq (1, local_IF + lf); - if (MODE_OUTPUT(setting_mode)) + if (MODE_OUTPUT(setting_mode)) // No substepping in output mode return(0); float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+setting_attenuate; if (RSSI < subRSSI) RSSI = subRSSI; t++; - if ((operation_requested && break_on_operation ) || (MODE_OUTPUT(setting_mode))) // output modes do not step. + if (operation_requested && break_on_operation) // output modes do not step. break; // abort } while (t < vbwSteps); return(RSSI); @@ -747,70 +757,70 @@ static bool sweep(bool break_on_operation) temppeakLevel = -150; float temp_min_level = 100; // spur_old_stepdelay = 0; -//again: + //again: for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking); // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; - -// if (setting_spur == 1) { // First pass -// temp_t[i] = RSSI; -// continue; // Skip all other processing -// } -// if (setting_spur == -1) // Second pass -// RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes - temp_t[i] = RSSI; - if (setting_subtract_stored) { - RSSI = RSSI - stored_t[i] ; - } - // stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace - if (scandirty || setting_average == AV_OFF) { - actual_t[i] = RSSI; - age[i] = 0; - } else { - switch(setting_average) { - case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; - case AV_MAX_HOLD: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; - case AV_MAX_DECAY: - if (actual_t[i] < RSSI) { - actual_t[i] = RSSI; - age[i] = 0; - } else { - if (age[i] > setting_decay) - actual_t[i] -= 0.5; - else - age[i] += 1; + if (MODE_INPUT(setting_mode)) { + // if (setting_spur == 1) { // First pass + // temp_t[i] = RSSI; + // continue; // Skip all other processing + // } + // if (setting_spur == -1) // Second pass + // RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes + temp_t[i] = RSSI; + if (setting_subtract_stored) { + RSSI = RSSI - stored_t[i] ; + } + // stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace + if (scandirty || setting_average == AV_OFF) { + actual_t[i] = RSSI; + age[i] = 0; + } else { + switch(setting_average) { + case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; + case AV_MAX_HOLD: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; + case AV_MAX_DECAY: + if (actual_t[i] < RSSI) { + actual_t[i] = RSSI; + age[i] = 0; + } else { + if (age[i] > setting_decay) + actual_t[i] -= 0.5; + else + age[i] += 1; + } + break; + case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; + case AV_16: actual_t[i] = (actual_t[i]*15 + RSSI) / 16.0; break; } - break; - case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; - case AV_16: actual_t[i] = (actual_t[i]*15 + RSSI) / 16.0; break; } - } #if 1 -// START_PROFILE - if (i == 0) { - cur_max = 0; // Always at least one maximum - temppeakIndex = 0; - temppeakLevel = actual_t[i]; - max_index[0] = 0; - downslope = true; - } - if (downslope) { - if (temppeakLevel > actual_t[i]) { // Follow down - temppeakIndex = i; // Latest minimum + // START_PROFILE + if (i == 0) { + cur_max = 0; // Always at least one maximum + temppeakIndex = 0; temppeakLevel = actual_t[i]; - } else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found - temppeakIndex = i; // This is now the latest maximum - temppeakLevel = actual_t[i]; - downslope = false; + max_index[0] = 0; + downslope = true; } - } else { - if (temppeakLevel < actual_t[i]) { // Follow up - temppeakIndex = i; - temppeakLevel = actual_t[i]; - } else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found + if (downslope) { + if (temppeakLevel > actual_t[i]) { // Follow down + temppeakIndex = i; // Latest minimum + temppeakLevel = actual_t[i]; + } else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found + temppeakIndex = i; // This is now the latest maximum + temppeakLevel = actual_t[i]; + downslope = false; + } + } else { + if (temppeakLevel < actual_t[i]) { // Follow up + temppeakIndex = i; + temppeakLevel = actual_t[i]; + } else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found int j = 0; // Insertion index while (j= temppeakLevel) // Find where to insert @@ -819,20 +829,21 @@ static bool sweep(bool break_on_operation) int k = MAX_MAX-1; while (k > j) { // Shift to make room for max max_index[k] = max_index[k-1]; -// maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging + // maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging k--; } max_index[j] = temppeakIndex; -// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging + // maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging if (cur_max < MAX_MAX) { cur_max++; } -//STOP_PROFILE + //STOP_PROFILE } temppeakIndex = i; // Latest minimum temppeakLevel = actual_t[i]; downslope = true; + } } } #else @@ -846,75 +857,77 @@ static bool sweep(bool break_on_operation) temp_min_level = actual_t[i]; #endif } -// if (setting_spur == 1) { -// setting_spur = -1; -// goto again; -// } else if (setting_spur == -1) -// setting_spur = 1; + // if (setting_spur == 1) { + // setting_spur = -1; + // goto again; + // } else if (setting_spur == -1) + // setting_spur = 1; if (scandirty) { scandirty = false; draw_cal_status(); } #if 1 - int i = 0; - int m = 0; - while (i < cur_max) { // For all maxima found + if (MODE_INPUT(setting_mode)) { + int i = 0; + int m = 0; + while (i < cur_max) { // For all maxima found + while (m < MARKERS_MAX) { + if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found + markers[m].index = max_index[i]; + markers[m].frequency = frequencies[markers[m].index]; + m++; + break; // Next maximum + } + m++; // Try next marker + } + i++; + } while (m < MARKERS_MAX) { - if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found - markers[m].index = max_index[i]; + if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found + markers[m].index = 0; // Enabled but no max markers[m].frequency = frequencies[markers[m].index]; - m++; - break; // Next maximum } m++; // Try next marker } - i++; - } - while (m < MARKERS_MAX) { - if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found - markers[m].index = 0; // Enabled but no max - markers[m].frequency = frequencies[markers[m].index]; - } - m++; // Try next marker - } - if (setting_measurement == M_IMD && markers[0].index > 10) { - markers[1].enabled = search_maximum(1, markers[0].index*2, 8); - markers[2].enabled = search_maximum(2, markers[0].index*3, 12); - markers[3].enabled = search_maximum(3, markers[0].index*4, 16); - } else if (setting_measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) { - int l = markers[0].index; - int r = markers[1].index; - if (r < l) { - l = markers[1].index; - r = markers[0].index; + if (setting_measurement == M_IMD && markers[0].index > 10) { + markers[1].enabled = search_maximum(1, markers[0].index*2, 8); + markers[2].enabled = search_maximum(2, markers[0].index*3, 12); + markers[3].enabled = search_maximum(3, markers[0].index*4, 16); + } else if (setting_measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) { + int l = markers[0].index; + int r = markers[1].index; + if (r < l) { + l = markers[1].index; + r = markers[0].index; + } + markers[2].enabled = search_maximum(2, l - (r-l), 10); + markers[3].enabled = search_maximum(3, r + (r-l), 10); } - markers[2].enabled = search_maximum(2, l - (r-l), 10); - markers[3].enabled = search_maximum(3, r + (r-l), 10); - } - peakIndex = max_index[0]; - peakLevel = actual_t[peakIndex]; - peakFreq = frequencies[peakIndex]; + peakIndex = max_index[0]; + peakLevel = actual_t[peakIndex]; + peakFreq = frequencies[peakIndex]; #else - int peak_marker = 0; - markers[peak_marker].enabled = true; - markers[peak_marker].index = peakIndex; - markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; + int peak_marker = 0; + markers[peak_marker].enabled = true; + markers[peak_marker].index = peakIndex; + markers[peak_marker].frequency = frequencies[markers[peak_marker].index]; #endif - min_level = temp_min_level; + min_level = temp_min_level; #if 0 // Auto ref level setting - int scale = get_trace_scale(2); - int rp = (NGRIDY - get_trace_refpos(2)) * scale; - if (scale > 0 && peakLevel > rp && peakLevel - min_level < 8 * scale ) { - SetRefpos((((int)(peakLevel/scale)) + 1) * scale); - } - if (scale > 0 && min_level < rp - 9*scale && peakLevel - min_level < 8 * scale ) { - int new_rp = (((int)((min_level + 9*scale)/scale)) - 1) * scale; - if (new_rp < rp) - SetRefpos(new_rp); - } + int scale = get_trace_scale(2); + int rp = (NGRIDY - get_trace_refpos(2)) * scale; + if (scale > 0 && peakLevel > rp && peakLevel - min_level < 8 * scale ) { + SetRefpos((((int)(peakLevel/scale)) + 1) * scale); + } + if (scale > 0 && min_level < rp - 9*scale && peakLevel - min_level < 8 * scale ) { + int new_rp = (((int)((min_level + 9*scale)/scale)) - 1) * scale; + if (new_rp < rp) + SetRefpos(new_rp); + } #endif + } // redraw_marker(peak_marker, FALSE); palSetPad(GPIOC, GPIOC_LED); return true; diff --git a/si4432.c b/si4432.c index 0042f32..9556736 100644 --- a/si4432.c +++ b/si4432.c @@ -131,6 +131,8 @@ byte SI4432_Read_Byte( byte ADR ) void SI4432_Reset(void) { int count = 0; + SI4432_Read_Byte ( 0x03 ); // Clear pending interrupts + SI4432_Read_Byte ( 0x04 ); // always perform a system reset (don't send 0x87) SI4432_Write_Byte( 0x07, 0x80); chThdSleepMilliseconds(50); @@ -225,7 +227,7 @@ void SI4432_Set_Frequency ( long Freq ) { int N = Freq / 10000000; Carrier = ( 4 * ( Freq - N * 10000000 )) / 625; int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 ); -#if 0 +#if 1 SI4432_Write_Byte ( 0x75, Freq_Band ); SI4432_Write_Byte ( 0x76, (Carrier>>8) & 0xFF ); SI4432_Write_Byte ( 0x77, Carrier & 0xFF ); @@ -266,6 +268,20 @@ float SI4432_RSSI(uint32_t i, int s) void SI4432_Sub_Init(void) { SI4432_Reset(); + + + //set VCO and PLL Only for SI4432 V2 + SI4432_Write_Byte(0x72, 0x1F); //write 0x1F to the Frequency Deviation register + SI4432_Write_Byte(0x5A, 0x7F); //write 0x7F to the VCO Current Trimming register + SI4432_Write_Byte(0x58, 0x80); //write 0xD7 to the ChargepumpCurrentTrimmingOverride register + SI4432_Write_Byte(0x59, 0x40); //write 0x40 to the Divider Current Trimming register + + //set the AGC + SI4432_Write_Byte(0x6A, 0x0B); //write 0x0B to the AGC Override 2 register + //set ADC reference voltage to 0.9V + SI4432_Write_Byte(0x68, 0x04); //write 0x04 to the Deltasigma ADC Tuning 2 register + SI4432_Write_Byte(0x1F, 0x03); //write 0x03 to the Clock Recovery Gearshift Override register + SI4432_Write_Byte(0x05, 0x0); SI4432_Write_Byte(0x06, 0x0); // Enable receiver chain diff --git a/ui_sa.c b/ui_sa.c index c509c52..3fb55e5 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -570,6 +570,7 @@ const menuitem_t menu_lowoutputmode[] = { { MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", NULL}, { MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", NULL}, { MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation}, + { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -579,6 +580,7 @@ const menuitem_t menu_highoutputmode[] = { { MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", NULL}, { MT_FORM | MT_SUBMENU, 0, "LEVEL: %s", menu_drive_wide}, { MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation}, + { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; From 993388625e19fbd332a4ca65c105652feedad30f Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 7 Apr 2020 14:34:15 +0200 Subject: [PATCH 048/193] Improved SI4432 setup and selftest for sample time and attenuator --- main.c | 2 +- sa_core.c | 158 +++++++++++++++++++++++++++++++++++------------------- si4432.c | 45 +++++++++------- ui_sa.c | 46 ++++++++++------ 4 files changed, 162 insertions(+), 89 deletions(-) diff --git a/main.c b/main.c index f9d28d7..0bb8ddf 100644 --- a/main.c +++ b/main.c @@ -125,7 +125,7 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) { - if (dirty) +// if (dirty) completed = sweep(true); sweep_mode&=~SWEEP_ONCE; } else if (sweep_mode & SWEEP_SELFTEST) { diff --git a/sa_core.c b/sa_core.c index 649f75b..9c1a802 100644 --- a/sa_core.c +++ b/sa_core.c @@ -13,7 +13,7 @@ int setting_rbw = 0; int setting_average = 0; int setting_show_stored = 0; int setting_subtract_stored = 0; -int setting_drive=1; // 0-3 , 3=+20dBm +int setting_drive=13; // 0-7 , 7=+20dBm, 3dB steps int setting_agc = true; int setting_lna = false; int setting_tracking = false; @@ -42,12 +42,12 @@ void reset_settings(int m) { setting_mode = m; setting_attenuate = 0; - setting_step_atten = 0; setting_rbw = 0; setting_average = 0; setting_show_stored = 0; setting_subtract_stored = 0; - setting_drive=0; // 0-3 , 3=+20dBm + setting_drive=13; + setting_step_atten = 0; // Only used in low output mode setting_agc = true; setting_lna = false; setting_tracking = false; @@ -70,7 +70,7 @@ void reset_settings(int m) SetRefpos(-10); break; case M_GENLOW: - setting_drive=1; // 0-3 , 3=+20dBm + setting_drive=8; minFreq = 0; maxFreq = 520000000; set_sweep_frequency(ST_CENTER, (int32_t) 10000000); @@ -84,6 +84,7 @@ void reset_settings(int m) SetRefpos(-30); break; case M_GENHIGH: + setting_drive=8; minFreq = 240000000; maxFreq = 960000000; set_sweep_frequency(ST_CENTER, (int32_t) 300000000); @@ -128,14 +129,7 @@ void set_measurement(int m) } void SetDrive(int d) { - setting_drive = (d & 3); - if (setting_mode == M_GENHIGH) { - if (!(d & 4)) - setting_step_atten = 1; - else - setting_step_atten = 0; - setting_drive = d; - } + setting_drive = d; dirty = true; } @@ -158,16 +152,16 @@ int GetMode(void) #define POWER_STEP 0 // Should be 5 dB but appearently it is lower -#define POWER_OFFSET 2 +#define POWER_OFFSET 12 #define SWITCH_ATTENUATION 29 int GetAttenuation(void) { if (setting_mode == M_GENLOW) { if (setting_step_atten) - return ( - (POWER_OFFSET + setting_attenuate - (setting_step_atten-1)*POWER_STEP + SWITCH_ATTENUATION)); + return ( -(POWER_OFFSET + setting_attenuate - (setting_step_atten-1)*POWER_STEP + SWITCH_ATTENUATION)); else - return ( -(POWER_OFFSET + setting_attenuate)); + return ( -POWER_OFFSET - setting_attenuate + (setting_drive & 7) * 3); } return(setting_attenuate); } @@ -176,24 +170,27 @@ int GetAttenuation(void) void SetAttenuation(int a) { if (setting_mode == M_GENLOW) { + setting_drive = 0; a = a + POWER_OFFSET; - if( a > - SWITCH_ATTENUATION + 3*POWER_STEP) { + if (a > 0) { + setting_drive++; + a = a - 3; + } + if (a > 0) { + setting_drive++; + a = a - 3; + } + if (a > 0) { + setting_drive++; + a = a - 3; + } + if (a > 0) + a = 0; + if( a > - SWITCH_ATTENUATION) { setting_step_atten = 0; } else { a = a + SWITCH_ATTENUATION; -#if 0 - if (a >= 2 * POWER_STEP) { - setting_step_atten = 3; // Max drive - a = a - 2 * POWER_STEP; - } else if (a >= POWER_STEP ) { - setting_step_atten = 2; // Max drive - a = a - POWER_STEP; - } else { - setting_step_atten = 1; - } -#else - setting_step_atten = 1; // drive level is unpredictable -#endif + setting_step_atten = 1; } a = -a; } else { @@ -388,21 +385,14 @@ void SetMode(int m) void apply_settings(void) { if (setting_step_delay == 0){ - if (MODE_LOW(setting_mode)) { - if (actual_rbw >300.0) actualStepDelay = 400; - else if (actual_rbw >100.0) actualStepDelay = 500; - else if (actual_rbw > 30.0) actualStepDelay = 900; - else if (actual_rbw > 10.0) actualStepDelay = 900; - else if (actual_rbw > 3.0) actualStepDelay = 1000; - else actualStepDelay = 1500; - } else { - if (actual_rbw >300.0) actualStepDelay = 900; - else if (actual_rbw >100.0) actualStepDelay = 900; - else if (actual_rbw > 30.0) actualStepDelay = 900; - else if (actual_rbw > 10.0) actualStepDelay = 1800; - else if (actual_rbw > 3.0) actualStepDelay = 6000; - else actualStepDelay = 8000; - } + if (actual_rbw >142.0) actualStepDelay = 350; + else if (actual_rbw > 75.0) actualStepDelay = 450; + else if (actual_rbw > 56.0) actualStepDelay = 600; + else if (actual_rbw > 37.0) actualStepDelay = 800; + else if (actual_rbw > 18.0) actualStepDelay = 1100; + else if (actual_rbw > 9.0) actualStepDelay = 2000; + else if (actual_rbw > 5.0) actualStepDelay = 3500; + else actualStepDelay = 6000; } else actualStepDelay = setting_step_delay; PE4302_Write_Byte(setting_attenuate * 2); @@ -501,15 +491,14 @@ case M_GENLOW: // Mixed output from 0 SI4432_Sel = 0; if (setting_step_atten) { SetSwitchReceive(); - SI4432_Transmit(setting_step_atten-1); } else { SetSwitchTransmit(); - SI4432_Transmit(0); // To prevent damage to the BPF always set low drive } + SI4432_Transmit(setting_drive); // Not to overdrive the mixer SI4432_Sel = 1; SetSwitchReceive(); - SI4432_Transmit(setting_drive); + SI4432_Transmit(13); // Fix LO drive a 10dBm break; case M_GENHIGH: // Direct output from 1 @@ -518,12 +507,12 @@ case M_GENHIGH: // Direct output from 1 SetSwitchReceive(); SI4432_Sel = 1; - if (setting_step_atten) { + if (setting_drive < 8) { SetSwitchReceive(); } else { SetSwitchTransmit(); } - SI4432_Transmit(setting_drive & 3); + SI4432_Transmit(setting_drive); break; } @@ -764,6 +753,10 @@ static bool sweep(bool break_on_operation) // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; + if (MODE_OUTPUT(setting_mode)) { + osalThreadSleepMilliseconds(10); + } + if (MODE_INPUT(setting_mode)) { // if (setting_spur == 1) { // First pass // temp_t[i] = RSSI; @@ -1086,7 +1079,7 @@ enum { TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ, TPH_30MHZ }; -#define TEST_COUNT 14 +#define TEST_COUNT 16 static const struct { int kind; @@ -1109,8 +1102,10 @@ static const struct { {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 9 LPF cutoff {TC_END, 0, 0, 0, 0, 0, 0}, {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -80 }, // 11 Measure power level and noise - {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 13 Measure powerlevel and noise - {TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 14 Calibrate power high mode + {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 12 Measure powerlevel and noise + {TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 13 Calibrate power high mode + {TC_END, 0, 0, 0, 0, 0, 0}, + {TC_MEASURE, TP_30MHZ, 30, 1, -25, 30, -80 }, // 15 Measure RBW step time {TC_END, 0, 0, 0, 0, 0, 0}, }; @@ -1130,6 +1125,7 @@ static float test_value; static void test_acquire(int i) { + (void)i; pause_sweep(); #if 0 if (test_case[i].center < 300) @@ -1137,8 +1133,6 @@ static void test_acquire(int i) else setting_mode = M_HIGH; #endif - set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); - set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); SetAverage(4); sweep(false); sweep(false); @@ -1371,13 +1365,67 @@ common_silent: } trace[TRACE_STORED].enabled = true; SetRefpos(test_case[i].pass+10); + set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); + set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); draw_cal_status(); } extern void menu_autosettings_cb(int item); +extern float SI4432_force_RBW(int i); void self_test(void) { +#if 1 // RAttenuator test + int local_test_status; + in_selftest = true; + reset_settings(M_LOW); + int i = 14; // calibrate low mode power on 30 MHz; + test_prepare(i); + for (int j= 0; j < 32; j++ ) { + test_prepare(i); + SetAttenuation(j); + test_acquire(i); // Acquire test + local_test_status = test_validate(i); // Validate test + shell_printf("Target %d, actual %f\n\r",j, peakLevel); + } + return; +#else + +#if 0 // RBW step time search + int local_test_status; + in_selftest = true; + reset_settings(M_LOW); + int i = 14; // calibrate low mode power on 30 MHz; + test_prepare(i); + setting_step_delay = 6000; + for (int j= 0; j < 57; j++ ) { + setting_step_delay = setting_step_delay * 4/3; + setting_rbw = SI4432_force_RBW(j); + shell_printf("RBW = %d, ",setting_rbw); + test_prepare(i); + test_acquire(i); // Acquire test + local_test_status = test_validate(i); // Validate test + float saved_peakLevel = peakLevel; + if (peakLevel < -30) { + shell_printf("Peak level too low, abort\n\r"); + return; + } + + shell_printf("Start level = %f, ",peakLevel); + while (setting_step_delay > 100 && peakLevel > saved_peakLevel - 1) { + setting_step_delay = setting_step_delay * 3 / 4; +// test_prepare(i); +// shell_printf("RBW = %f\n\r",SI4432_force_RBW(j)); + test_acquire(i); // Acquire test + local_test_status = test_validate(i); // Validate test + // shell_printf("Step %f, %d",peakLevel, setting_step_delay); + } + setting_step_delay = setting_step_delay * 4 / 3; + shell_printf("End level = %f, step time = %d\n\r",peakLevel, setting_step_delay); + } + return; +#else + in_selftest = true; menu_autosettings_cb(0); for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting @@ -1408,6 +1456,8 @@ void self_test(void) set_refer_output(0); reset_settings(M_LOW); in_selftest = false; +#endif +#endif } void reset_calibration(void) diff --git a/si4432.c b/si4432.c index 9556736..83c2e01 100644 --- a/si4432.c +++ b/si4432.c @@ -145,12 +145,14 @@ void SI4432_Reset(void) void SI4432_Transmit(int d) { int count = 0; - SI4432_Write_Byte(0x6D, (byte) (0x1C+d)); + SI4432_Write_Byte(0x6D, (byte) (0x18+(d & 7))); if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 2) return; // Already in transmit mode - chThdSleepMilliseconds(10); - SI4432_Write_Byte( 0x07, 0x0b); chThdSleepMilliseconds(20); + SI4432_Write_Byte( 0x07, 0x03); + chThdSleepMilliseconds(20); + SI4432_Write_Byte( 0x07, 0x0b); + chThdSleepMilliseconds(30); while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 2) { chThdSleepMilliseconds(10); } @@ -161,9 +163,11 @@ void SI4432_Receive(void) int count = 0; if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 1) return; // Already in receive mode - chThdSleepMilliseconds(10); - SI4432_Write_Byte( 0x07, 0x07); chThdSleepMilliseconds(20); + SI4432_Write_Byte( 0x07, 0x03); + chThdSleepMilliseconds(20); + SI4432_Write_Byte( 0x07, 0x07); + chThdSleepMilliseconds(30); while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 1) { chThdSleepMilliseconds(5); } @@ -174,17 +178,17 @@ void SI4432_Receive(void) // for which WISH is greater than the first entry, use those values, // Return the first entry of the following triple for the RBW actually achieved static const short RBW_choices[] = { // Each quadrupple is: ndec, fils, WISH*10, corr*10 - 5,1,26,5, 5,2,28,5, 5,3,31,5, 5,4,32,5, 5,5,37,5, 5,6,42,5, - 5,7,45,5, 4,1,49,5, - 4,2,54,5, 4,3,59,5, 4,4,61,5, 4,5,72,5, 4,6,82,5, 4,7,88,5, - 3,1,95,5, 3,2,106,5, 3,3,115,5, 3,4,121,5, 3,5,142,5, 3,6,162,5, - 3,7,175,5, 2,1,189,5, 2,2,210,5, 2,3,227,5, 2,4,240,5, 2,5,282,5, - 2,6,322,5, 2,7,347,5, 1,1,377,5, 1,2,417,5, 1,3,452,5, 1,4,479,5, - 1,5,562,5, 1,6,641,5, 1,7,692,5, 0,1,752,5, 0,2,832,5, 0,3,900,5, - 0,4,953,5, 0,5,1121,5, 0,6,1279,5, 0,7,1379,5, 1,4,1428,5, 1,5,1678,5, - 1,9,1811,5, 0,15,1915,5, 0,1,2251,5, 0,2,2488,5, 0,3,2693,5, - 0,4,2849,5, 0,8,3355,5, 0,9,3618,5, 0,10,4202,5, 0,11,4684,5, 0,12,5188,5, - 0,13,5770,5, 0,14,6207,5 + 5,1,26,0, 5,2,28,0, 5,3,31,0, 5,4,32,0, 5,5,37,0, 5,6,42,10, + 5,7,45,10, 4,1,49,10, + 4,2,54,10, 4,3,59,10, 4,4,61,10, 4,5,72,10, 4,6,82,10, 4,7,88,10, + 3,1,95,10, 3,2,106,5, 3,3,115,0, 3,4,121,0, 3,5,142,0, 3,6,162,10, + 3,7,175,10, 2,1,189,10, 2,2,210,10, 2,3,227,10, 2,4,240,10, 2,5,282,5, + 2,6,322,10, 2,7,347,10, 1,1,377,10, 1,2,417,10, 1,3,452,10, 1,4,479,5, + 1,5,562,10, 1,6,641,10, 1,7,692,10, 0,1,752,10, 0,2,832,10, 0,3,900,5, + 0,4,953,10, 0,5,1121,10, 0,6,1279,10, 0,7,1379,5, 1,4,1428,0, 1,5,1678,-10, + 1,9,1811,65, 0,15,1915,120, 0,1,2251,-5, 0,2,2488,0, 0,3,2693,-5, + 0,4,2849,0, 0,8,3355,30, 0,9,3618,60, 0,10,4202,25, 0,11,4684,25, 0,12,5188,35, + 0,13,5770,35, 0,14,6207,35 }; static float SI4432_RSSI_correction = 0; @@ -203,7 +207,12 @@ float SI4432_SET_RBW(float w) { SI4432_RSSI_correction = RBW_choices[i]/10.0; uint8_t BW = (dwn3 << 7) | (ndec << 4) | fils ; SI4432_Write_Byte(0x1C , BW ) ; - return ((float)WISH / 10.0) ; + return (((float)WISH) / 10.0) ; +} + +float SI4432_force_RBW(int i) +{ + return(SI4432_SET_RBW((float)(RBW_choices[i*4+2]/10.0))); } float SI4432_RBW_table(int i){ @@ -255,7 +264,7 @@ float SI4432_RSSI(uint32_t i, int s) RSSI_RAW = (unsigned char)SI4432_Read_Byte( 0x26 ) ; // if (MODE_INPUT(setting_mode) && RSSI_RAW == 0) // SI4432_Init(); - float dBm = (RSSI_RAW-240)/2.0; + float dBm = (RSSI_RAW-240)/2.0 - SI4432_RSSI_correction; #ifdef __SIMULATION__ dBm = Simulated_SI4432_RSSI(i,s); #endif diff --git a/ui_sa.c b/ui_sa.c index 3fb55e5..37940f9 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -521,35 +521,49 @@ static void menu_pause_cb(int item, uint8_t data) } //const int menu_drive_value[]={5,10,15,20}; -const char *menu_drive_text[]={"-24dBm","-20dBm","-16dBm","-12dBm"," 6dBm"," 10dBm"," 14dBm"," 18dBm"}; +const char *menu_drive_text[]={"-30dBm","-27dBm","-24dBm","-21dBm","-18dBm","-15dBm","-12dBm"," -9dBm", " -6dBm"," -3dBm"," 0dBm"," 3dBm"," 6dBm"," 10dBm"," 14dBm"," 18dBm"}; // ===[MENU DEFINITION]========================================================= static const menuitem_t menu_drive[] = { - { MT_CALLBACK, 3, " 20dBm", menu_drive_cb}, - { MT_CALLBACK, 2, " 16dBm", menu_drive_cb}, - { MT_CALLBACK, 1, " 12dBm", menu_drive_cb}, - { MT_CALLBACK, 0, " 8dBm", menu_drive_cb}, + { MT_CALLBACK, 7, " 20dBm", menu_drive_cb}, + { MT_CALLBACK, 6, " 16dBm", menu_drive_cb}, + { MT_CALLBACK, 5, " 12dBm", menu_drive_cb}, + { MT_CALLBACK, 4, " 8dBm", menu_drive_cb}, { MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_drive_wide2[] = { - { MT_FORM | MT_CALLBACK, 2, "-16dBm", menu_drive_cb }, - { MT_FORM | MT_CALLBACK, 1, "-20dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 0, "-24dBm", menu_drive_cb}, +static const menuitem_t menu_drive_wide3[] = { + { MT_FORM | MT_CALLBACK, 5, "-15dBm", menu_drive_cb }, + { MT_FORM | MT_CALLBACK, 4, "-18dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 3, "-21dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 2, "-24dBm", menu_drive_cb }, + { MT_FORM | MT_CALLBACK, 1, "-27dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 0, "-30dBm", menu_drive_cb}, { MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL }, - { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_drive_wide2[] = { + { MT_FORM | MT_CALLBACK, 10, " 0dBm", menu_drive_cb }, + { MT_FORM | MT_CALLBACK, 9, " -3dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 8, " -6dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 7, " -9dBm", menu_drive_cb }, + { MT_FORM | MT_CALLBACK, 6, "-12dBm", menu_drive_cb}, + { MT_FORM | MT_SUBMENU, 255, S_RARROW" MORE", menu_drive_wide3}, + { MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL }, + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_drive_wide[] = { - { MT_FORM | MT_CALLBACK, 7, " 18dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 6, " 14dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 5, " 10dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 4, " 6dBm", menu_drive_cb}, - { MT_FORM | MT_CALLBACK, 3, "-12dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 15, " 18dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 14, " 14dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 13, " 10dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 12, " 6dBm", menu_drive_cb}, + { MT_FORM | MT_CALLBACK, 11, " 3dBm", menu_drive_cb}, { MT_FORM | MT_SUBMENU, 255, S_RARROW" MORE", menu_drive_wide2}, { MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel @@ -951,7 +965,7 @@ static void menu_item_modify_attribute( mark = true; } - } else if (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2) { + } else if (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3) { if (menu[item].data == setting_drive){ mark = true; } From 6422f9c5ed9bde1b90e1c42e4ee33791ffbdb164 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 7 Apr 2020 15:08:14 +0200 Subject: [PATCH 049/193] spur table updated and default IF corrected --- main.c | 2 +- sa_core.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 0bb8ddf..2c3e0e9 100644 --- a/main.c +++ b/main.c @@ -830,7 +830,7 @@ void load_default_properties(void) //current_props.magic = CONFIG_MAGIC; current_props._frequency0 = 0; // start = 0Hz current_props._frequency1 = 350000000; // end = 350MHz - current_props._frequency_IF= 433900000, + current_props._frequency_IF= 433800000, current_props._sweep_points = POINTS_COUNT; #ifdef VNA__ diff --git a/sa_core.c b/sa_core.c index 9c1a802..c3c96ef 100644 --- a/sa_core.c +++ b/sa_core.c @@ -603,7 +603,14 @@ static const unsigned int spur_IF = 433800000; static const unsigned int spur_alternate_IF = 434000000; static const int spur_table[] = { - 870000, + 420000, + 490000, + 510000, + 1600000, + 1840000, + 2960000, +/* + 870000, 970000, 1460000, 1610000, @@ -619,6 +626,7 @@ static const int spur_table[] = 8140000, 10870000, 14880000, +*/ #ifdef IF_AT_4339 780000, 830000, @@ -1375,7 +1383,7 @@ extern float SI4432_force_RBW(int i); void self_test(void) { -#if 1 // RAttenuator test +#if 0 // RAttenuator test int local_test_status; in_selftest = true; reset_settings(M_LOW); From e1d24a2b98afb14bf31d5af09579188062ab20e2 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 7 Apr 2020 16:56:05 +0200 Subject: [PATCH 050/193] Modulation repaired --- Makefile | 4 ++-- sa_core.c | 4 ++-- si4432.c | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index e16ea2e..341524d 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ # Compiler options here. ifeq ($(USE_OPT),) -# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage - USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/sa_core.c b/sa_core.c index c3c96ef..43c5654 100644 --- a/sa_core.c +++ b/sa_core.c @@ -761,7 +761,7 @@ static bool sweep(bool break_on_operation) // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; - if (MODE_OUTPUT(setting_mode)) { + if (MODE_OUTPUT(setting_mode) && setting_modulation == MO_NONE) { osalThreadSleepMilliseconds(10); } @@ -1495,7 +1495,7 @@ void calibrate(void) ili9341_drawstring_7x13("Calibration failed", 30, 120); goto quit; } else { - SetPowerLevel(-23); + SetPowerLevel(-22); // Should be -22.5dBm chThdSleepMilliseconds(1000); } } diff --git a/si4432.c b/si4432.c index 83c2e01..9f7edb9 100644 --- a/si4432.c +++ b/si4432.c @@ -406,25 +406,25 @@ void PE4302_shiftOut(uint8_t val) SPI2_SDI_HIGH; else SPI2_SDI_LOW; - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); SPI2_CLK_HIGH; - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); SPI2_CLK_LOW; - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); } } void PE4302_Write_Byte(unsigned char DATA ) { - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); SPI2_CLK_LOW; - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); PE4302_shiftOut(DATA); - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); CS_PE_HIGH; - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); CS_PE_LOW; - chThdSleepMicroseconds(PE4302_DELAY); +// chThdSleepMicroseconds(PE4302_DELAY); } From 2981beb9a0298bea8e11074324bf1c45917d1768 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 7 Apr 2020 21:38:34 +0200 Subject: [PATCH 051/193] Improved FM modulation --- ili9341.c | 4 ++-- sa_core.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ili9341.c b/ili9341.c index 7417ef7..4620adc 100644 --- a/ili9341.c +++ b/ili9341.c @@ -467,7 +467,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) dmaStreamEnable(dmarx); // Wait DMA completion dmaWaitCompletion(dmatx); -#if 1 +#if 0 int count = 0; while ((dmarx)->channel->CNDTR > 0U) { chThdSleepMicroseconds(100); @@ -477,7 +477,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out) dmaStreamDisable(dmarx); #else dmaWaitCompletion(dmarx); -#endif; +#endif chSysUnlock(); CS_HIGH; diff --git a/sa_core.c b/sa_core.c index 43c5654..908acfe 100644 --- a/sa_core.c +++ b/sa_core.c @@ -709,9 +709,19 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) chThdSleepMicroseconds(250); } else if (MODE_OUTPUT(setting_mode) && (setting_modulation == MO_NFM || setting_modulation == MO_WFM )) { SI4432_Sel = 1; - SI4432_Write_Byte(0x79, modulation_counter); // Use frequency hopping channel for FM modulation - if (modulation_counter == 3) - modulation_counter = 0; + int offset; + if (setting_modulation == MO_NFM ) { + offset = modulation_counter ; + SI4432_Write_Byte(0x73, (offset & 0xff )); // Use frequency hopping channel for FM modulation + SI4432_Write_Byte(0x74, ((offset >> 8) & 0x03 )); // Use frequency hopping channel for FM modulation + } + else { + offset = modulation_counter * 100; + SI4432_Write_Byte(0x73, (offset & 0xff )); // Use frequency hopping channel for FM modulation + SI4432_Write_Byte(0x74, ((offset >> 8) & 0x03 )); // Use frequency hopping channel for FM modulation + } + if (modulation_counter == 2) + modulation_counter = -2; else modulation_counter++; chThdSleepMicroseconds(250); From 8bd2b4f8991515267095443b8b0042fceaf38121 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 8 Apr 2020 08:45:25 +0200 Subject: [PATCH 052/193] Problems with drive level --- sa_core.c | 12 ++++++++---- si4432.c | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sa_core.c b/sa_core.c index 908acfe..8ec0bd4 100644 --- a/sa_core.c +++ b/sa_core.c @@ -13,7 +13,7 @@ int setting_rbw = 0; int setting_average = 0; int setting_show_stored = 0; int setting_subtract_stored = 0; -int setting_drive=13; // 0-7 , 7=+20dBm, 3dB steps +int setting_drive; // 0-7 , 7=+20dBm, 3dB steps int setting_agc = true; int setting_lna = false; int setting_tracking = false; @@ -46,7 +46,7 @@ void reset_settings(int m) setting_average = 0; setting_show_stored = 0; setting_subtract_stored = 0; - setting_drive=13; + setting_drive=12; setting_step_atten = 0; // Only used in low output mode setting_agc = true; setting_lna = false; @@ -494,11 +494,11 @@ case M_GENLOW: // Mixed output from 0 } else { SetSwitchTransmit(); } - SI4432_Transmit(setting_drive); // Not to overdrive the mixer + SI4432_Transmit(setting_drive); SI4432_Sel = 1; SetSwitchReceive(); - SI4432_Transmit(13); // Fix LO drive a 10dBm + SI4432_Transmit(12); // Fix LO drive a 10dBm break; case M_GENHIGH: // Direct output from 1 @@ -516,6 +516,10 @@ case M_GENHIGH: // Direct output from 1 break; } + SI4432_Sel = 1; + SI4432_Write_Byte(0x73, 0); // Back to nominal offset + SI4432_Write_Byte(0x74, 0); + } void update_rbw(void) diff --git a/si4432.c b/si4432.c index 9f7edb9..90ab674 100644 --- a/si4432.c +++ b/si4432.c @@ -278,12 +278,13 @@ void SI4432_Sub_Init(void) { SI4432_Reset(); - +#if 1 // Not sure if these add any value //set VCO and PLL Only for SI4432 V2 SI4432_Write_Byte(0x72, 0x1F); //write 0x1F to the Frequency Deviation register SI4432_Write_Byte(0x5A, 0x7F); //write 0x7F to the VCO Current Trimming register SI4432_Write_Byte(0x58, 0x80); //write 0xD7 to the ChargepumpCurrentTrimmingOverride register SI4432_Write_Byte(0x59, 0x40); //write 0x40 to the Divider Current Trimming register +#endif //set the AGC SI4432_Write_Byte(0x6A, 0x0B); //write 0x0B to the AGC Override 2 register From 46e09bc8faa5cdbf1780fd6862665884932ba764 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 8 Apr 2020 18:32:54 +0200 Subject: [PATCH 053/193] Various small improvements --- Makefile | 4 ++-- sa_core.c | 14 +++++++------- ui_sa.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 341524d..e16ea2e 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage -# USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/sa_core.c b/sa_core.c index 8ec0bd4..1ec7be5 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1,8 +1,8 @@ -// --------------------------------------------------- #include "SI4432.h" // comment out for simulation -int setting_mode = M_LOW; +int setting_mode = -1; // To force initialzation + int dirty = true; @@ -152,7 +152,7 @@ int GetMode(void) #define POWER_STEP 0 // Should be 5 dB but appearently it is lower -#define POWER_OFFSET 12 +#define POWER_OFFSET 20 #define SWITCH_ATTENUATION 29 int GetAttenuation(void) @@ -170,7 +170,7 @@ int GetAttenuation(void) void SetAttenuation(int a) { if (setting_mode == M_GENLOW) { - setting_drive = 0; + setting_drive = 8; // Start at lowest drive level; a = a + POWER_OFFSET; if (a > 0) { setting_drive++; @@ -385,9 +385,9 @@ void SetMode(int m) void apply_settings(void) { if (setting_step_delay == 0){ - if (actual_rbw >142.0) actualStepDelay = 350; - else if (actual_rbw > 75.0) actualStepDelay = 450; - else if (actual_rbw > 56.0) actualStepDelay = 600; + if (actual_rbw >142.0) actualStepDelay = 450; + else if (actual_rbw > 75.0) actualStepDelay = 550; + else if (actual_rbw > 56.0) actualStepDelay = 650; else if (actual_rbw > 37.0) actualStepDelay = 800; else if (actual_rbw > 18.0) actualStepDelay = 1100; else if (actual_rbw > 9.0) actualStepDelay = 2000; diff --git a/ui_sa.c b/ui_sa.c index 37940f9..b1806e7 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -528,10 +528,10 @@ const char *menu_drive_text[]={"-30dBm","-27dBm","-24dBm","-21dBm","-18dBm","-15 // ===[MENU DEFINITION]========================================================= static const menuitem_t menu_drive[] = { - { MT_CALLBACK, 7, " 20dBm", menu_drive_cb}, - { MT_CALLBACK, 6, " 16dBm", menu_drive_cb}, - { MT_CALLBACK, 5, " 12dBm", menu_drive_cb}, - { MT_CALLBACK, 4, " 8dBm", menu_drive_cb}, + { MT_CALLBACK, 15, " 20dBm", menu_drive_cb}, + { MT_CALLBACK, 14, " 16dBm", menu_drive_cb}, + { MT_CALLBACK, 13, " 12dBm", menu_drive_cb}, + { MT_CALLBACK, 12, " 8dBm", menu_drive_cb}, { MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 1f86864f9ae313778ff87f31373fdc16cda1b570 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 8 Apr 2020 19:17:17 +0200 Subject: [PATCH 054/193] Automatic attenuation added --- sa_core.c | 21 +++++++++++++++ ui_sa.c | 81 ++++++++++++++++++++++--------------------------------- 2 files changed, 53 insertions(+), 49 deletions(-) diff --git a/sa_core.c b/sa_core.c index 1ec7be5..7a718d9 100644 --- a/sa_core.c +++ b/sa_core.c @@ -8,6 +8,7 @@ int setting_mode = -1; // To force initialzation int dirty = true; int scandirty = true; int setting_attenuate = 0; +int setting_auto_attenuation; int setting_step_atten; int setting_rbw = 0; int setting_average = 0; @@ -45,6 +46,7 @@ void reset_settings(int m) setting_rbw = 0; setting_average = 0; setting_show_stored = 0; + setting_auto_attenuation = true; setting_subtract_stored = 0; setting_drive=12; setting_step_atten = 0; // Only used in low output mode @@ -68,6 +70,7 @@ void reset_settings(int m) set_sweep_frequency(ST_START, (int32_t) 0); set_sweep_frequency(ST_STOP, (int32_t) 350000000); SetRefpos(-10); + setting_attenuate = 30; break; case M_GENLOW: setting_drive=8; @@ -166,6 +169,12 @@ int GetAttenuation(void) return(setting_attenuate); } +void set_auto_attenuation(void) +{ + setting_auto_attenuation = true; + setting_attenuate = 30; + +} void SetAttenuation(int a) { @@ -202,6 +211,7 @@ void SetAttenuation(int a) a=31; // if (setting_attenuate == a) // return; + setting_auto_attenuation = false; setting_attenuate = a; dirty = true; } @@ -882,6 +892,17 @@ static bool sweep(bool break_on_operation) scandirty = false; draw_cal_status(); } + if (setting_mode == M_LOW && setting_auto_attenuation ) { + if (actual_t[max_index[0]] - setting_attenuate < -30 && setting_attenuate >= 10) { + setting_attenuate -= 10; + redraw_request |= REDRAW_CAL_STATUS; + dirty = true; // Must be above if(scandirty!!!!!) + } else if (actual_t[max_index[0]] - setting_attenuate > -20 && setting_attenuate <= 20) { + setting_attenuate += 10; + redraw_request |= REDRAW_CAL_STATUS; + dirty = true; // Must be above if(scandirty!!!!!) + } + } #if 1 if (MODE_INPUT(setting_mode)) { int i = 0; diff --git a/ui_sa.c b/ui_sa.c index b1806e7..c8036c2 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -13,6 +13,7 @@ void set_refer_output(int); int get_refer_output(void); void SetAttenuation(int); int GetAttenuation(void); +void set_auto_attenuation(void); void SetPowerLevel(int); void SetGenerate(int); void SetRBW(int); @@ -387,6 +388,13 @@ static void menu_measure_cb(int item, uint8_t data) // draw_cal_status(); } +static void menu_atten_cb(int item, uint8_t data) +{ + set_auto_attenuation(); + menu_move_back(); + ui_mode_normal(); +} + static void menu_storage_cb(int item, uint8_t data) { (void)item; @@ -609,16 +617,6 @@ static const menuitem_t menu_average[] = { { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; -#if 0 -static const menuitem_t menu_storage[] = { - { MT_CALLBACK, 0, "STORE", menu_storage_cb}, - { MT_CALLBACK, 1, "CLEAR", menu_storage_cb}, - { MT_CALLBACK, 2, "SUBTRACT", menu_storage_cb}, - { MT_CALLBACK, 3, "WATERFALL",menu_storage_cb}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; -#endif static const menuitem_t menu_rbw[] = { { MT_CALLBACK, 0, " AUTO", menu_rbw_cb}, @@ -650,6 +648,7 @@ static const menuitem_t menu_reffer2[] = { { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; + static const menuitem_t menu_reffer[] = { { MT_FORM | MT_CALLBACK, 0, "OFF" , menu_reffer_cb}, { MT_FORM | MT_CALLBACK, 1, "30MHz", menu_reffer_cb}, @@ -661,58 +660,42 @@ static const menuitem_t menu_reffer[] = { { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_acquire[] = { - { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, - { MT_KEYPAD, KM_ATTENUATION, "ATTEN", NULL}, - { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_SUBMENU,0, "CALC", menu_average}, +static const menuitem_t menu_atten[] = { + { MT_CALLBACK,0, "AUTO", menu_atten_cb}, + { MT_KEYPAD, KM_ATTENUATION, "MANUAL", NULL}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_acquire[] = { + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, + { MT_SUBMENU, 0, "ATTEN", menu_atten}, + { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_SUBMENU,0, "AVER", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel +}; + static const menuitem_t menu_acquirehigh[] = { - { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_SUBMENU,0, "CALC", menu_average}, + { MT_SUBMENU,0, "AVER", menu_average}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; static const menuitem_t menu_display[] = { - { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, - { MT_SUBMENU,0, "\2SCALE/\0DIV", menu_dBper}, - { MT_CALLBACK, 0, "STORE", menu_storage_cb}, - { MT_CALLBACK, 1, "CLEAR", menu_storage_cb}, - { MT_CALLBACK, 2, "SUBTRACT", menu_storage_cb}, - { MT_CALLBACK, 3, "WATERFALL",menu_storage_cb}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; - -#if 0 -static const menuitem_t menu_scale[] = { - { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, - { MT_SUBMENU,0, "\2SCALE/\0DIV", menu_dBper}, - { MT_KEYPAD, KM_ATTENUATION, "ATTEN", NULL}, - { MT_SUBMENU,0, "AVERAGE", menu_average}, - { MT_KEYPAD, 0, "\2SPUR\0REDUCT.", menu_spur_cb}, - { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, + { MT_SUBMENU, 0, "\2SCALE/\0DIV", menu_dBper}, + { MT_CALLBACK,0, "STORE", menu_storage_cb}, + { MT_CALLBACK,1, "CLEAR", menu_storage_cb}, + { MT_CALLBACK,2, "SUBTRACT", menu_storage_cb}, + { MT_CALLBACK,3, "WATERFALL",menu_storage_cb}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_scalehigh[] = { - { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, - { MT_SUBMENU,0, "\2SCALE/\0DIV", menu_dBper}, - { MT_SUBMENU,0, "AVERAGE", menu_average}, - { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; - -#endif - static const menuitem_t menu_stimulus[8] = { { MT_KEYPAD, KM_START, "START", NULL}, { MT_KEYPAD, KM_STOP, "STOP", NULL}, @@ -858,7 +841,7 @@ static const menuitem_t menu_mode[] = { #if 1 const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "ACQUIRE", menu_acquire}, - { MT_SUBMENU, 0, "SCAN", menu_stimulus}, + { MT_SUBMENU, 0, "FREQ", menu_stimulus}, { MT_SUBMENU, 0, "DISPLAY", menu_display}, { MT_SUBMENU, 0, "MARKER", menu_marker}, { MT_SUBMENU, 0, "MEASURE", menu_measure}, @@ -871,7 +854,7 @@ const menuitem_t menu_top[] = { const menuitem_t menu_tophigh[] = { { MT_SUBMENU, 0, "ACQUIRE", menu_acquirehigh}, - { MT_SUBMENU, 0, "SCAN", menu_stimulus}, + { MT_SUBMENU, 0, "FREQ", menu_stimulus}, { MT_SUBMENU, 0, "DISPLAY", menu_display}, { MT_SUBMENU, 0, "MARKER", menu_marker}, { MT_SUBMENU, 0, "MEASURE", menu_measure}, From e3d96b9beda24e7dec995aa81443d0b7936c077f Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 9 Apr 2020 08:21:33 +0200 Subject: [PATCH 055/193] Auto reflevel and auto attenuation added --- nanovna.h | 2 +- sa_core.c | 69 ++++++++++++++++++++++++++++++++++++++++--------------- ui_sa.c | 50 ++++++++++++++++++++++++++++++---------- 3 files changed, 89 insertions(+), 32 deletions(-) diff --git a/nanovna.h b/nanovna.h index d5ff1e4..86ef5ce 100644 --- a/nanovna.h +++ b/nanovna.h @@ -637,7 +637,7 @@ int get_waterfall(void); void toggle_tracking(void); void calibrate(void); void reset_calibration(void); -void SetRefpos(int); +void SetReflevel(int); void SetScale(int); void SetRBW(int); void SetRX(int); diff --git a/sa_core.c b/sa_core.c index 7a718d9..1cd63b6 100644 --- a/sa_core.c +++ b/sa_core.c @@ -17,6 +17,9 @@ int setting_subtract_stored = 0; int setting_drive; // 0-7 , 7=+20dBm, 3dB steps int setting_agc = true; int setting_lna = false; +int setting_auto_reflevel; +int setting_reflevel; +int setting_scale; int setting_tracking = false; int setting_modulation = MO_NONE; int setting_step_delay = 0; @@ -42,6 +45,8 @@ int in_selftest = false; void reset_settings(int m) { setting_mode = m; + SetScale(10); + SetReflevel(-10); setting_attenuate = 0; setting_rbw = 0; setting_average = 0; @@ -56,8 +61,9 @@ void reset_settings(int m) setting_modulation = MO_NONE; setting_step_delay = 0; setting_vbw = 0; + setting_auto_reflevel = true; // Must be after SetReflevel setting_decay=20; - setting_noise=20; + setting_noise=5; trace[TRACE_STORED].enabled = false; trace[TRACE_TEMP].enabled = false; @@ -69,7 +75,6 @@ void reset_settings(int m) maxFreq = 520000000; set_sweep_frequency(ST_START, (int32_t) 0); set_sweep_frequency(ST_STOP, (int32_t) 350000000); - SetRefpos(-10); setting_attenuate = 30; break; case M_GENLOW: @@ -84,7 +89,6 @@ void reset_settings(int m) maxFreq = 960000000; set_sweep_frequency(ST_START, (int32_t) minFreq); set_sweep_frequency(ST_STOP, (int32_t) maxFreq); - SetRefpos(-30); break; case M_GENHIGH: setting_drive=8; @@ -94,7 +98,6 @@ void reset_settings(int m) set_sweep_frequency(ST_SPAN, 0); break; } - SetScale(10); dirty = true; } @@ -119,7 +122,7 @@ void set_decay(int d) void set_noise(int d) { - if (d < 5 || d > 200) + if (d < 2 || d > 50) return; setting_noise = d; dirty = true; @@ -173,7 +176,11 @@ void set_auto_attenuation(void) { setting_auto_attenuation = true; setting_attenuate = 30; +} +void set_auto_reflevel(void) +{ + setting_auto_reflevel = true; } void SetAttenuation(int a) @@ -211,7 +218,6 @@ void SetAttenuation(int a) a=31; // if (setting_attenuate == a) // return; - setting_auto_attenuation = false; setting_attenuate = a; dirty = true; } @@ -371,20 +377,29 @@ int GetAGC(void) return(setting_agc); } -void SetRefpos(int level) +void SetReflevel(int level) { + setting_reflevel = (level / setting_scale) * setting_scale; set_trace_refpos(0, NGRIDY - level / get_trace_scale(0)); set_trace_refpos(1, NGRIDY - level / get_trace_scale(0)); set_trace_refpos(2, NGRIDY - level / get_trace_scale(0)); dirty = true; } +//int GetRefpos(void) { +// return (NGRIDY - get_trace_refpos(2)) * get_trace_scale(2); +//} + void SetScale(int s) { + setting_scale = s; set_trace_scale(0, s); set_trace_scale(1, s); set_trace_scale(2, s); } +//int GetScale(void) { +// return get_trace_refpos(2); +//} void SetMode(int m) { if (setting_mode == m) @@ -878,9 +893,10 @@ static bool sweep(bool break_on_operation) temppeakLevel = actual_t[i]; } } +#endif if (temp_min_level > actual_t[i]) temp_min_level = actual_t[i]; -#endif + } // if (setting_spur == 1) { // setting_spur = -1; @@ -892,13 +908,28 @@ static bool sweep(bool break_on_operation) scandirty = false; draw_cal_status(); } - if (setting_mode == M_LOW && setting_auto_attenuation ) { + if (setting_mode == M_LOW && setting_auto_attenuation && max_index[0] > 0) { if (actual_t[max_index[0]] - setting_attenuate < -30 && setting_attenuate >= 10) { - setting_attenuate -= 10; + setting_attenuate -= setting_scale; redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) } else if (actual_t[max_index[0]] - setting_attenuate > -20 && setting_attenuate <= 20) { - setting_attenuate += 10; + setting_attenuate += setting_scale; + redraw_request |= REDRAW_CAL_STATUS; + dirty = true; // Must be above if(scandirty!!!!!) + } + } + if (MODE_INPUT(setting_mode) && setting_auto_reflevel && max_index[0] > 0) { + if (actual_t[max_index[0]] > setting_reflevel - setting_scale/2) { + SetReflevel(setting_reflevel + setting_scale); + redraw_request |= REDRAW_CAL_STATUS; + dirty = true; // Must be above if(scandirty!!!!!) + } else if (temp_min_level < setting_reflevel - 9 * setting_scale && actual_t[max_index[0]] < setting_reflevel - setting_scale * 3 / 2) { + SetReflevel(setting_reflevel - setting_scale); + redraw_request |= REDRAW_CAL_STATUS; + dirty = true; // Must be above if(scandirty!!!!!) + } else if (temp_min_level > setting_reflevel - 9 * setting_scale + setting_scale * 3 / 2) { + SetReflevel(setting_reflevel + setting_scale); redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) } @@ -951,15 +982,15 @@ static bool sweep(bool break_on_operation) #endif min_level = temp_min_level; #if 0 // Auto ref level setting - int scale = get_trace_scale(2); - int rp = (NGRIDY - get_trace_refpos(2)) * scale; + int scale = setting_scale; + int rp = GetRepos(); if (scale > 0 && peakLevel > rp && peakLevel - min_level < 8 * scale ) { - SetRefpos((((int)(peakLevel/scale)) + 1) * scale); + SetReflevel((((int)(peakLevel/scale)) + 1) * scale); } if (scale > 0 && min_level < rp - 9*scale && peakLevel - min_level < 8 * scale ) { int new_rp = (((int)((min_level + 9*scale)/scale)) - 1) * scale; if (new_rp < rp) - SetRefpos(new_rp); + SetReflevel(new_rp); } #endif @@ -994,7 +1025,7 @@ void draw_cal_status(void) ili9341_set_background(DEFAULT_BG_COLOR); - int yMax = (NGRIDY - get_trace_refpos(0)) * get_trace_scale(0); + int yMax = setting_reflevel; plot_printf(buf, BLEN, "%ddB", yMax); buf[5]=0; if (level_is_calibrated()) @@ -1005,7 +1036,7 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); y += YSTEP*2; - plot_printf(buf, BLEN, "%ddB/",(int)get_trace_scale(0)); + plot_printf(buf, BLEN, "%ddB/",(int)setting_scale); ili9341_drawstring(buf, x, y); if (setting_attenuate) { @@ -1101,7 +1132,7 @@ void draw_cal_status(void) y = HEIGHT-7 + OFFSETY; - plot_printf(buf, BLEN, "%ddB", (int)(yMax - get_trace_scale(0) * NGRIDY)); + plot_printf(buf, BLEN, "%ddB", (int)(yMax - setting_scale * NGRIDY)); buf[5]=0; if (level_is_calibrated()) color = DEFAULT_FG_COLOR; @@ -1407,7 +1438,7 @@ common_silent: goto common; } trace[TRACE_STORED].enabled = true; - SetRefpos(test_case[i].pass+10); + SetReflevel(test_case[i].pass+10); set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); draw_cal_status(); diff --git a/ui_sa.c b/ui_sa.c index c8036c2..7734392 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -14,6 +14,8 @@ int get_refer_output(void); void SetAttenuation(int); int GetAttenuation(void); void set_auto_attenuation(void); +void set_auto_reflevel(void); + void SetPowerLevel(int); void SetGenerate(int); void SetRBW(int); @@ -32,7 +34,7 @@ void SetSubtractStorage(void); void toggle_waterfall(void); void SetMode(int); int GetMode(void); -void SetRefpos(int); +void SetReflevel(int); void SetScale(int); void AllDirty(void); void MenuDirty(void); @@ -49,6 +51,10 @@ extern int setting_lna; extern int setting_agc; extern int setting_decay; extern int setting_noise; +extern int setting_auto_reflevel; +extern int setting_auto_attenuation; +extern int setting_reflevel; +extern int setting_scale; void SetModulation(int); extern int setting_modulation; void set_measurement(int); @@ -390,11 +396,22 @@ static void menu_measure_cb(int item, uint8_t data) static void menu_atten_cb(int item, uint8_t data) { + (void)item; + (void)data; set_auto_attenuation(); menu_move_back(); ui_mode_normal(); } +static void menu_reflevel_cb(int item, uint8_t data) +{ + (void)item; + (void)data; + set_auto_reflevel(); + menu_move_back(); + ui_mode_normal(); +} + static void menu_storage_cb(int item, uint8_t data) { (void)item; @@ -684,14 +701,21 @@ static const menuitem_t menu_acquirehigh[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_reflevel[] = { + { MT_CALLBACK,0, "AUTO", menu_reflevel_cb}, + { MT_KEYPAD, KM_REFPOS, "MANUAL", NULL}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + static const menuitem_t menu_display[] = { - { MT_KEYPAD, KM_REFPOS, "\2REF\0LEVEL", NULL}, - { MT_SUBMENU, 0, "\2SCALE/\0DIV", menu_dBper}, - { MT_CALLBACK,0, "STORE", menu_storage_cb}, - { MT_CALLBACK,1, "CLEAR", menu_storage_cb}, - { MT_CALLBACK,2, "SUBTRACT", menu_storage_cb}, - { MT_CALLBACK,3, "WATERFALL",menu_storage_cb}, + { MT_SUBMENU, 0, "\2REF\0LEVEL", menu_reflevel}, + { MT_SUBMENU, 0, "\2SCALE/\0DIV",menu_dBper}, + { MT_CALLBACK,0, "STORE", menu_storage_cb}, + { MT_CALLBACK,1, "CLEAR", menu_storage_cb}, + { MT_CALLBACK,2, "SUBTRACT", menu_storage_cb}, + { MT_CALLBACK,3, "WATERFALL", menu_storage_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1021,12 +1045,12 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0); break; case KM_SCALE: - uistat.value = get_trace_scale(uistat.current_trace) * 1000; - plot_printf(uistat.text, sizeof uistat.text, "%ddB/", uistat.value / 1000); + uistat.value = setting_scale; + plot_printf(uistat.text, sizeof uistat.text, "%ddB/", uistat.value); break; case KM_REFPOS: - uistat.value = get_trace_refpos(uistat.current_trace) * 1000; - plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value / 1000); + uistat.value = setting_reflevel; + plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); break; case KM_ATTENUATION: uistat.value = GetAttenuation(); @@ -1097,9 +1121,11 @@ set_numeric_value(void) set_trace_scale(2, uistat.value / 1000.0); break; case KM_REFPOS: - SetRefpos(uistat.value); + setting_auto_reflevel = false; + SetReflevel(uistat.value); break; case KM_ATTENUATION: + setting_auto_attenuation = false; SetAttenuation(uistat.value); break; case KM_ACTUALPOWER: From 39a32fc6b8612224625ef8c977c93555568b2775 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 9 Apr 2020 08:31:00 +0200 Subject: [PATCH 056/193] Show if auto is selected --- ui_sa.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui_sa.c b/ui_sa.c index 7734392..f86c096 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1005,6 +1005,12 @@ static void menu_item_modify_attribute( } else if (menu == menu_marker_sel) { if (item < MARKERS_MAX && markers[item].enabled) mark = true; + } else if (menu == menu_reflevel) { + if ((item == 0 && setting_auto_reflevel) || (item == 1 && !setting_auto_reflevel)) + mark = true; + } else if (menu == menu_atten) { + if ((item == 0 && setting_auto_attenuation ) || (item == 1 && !setting_auto_attenuation)) + mark = true; } if (mark) { *bg = DEFAULT_MENU_TEXT_COLOR; From 1af2a7c0ae0d0cfa9a0272d272bffde38801df0d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 9 Apr 2020 09:00:44 +0200 Subject: [PATCH 057/193] Selftest should not do auto settings --- sa_core.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/sa_core.c b/sa_core.c index 1cd63b6..d1d2299 100644 --- a/sa_core.c +++ b/sa_core.c @@ -908,7 +908,7 @@ static bool sweep(bool break_on_operation) scandirty = false; draw_cal_status(); } - if (setting_mode == M_LOW && setting_auto_attenuation && max_index[0] > 0) { + if (!in_selftest && setting_mode == M_LOW && setting_auto_attenuation && max_index[0] > 0) { if (actual_t[max_index[0]] - setting_attenuate < -30 && setting_attenuate >= 10) { setting_attenuate -= setting_scale; redraw_request |= REDRAW_CAL_STATUS; @@ -919,7 +919,7 @@ static bool sweep(bool break_on_operation) dirty = true; // Must be above if(scandirty!!!!!) } } - if (MODE_INPUT(setting_mode) && setting_auto_reflevel && max_index[0] > 0) { + if (!in_selftest && MODE_INPUT(setting_mode) && setting_auto_reflevel && max_index[0] > 0) { if (actual_t[max_index[0]] > setting_reflevel - setting_scale/2) { SetReflevel(setting_reflevel + setting_scale); redraw_request |= REDRAW_CAL_STATUS; @@ -1028,8 +1028,12 @@ void draw_cal_status(void) int yMax = setting_reflevel; plot_printf(buf, BLEN, "%ddB", yMax); buf[5]=0; - if (level_is_calibrated()) - color = DEFAULT_FG_COLOR; + if (level_is_calibrated()) { + if (setting_auto_reflevel) + color = BRIGHT_COLOR_GREEN; + else + color = DEFAULT_FG_COLOR; + } else color = BRIGHT_COLOR_RED; ili9341_set_foreground(color); @@ -1039,16 +1043,18 @@ void draw_cal_status(void) plot_printf(buf, BLEN, "%ddB/",(int)setting_scale); ili9341_drawstring(buf, x, y); - if (setting_attenuate) { - ili9341_set_foreground(BRIGHT_COLOR_GREEN); - y += YSTEP*2; - ili9341_drawstring("Attn:", x, y); + if (setting_auto_attenuation) + color = BRIGHT_COLOR_GREEN; + else + color = DEFAULT_FG_COLOR; + ili9341_set_foreground(color); + y += YSTEP*2; + ili9341_drawstring("Attn:", x, y); - y += YSTEP; - plot_printf(buf, BLEN, "-%ddB", setting_attenuate); - buf[5]=0; - ili9341_drawstring(buf, x, y); - } + y += YSTEP; + plot_printf(buf, BLEN, "-%ddB", setting_attenuate); + buf[5]=0; + ili9341_drawstring(buf, x, y); if (setting_average>0) { ili9341_set_foreground(BRIGHT_COLOR_BLUE); @@ -1135,7 +1141,10 @@ void draw_cal_status(void) plot_printf(buf, BLEN, "%ddB", (int)(yMax - setting_scale * NGRIDY)); buf[5]=0; if (level_is_calibrated()) - color = DEFAULT_FG_COLOR; + if (setting_auto_reflevel) + color = BRIGHT_COLOR_GREEN; + else + color = DEFAULT_FG_COLOR; else color = BRIGHT_COLOR_RED; ili9341_set_foreground(color); @@ -1441,6 +1450,7 @@ common_silent: SetReflevel(test_case[i].pass+10); set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); + SetAttenuation(0); draw_cal_status(); } From 3dd7bdbdf89f15cb0abdce077fc3df3d4b05622f Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 9 Apr 2020 15:38:19 +0200 Subject: [PATCH 058/193] Small SI4432 initialization change with BIG improvement --- si4432.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/si4432.c b/si4432.c index 90ab674..71ba3c7 100644 --- a/si4432.c +++ b/si4432.c @@ -236,7 +236,7 @@ void SI4432_Set_Frequency ( long Freq ) { int N = Freq / 10000000; Carrier = ( 4 * ( Freq - N * 10000000 )) / 625; int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 ); -#if 1 +#if 0 SI4432_Write_Byte ( 0x75, Freq_Band ); SI4432_Write_Byte ( 0x76, (Carrier>>8) & 0xFF ); SI4432_Write_Byte ( 0x77, Carrier & 0xFF ); @@ -278,20 +278,29 @@ void SI4432_Sub_Init(void) { SI4432_Reset(); -#if 1 // Not sure if these add any value + + SI4432_Write_Byte(0x69, 0x60); //AGC override according to WBS3 + + +#if 0 // Not sure if these add any value //set VCO and PLL Only for SI4432 V2 SI4432_Write_Byte(0x72, 0x1F); //write 0x1F to the Frequency Deviation register + // VCO tuning registers SI4432_Write_Byte(0x5A, 0x7F); //write 0x7F to the VCO Current Trimming register SI4432_Write_Byte(0x58, 0x80); //write 0xD7 to the ChargepumpCurrentTrimmingOverride register SI4432_Write_Byte(0x59, 0x40); //write 0x40 to the Divider Current Trimming register #endif - - //set the AGC +#if 0 + //set the AGC, BAD FOR PERFORMANCE!!!!!! SI4432_Write_Byte(0x6A, 0x0B); //write 0x0B to the AGC Override 2 register - //set ADC reference voltage to 0.9V + //set ADC reference voltage to 0.9V, BAD FOR PERFORMANCE!!!!!! SI4432_Write_Byte(0x68, 0x04); //write 0x04 to the Deltasigma ADC Tuning 2 register + SI4432_Write_Byte(0x1F, 0x03); //write 0x03 to the Clock Recovery Gearshift Override register +#endif + + SI4432_Write_Byte(0x05, 0x0); SI4432_Write_Byte(0x06, 0x0); // Enable receiver chain From e5af80877ec1f9befdafd7f390067afd0875b24c Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 9 Apr 2020 17:16:09 +0200 Subject: [PATCH 059/193] COmpleted spur table and spur finding --- sa_core.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/sa_core.c b/sa_core.c index d1d2299..b31623b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -635,9 +635,15 @@ static const int spur_table[] = 420000, 490000, 510000, - 1600000, - 1840000, - 2960000, + 1592000, + 1834000, + 2734000, + 2942000, + 4914000, + 7371000, + 8236000, + 8928000, + 18928000, /* 870000, 970000, @@ -711,12 +717,11 @@ char age[POINTS_COUNT]; float perform(bool break_on_operation, int i, int32_t f, int tracking) { -// long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0); + int was_avoiding_spur = false; + // long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0); long local_IF; if (MODE_HIGH(setting_mode)) local_IF = 0; - else if (setting_mode == M_LOW && avoid_spur(f)) - local_IF = spur_alternate_IF; else local_IF = frequency_IF; @@ -725,9 +730,6 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) scandirty = true; dirty = false; } - if (local_IF) { - setFreq (0, local_IF); - } if (MODE_OUTPUT(setting_mode) && setting_modulation == MO_AM) { int p = setting_attenuate * 2 + modulation_counter; PE4302_Write_Byte(p); @@ -759,8 +761,17 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) int t = 0; do { int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw)); - if (MODE_INPUT(setting_mode) && tracking) - setFreq (0, local_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible + if (setting_mode == M_LOW && tracking) { + setFreq (0, frequency_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible + } else if (MODE_LOW(setting_mode)) { + if (setting_mode == M_LOW && avoid_spur(f)) { + local_IF = spur_alternate_IF; + } else + local_IF = frequency_IF ; + } else + local_IF= 0; + if (local_IF) + setFreq (0, local_IF); #if 0 if (lf >11000000 || lf < 9000000) { lf = lf; @@ -1184,11 +1195,11 @@ static const struct { {TC_FLAT, TP_10MHZEXTRA, 10, 4, -25, 20, -70}, // 8 BPF pass band flatness {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 9 LPF cutoff {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -80 }, // 11 Measure power level and noise + {TC_MEASURE, TP_30MHZ, 30, 7, -30, 30, -80 }, // 11 Measure power level and noise {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 12 Measure powerlevel and noise {TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 13 Calibrate power high mode {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 1, -25, 30, -80 }, // 15 Measure RBW step time + {TC_MEASURE, TP_30MHZ, 30, 1, -30, 30, -80 }, // 15 Measure RBW step time {TC_END, 0, 0, 0, 0, 0, 0}, }; From dfc59a87f73539439c0f51eec808c77323ef9e6f Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 9 Apr 2020 18:04:51 +0200 Subject: [PATCH 060/193] Repaired broken BPF --- sa_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sa_core.c b/sa_core.c index b31623b..4b24505 100644 --- a/sa_core.c +++ b/sa_core.c @@ -763,15 +763,15 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw)); if (setting_mode == M_LOW && tracking) { setFreq (0, frequency_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible + local_IF = frequency_IF ; } else if (MODE_LOW(setting_mode)) { if (setting_mode == M_LOW && avoid_spur(f)) { local_IF = spur_alternate_IF; } else local_IF = frequency_IF ; + setFreq (0, local_IF); } else local_IF= 0; - if (local_IF) - setFreq (0, local_IF); #if 0 if (lf >11000000 || lf < 9000000) { lf = lf; From 174afddeaa3f2a01798b758a40b832a68b408f62 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 09:39:06 +0200 Subject: [PATCH 061/193] Automated spur table search --- sa_core.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/sa_core.c b/sa_core.c index 4b24505..b2c0457 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1,4 +1,3 @@ - #include "SI4432.h" // comment out for simulation int setting_mode = -1; // To force initialzation @@ -717,7 +716,6 @@ char age[POINTS_COUNT]; float perform(bool break_on_operation, int i, int32_t f, int tracking) { - int was_avoiding_spur = false; // long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0); long local_IF; if (MODE_HIGH(setting_mode)) @@ -765,7 +763,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) setFreq (0, frequency_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible local_IF = frequency_IF ; } else if (MODE_LOW(setting_mode)) { - if (setting_mode == M_LOW && avoid_spur(f)) { + if (setting_mode == M_LOW && !in_selftest && avoid_spur(f)) { local_IF = spur_alternate_IF; } else local_IF = frequency_IF ; @@ -1041,29 +1039,31 @@ void draw_cal_status(void) buf[5]=0; if (level_is_calibrated()) { if (setting_auto_reflevel) - color = BRIGHT_COLOR_GREEN; - else color = DEFAULT_FG_COLOR; + else + color = BRIGHT_COLOR_GREEN; } else color = BRIGHT_COLOR_RED; ili9341_set_foreground(color); ili9341_drawstring(buf, x, y); + color = DEFAULT_FG_COLOR; + ili9341_set_foreground(color); y += YSTEP*2; plot_printf(buf, BLEN, "%ddB/",(int)setting_scale); ili9341_drawstring(buf, x, y); if (setting_auto_attenuation) - color = BRIGHT_COLOR_GREEN; - else color = DEFAULT_FG_COLOR; + else + color = BRIGHT_COLOR_GREEN; ili9341_set_foreground(color); y += YSTEP*2; ili9341_drawstring("Attn:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "-%ddB", setting_attenuate); + plot_printf(buf, BLEN, "%ddB", -setting_attenuate); buf[5]=0; ili9341_drawstring(buf, x, y); @@ -1113,7 +1113,13 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); if (dirty) - ili9341_set_foreground(BRIGHT_COLOR_RED); + color = BRIGHT_COLOR_RED; + else if (setting_step_delay) + color = BRIGHT_COLOR_GREEN; + else + color = DEFAULT_FG_COLOR; + + ili9341_set_foreground(color); y += YSTEP*2; ili9341_drawstring("Scan:", x, y); @@ -1153,9 +1159,9 @@ void draw_cal_status(void) buf[5]=0; if (level_is_calibrated()) if (setting_auto_reflevel) - color = BRIGHT_COLOR_GREEN; - else color = DEFAULT_FG_COLOR; + else + color = BRIGHT_COLOR_GREEN; else color = BRIGHT_COLOR_RED; ili9341_set_foreground(color); @@ -1468,9 +1474,70 @@ common_silent: extern void menu_autosettings_cb(int item); extern float SI4432_force_RBW(int i); +int last_spur = 0; +int add_spur(int f) +{ + for (int i = 0; i < last_spur; i++) { + if (temp_t[i] == f) { + stored_t[i] += 1; + return stored_t[i]; + } + } + if (last_spur < 290) { + temp_t[last_spur] = f; + stored_t[last_spur++] = 1; + } + return 1; +} + void self_test(void) { -#if 0 // RAttenuator test +#if 1 + in_selftest = true; + reset_settings(M_LOW); + test_prepare(4); + int f; // Start search at 400kHz +// int i = 0; // Index in spur table (temp_t) + float p2, p1, p; + +#define FREQ_STEP 3000 + + SetRBW(FREQ_STEP/1000); + last_spur = 0; + for (int j = 0; j < 10; j++) { + + p2 = perform(false, 0, f, false); + vbwSteps = 1; + f += FREQ_STEP; + p1 = perform(false, 1, f, false); + f += FREQ_STEP; + shell_printf("\n\rStarting with %4.2f, %4.2f and IF at %d\n\r", p2, p1, frequency_IF); + + f = 400000; + while (f < 100000000) { + p = perform(false, 1, f, false); +#define SPUR_DELTA 6 + if ( p2 < p1 - SPUR_DELTA && p < p1 - SPUR_DELTA) { +// temp_t[i++] = f - FREQ_STEP; + shell_printf("Spur of %4.2f at %d with count %d\n\r", p1,(f - FREQ_STEP)/1000, add_spur(f - FREQ_STEP)); + } + // else + // shell_printf("%f at %d\n\r", p1,f - FREQ_STEP); + p2 = p1; + p1 = p; + f += FREQ_STEP; + } + } + shell_printf("\n\rTable for IF at %d\n\r", frequency_IF); + for (int j = 0; j < last_spur; j++) { + if ((int)stored_t[j] > 1) + shell_printf("%d, %d\n\r", ((int)temp_t[j])/1000, (int)stored_t[j]); + } + while(1) ; + return; + + +#elif 0 // RAttenuator test int local_test_status; in_selftest = true; reset_settings(M_LOW); @@ -1484,9 +1551,8 @@ void self_test(void) shell_printf("Target %d, actual %f\n\r",j, peakLevel); } return; -#else - -#if 0 // RBW step time search +#elif 0 + // RBW step time search int local_test_status; in_selftest = true; reset_settings(M_LOW); @@ -1552,7 +1618,6 @@ void self_test(void) reset_settings(M_LOW); in_selftest = false; #endif -#endif } void reset_calibration(void) From c848c4270340b9f842ef1d95da393768752cc42d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 10:53:45 +0200 Subject: [PATCH 062/193] Updated spur table for 433.8MHz --- sa_core.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sa_core.c b/sa_core.c index b2c0457..c9aa774 100644 --- a/sa_core.c +++ b/sa_core.c @@ -631,18 +631,17 @@ static const unsigned int spur_IF = 433800000; static const unsigned int spur_alternate_IF = 434000000; static const int spur_table[] = { - 420000, - 490000, - 510000, - 1592000, + 580000, + 1600000, 1834000, - 2734000, - 2942000, - 4914000, - 7371000, - 8236000, - 8928000, - 18928000, + 4933000, + 4960000, + 10000000, + 10960000, + 16960000, + 22960000, + 28960000, + /* 870000, 970000, From 3558543dea83fc785637ecb8a9bfe8d32f51e131 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 10:55:02 +0200 Subject: [PATCH 063/193] Self test enabled --- sa_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sa_core.c b/sa_core.c index c9aa774..fa812ee 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1491,7 +1491,7 @@ int add_spur(int f) void self_test(void) { -#if 1 +#if 0 in_selftest = true; reset_settings(M_LOW); test_prepare(4); From cc536a478747681ba2f658d6b86e073af78be12d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 13:52:14 +0200 Subject: [PATCH 064/193] Spur table extended --- sa_core.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/sa_core.c b/sa_core.c index fa812ee..eeb80f2 100644 --- a/sa_core.c +++ b/sa_core.c @@ -632,16 +632,38 @@ static const unsigned int spur_alternate_IF = 434000000; static const int spur_table[] = { 580000, + 961000, 1600000, - 1834000, + 1837000, + 2755000, + 2961000, 4933000, 4960000, + 6961000, + 6980000, + 8267000, + 8961000, 10000000, 10960000, + 11600000, 16960000, 22960000, 28960000, + /* +0.52 +6.96 +1.84 +2.77 + + + + 4934 + 4960 + 8928 + 7371 + + /* 870000, 970000, @@ -699,8 +721,9 @@ int avoid_spur(int f) // window = 50000; if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0) return(false); + f = f + window/2; for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { - if (f/window == spur_table[i]/window) { + if (f/window == (spur_table[i] + window/2)/window) { // spur_old_stepdelay = actualStepDelay; // actualStepDelay += 4000; return true; @@ -757,7 +780,8 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) float RSSI = -150.0; int t = 0; do { - int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw)); + int lf = (uint32_t)(f + (int)((t * 500 - vbwSteps * 250) * actual_rbw)); + if (lf < 0) lf = 0; if (setting_mode == M_LOW && tracking) { setFreq (0, frequency_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible local_IF = frequency_IF ; From 012f915af9fc262e71c42b46c19e22869c21e06f Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 16:33:46 +0200 Subject: [PATCH 065/193] Calibrate frequency --- sa_core.c | 24 +++++++++++++++++++++--- si4432.c | 13 ++++++++++--- ui_sa.c | 19 ++++++++++++++++++- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/sa_core.c b/sa_core.c index eeb80f2..7f16767 100644 --- a/sa_core.c +++ b/sa_core.c @@ -634,8 +634,9 @@ static const int spur_table[] = 580000, 961000, 1600000, - 1837000, - 2755000, + 1837000, // Real signal + 2755000, // Real signal + 2760000, 2961000, 4933000, 4960000, @@ -664,7 +665,7 @@ static const int spur_table[] = 7371 -/* + 870000, 970000, 1460000, @@ -714,6 +715,23 @@ static const int spur_table[] = #endif }; +int binary_search(int f) +{ + int L = 0; + int R = (sizeof spur_table)/sizeof(int); + while (L <= R) { + int m = (L + R) / 2; + if (spur_table[m] < f) + L = m + 1; + else if (spur_table[m] > f) + R = m - 1; + else + return m; + } + return 0; +} + + int avoid_spur(int f) { int window = ((int)actual_rbw ) * 1000*2; diff --git a/si4432.c b/si4432.c index 71ba3c7..b79572c 100644 --- a/si4432.c +++ b/si4432.c @@ -218,11 +218,18 @@ float SI4432_force_RBW(int i) float SI4432_RBW_table(int i){ if (i < 0) return 0; - if (i * 4 >= (sizeof RBW_choices) / 2 ) + if (i * 4 >= (int)(sizeof RBW_choices) / 2 ) return 0; return(RBW_choices[i*4-1]); } +int setting_10mhz = 10000000; + +void set_10mhz(int f) +{ + setting_10mhz = f; +} + void SI4432_Set_Frequency ( long Freq ) { int hbsel; long Carrier; @@ -233,8 +240,8 @@ void SI4432_Set_Frequency ( long Freq ) { hbsel = 0; } int sbsel = 1; - int N = Freq / 10000000; - Carrier = ( 4 * ( Freq - N * 10000000 )) / 625; + int N = Freq / setting_10mhz; + Carrier = ( 4 * ( Freq - N * setting_10mhz )) / 625; int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 ); #if 0 SI4432_Write_Byte ( 0x75, Freq_Band ); diff --git a/ui_sa.c b/ui_sa.c index f86c096..0b4aa47 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -55,6 +55,8 @@ extern int setting_auto_reflevel; extern int setting_auto_attenuation; extern int setting_reflevel; extern int setting_scale; +extern int setting_10mhz; +void set_10mhz(int); void SetModulation(int); extern int setting_modulation; void set_measurement(int); @@ -65,7 +67,7 @@ extern int setting_step_delay; enum { KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, - KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE + KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE, KM_10MHZ }; @@ -173,6 +175,7 @@ static const keypads_t * const keypads_mode_tbl[] = { keypads_level, // KM_LOWOUTLEVEL keypads_level, // KM_DECAY keypads_level, // KM_NOISE + keypads_level, // KM_10MHz }; #ifdef __VNA__ @@ -610,6 +613,7 @@ const menuitem_t menu_lowoutputmode[] = { { MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", NULL}, { MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation}, { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL}, + { MT_FORM | MT_KEYPAD, KM_10MHZ, "10MHZ: %s", NULL}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -787,6 +791,7 @@ static const menuitem_t menu_settings2[] = { MT_CALLBACK, 2, "BPF", menu_settings2_cb}, { MT_KEYPAD, KM_DECAY, "\2HOLD\0TIME", NULL}, { MT_KEYPAD, KM_NOISE, "\2NOISE\0LEVEL", NULL}, + { MT_KEYPAD, KM_10MHZ, "\00210MHZ\0ACTUAL", NULL}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1090,6 +1095,11 @@ static void fetch_numeric_target(void) uistat.value = setting_noise; plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value); break; + case KM_10MHZ: + uistat.value = setting_10mhz; + plot_printf(uistat.text, sizeof uistat.text, "%3.6fMHz", uistat.value / 1000000.0); + break; + } { @@ -1157,5 +1167,12 @@ set_numeric_value(void) case KM_NOISE: set_noise(uistat.value); break; + case KM_10MHZ: + if (uistat.value < 9000000) { + set_10mhz(setting_10mhz + uistat.value); + } else + set_10mhz(uistat.value); + dirty = true; + break; } } From 6ae3ef90190425cbb0a1d3a76707bd7a3ef594a8 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 17:04:46 +0200 Subject: [PATCH 066/193] Prepare for 8 menu buttons --- ui.c | 9 +++++---- ui_sa.c | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ui.c b/ui.c index 874a530..adbcfa0 100644 --- a/ui.c +++ b/ui.c @@ -1497,7 +1497,7 @@ draw_menu_buttons(const menuitem_t *menu) { int i = 0; char text[30]; - for (i = 0; i < 7; i++) { + for (i = 0; i < 8; i++) { const char *l1, *l2; if (MT_MASK(menu[i].type) == MT_NONE) break; @@ -1597,7 +1597,7 @@ menu_apply_touch(void) int i; touch_position(&touch_x, &touch_y); - for (i = 0; i < 7; i++) { + for (i = 0; i < 8; i++) { if (MT_MASK(menu[i].type) == MT_NONE) break; if (MT_MASK(menu[i].type == MT_BLANK) || MT_MASK(menu[i].type) == MT_TITLE) @@ -1629,8 +1629,9 @@ draw_menu(void) static void erase_menu_buttons(void) { - ili9341_fill(area_width, 0, 320 - area_width, area_height, DEFAULT_BG_COLOR); -// ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*7, DEFAULT_BG_COLOR); +// ili9341_fill(area_width, 0, 320 - area_width, area_height, DEFAULT_BG_COLOR); + ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR); + draw_frequencies(); } static void diff --git a/ui_sa.c b/ui_sa.c index 0b4aa47..2a17436 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -731,6 +731,7 @@ static const menuitem_t menu_stimulus[8] = { { MT_KEYPAD, KM_SPAN, "SPAN", NULL}, { MT_KEYPAD, KM_CW, "CW FREQ", NULL}, { MT_CALLBACK,0, "\2PAUSE\0SWEEP", menu_pause_cb}, + { MT_SUBMENU,0, "RBW", menu_rbw}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 5f3aed584464432462cc98f84dae53b1d411b4f2 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 17:49:25 +0200 Subject: [PATCH 067/193] Menu structure adapted --- main.c | 14 ++++- ui.c | 3 +- ui_sa.c | 186 ++++++++++++++++++++++++++++++++------------------------ 3 files changed, 119 insertions(+), 84 deletions(-) diff --git a/main.c b/main.c index 2c3e0e9..337a0ec 100644 --- a/main.c +++ b/main.c @@ -129,9 +129,13 @@ static THD_FUNCTION(Thread1, arg) completed = sweep(true); sweep_mode&=~SWEEP_ONCE; } else if (sweep_mode & SWEEP_SELFTEST) { - self_test(); // call from lowest level to save stack space + // call from lowest level to save stack space + self_test(); + sweep_mode = SWEEP_ENABLE; } else if (sweep_mode & SWEEP_CALIBRATE) { - calibrate(); // call from lowest level to save stack space + // call from lowest level to save stack space + calibrate(); + sweep_mode = SWEEP_ENABLE; } else { __WFI(); } @@ -168,6 +172,12 @@ static THD_FUNCTION(Thread1, arg) } } +int +is_paused(void) +{ + return !(sweep_mode & SWEEP_ENABLE); +} + static inline void pause_sweep(void) { diff --git a/ui.c b/ui.c index adbcfa0..f8bbddd 100644 --- a/ui.c +++ b/ui.c @@ -720,11 +720,12 @@ get_marker_frequency(int marker) static void menu_marker_op_cb(int item, uint8_t data) { + (void)item; uint32_t freq = get_marker_frequency(active_marker); if (freq == 0) return; // no active marker - switch (item) { + switch (data) { case 0: /* MARKER->START */ case 1: /* MARKER->STOP */ case 2: /* MARKER->CENTER */ diff --git a/ui_sa.c b/ui_sa.c index 2a17436..887cad0 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -15,7 +15,7 @@ void SetAttenuation(int); int GetAttenuation(void); void set_auto_attenuation(void); void set_auto_reflevel(void); - +int is_paused(void); void SetPowerLevel(int); void SetGenerate(int); void SetRBW(int); @@ -488,7 +488,7 @@ int menu_dBper_value[]={1,2,5,10,20}; static void menu_dBper_cb(int item, uint8_t data) { (void)item; - SetScale(menu_dBper_value[data]); + SetScale(data); menu_move_back(); ui_mode_normal(); // draw_cal_status(); @@ -542,8 +542,8 @@ static void menu_pause_cb(int item, uint8_t data) (void) data; (void) item; toggle_sweep(); - menu_move_back(); - ui_mode_normal(); +// menu_move_back(); +// ui_mode_normal(); draw_menu(); // draw_cal_status(); } @@ -652,11 +652,11 @@ static const menuitem_t menu_rbw[] = { static const menuitem_t menu_dBper[] = { - { MT_CALLBACK, 0, " 1dB/", menu_dBper_cb}, - { MT_CALLBACK, 1, " 2dB/", menu_dBper_cb}, - { MT_CALLBACK, 2, " 5dB/", menu_dBper_cb}, - { MT_CALLBACK, 3, " 10dB/", menu_dBper_cb}, - { MT_CALLBACK, 4, " 20dB/", menu_dBper_cb}, + { MT_CALLBACK, 1, " 1dB/", menu_dBper_cb}, + { MT_CALLBACK, 2, " 2dB/", menu_dBper_cb}, + { MT_CALLBACK, 5, " 5dB/", menu_dBper_cb}, + { MT_CALLBACK, 10," 10dB/", menu_dBper_cb}, + { MT_CALLBACK, 20," 20dB/", menu_dBper_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -688,22 +688,6 @@ static const menuitem_t menu_atten[] = { { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_acquire[] = { - { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, - { MT_SUBMENU, 0, "ATTEN", menu_atten}, - { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_SUBMENU,0, "AVER", menu_average}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel -}; - -static const menuitem_t menu_acquirehigh[] = { - { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, - { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_SUBMENU,0, "AVER", menu_average}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; static const menuitem_t menu_reflevel[] = { { MT_CALLBACK,0, "AUTO", menu_reflevel_cb}, @@ -713,29 +697,6 @@ static const menuitem_t menu_reflevel[] = { }; -static const menuitem_t menu_display[] = { - { MT_SUBMENU, 0, "\2REF\0LEVEL", menu_reflevel}, - { MT_SUBMENU, 0, "\2SCALE/\0DIV",menu_dBper}, - { MT_CALLBACK,0, "STORE", menu_storage_cb}, - { MT_CALLBACK,1, "CLEAR", menu_storage_cb}, - { MT_CALLBACK,2, "SUBTRACT", menu_storage_cb}, - { MT_CALLBACK,3, "WATERFALL", menu_storage_cb}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; - -static const menuitem_t menu_stimulus[8] = { - { MT_KEYPAD, KM_START, "START", NULL}, - { MT_KEYPAD, KM_STOP, "STOP", NULL}, - { MT_KEYPAD, KM_CENTER, "CENTER", NULL}, - { MT_KEYPAD, KM_SPAN, "SPAN", NULL}, - { MT_KEYPAD, KM_CW, "CW FREQ", NULL}, - { MT_CALLBACK,0, "\2PAUSE\0SWEEP", menu_pause_cb}, - { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, - { MT_NONE, 0, NULL, NULL } // sentinel -}; - static const menuitem_t menu_marker_type[] = { { MT_CALLBACK, M_REFERENCE, "REFERENCE", menu_marker_type_cb}, @@ -771,10 +732,10 @@ static const menuitem_t menu_marker_sel[] = { static const menuitem_t menu_marker[] = { { MT_SUBMENU, 0, "\2SELECT\0MARKER", menu_marker_sel}, { MT_SUBMENU, 0, "\2MARKER\0TYPE", menu_marker_type}, - { MT_CALLBACK, 0, S_RARROW"START", menu_marker_op_cb}, - { MT_CALLBACK, 0, S_RARROW"STOP", menu_marker_op_cb}, - { MT_CALLBACK, 0, S_RARROW"CENTER", menu_marker_op_cb}, - { MT_CALLBACK, 0, S_RARROW"SPAN", menu_marker_op_cb}, + { MT_CALLBACK, ST_START, S_RARROW"START", menu_marker_op_cb}, + { MT_CALLBACK, ST_STOP, S_RARROW"STOP", menu_marker_op_cb}, + { MT_CALLBACK, ST_CENTER, S_RARROW"CENTER", menu_marker_op_cb}, + { MT_CALLBACK, ST_SPAN, S_RARROW"SPAN", menu_marker_op_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -857,6 +818,65 @@ static const menuitem_t menu_config[] = { { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_acquire[] = { + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, + { MT_SUBMENU, 0, "ATTEN", menu_atten}, + { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_SUBMENU,0, "AVER", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_acquirehigh[] = { + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, + { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_SUBMENU,0, "AVER", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_display[] = { + { MT_CALLBACK,0, "\2PAUSE\0SWEEP", menu_pause_cb}, +// { MT_SUBMENU, 0, "\2REF\0LEVEL", menu_reflevel}, +// { MT_SUBMENU, 0, "\2SCALE/\0DIV",menu_dBper}, + { MT_CALLBACK,0, "STORE", menu_storage_cb}, + { MT_CALLBACK,1, "CLEAR", menu_storage_cb}, + { MT_CALLBACK,2, "SUBTRACT", menu_storage_cb}, + { MT_CALLBACK,3, "WATERFALL", menu_storage_cb}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_levelhigh[] = { + { MT_SUBMENU, 0, "\2REF\0LEVEL", menu_reflevel}, + { MT_SUBMENU, 0, "\2SCALE/\0DIV",menu_dBper}, + { MT_SUBMENU,0, "AVER", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK",NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_level[] = { + { MT_SUBMENU, 0, "\2REF\0LEVEL", menu_reflevel}, + { MT_SUBMENU, 0, "\2SCALE/\0DIV",menu_dBper}, + { MT_SUBMENU, 0, "ATTEN", menu_atten}, + { MT_SUBMENU,0, "AVER", menu_average}, + { MT_CANCEL, 0, S_LARROW" BACK",NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + +static const menuitem_t menu_stimulus[] = { + { MT_KEYPAD, KM_START, "START", NULL}, + { MT_KEYPAD, KM_STOP, "STOP", NULL}, + { MT_KEYPAD, KM_CENTER, "CENTER", NULL}, + { MT_KEYPAD, KM_SPAN, "SPAN", NULL}, + { MT_KEYPAD, KM_CW, "CW FREQ", NULL}, + { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + + + static const menuitem_t menu_mode[] = { { MT_FORM | MT_TITLE, 0, "MODE", NULL}, { MT_FORM | MT_CALLBACK, 0, "LOW INPUT", menu_mode_cb}, @@ -869,6 +889,30 @@ static const menuitem_t menu_mode[] = { { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; #if 1 +const menuitem_t menu_top[] = { + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, + { MT_SUBMENU, 0, "FREQ", menu_stimulus}, + { MT_SUBMENU, 0, "LEVEL", menu_level}, + { MT_SUBMENU, 0, "DISPLAY", menu_display}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "SETTINGS", menu_settings}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, + { MT_NONE, 0, NULL, NULL } // sentinel, + // MENUITEM_CLOSE, +}; + +const menuitem_t menu_tophigh[] = { + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, + { MT_SUBMENU, 0, "FREQ", menu_stimulus}, + { MT_SUBMENU, 0, "LEVEL", menu_levelhigh}, + { MT_SUBMENU, 0, "DISPLAY", menu_display}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "SETTINGS", menu_settingshigh}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, + { MT_NONE, 0, NULL, NULL } // sentinel, + // MENUITEM_CLOSE, +}; +#else const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "ACQUIRE", menu_acquire}, { MT_SUBMENU, 0, "FREQ", menu_stimulus}, @@ -893,30 +937,6 @@ const menuitem_t menu_tophigh[] = { MT_NONE, 0, NULL, NULL } // sentinel, // MENUITEM_CLOSE, }; -#else -const menuitem_t menu_top[] = { - { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, - { MT_SUBMENU, 0, "SCAN", menu_stimulus}, - { MT_SUBMENU, 0, "MARKER", menu_marker}, - { MT_SUBMENU, 0, "DISPLAY", menu_scale}, - { MT_SUBMENU, 0, "STORAGE", menu_storage}, - { MT_SUBMENU, 0, "SETTINGS", menu_settings}, - { MT_CANCEL, 0, S_LARROW" MODE",NULL}, - { MT_NONE, 0, NULL, NULL } // sentinel, - // MENUITEM_CLOSE, -}; - -const menuitem_t menu_tophigh[] = { - { MT_CALLBACK, 0, "AUTO", menu_autosettings_cb}, - { MT_SUBMENU, 0, "SCAN", menu_stimulus}, - { MT_SUBMENU, 0, "MARKER", menu_marker}, - { MT_SUBMENU, 0, "DISPLAY", menu_scalehigh}, - { MT_SUBMENU, 0, "STORAGE", menu_storage}, - { MT_SUBMENU, 0, "SETTINGS", menu_settingshigh}, - { MT_CANCEL, 0, S_LARROW" MODE",NULL}, - { MT_NONE, 0, NULL, NULL } // sentinel, - // MENUITEM_CLOSE, -}; #endif // ===[MENU DEFINITION END]====================================================== @@ -941,6 +961,7 @@ static void menu_item_modify_attribute( const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) { int mark = false; + int data = menu[item].data; if (menu == menu_mode) { if (item == GetMode()+1) { mark = true; @@ -970,7 +991,7 @@ static void menu_item_modify_attribute( mark = true; } } else if (menu == menu_dBper) { - if (menu_dBper_value[item] == get_trace_scale(1)){ + if (data == get_trace_scale(1)){ mark = true; } } else if (menu == menu_rbw) { @@ -979,18 +1000,21 @@ static void menu_item_modify_attribute( } } else if (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3) { - if (menu[item].data == setting_drive){ + if (data == setting_drive){ mark = true; } } else if (menu == menu_display) { - if (item ==2 && GetStorage()){ + if (item ==0 && is_paused()){ + mark = true; + } + if (item ==1 && GetStorage()){ mark = true; } - if (item == 4 && GetSubtractStorage()){ + if (item == 3 && GetSubtractStorage()){ mark = true; } - if (item == 5 && get_waterfall()){ + if (item == 4 && get_waterfall()){ mark = true; } } else if (menu == menu_settings2 || menu == menu_settingshigh2) { From c1a266e16e5d845c02282c7504d034c89943f2da Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 10 Apr 2020 17:55:49 +0200 Subject: [PATCH 068/193] Stop marker span confusion --- ui.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui.c b/ui.c index f8bbddd..87c3e60 100644 --- a/ui.c +++ b/ui.c @@ -764,6 +764,7 @@ menu_marker_op_cb(int item, uint8_t data) break; #endif } + menu_move_back(); ui_mode_normal(); draw_cal_status(); //redraw_all(); From df524ed2897f893384666d019ed364993d2aea9b Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 11 Apr 2020 07:51:29 +0200 Subject: [PATCH 069/193] Binary search in spur table --- Makefile | 2 +- sa_core.c | 16 +++++++++++----- ui.c | 2 +- ui_sa.c | 3 ++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index e16ea2e..770ad95 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # Compiler options here. ifeq ($(USE_OPT),) # USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage - USE_OPT = -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -fdce -fdse -fmerge-constants -fstore-merging -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/sa_core.c b/sa_core.c index 7f16767..fcfdf72 100644 --- a/sa_core.c +++ b/sa_core.c @@ -718,17 +718,19 @@ static const int spur_table[] = int binary_search(int f) { int L = 0; - int R = (sizeof spur_table)/sizeof(int); + int R = (sizeof spur_table)/sizeof(int) - 1; + int fmin = f - ((int)actual_rbw ) * 1000; + int fplus = f + ((int)actual_rbw ) * 1000; while (L <= R) { int m = (L + R) / 2; - if (spur_table[m] < f) + if (spur_table[m] < fmin) L = m + 1; - else if (spur_table[m] > f) + else if (spur_table[m] > fplus) R = m - 1; else - return m; + return true; // index is m } - return 0; + return false; } @@ -739,15 +741,19 @@ int avoid_spur(int f) // window = 50000; if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0) return(false); + return binary_search(f); +#if 0 f = f + window/2; for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) { if (f/window == (spur_table[i] + window/2)/window) { // spur_old_stepdelay = actualStepDelay; // actualStepDelay += 4000; + binary_search(f); return true; } } return false; +#endif } static int modulation_counter = 0; diff --git a/ui.c b/ui.c index 87c3e60..35a7b30 100644 --- a/ui.c +++ b/ui.c @@ -842,7 +842,7 @@ menu_marker_sel_cb(int item, uint8_t data) active_marker_select(item); } } else { - markers[item].enabled = M_TRACKING_ENABLED; // default tracking enabled + markers[item].enabled = M_ENABLED; // default tracking enabled active_marker_select(item); } if (markers[item].enabled) diff --git a/ui_sa.c b/ui_sa.c index 887cad0..a721dbd 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1,4 +1,3 @@ - void markmap_all_markers(void); static void menu_marker_type_cb(int item, uint8_t data); @@ -895,6 +894,7 @@ const menuitem_t menu_top[] = { { MT_SUBMENU, 0, "LEVEL", menu_level}, { MT_SUBMENU, 0, "DISPLAY", menu_display}, { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "MEASURE", menu_measure}, { MT_SUBMENU, 0, "SETTINGS", menu_settings}, { MT_CANCEL, 0, S_LARROW" MODE",NULL}, { MT_NONE, 0, NULL, NULL } // sentinel, @@ -907,6 +907,7 @@ const menuitem_t menu_tophigh[] = { { MT_SUBMENU, 0, "LEVEL", menu_levelhigh}, { MT_SUBMENU, 0, "DISPLAY", menu_display}, { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "MEASURE", menu_measure}, { MT_SUBMENU, 0, "SETTINGS", menu_settingshigh}, { MT_CANCEL, 0, S_LARROW" MODE",NULL}, { MT_NONE, 0, NULL, NULL } // sentinel, From e749f7f8ac23e4588d95a8b9d59d9912ff05a3da Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 11 Apr 2020 10:57:24 +0200 Subject: [PATCH 070/193] ICON experiment --- ili9341.c | 2 +- plot.c | 9 ++-- sa_core.c | 19 ++++---- ui.c | 3 ++ ui_sa.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 13 deletions(-) diff --git a/ili9341.c b/ili9341.c index 4620adc..bcca3ec 100644 --- a/ili9341.c +++ b/ili9341.c @@ -568,7 +568,7 @@ void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height ili9341_bulk(x, y, width, height); } -static void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, +void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap) { uint16_t *buf = spi_buffer; diff --git a/plot.c b/plot.c index 555d553..0e57e0f 100644 --- a/plot.c +++ b/plot.c @@ -1558,7 +1558,10 @@ void request_to_draw_cells_behind_menu(void) { // Values Hardcoded from ui.c - invalidate_rect(320-70, 0, 319, 239); + if (current_menu_is_form()) + invalidate_rect(25, 0, 319, 239); + else + invalidate_rect(320-60, 0, 319, 239); redraw_request |= REDRAW_CELLS; } @@ -1843,8 +1846,8 @@ static void cell_draw_marker_info(int x0, int y0) if (i >= 2 && in_selftest) { plot_printf(buf, sizeof buf, "DO NOT SWITCH OFF!!"); j = 2; - int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; - int ypos = 1 + (j/2)*(16) - y0; + int xpos = 1 + CELLOFFSETX +25 - x0; + int ypos = 1 + 16 - y0; cell_drawstring_7x13(buf, xpos, ypos); break; diff --git a/sa_core.c b/sa_core.c index fcfdf72..da76f41 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1238,8 +1238,8 @@ static const struct { float stop; } test_case [TEST_COUNT] = {// Condition Preparation Center Span Pass Width Stop - {TC_BELOW, TP_SILENT, 0.001, 0.0005, -10,0, 0}, // 1 Zero Hz leakage - {TC_BELOW, TP_SILENT, 0.01, 0.01, -40, 0, 0}, // 2 Phase noise of zero Hz + {TC_BELOW, TP_SILENT, 0.005, 0.01, -10,0, 0}, // 1 Zero Hz leakage + {TC_BELOW, TP_SILENT, 0.01, 0.01, -40, 0, 0}, // 2 Phase noise of zero Hz {TC_SIGNAL, TP_10MHZ, 20, 7, -40, 30, -90 }, // 3 {TC_SIGNAL, TP_10MHZ, 30, 7, -30, 30, -90 }, // 4 {TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 5 Wide band noise floor low mode @@ -1280,11 +1280,11 @@ static void test_acquire(int i) else setting_mode = M_HIGH; #endif - SetAverage(4); - sweep(false); - sweep(false); - sweep(false); +// SetAverage(4); sweep(false); +// sweep(false); +// sweep(false); +// sweep(false); plot_into_index(measured); redraw_request |= REDRAW_CELLS | REDRAW_FREQUENCY; } @@ -1463,7 +1463,8 @@ int test_validate(int i) if (current_test_status != TS_PASS || test_case[i+1].kind == TC_END) test_wait = true; -// draw_frequencies(); + test_status[i] = current_test_status; // Must be set before draw_all() !!!!!!!! + // draw_frequencies(); // draw_cal_status(); draw_all(TRUE); resume_sweep(); @@ -1654,8 +1655,8 @@ void self_test(void) i++; } ili9341_set_foreground(BRIGHT_COLOR_GREEN); - ili9341_drawstring_7x13("Self test complete", 30, 120); - ili9341_drawstring_7x13("Touch screen to continue", 30, 140); + ili9341_drawstring_7x13("Self test complete", 50, 200); + ili9341_drawstring_7x13("Touch screen to continue", 50, 215); wait_user(); ili9341_clear_screen(); diff --git a/ui.c b/ui.c index 35a7b30..83e9ce9 100644 --- a/ui.c +++ b/ui.c @@ -1554,6 +1554,9 @@ draw_menu_buttons(const menuitem_t *menu) if (menu[i].type & MT_FORM) { ili9341_fill(active_button_start+2, y+2, active_button_width-4, FONT_GET_HEIGHT*2+8, bg); ili9341_drawstring_size(text, active_button_start+6, y+6, 2); +// blit16BitWidthBitmap(240,y+6,16,16,&icons[3*16]); +// blit16BitWidthBitmap(256,y+6,16,16,&icons[0]); + } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { #define BIG_BUTTON_FONT 1 diff --git a/ui_sa.c b/ui_sa.c index a721dbd..408eb41 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -62,6 +62,142 @@ void set_measurement(int); // extern int settingSpeed; extern int setting_step_delay; +void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, + const uint16_t *bitmap); + +const uint16_t icons [] = +{ + + /* Character 0 (0x00): + width 16 + +-----------------+ + | | + | *************** | + | * * | + |** * | + | * * * | + | * * * | + | * * * * | + | * * * * | + | * * * * * | + | * * * * * * | + | * * * * * * * | + | * * * * * * * | + |** *********** * | + | * * | + | *************** | + | | + +-----------------+ */ + 0x0000, + 0x7fff, + 0x4001, + 0xc001, + 0x4001, + 0x4001, + 0x4801, + 0x4801, + 0x4a89, + 0x4aa9, + 0x4aa9, + 0x5ffd, + 0xc001, + 0x4001, + 0x7fff, + 0x0000, + + /* Character 1 (0x01: + width 16 + +-----------------+ + | | + | ** | + | **** | + | ************ | + | **** | + | ** | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +-----------------+ */ + 0x0000, + 0x0060, + 0x0038, + 0x0ffe, + 0x0038, + 0x0060, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + + /* Character 2 (0x02): + width 16 + +-----------------+ + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | ** | + | **** | + | ************ | + | **** | + | ** | + | | + +-----------------+ */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0060, + 0x0038, + 0x0ffe, + 0x0038, + 0x0060, + 0x0000, + + /* High arrow left 0x03 */ + + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000011110000000, + 0b0000111111111110, + 0b0000011110000000, + 0b0000000110000000, + 0b0000000000000000, +}; enum { @@ -279,6 +415,7 @@ static void menu_config_cb(int item, uint8_t data) draw_menu(); break; case 2: + sweep_mode = 0; // Suspend sweep to save time menu_move_back(); ui_mode_normal(); sweep_mode = SWEEP_SELFTEST; From 1a2664943fb6b4e1395eb7600165e41e9e8e86e2 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 12 Apr 2020 15:21:59 +0200 Subject: [PATCH 071/193] Many marker and measurement related updates --- Makefile | 4 +- main.c | 8 +- nanovna.h | 8 +- plot.c | 54 ++++--- sa_core.c | 51 ++++--- ui.c | 113 +++++++++++---- ui_sa.c | 411 ++++++++++++++++++++++++++++++++++++++++-------------- 7 files changed, 464 insertions(+), 185 deletions(-) diff --git a/Makefile b/Makefile index 770ad95..2af90d0 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ # Compiler options here. ifeq ($(USE_OPT),) -# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage - USE_OPT = -fdce -fdse -fmerge-constants -fstore-merging -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage + USE_OPT = -Og -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -fdce -fdse -fmerge-constants -fstore-merging -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/main.c b/main.c index 337a0ec..59acdd5 100644 --- a/main.c +++ b/main.c @@ -827,10 +827,10 @@ static const trace_t def_trace[TRACES_MAX] = {//enable, type, channel, reserved, }; static const marker_t def_markers[MARKERS_MAX] = { - { M_TRACKING_ENABLED, M_REFERENCE, 30, 0 }, - { M_DISABLED, M_NORMAL, 40, 0 }, - { M_DISABLED, M_NORMAL, 60, 0 }, - { M_DISABLED, M_NORMAL, 80, 0 } + { M_ENABLED, M_REFERENCE | M_TRACKING, 30, 0 }, + { M_DISABLED, M_NORMAL, 40, 0 }, + { M_DISABLED, M_NORMAL, 60, 0 }, + { M_DISABLED, M_NORMAL, 80, 0 } }; // Load propeties default settings diff --git a/nanovna.h b/nanovna.h index 86ef5ce..522505c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -319,11 +319,11 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]); #endif // marker enum { - M_REFERENCE, M_NORMAL, M_DELTA, M_TRACKING + M_NORMAL=0,M_REFERENCE=1, M_DELTA=2, M_NOISE=4, M_TRACKING=8 // Tracking must be last. }; enum { - M_DISABLED, M_ENABLED, M_TRACKING_ENABLED + M_DISABLED = false, M_ENABLED = true }; typedef struct { @@ -333,7 +333,6 @@ typedef struct { uint32_t frequency; } marker_t; - #define MARKERS_MAX 4 extern int8_t previous_marker; @@ -568,6 +567,7 @@ typedef struct uistat { // uint32_t previous_value; uint8_t lever_mode; uint8_t marker_delta; + uint8_t marker_noise; uint8_t marker_tracking; char text[20]; } uistat_t; @@ -647,7 +647,7 @@ void wait_user(void); void calibrate(void); enum { - M_OFF, M_IMD, M_OIP3 + M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE }; /*EOF*/ diff --git a/plot.c b/plot.c index 0e57e0f..8b662c8 100644 --- a/plot.c +++ b/plot.c @@ -63,18 +63,28 @@ typedef uint16_t map_t; typedef uint32_t map_t; #endif -uint16_t marker_color[3] = +uint16_t marker_color(int mtype) { - RGBHEX(0xFFFFFF), - RGBHEX(0xFFFF00), - RGBHEX(0x00FF00) -}; + if (mtype & M_REFERENCE) + return(RGBHEX(0xFFFFFF)); + if (mtype & M_DELTA) + return(RGBHEX(0x00FF00)); + if (mtype & M_NOISE) + return(RGBHEX(0x00FFFF)); + return(RGBHEX(0xFFFF00)); +} + +//#if 4 != M_TRACKING +//#error "Wrong marker numbers" +//#endif -char marker_letter[3] = +char marker_letter[5] = { 'R', + ' ', + 'D', 'N', - 'D' + 'T' }; map_t markmap[2][MAX_MARKMAP_Y]; @@ -782,7 +792,7 @@ static void trace_get_value_string( buf2[0]=' '; uint32_t dfreq = 0; float rlevel = 0; - if (mtype == M_DELTA) { + if (mtype & M_DELTA) { if (ri > i) { dfreq = frequencies[ri] - frequencies[i]; buf2[0] = '-'; @@ -803,10 +813,12 @@ static void trace_get_value_string( // frequency_string(&buf2[1], sizeof(buf2) -1, dfreq); v = logmag(&coeff[i]); + if (mtype & M_NOISE) + v = v - 10*log10(GetActualRBW()*1000.0); if (v == -INFINITY) plot_printf(buf, len, "-INF"); else - plot_printf(buf, len, "%s %.1f", buf2, v - rlevel); + plot_printf(buf, len, "%s %.1f%s", buf2, v - rlevel,(mtype & M_NOISE?"/Hz":"")); } #ifdef __VNA__ static int @@ -1401,12 +1413,12 @@ draw_cell(int m, int n) if (x + MARKER_WIDTH >= 0 && x < CELLWIDTH && y + MARKER_HEIGHT >= 0 && y < CELLHEIGHT) - draw_marker(x, y, marker_color[markers[i].mtype], i); + draw_marker(x, y, marker_color(markers[i].mtype), i); #else if (x + MARKER_WIDTH >= 0 && x - MARKER_WIDTH < CELLWIDTH && y + MARKER_HEIGHT >= 0 && y - MARKER_HEIGHT < CELLHEIGHT) - draw_marker(x, y, marker_color[markers[i].mtype], i); + draw_marker(x, y, marker_color(markers[i].mtype), i); #endif // draw_marker(x, y, config.trace_color[t], i); // } @@ -1820,7 +1832,7 @@ static void cell_draw_marker_info(int x0, int y0) int ref_marker = 0; int j = 0; for (int i = 0; i < MARKER_COUNT; i++) { - if (markers[i].enabled && markers[i].mtype == M_REFERENCE) { + if (markers[i].enabled && markers[i].mtype & M_REFERENCE) { ref_marker = i; break; } @@ -1843,6 +1855,7 @@ static void cell_draw_marker_info(int x0, int y0) cell_drawstring_7x13(buf, xpos, ypos); break; } +#if 0 if (i >= 2 && in_selftest) { plot_printf(buf, sizeof buf, "DO NOT SWITCH OFF!!"); j = 2; @@ -1852,6 +1865,7 @@ static void cell_draw_marker_info(int x0, int y0) cell_drawstring_7x13(buf, xpos, ypos); break; } +#endif if (!markers[i].enabled) continue; int idx = markers[i].index; @@ -1870,25 +1884,31 @@ static void cell_draw_marker_info(int x0, int y0) int k = 0; if (i == active_marker) { // ili9341_set_foreground(DEFAULT_BG_COLOR); -// ili9341_set_background(marker_color[markers[i].mtype]); +// ili9341_set_background(marker_color(markers[i].mtype)); buf[k++] = '\033'; // Right arrow (?) } else { // ili9341_set_background(DEFAULT_BG_COLOR); -// ili9341_set_foreground(marker_color[markers[i].mtype]); +// ili9341_set_foreground(marker_color(markers[i].mtype)); buf[k++] = ' '; // buf[k++] = ' '; } buf[k++] = i+'1'; -// buf[k++] = marker_letter[markers[i].mtype]; + if (markers[i].mtype & M_REFERENCE) + buf[k++] = 'R'; + if (markers[i].mtype & M_DELTA) + buf[k++] = 'D'; + if (markers[i].mtype & M_NOISE) + buf[k++] = 'N'; buf[k++] = 0; ili9341_set_background(DEFAULT_BG_COLOR); - ili9341_set_foreground(marker_color[markers[i].mtype]); + ili9341_set_foreground(marker_color(markers[i].mtype)); cell_drawstring_7x13(buf, xpos, ypos); + xpos += strlen(buf)*7; // cell_drawstring_size(buf, xpos, ypos, 2); trace_get_value_string( t, buf, sizeof buf, idx, measured[trace[t].channel], frequencies, sweep_points, ridx, markers[i].mtype); - cell_drawstring_7x13(buf, xpos+3*7, ypos); + cell_drawstring_7x13(buf, xpos, ypos); // cell_drawstring_size(buf, xpos+3*7, ypos, 2); j++; } diff --git a/sa_core.c b/sa_core.c index da76f41..3820e86 100644 --- a/sa_core.c +++ b/sa_core.c @@ -736,7 +736,7 @@ int binary_search(int f) int avoid_spur(int f) { - int window = ((int)actual_rbw ) * 1000*2; +// int window = ((int)actual_rbw ) * 1000*2; // if (window < 50000) // window = 50000; if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0) @@ -826,7 +826,12 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) setFreq (1, local_IF + lf); if (MODE_OUTPUT(setting_mode)) // No substepping in output mode return(0); - float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+setting_attenuate; + float signal_path_loss; + if (setting_mode == M_LOW) + signal_path_loss = -9.5; // Loss in dB + else + signal_path_loss = 7; // Loss in dB (+ is gain) + float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+ setting_attenuate - signal_path_loss; if (RSSI < subRSSI) RSSI = subRSSI; t++; @@ -965,11 +970,11 @@ static bool sweep(bool break_on_operation) draw_cal_status(); } if (!in_selftest && setting_mode == M_LOW && setting_auto_attenuation && max_index[0] > 0) { - if (actual_t[max_index[0]] - setting_attenuate < -30 && setting_attenuate >= 10) { + if (actual_t[max_index[0]] - setting_attenuate < -32 && setting_attenuate >= 10) { setting_attenuate -= setting_scale; redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) - } else if (actual_t[max_index[0]] - setting_attenuate > -20 && setting_attenuate <= 20) { + } else if (actual_t[max_index[0]] - setting_attenuate > -18 && setting_attenuate <= 20) { setting_attenuate += setting_scale; redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) @@ -980,11 +985,11 @@ static bool sweep(bool break_on_operation) SetReflevel(setting_reflevel + setting_scale); redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) - } else if (temp_min_level < setting_reflevel - 9 * setting_scale && actual_t[max_index[0]] < setting_reflevel - setting_scale * 3 / 2) { + } else if (temp_min_level < setting_reflevel - 9 * setting_scale - 2 && actual_t[max_index[0]] < setting_reflevel - setting_scale * 3 / 2) { SetReflevel(setting_reflevel - setting_scale); redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) - } else if (temp_min_level > setting_reflevel - 9 * setting_scale + setting_scale * 3 / 2) { + } else if (temp_min_level > setting_reflevel - 9 * setting_scale + setting_scale + 2) { SetReflevel(setting_reflevel + setting_scale); redraw_request |= REDRAW_CAL_STATUS; dirty = true; // Must be above if(scandirty!!!!!) @@ -996,7 +1001,7 @@ static bool sweep(bool break_on_operation) int m = 0; while (i < cur_max) { // For all maxima found while (m < MARKERS_MAX) { - if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found + if (markers[m].enabled && markers[m].mtype & M_TRACKING) { // Available marker found markers[m].index = max_index[i]; markers[m].frequency = frequencies[markers[m].index]; m++; @@ -1007,7 +1012,7 @@ static bool sweep(bool break_on_operation) i++; } while (m < MARKERS_MAX) { - if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found + if (markers[m].enabled && markers[m].mtype & M_TRACKING) { // More available markers found markers[m].index = 0; // Enabled but no max markers[m].frequency = frequencies[markers[m].index]; } @@ -1024,8 +1029,8 @@ static bool sweep(bool break_on_operation) l = markers[1].index; r = markers[0].index; } - markers[2].enabled = search_maximum(2, l - (r-l), 10); - markers[3].enabled = search_maximum(3, r + (r-l), 10); + } else if (setting_measurement == M_PHASE_NOISE && markers[0].index > 10) { + markers[1].index = markers[0].index + (setting_mode == M_LOW ? 290/4 : -290/4); // Position phase noise marker at requested offset } peakIndex = max_index[0]; peakLevel = actual_t[peakIndex]; @@ -1238,21 +1243,21 @@ static const struct { float stop; } test_case [TEST_COUNT] = {// Condition Preparation Center Span Pass Width Stop - {TC_BELOW, TP_SILENT, 0.005, 0.01, -10,0, 0}, // 1 Zero Hz leakage - {TC_BELOW, TP_SILENT, 0.01, 0.01, -40, 0, 0}, // 2 Phase noise of zero Hz - {TC_SIGNAL, TP_10MHZ, 20, 7, -40, 30, -90 }, // 3 - {TC_SIGNAL, TP_10MHZ, 30, 7, -30, 30, -90 }, // 4 - {TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 5 Wide band noise floor low mode - {TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 6 Wide band noise floor high mode - {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 50, -70 }, // 7 BPF loss and stop band - {TC_FLAT, TP_10MHZEXTRA, 10, 4, -25, 20, -70}, // 8 BPF pass band flatness - {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 9 LPF cutoff + {TC_BELOW, TP_SILENT, 0.005, 0.01, 0,0, 0}, // 1 Zero Hz leakage + {TC_BELOW, TP_SILENT, 0.01, 0.01, -30, 0, 0}, // 2 Phase noise of zero Hz + {TC_SIGNAL, TP_10MHZ, 20, 7, -37, 30, -80 }, // 3 + {TC_SIGNAL, TP_10MHZ, 30, 7, -32, 30, -80 }, // 4 + {TC_BELOW, TP_SILENT, 200, 100, -70, 0, 0}, // 5 Wide band noise floor low mode + {TC_BELOW, TPH_SILENT, 600, 720, -65, 0, 0}, // 6 Wide band noise floor high mode + {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -13, 55, -60 }, // 7 BPF loss and stop band + {TC_FLAT, TP_10MHZEXTRA, 10, 4, -18, 20, -60}, // 8 BPF pass band flatness + {TC_BELOW, TP_30MHZ, 430, 60, -65, 0, -75}, // 9 LPF cutoff {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 7, -30, 30, -80 }, // 11 Measure power level and noise - {TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 12 Measure powerlevel and noise - {TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 13 Calibrate power high mode + {TC_MEASURE, TP_30MHZ, 30, 7, -22.5, 30, -70 }, // 11 Measure power level and noise + {TC_MEASURE, TP_30MHZ, 270, 4, -45, 30, -75 }, // 12 Measure powerlevel and noise + {TC_MEASURE, TPH_30MHZ, 270, 4, -45, 30, -75 }, // 13 Calibrate power high mode {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 1, -30, 30, -80 }, // 15 Measure RBW step time + {TC_MEASURE, TP_30MHZ, 30, 1, -20, 30, -70 }, // 15 Measure RBW step time {TC_END, 0, 0, 0, 0, 0, 0}, }; diff --git a/ui.c b/ui.c index 83e9ce9..ba27e04 100644 --- a/ui.c +++ b/ui.c @@ -29,6 +29,7 @@ uistat_t uistat = { current_trace: 0, lever_mode: LM_MARKER, marker_delta: FALSE, + marker_noise: FALSE, marker_tracking : FALSE, text : "", }; @@ -441,6 +442,7 @@ enum { #define MT_FORM 0x80 // Or with menu type to get large button with current value #define MT_BACK 0x40 #define MT_LEAVE 0x20 +#define MT_ICON 0x10 #define MT_MASK(x) (0xF & (x)) typedef void (*menuaction_cb_t)(int item, uint8_t data); @@ -791,7 +793,7 @@ menu_marker_search_cb(int item, uint8_t data) i = marker_search_right(markers[active_marker].index); break; case 4: /* tracking */ - uistat.marker_tracking = !uistat.marker_tracking; + markers[active_marker].mtype ^= M_TRACKING; break; } if (i != -1) @@ -831,7 +833,7 @@ static void menu_marker_sel_cb(int item, uint8_t data) { (void)data; - int t; +// int t; if (item >= 0 && item < MARKERS_MAX) { if (markers[item].enabled) { if (item == active_marker) { @@ -842,19 +844,30 @@ menu_marker_sel_cb(int item, uint8_t data) active_marker_select(item); } } else { - markers[item].enabled = M_ENABLED; // default tracking enabled + markers[item].enabled = M_ENABLED; active_marker_select(item); + markers[item].mtype = M_NORMAL; + markers[item].mtype |= (uistat.marker_delta ? M_DELTA : 0); + markers[item].mtype |= (uistat.marker_noise ? M_NOISE : 0); + markers[item].mtype |= (uistat.marker_tracking ? M_TRACKING : 0); } - if (markers[item].enabled) - menu_push_submenu(menu_marker_type); - + // if (markers[item].enabled) + // menu_push_submenu(menu_marker_type); +#if 0 } else if (item == 4) { /* all off */ for (t = 0; t < MARKERS_MAX; t++) markers[t].enabled = M_DISABLED; previous_marker = -1; active_marker = -1; - } else if (item == 5) { /* marker delta */ +#endif + } else if (item == 4) { /* marker delta */ uistat.marker_delta = !uistat.marker_delta; + } else if (item == 5) { /* marker noise */ + uistat.marker_noise = !uistat.marker_noise; + // if (uistat.marker_noise) uistat.marker_delta = true; //Default behavior + } else if (item == 6) { /* marker tracking */ + uistat.marker_tracking = !uistat.marker_tracking; + // if (uistat.marker_tracking) uistat.marker_noise = false; //Default behavior } redraw_marker(active_marker); draw_menu(); @@ -1554,32 +1567,33 @@ draw_menu_buttons(const menuitem_t *menu) if (menu[i].type & MT_FORM) { ili9341_fill(active_button_start+2, y+2, active_button_width-4, FONT_GET_HEIGHT*2+8, bg); ili9341_drawstring_size(text, active_button_start+6, y+6, 2); -// blit16BitWidthBitmap(240,y+6,16,16,&icons[3*16]); -// blit16BitWidthBitmap(256,y+6,16,16,&icons[0]); - + if (menu[i].type & MT_ICON) { + blit16BitWidthBitmap(240,y+6,16,16,&left_icons[((menu[i].data >>4)&0xf)*16]); + blit16BitWidthBitmap(256,y+6,16,16,&right_icons[((menu[i].data >>0)&0xf)*16]); + } } else { - if (menu_is_multiline(menu[i].label, &l1, &l2)) { + if (menu_is_multiline(menu[i].label, &l1, &l2)) { #define BIG_BUTTON_FONT 1 #ifdef BIG_BUTTON_FONT #undef FONT_HEIGHT #define FONT_HEIGHT 13 - ili9341_fill(active_button_start+1, y+1, active_button_width-2, 13+13 -2, bg); - ili9341_drawstring_7x13(l1, active_button_start+2, y+1); - ili9341_drawstring_7x13(l2, active_button_start+2, y+1+13-1); + ili9341_fill(active_button_start+1, y+1, active_button_width-2, 13+13 -2, bg); + ili9341_drawstring_7x13(l1, active_button_start+2, y+1); + ili9341_drawstring_7x13(l2, active_button_start+2, y+1+13-1); #else - ili9341_fill(active_button_start+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(l1, active_button_start+5, y+7); - ili9341_drawstring(l2, active_button_start+5, y+7+FONT_GET_HEIGHT+1); + ili9341_fill(active_button_start+3, y+5, active_button_width-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(l1, active_button_start+5, y+7); + ili9341_drawstring(l2, active_button_start+5, y+7+FONT_GET_HEIGHT+1); #endif - } else { + } else { #ifdef BIG_BUTTON_FONT - ili9341_fill(active_button_start+1, y+1, active_button_width-2, 13+13 -2, bg); - ili9341_drawstring_7x13(menu[i].label, active_button_start+2, y+6); + ili9341_fill(active_button_start+1, y+1, active_button_width-2, 13+13 -2, bg); + ili9341_drawstring_7x13(menu[i].label, active_button_start+2, y+6); #else - ili9341_fill(active_button_start+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(menu[i].label, active_button_start+5, y+10); + ili9341_fill(active_button_start+3, y+8, active_button_width-6, 2+FONT_GET_HEIGHT+2, bg); + ili9341_drawstring(menu[i].label, active_button_start+5, y+10); #endif - } + } } } } @@ -1799,7 +1813,7 @@ ui_mode_keypad(int _keypad_mode) ui_mode = UI_KEYPAD; area_width = AREA_WIDTH_NORMAL - MENU_BUTTON_WIDTH; area_height = HEIGHT - 32; - if (!menu_is_form(menu_stack[menu_current_level])) + if (!current_menu_is_form()) draw_menu(); draw_keypad(); draw_numeric_area_frame(); @@ -1821,18 +1835,25 @@ ui_mode_normal(void) static void lever_move_marker(int status) { + int step = 1; + int count = 0; do { if (active_marker >= 0 && markers[active_marker].enabled) { if ((status & EVT_DOWN) && markers[active_marker].index > 0) { - markers[active_marker].index--; + markers[active_marker].index -= step; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } if ((status & EVT_UP) && markers[active_marker].index < sweep_points-1) { - markers[active_marker].index++; + markers[active_marker].index += step; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } + count++; + if (count > 10) { + step *= 2; + count = 0; + } } status = btn_wait_release(); } while (status != 0); @@ -2227,7 +2248,7 @@ ui_process_keypad(void) } redraw_frame(); - if (menu_is_form(menu_stack[menu_current_level])) { + if (current_menu_is_form()) { ui_mode_menu(); //Reactivate menu after keypad selection = -1; ensure_selection(); @@ -2342,6 +2363,41 @@ touch_lever_mode_select(void) return FALSE; } +static int +touch_marker_select(void) +{ + int selected_marker = 0; + int touch_x, touch_y; + touch_position(&touch_x, &touch_y); + if (current_menu_is_form() || touch_x > 320-MENU_BUTTON_WIDTH || touch_x < 25 || touch_y > 30) + return FALSE; + if (touch_y > 15) + selected_marker = 2; + selected_marker += (touch_x >150 ? 1 : 0); + for (int i = 0; i < MARKERS_MAX; i++) { + if (markers[i].enabled) { + if (selected_marker == 0) { + active_marker = i; + break; + } + selected_marker --; + } + } + if (touch_y < 25) { +#ifdef __VNA__ + if (touch_x < FREQUENCIES_XPOS2 && get_electrical_delay() != 0.0) { + select_lever_mode(LM_EDELAY); + } else { +#endif + select_lever_mode(LM_MARKER); +#ifdef __VNA__ + } +#endif + return TRUE; + } + return FALSE; +} + static void ui_process_touch(void) { @@ -2355,11 +2411,14 @@ void ui_process_touch(void) // Try drag marker if (touch_pickup_marker()) break; + if (touch_marker_select()) + break; // Try select lever mode (top and bottom screen) if (touch_lever_mode_select()) { touch_wait_release(); break; } + // switch menu mode after release touch_wait_release(); selection = -1; // hide keyboard mode selection diff --git a/ui_sa.c b/ui_sa.c index 408eb41..e8aefa4 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -65,54 +65,33 @@ extern int setting_step_delay; void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap); -const uint16_t icons [] = +const uint16_t left_icons [] = { - - /* Character 0 (0x00): - width 16 - +-----------------+ - | | - | *************** | - | * * | - |** * | - | * * * | - | * * * | - | * * * * | - | * * * * | - | * * * * * | - | * * * * * * | - | * * * * * * * | - | * * * * * * * | - |** *********** * | - | * * | - | *************** | - | | - +-----------------+ */ +#define I_EMPTY 0*16 + 0x0000, + 0x0000, + 0x0000, + 0x0001, + 0x0001, + 0x0001, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0001, + 0x0001, + 0x0001, + 0x0000, 0x0000, - 0x7fff, - 0x4001, - 0xc001, - 0x4001, - 0x4001, - 0x4801, - 0x4801, - 0x4a89, - 0x4aa9, - 0x4aa9, - 0x5ffd, - 0xc001, - 0x4001, - 0x7fff, 0x0000, - /* Character 1 (0x01: - width 16 - +-----------------+ +#define I_HIGH_INPUT 1*16 + /* +-----------------+ | | | ** | - | **** | + | *** | | ************ | - | **** | + | *** | | ** | | | | | @@ -126,25 +105,24 @@ const uint16_t icons [] = | | +-----------------+ */ 0x0000, + 0x0000, 0x0060, - 0x0038, - 0x0ffe, - 0x0038, + 0x0039, + 0x0fff, + 0x0039, 0x0060, 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0x0001, + 0x0001, + 0x0001, 0x0000, 0x0000, 0x0000, - /* Character 2 (0x02): - width 16 - +-----------------+ +#define I_LOW_INPUT 2*16 + /* +-----------------+ | | | | | | @@ -165,38 +143,194 @@ const uint16_t icons [] = 0x0000, 0x0000, 0x0000, - 0x0000, - 0x0000, - 0x0000, + 0x0001, + 0x0001, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0060, - 0x0038, - 0x0ffe, - 0x0038, + 0x0039, + 0x0fff, + 0x0039, 0x0060, 0x0000, - /* High arrow left 0x03 */ +#define I_LOW_OUTPUT 3*16 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, + 0b0000000000000001, + 0b0000000000000001, + 0b0000000000000001, 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, + 0b0000000110000000, + 0b0000011110000001, + 0b0000111111111111, + 0b0000011110000001, + 0b0000000110000000, 0b0000000000000000, 0b0000000000000000, + +#define I_HIGH_OUTPUT 4*16 + 0b0000000000000000, 0b0000000000000000, 0b0000000110000000, - 0b0000011110000000, - 0b0000111111111110, - 0b0000011110000000, + 0b0000011110000001, + 0b0000111111111111, + 0b0000011110000001, 0b0000000110000000, 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000001, + 0b0000000000000001, + 0b0000000000000001, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + +#define I_CONNECT 5*16 + + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000110000, + 0b0000000000111101, + 0b0000001111111111, + 0b0000010000111101, + 0b0000100000110000, + 0b0001000000000000, + 0b0001000000000000, + 0b0000100000110000, + 0b0000010000111101, + 0b0000001111111111, + 0b0000000000111101, + 0b0000000000110000, + 0b0000000000000000, + 0b0000000000000000, + +}; + +const uint16_t right_icons [] = +{ +#define I_SA 0 + /* Character 0 (0x00): + width 16 + +-----------------+ + | | + | *************** | + | * * | + |** * | + | * * * | + | * * * | + | * * * * | + | * * * * | + | * * * * * | + | * * * * * * | + | * * * * * * * | + | * * * * * * * | + |** *********** * | + | * * | + | *************** | + | | + +-----------------+ */ + 0x0000, + 0x7fff, + 0x4001, + 0xc001, + 0xc001, + 0xc001, + 0x4801, + 0x4801, + 0x4a89, + 0x4aa9, + 0xcaa9, + 0xdffd, + 0xc001, + 0x4001, + 0x7fff, + 0x0000, + +#define I_GEN 1 + /* Character 0 (0x00): + width 16 + +-----------------+ + | | + | *************** | + | * * | + |** * | + | * ***** ** * | + | * * * * * | + | * * * * * | + | * * * * * | + | * * * * * | + | * * * * * | + | * * * * * | + | * ** ***** * | + |** * | + | * * | + | *************** | + | | + +-----------------+ */ + 0x0000, + 0x7fff, + 0x4001, + 0xc001, + 0xcf8d, + 0xc889, + 0x4889, + 0x4889, + 0x4889, + 0x4889, + 0xc889, + 0xd8f9, + 0xc001, + 0x4001, + 0x7fff, + 0x0000, + +#define I_CONFIG 2 + + 0b0000000000000000, + 0b0111111111111111, + 0b0100000000000001, + 0b1100000011000001, + 0b1100001110001001, + 0b1100011100011101, + 0b0100001110111001, + 0b0100001111111001, + 0b0100011111110001, + 0b0100111110000001, + 0b1101111100000001, + 0b1101111000000001, + 0b1100100000000001, + 0b0100000000000001, + 0b0111111111111111, + 0b0000000000000000, + +#define I_SINUS 3 + + 0b0000000000000000, + 0b0111111111111111, // 1 + 0b0100000000000001, // 2 + 0b1100000000000001, // 3 + 0b1100000000110001, // 4 + 0b1100000001001001, // 5 + 0b0100000010000101, // 6 + 0b0101000010000101, // 7 + 0b0101000010000101, // 8 + 0b0101000010000001, // 9 + 0b1100100100000001, //10 + 0b1100011000000001, //11 + 0b1100000000000001, //12 + 0b0100000000000001, //13 + 0b0111111111111111, //14 + 0b0000000000000000, }; @@ -369,8 +503,8 @@ void menu_autosettings_cb(int item, uint8_t data) for (int i = 1; i= 0 && markers[active_marker].enabled) { - if (item == 3 && markers[active_marker].enabled == M_TRACKING_ENABLED) + } else if (menu == menu_marker_type && active_marker >= 0 && markers[active_marker].enabled == M_ENABLED) { + if (data & markers[active_marker].mtype) + mark = true; + else if (data==markers[active_marker].mtype) // This catches the M_NORMAL case mark = true; - else if (item == markers[active_marker].mtype) + } else if (menu == menu_marker_search) { + if (item == 4 && markers[active_marker].mtype & M_TRACKING) mark = true; } else if (menu == menu_marker_sel) { if (item < MARKERS_MAX && markers[item].enabled) mark = true; + else if (item == 4 && uistat.marker_delta) + mark = true; + else if (item == 5 && uistat.marker_noise) + mark = true; + else if (item == 6 && uistat.marker_tracking) + mark = true; } else if (menu == menu_reflevel) { if ((item == 0 && setting_auto_reflevel) || (item == 1 && !setting_auto_reflevel)) mark = true; From ca8d1382f588ef0ed5c53aef19bf4cef78a8ed61 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 12 Apr 2020 15:54:27 +0200 Subject: [PATCH 072/193] Improved IMD --- sa_core.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/sa_core.c b/sa_core.c index 3820e86..b725708 100644 --- a/sa_core.c +++ b/sa_core.c @@ -567,15 +567,42 @@ void update_rbw(void) vbwSteps = 1; dirty = true; } + +int binary_search_frequency(int f) +{ + int L = 0; + int R = (sizeof frequencies)/sizeof(int) - 1; + int fmin = f - ((int)actual_rbw ) * 1000; + int fplus = f + ((int)actual_rbw ) * 1000; + while (L <= R) { + int m = (L + R) / 2; + if (frequencies[m] < fmin) + L = m + 1; + else if (frequencies[m] > fplus) + R = m - 1; + else + return m; // index is m + } + return -1; +} + + #define MAX_MAX 4 int search_maximum(int m, int center, int span) { + center = binary_search_frequency(center); + if (center < 0) + return false; int from = center - span/2; int found = false; int to = center + span/2; int cur_max = 0; // Always at least one maximum int max_index[4]; + if (from<0) + from = 0; + if (to > POINTS_COUNT-1) + to = POINTS_COUNT-1; temppeakIndex = 0; temppeakLevel = actual_t[from]; max_index[cur_max] = from; @@ -1019,9 +1046,9 @@ static bool sweep(bool break_on_operation) m++; // Try next marker } if (setting_measurement == M_IMD && markers[0].index > 10) { - markers[1].enabled = search_maximum(1, markers[0].index*2, 8); - markers[2].enabled = search_maximum(2, markers[0].index*3, 12); - markers[3].enabled = search_maximum(3, markers[0].index*4, 16); + markers[1].enabled = search_maximum(1, frequencies[markers[0].index]*2, 8); + markers[2].enabled = search_maximum(2, frequencies[markers[0].index]*3, 12); + markers[3].enabled = search_maximum(3, frequencies[markers[0].index]*4, 16); } else if (setting_measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) { int l = markers[0].index; int r = markers[1].index; From 5b661b90934158d076c25dea3911f4b196dead97 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 12 Apr 2020 17:39:19 +0200 Subject: [PATCH 073/193] Hangup in offset keypad solved --- Makefile | 2 +- nanovna.h | 4 ++++ plot.c | 2 ++ sa_core.c | 12 +++++++++++- ui.c | 6 ++++++ ui_sa.c | 7 +++++-- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2af90d0..4865a71 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # Compiler options here. ifeq ($(USE_OPT),) USE_OPT = -Og -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage -# USE_OPT = -fdce -fdse -fmerge-constants -fstore-merging -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage +# USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer -falign-functions=16 --specs=nano.specs -fstack-usage endif # C specific options here (added to USE_OPT). diff --git a/nanovna.h b/nanovna.h index 522505c..1db0c1a 100644 --- a/nanovna.h +++ b/nanovna.h @@ -26,6 +26,10 @@ //#define __SIMULATION__ //#define __PIPELINE__ #define __SCROLL__ +#define __ICONS__ +#define __MEASURE__ +#define __SELFTEST__ + /* * main.c */ diff --git a/plot.c b/plot.c index 8b662c8..0f6e086 100644 --- a/plot.c +++ b/plot.c @@ -1429,7 +1429,9 @@ draw_cell(int m, int n) if (n == 0) cell_draw_marker_info(x0, y0); #endif +#ifdef __SELFTEST__ cell_draw_test_info(x0, y0); +#endif // PULSE; // Draw reference position (<10 system ticks for all screen calls) for (t = 0; t < TRACES_MAX; t++) { diff --git a/sa_core.c b/sa_core.c index b725708..355b754 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1045,6 +1045,7 @@ static bool sweep(bool break_on_operation) } m++; // Try next marker } +#ifdef __MEASURE__ if (setting_measurement == M_IMD && markers[0].index > 10) { markers[1].enabled = search_maximum(1, frequencies[markers[0].index]*2, 8); markers[2].enabled = search_maximum(2, frequencies[markers[0].index]*3, 12); @@ -1059,6 +1060,7 @@ static bool sweep(bool break_on_operation) } else if (setting_measurement == M_PHASE_NOISE && markers[0].index > 10) { markers[1].index = markers[0].index + (setting_mode == M_LOW ? 290/4 : -290/4); // Position phase noise marker at requested offset } +#endif peakIndex = max_index[0]; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; @@ -1249,6 +1251,7 @@ void draw_cal_status(void) } // -------------------- Self testing ------------------------------------------------- +#ifdef __SELFTEST__ enum { TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT, TC_MEASURE, TC_SET, TC_END, @@ -1569,10 +1572,13 @@ int add_spur(int f) } return 1; } +#endif void self_test(void) { -#if 0 +#ifdef __SELFTEST__ + + #if 0 in_selftest = true; reset_settings(M_LOW); test_prepare(4); @@ -1698,6 +1704,8 @@ void self_test(void) reset_settings(M_LOW); in_selftest = false; #endif + +#endif } void reset_calibration(void) @@ -1710,6 +1718,7 @@ const int power_rbw [5] = { 100, 300, 30, 10, 3 }; void calibrate(void) { +#ifdef __CALIBRATE__ int local_test_status; float last_peak_level; in_selftest = true; @@ -1766,6 +1775,7 @@ quit: sweep_mode = SWEEP_ENABLE; set_refer_output(0); reset_settings(M_LOW); +#endif } diff --git a/ui.c b/ui.c index ba27e04..290e3cd 100644 --- a/ui.c +++ b/ui.c @@ -1567,10 +1567,12 @@ draw_menu_buttons(const menuitem_t *menu) if (menu[i].type & MT_FORM) { ili9341_fill(active_button_start+2, y+2, active_button_width-4, FONT_GET_HEIGHT*2+8, bg); ili9341_drawstring_size(text, active_button_start+6, y+6, 2); +#ifdef __ICONS__ if (menu[i].type & MT_ICON) { blit16BitWidthBitmap(240,y+6,16,16,&left_icons[((menu[i].data >>4)&0xf)*16]); blit16BitWidthBitmap(256,y+6,16,16,&right_icons[((menu[i].data >>0)&0xf)*16]); } +#endif } else { if (menu_is_multiline(menu[i].label, &l1, &l2)) { #define BIG_BUTTON_FONT 1 @@ -1841,11 +1843,15 @@ lever_move_marker(int status) if (active_marker >= 0 && markers[active_marker].enabled) { if ((status & EVT_DOWN) && markers[active_marker].index > 0) { markers[active_marker].index -= step; + if (markers[active_marker].index < 5) + markers[active_marker].index = 5 ; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } if ((status & EVT_UP) && markers[active_marker].index < sweep_points-1) { markers[active_marker].index += step; + if (markers[active_marker].index > POINTS_COUNT-5) + markers[active_marker].index = POINTS_COUNT-5 ; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } diff --git a/ui_sa.c b/ui_sa.c index e8aefa4..705e227 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -65,6 +65,7 @@ extern int setting_step_delay; void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap); + const uint16_t left_icons [] = { #define I_EMPTY 0*16 @@ -333,7 +334,6 @@ const uint16_t right_icons [] = 0b0000000000000000, }; - enum { KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE, KM_10MHZ @@ -454,7 +454,8 @@ static const char * const keypad_mode_label[] = { #endif #ifdef __SA__ static const char * const keypad_mode_label[] = { - "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL", "LEVEL" + "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", // 0-7 + "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL", "LEVEL", "OFFSET" // 8-16 }; #endif @@ -630,6 +631,7 @@ static void menu_measure_cb(int item, uint8_t data) { (void)item; menu_move_back(); +#ifdef __MEASURE__ switch(data) { case M_OFF: // Off reset_settings(GetMode()); @@ -682,6 +684,7 @@ static void menu_measure_cb(int item, uint8_t data) break; } +#endif // selection = -1; ui_mode_normal(); // draw_cal_status(); From 01f7fb629e69b3d632170add1ad80716f875164d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 12 Apr 2020 17:55:20 +0200 Subject: [PATCH 074/193] Added board identification --- NANOVNA_STM32_F072/board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index 1a43c50..5724a6c 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -21,7 +21,7 @@ * Board identifier. */ #define BOARD_NANOVNA_STM32_F072 -#define BOARD_NAME "tinySA" +#define BOARD_NAME "tinySA v0.1" #define BOARD_VERSION 0 /* * Board frequencies. From 1ac5ab7f1e8a4c4d22cf88b8c79770fd14c490bb Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 12 Apr 2020 17:56:21 +0200 Subject: [PATCH 075/193] Added v0.2 identification --- NANOVNA_STM32_F072/board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index d57efad..7a8ac43 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -21,7 +21,7 @@ * Board identifier. */ #define BOARD_NANOVNA_STM32_F072 -#define BOARD_NAME "tinySA v0.1" +#define BOARD_NAME "tinySA v0.2" #define BOARD_VERSION 0 /* * Board frequencies. From c259ca4727993c455802d7dafb350ec794aa056e Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 12 Apr 2020 18:36:58 +0200 Subject: [PATCH 076/193] Marker search repaired --- plot.c | 40 +++++++++++++++++++++++----------------- ui_sa.c | 7 ++++++- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/plot.c b/plot.c index 0f6e086..e02e6cd 100644 --- a/plot.c +++ b/plot.c @@ -1144,7 +1144,7 @@ marker_position(int m, int t, int *x, int *y) static int greater(int x, int y) { return x > y; } static int lesser(int x, int y) { return x < y; } -static int (*compare)(int x, int y) = lesser; +static int (*compare)(int x, int y) = greater; int marker_search(void) @@ -1157,9 +1157,9 @@ marker_search(void) int value = CELL_Y(trace_index[TRACE_ACTUAL][0]); for (i = 0; i < sweep_points; i++) { - index_t index = trace_index[TRACE_ACTUAL][i]; - if ((*compare)(value, CELL_Y(index))) { - value = CELL_Y(index); + int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); + if ((*compare)(value, new_value)) { + value = new_value; found = i; } } @@ -1173,30 +1173,36 @@ set_marker_search(int mode) compare = (mode == 0) ? greater : lesser; } +int +search_is_greater(void) +{ + return(compare == greater); +} + int marker_search_left(int from) { int i; int found = -1; -#define MINMAX_DELTA -10 +#define MINMAX_DELTA -5 if (uistat.current_trace == -1) return -1; int value = CELL_Y(trace_index[TRACE_ACTUAL][from]); for (i = from - 1; i >= 0; i--) { - index_t index = trace_index[TRACE_ACTUAL][i]; - if ((*compare)(value - MINMAX_DELTA, CELL_Y(index))) + int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); + if ((*compare)(value + MINMAX_DELTA, new_value)) break; - value = CELL_Y(index); + value = new_value; } for (; i >= 0; i--) { - index_t index = trace_index[TRACE_ACTUAL][i]; - if ((*compare)(CELL_Y(index), value + MINMAX_DELTA)) { + int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); + if ((*compare)(new_value, value - MINMAX_DELTA)) { break; } found = i; - value = CELL_Y(index); + value = new_value; } return found; } @@ -1211,19 +1217,19 @@ marker_search_right(int from) return -1; int value = CELL_Y(trace_index[TRACE_ACTUAL][from]); for (i = from + 1; i < sweep_points; i++) { - index_t index = trace_index[TRACE_ACTUAL][i]; - if ((*compare)(value, CELL_Y(index))) + int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); + if ((*compare)(value+MINMAX_DELTA, new_value)) break; - value = CELL_Y(index); + value = new_value; } for (; i < sweep_points; i++) { - index_t index = trace_index[TRACE_ACTUAL][i]; - if ((*compare)(CELL_Y(index), value)) { + int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); + if ((*compare)(new_value, value-MINMAX_DELTA)) { break; } found = i; - value = CELL_Y(index); + value = new_value; } return found; } diff --git a/ui_sa.c b/ui_sa.c index 705e227..396d3be 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -752,6 +752,7 @@ static void menu_marker_type_cb(int item, uint8_t data) markers[i].mtype &= ~M_REFERENCE; } markers[active_marker].mtype |= M_REFERENCE; + markers[active_marker].mtype &= ~M_DELTA; } else { if (data == M_DELTA && (markers[active_marker].mtype & M_REFERENCE)) markers[active_marker].mtype &= ~M_REFERENCE; @@ -1357,9 +1358,13 @@ static void menu_item_modify_attribute( } else if (menu == menu_marker_type && active_marker >= 0 && markers[active_marker].enabled == M_ENABLED) { if (data & markers[active_marker].mtype) mark = true; - else if (data==markers[active_marker].mtype) // This catches the M_NORMAL case + else if (item < 5 && data==markers[active_marker].mtype) // This catches the M_NORMAL case mark = true; } else if (menu == menu_marker_search) { + if (item == 0 && search_is_greater()) + mark = true; + if (item == 1 && !search_is_greater()) + mark = true; if (item == 4 && markers[active_marker].mtype & M_TRACKING) mark = true; } else if (menu == menu_marker_sel) { From 3aa934bad8c7b6121ae6f6aaeb507b2fcff06ed3 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 13 Apr 2020 12:21:54 +0200 Subject: [PATCH 077/193] Tracking generator output and cleaning up UI --- ili9341.c | 4 +-- main.c | 1 + nanovna.h | 2 +- plot.c | 7 +++-- sa_core.c | 35 +++++++++++++++++++---- ui_sa.c | 85 +++++++++++++++++++++++++++++++++---------------------- 6 files changed, 88 insertions(+), 46 deletions(-) diff --git a/ili9341.c b/ili9341.c index bcca3ec..388986c 100644 --- a/ili9341.c +++ b/ili9341.c @@ -608,8 +608,8 @@ void ili9341_drawstring_7x13(const char *str, int x, int y) { while (*str) { uint8_t ch = *str++; - const uint16_t *char_buf = &x7x13b_bits[(ch * 13)]; - blit16BitWidthBitmap(x, y, 7, 11, char_buf); + const uint16_t *char_buf = &x7x13b_bits[(ch * 13)]; // All chars start at row 2 + blit16BitWidthBitmap(x, y, 7, 12, char_buf); // Only 'Q' has 12 rows x += 7; } } diff --git a/main.c b/main.c index 59acdd5..bba6558 100644 --- a/main.c +++ b/main.c @@ -2662,6 +2662,7 @@ int main(void) ui_init(); //Initialize graph plotting plot_init(); + redraw_frame(); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO-1, Thread1, NULL); diff --git a/nanovna.h b/nanovna.h index 1db0c1a..50c8b55 100644 --- a/nanovna.h +++ b/nanovna.h @@ -132,7 +132,7 @@ enum { }; enum { - MO_NONE, MO_AM, MO_NFM, MO_WFM, + MO_NONE, MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL, }; #define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH ) diff --git a/plot.c b/plot.c index e02e6cd..f0d2123 100644 --- a/plot.c +++ b/plot.c @@ -1512,9 +1512,9 @@ draw_all_cells(bool flush_markmap) b = (k-128)*4; } #else - volatile int k = (actual_t[i]+120)* 2; - if (k > 255) k = 255; - volatile unsigned int r=0,g=0,b=0; + int k = (actual_t[i]+120)* 2 * 8; + k &= 255; + unsigned int r=0,g=0,b=0; if (k < 64) { b = 255; g = k*2 + 128; @@ -2089,6 +2089,7 @@ toggle_waterfall(void) { if (!waterfall) { _height = HEIGHT_SCROLL; + ili9341_fill(5*5, HEIGHT, 320 - 5*5, 236-HEIGHT, 0); waterfall = true; fullscreen = false; } else { diff --git a/sa_core.c b/sa_core.c index 355b754..bb8bb9e 100644 --- a/sa_core.c +++ b/sa_core.c @@ -27,6 +27,7 @@ int setting_decay; int setting_noise; float actual_rbw = 0; float setting_vbw = 0; +int setting_tracking_output; int setting_measurement; @@ -63,6 +64,7 @@ void reset_settings(int m) setting_auto_reflevel = true; // Must be after SetReflevel setting_decay=20; setting_noise=5; + setting_tracking_output = false; trace[TRACE_STORED].enabled = false; trace[TRACE_TEMP].enabled = false; @@ -138,6 +140,18 @@ void SetDrive(int d) dirty = true; } +void set_tracking_output(int t) +{ + setting_tracking_output = t; + dirty = true; +} + +void toggle_tracking_output(void) +{ + setting_tracking_output = !setting_tracking_output; + dirty = true; +} + void SetModulation(int m) { setting_modulation = m; @@ -420,6 +434,7 @@ void apply_settings(void) } else actualStepDelay = setting_step_delay; PE4302_Write_Byte(setting_attenuate * 2); +#if 0 if (setting_modulation == MO_NFM ) { SI4432_Sel = 1; SI4432_Write_Byte(0x7A, 1); // Use frequency hopping channel width for FM modulation @@ -430,6 +445,7 @@ void apply_settings(void) SI4432_Sel = 1; SI4432_Write_Byte(0x79, 0); // IF no FM back to channel 0 } +#endif SetRX(setting_mode); SI4432_SetReference(setting_refer); update_rbw(); @@ -494,7 +510,10 @@ case M_LOW: // Mixed into 0 SetAGCLNA(); SI4432_Sel = 1; - SetSwitchReceive(); + if (setting_tracking_output) + SetSwitchTransmit(); + else + SetSwitchReceive(); // SI4432_Receive(); For noise testing only SI4432_Transmit(setting_drive); // SI4432_SetReference(setting_refer); @@ -521,9 +540,13 @@ case M_GENLOW: // Mixed output from 0 SI4432_Transmit(setting_drive); SI4432_Sel = 1; - SetSwitchReceive(); - SI4432_Transmit(12); // Fix LO drive a 10dBm - + if (setting_modulation == MO_EXTERNAL) { + SetSwitchTransmit(); // High input for external LO scuh as tracking output of other tinySA + SI4432_Receive(); + } else { + SetSwitchReceive(); + SI4432_Transmit(12); // Fix LO drive a 10dBm + } break; case M_GENHIGH: // Direct output from 1 SI4432_Sel = 0; @@ -576,9 +599,9 @@ int binary_search_frequency(int f) int fplus = f + ((int)actual_rbw ) * 1000; while (L <= R) { int m = (L + R) / 2; - if (frequencies[m] < fmin) + if ((int)frequencies[m] < fmin) L = m + 1; - else if (frequencies[m] > fplus) + else if ((int)frequencies[m] > fplus) R = m - 1; else return m; // index is m diff --git a/ui_sa.c b/ui_sa.c index 396d3be..f3b28e6 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -45,6 +45,7 @@ void set_decay(int); void set_noise(int); extern int32_t frequencyExtra; extern int setting_tracking; +extern int setting_tracking_output; extern int setting_drive; extern int setting_lna; extern int setting_agc; @@ -150,13 +151,13 @@ const uint16_t left_icons [] = 0x0000, 0x0000, 0x0000, - 0x0000, 0x0060, 0x0039, 0x0fff, 0x0039, 0x0060, 0x0000, + 0x0000, #define I_LOW_OUTPUT 3*16 @@ -170,9 +171,9 @@ const uint16_t left_icons [] = 0b0000000000000000, 0b0000000000000000, 0b0000000110000000, - 0b0000011110000001, + 0b0000011100000001, 0b0000111111111111, - 0b0000011110000001, + 0b0000011100000001, 0b0000000110000000, 0b0000000000000000, 0b0000000000000000, @@ -182,9 +183,9 @@ const uint16_t left_icons [] = 0b0000000000000000, 0b0000000000000000, 0b0000000110000000, - 0b0000011110000001, + 0b0000011100000001, 0b0000111111111111, - 0b0000011110000001, + 0b0000011100000001, 0b0000000110000000, 0b0000000000000000, 0b0000000000000000, @@ -300,16 +301,16 @@ const uint16_t right_icons [] = 0b0000000000000000, 0b0111111111111111, 0b0100000000000001, - 0b1100000011000001, - 0b1100001110001001, - 0b1100011100011101, - 0b0100001110111001, + 0b1100000010000001, + 0b1100001111000001, + 0b1100011110001001, + 0b0100011100011101, + 0b0100011110111001, 0b0100001111111001, 0b0100011111110001, - 0b0100111110000001, + 0b1100111110000001, 0b1101111100000001, - 0b1101111000000001, - 0b1100100000000001, + 0b1100111000000001, 0b0100000000000001, 0b0111111111111111, 0b0000000000000000, @@ -454,7 +455,7 @@ static const char * const keypad_mode_label[] = { #endif #ifdef __SA__ static const char * const keypad_mode_label[] = { - "error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", // 0-7 + "error", "START", "STOP", "CENTER", "SPAN", "FREQ", "REFPOS", "SCALE", // 0-7 "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL", "LEVEL", "OFFSET" // 8-16 }; #endif @@ -573,8 +574,8 @@ static void menu_dfu_cb(int item, uint8_t data) } -const int menu_modulation_value[]={MO_NONE,MO_AM, MO_NFM, MO_WFM}; -const char *menu_modulation_text[]={"NONE","AM","NARROW FM","WIDE FM"}; +const int menu_modulation_value[]={MO_NONE,MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL}; +const char *menu_modulation_text[]={"NONE","AM","NARROW FM","WIDE FM", "EXTERNAL"}; static void menu_modulation_cb(int item, uint8_t data) { @@ -829,6 +830,9 @@ static void menu_settings2_cb(int item, uint8_t data) case 2: toggle_tracking(); break; + case 3: + toggle_tracking_output(); + break; } draw_menu(); // draw_cal_status(); @@ -900,6 +904,7 @@ const menuitem_t menu_modulation[] = { { MT_FORM | MT_CALLBACK, 1, "AM", menu_modulation_cb}, { MT_FORM | MT_CALLBACK, 2, "NARROW FM", menu_modulation_cb}, { MT_FORM | MT_CALLBACK, 3, "WIDE FM", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, 4, "EXTERNAL", menu_modulation_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1058,7 +1063,7 @@ const menuitem_t menu_marker_ops[] = { static const menuitem_t menu_marker[] = { { MT_SUBMENU, 0, "\2SELECT\0MARKERS", menu_marker_sel}, - { MT_SUBMENU, 0, "\2MARKER\0TYPE", menu_marker_type}, + { MT_SUBMENU, 0, "\2CHANGE\0MARKER", menu_marker_type}, { MT_SUBMENU, 0, "\2MARKER\0OPS", menu_marker_ops}, { MT_SUBMENU, 0, "\2SEARCH\0MARKER", menu_marker_search}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, @@ -1085,12 +1090,13 @@ static const menuitem_t menu_settings2[] = static const menuitem_t menu_settings[] = { - { MT_KEYPAD, KM_ACTUALPOWER, "\2ACTUAL\0POWER", NULL}, - { MT_KEYPAD, KM_IF, "\2IF\0FREQ", NULL}, - { MT_KEYPAD, KM_SAMPLETIME, "\2SAMPLE\0TIME", NULL}, - { MT_SUBMENU,0, "\2LO\0DRIVE", menu_drive}, - { MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2}, - { MT_CANCEL, 0, S_LARROW" BACK", NULL }, + { MT_CALLBACK, 3, "\2TRACKING\0OUTPUT",menu_settings2_cb}, + { MT_KEYPAD, KM_ACTUALPOWER, "\2ACTUAL\0POWER", NULL}, + { MT_KEYPAD, KM_IF, "\2IF\0FREQ", NULL}, + { MT_KEYPAD, KM_SAMPLETIME, "\2SAMPLE\0TIME", NULL}, + { MT_SUBMENU,0, "\2LO\0DRIVE", menu_drive}, + { MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2}, + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1148,7 +1154,7 @@ static const menuitem_t menu_acquire[] = { { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, { MT_SUBMENU, 0, "ATTEN", menu_atten}, { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_SUBMENU,0, "AVER", menu_average}, + { MT_SUBMENU,0, "CALC", menu_average}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1156,7 +1162,7 @@ static const menuitem_t menu_acquire[] = { static const menuitem_t menu_acquirehigh[] = { { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, { MT_SUBMENU,0, "RBW", menu_rbw}, - { MT_SUBMENU,0, "AVER", menu_average}, + { MT_SUBMENU,0, "CALC", menu_average}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1195,7 +1201,7 @@ static const menuitem_t menu_stimulus[] = { { MT_KEYPAD, KM_STOP, "STOP", NULL}, { MT_KEYPAD, KM_CENTER, "CENTER", NULL}, { MT_KEYPAD, KM_SPAN, "SPAN", NULL}, - { MT_KEYPAD, KM_CW, "CW FREQ", NULL}, + { MT_KEYPAD, KM_CW, "\2ZERO\0SPAN", NULL}, { MT_SUBMENU,0, "RBW", menu_rbw}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel @@ -1204,13 +1210,13 @@ static const menuitem_t menu_stimulus[] = { static const menuitem_t menu_mode[] = { - { MT_FORM | MT_TITLE, 0, "MODE", NULL}, - { MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "LOW INPUT", menu_mode_cb}, - { MT_FORM | MT_CALLBACK | MT_ICON, I_HIGH_INPUT+I_SA, "HIGH INPUT", menu_mode_cb}, - { MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINUS, "LOW OUTPUT", menu_mode_cb}, - { MT_FORM | MT_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN,"HIGH OUTPUT", menu_mode_cb}, - { MT_FORM | MT_SUBMENU | MT_ICON, I_CONNECT+I_GEN, "CAL OUTPUT: %s", menu_reffer}, - { MT_FORM | MT_SUBMENU | MT_ICON, I_EMPTY+I_CONFIG,"CONFIG", menu_config}, + { MT_FORM | MT_TITLE, 0, "MODE", NULL}, + { MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "LOW INPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK | MT_ICON, I_HIGH_INPUT+I_SA, "HIGH INPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINUS, "LOW OUTPUT", menu_mode_cb}, + { MT_FORM | MT_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "HIGH OUTPUT", menu_mode_cb}, + { MT_FORM | MT_SUBMENU | MT_ICON, I_CONNECT+I_GEN, "CAL OUTPUT: %s", menu_reffer}, + { MT_FORM | MT_SUBMENU | MT_ICON, I_EMPTY+I_CONFIG, "CONFIG", menu_config}, // { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1319,7 +1325,11 @@ static void menu_item_modify_attribute( mark = true; } } else if (menu == menu_dBper) { - if (data == get_trace_scale(1)){ + if (data == setting_scale){ + mark = true; + } + } else if (menu == menu_measure && MT_MASK(menu[item].type) == MT_CALLBACK) { + if (data == setting_measurement){ mark = true; } } else if (menu == menu_rbw) { @@ -1331,7 +1341,10 @@ static void menu_item_modify_attribute( if (data == setting_drive){ mark = true; } - + } else if (menu == menu_modulation && MT_MASK(menu[item].type) == MT_CALLBACK) { + if (data == setting_modulation){ + mark = true; + } } else if (menu == menu_display) { if (item ==0 && is_paused()){ mark = true; @@ -1345,6 +1358,10 @@ static void menu_item_modify_attribute( if (item == 4 && get_waterfall()){ mark = true; } + } else if (menu == menu_settings) { + if (item ==0 && setting_tracking_output){ + mark = true; + } } else if (menu == menu_settings2 || menu == menu_settingshigh2) { if (item ==0 && setting_agc){ mark = true; From 409d836a123fce56062c0102bb02c989a3df07c7 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 13 Apr 2020 13:44:14 +0200 Subject: [PATCH 078/193] Tracking generator error corrected --- sa_core.c | 5 ++++- ui_sa.c | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sa_core.c b/sa_core.c index bb8bb9e..7cfeba9 100644 --- a/sa_core.c +++ b/sa_core.c @@ -862,8 +862,11 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) } else if (MODE_LOW(setting_mode)) { if (setting_mode == M_LOW && !in_selftest && avoid_spur(f)) { local_IF = spur_alternate_IF; - } else + } else { local_IF = frequency_IF ; + } + if (setting_mode == M_GENLOW && setting_modulation == MO_EXTERNAL) + local_IF += lf; setFreq (0, local_IF); } else local_IF= 0; diff --git a/ui_sa.c b/ui_sa.c index f3b28e6..d50895a 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -12,6 +12,7 @@ void set_refer_output(int); int get_refer_output(void); void SetAttenuation(int); int GetAttenuation(void); +int search_is_greater(void); void set_auto_attenuation(void); void set_auto_reflevel(void); int is_paused(void); @@ -43,6 +44,7 @@ void redrawHisto(void); void self_test(void); void set_decay(int); void set_noise(int); +void toggle_tracking_output(void); extern int32_t frequencyExtra; extern int setting_tracking; extern int setting_tracking_output; From 43f98e0f1fa7aa2f59023e4352e8139c877b7495 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 13 Apr 2020 17:01:00 +0200 Subject: [PATCH 079/193] Attenuation always positive on screen --- sa_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sa_core.c b/sa_core.c index 7cfeba9..1e933ec 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1170,7 +1170,7 @@ void draw_cal_status(void) ili9341_drawstring("Attn:", x, y); y += YSTEP; - plot_printf(buf, BLEN, "%ddB", -setting_attenuate); + plot_printf(buf, BLEN, "%ddB", setting_attenuate); buf[5]=0; ili9341_drawstring(buf, x, y); From 1a356f5253ff90b2058ad62327ed78732b72e6b6 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 13 Apr 2020 17:28:45 +0200 Subject: [PATCH 080/193] Waterfall with improved colors --- plot.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/plot.c b/plot.c index f0d2123..e1d59f6 100644 --- a/plot.c +++ b/plot.c @@ -1467,6 +1467,12 @@ draw_cell(int m, int n) ili9341_bulk(OFFSETX + x0, OFFSETY + y0, w, h); } +extern float peakLevel; +extern float min_level; +int w_max = -130; +int w_min = 0; + + static void draw_all_cells(bool flush_markmap) { @@ -1512,6 +1518,27 @@ draw_all_cells(bool flush_markmap) b = (k-128)*4; } #else + if (w_min > (int)min_level) + w_min = (int)min_level; + if (w_max < (int)peakLevel) + w_max = (int)peakLevel; +/* + def rgb(minimum, maximum, value): + minimum, maximum = float(minimum), float(maximum) + ratio = 2 * (value-minimum) / (maximum - minimum) + b = int(max(0, 255*(1 - ratio))) + r = int(max(0, 255*(ratio - 1))) + g = 255 - b - r + return r, g, b + */ + int r,g,b; + float ratio = (int)(510.0 * (actual_t[i] - w_min) / (w_max - actual_t[i])); + b = 255 - ratio; + if (b < 0) b = 0; + r = ratio - 255; + if (r < 0) r = 0; + g = 255 - b - r; +#if 0 int k = (actual_t[i]+120)* 2 * 8; k &= 255; unsigned int r=0,g=0,b=0; @@ -1529,6 +1556,7 @@ draw_all_cells(bool flush_markmap) g = 255 - (k-192)*2; r = 255; } +#endif #endif spi_buffer[i] = RGB565(r,g,b); } @@ -2079,6 +2107,7 @@ redraw_frame(void) draw_cal_status(); } + int get_waterfall(void) { return(waterfall); @@ -2092,6 +2121,11 @@ toggle_waterfall(void) ili9341_fill(5*5, HEIGHT, 320 - 5*5, 236-HEIGHT, 0); waterfall = true; fullscreen = false; + w_min = (int)min_level; + w_max = (int)peakLevel; + if (w_max < w_min + 20) + w_max = w_min + 20; + } else { _height = HEIGHT_NOSCROLL; waterfall = false; From a6b9e489216b93cb6e44ac9dbe041f055abcfcc6 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 14 Apr 2020 19:11:22 +0200 Subject: [PATCH 081/193] Waterfall improvement and extra measurements --- ili9341.c | 4 +- mcuconf.h | 2 +- nanovna.h | 11 +++- plot.c | 43 ++++++++++------ sa_core.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++- ui.c | 25 ++++++--- ui_sa.c | 42 +++++++++++++-- 7 files changed, 243 insertions(+), 35 deletions(-) diff --git a/ili9341.c b/ili9341.c index 388986c..99204fb 100644 --- a/ili9341.c +++ b/ili9341.c @@ -309,9 +309,9 @@ static const uint8_t ili9341_init_seq[] = { // gamma set for curve 01/2/04/08 ILI9341_GAMMA_SET, 1, 0x01, // positive gamma correction -//ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00, +ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00, // negativ gamma correction -//ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F, +ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F, // Column Address Set //ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320 // Page Address Set diff --git a/mcuconf.h b/mcuconf.h index e04096c..6d4550a 100644 --- a/mcuconf.h +++ b/mcuconf.h @@ -201,7 +201,7 @@ /* * UART driver system settings. */ -#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART1 TRUE #define STM32_UART_USE_USART2 FALSE #define STM32_UART_USART1_IRQ_PRIORITY 3 #define STM32_UART_USART2_IRQ_PRIORITY 3 diff --git a/nanovna.h b/nanovna.h index 50c8b55..0c3ee99 100644 --- a/nanovna.h +++ b/nanovna.h @@ -365,6 +365,10 @@ void set_marker_search(int mode); int marker_search(void); int marker_search_left(int from); int marker_search_right(int from); +int marker_search_left_max(int from); +int marker_search_right_max(int from); +int marker_search_left_min(int from); +int marker_search_right_min(int from); // _request flag for update screen #define REDRAW_CELLS (1<<0) @@ -380,7 +384,10 @@ extern volatile uint8_t redraw_request; */ // SPI bus revert byte order //gggBBBbb RRRrrGGG -#define RGB565(r,g,b) ( (((g)&0x1c)<<11) | (((b)&0xf8)<<5) | ((r)&0xf8) | (((g)&0xe0)>>5) ) +#define byteReverse16(x) (uint16_t)(((x) << 8) & 0xff00) | (((x) >> 8) & 0xff) +#define RGB565(r,g,b) byteReverse16( ((((uint16_t)r)<<8)&0b1111100000000000) | ((((uint16_t)g)<<3)&0b0000011111100000) | ((((uint16_t)b)>>3)&0b0000000000011111) ) + +//#define RGB565(r,g,b) ( (((g)&0x1c)<<11) | (((b)&0xf8)<<5) | ((r)&0xf8) | (((g)&0xe0)>>5) ) #define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) ) // Define size of screen buffer in pixels (one pixel 16bit size) @@ -651,7 +658,7 @@ void wait_user(void); void calibrate(void); enum { - M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE + M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_STOP_BAND, M_PASS_BAND }; /*EOF*/ diff --git a/plot.c b/plot.c index e1d59f6..0f246fe 100644 --- a/plot.c +++ b/plot.c @@ -1141,10 +1141,10 @@ marker_position(int m, int t, int *x, int *y) *y = CELL_Y(index); } -static int greater(int x, int y) { return x > y; } -static int lesser(int x, int y) { return x < y; } +static int greater(int x, int y, int d) { return x - d > y; } +static int lesser(int x, int y, int d) { return x - d < y; } -static int (*compare)(int x, int y) = greater; +static int (*compare)(int x, int y, int d) = greater; int marker_search(void) @@ -1158,7 +1158,7 @@ marker_search(void) int value = CELL_Y(trace_index[TRACE_ACTUAL][0]); for (i = 0; i < sweep_points; i++) { int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); - if ((*compare)(value, new_value)) { + if ((*compare)(value, new_value, 0)) { value = new_value; found = i; } @@ -1179,30 +1179,32 @@ search_is_greater(void) return(compare == greater); } +#define MINMAX_DELTA 10 + int marker_search_left(int from) { int i; int found = -1; -#define MINMAX_DELTA -5 if (uistat.current_trace == -1) return -1; int value = CELL_Y(trace_index[TRACE_ACTUAL][from]); for (i = from - 1; i >= 0; i--) { int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); - if ((*compare)(value + MINMAX_DELTA, new_value)) + if ((*compare)(value, new_value, MINMAX_DELTA)) break; - value = new_value; } for (; i >= 0; i--) { int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); - if ((*compare)(new_value, value - MINMAX_DELTA)) { + if ((*compare)(new_value, value, -MINMAX_DELTA)) { break; } - found = i; - value = new_value; + if ((*compare)(value, new_value, 0)) { + found = i; + value = new_value; + } } return found; } @@ -1218,18 +1220,19 @@ marker_search_right(int from) int value = CELL_Y(trace_index[TRACE_ACTUAL][from]); for (i = from + 1; i < sweep_points; i++) { int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); - if ((*compare)(value+MINMAX_DELTA, new_value)) + if ((*compare)(value, new_value, MINMAX_DELTA)) break; value = new_value; } - for (; i < sweep_points; i++) { int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]); - if ((*compare)(new_value, value-MINMAX_DELTA)) { + if ((*compare)(new_value, value, -MINMAX_DELTA)) { break; } - found = i; - value = new_value; + if ((*compare)(value, new_value, 0)) { + found = i; + value = new_value; + } } return found; } @@ -1532,12 +1535,20 @@ draw_all_cells(bool flush_markmap) return r, g, b */ int r,g,b; - float ratio = (int)(510.0 * (actual_t[i] - w_min) / (w_max - actual_t[i])); + float ratio = (int)(510.0 * (actual_t[i] - w_min) / (w_max - w_min)); +// float ratio = (i*2); // Uncomment for testing the waterfall colors b = 255 - ratio; + if (b > 255) b = 255; if (b < 0) b = 0; r = ratio - 255; + if (r > 255) r = 255; if (r < 0) r = 0; +// g = 255 - b; // if red is too weak to be seen..... g = 255 - b - r; +#define gamma_correct(X,L) X = (L + X * (255 - L)/255 ) + gamma_correct(r,128); + gamma_correct(g,128); + gamma_correct(b,128); #if 0 int k = (actual_t[i]+120)* 2 * 8; k &= 255; diff --git a/sa_core.c b/sa_core.c index 1e933ec..ebf9998 100644 --- a/sa_core.c +++ b/sa_core.c @@ -99,6 +99,13 @@ void reset_settings(int m) set_sweep_frequency(ST_SPAN, 0); break; } + for (int i = 0; i< MARKERS_MAX; i++) { + markers[i].enabled = M_DISABLED; + markers[i].mtype = M_NORMAL; + } + markers[0].mtype = M_REFERENCE | M_TRACKING; + markers[0].enabled = M_ENABLED; + dirty = true; } @@ -965,7 +972,7 @@ static bool sweep(bool break_on_operation) if (temppeakLevel > actual_t[i]) { // Follow down temppeakIndex = i; // Latest minimum temppeakLevel = actual_t[i]; - } else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found + } else if (temppeakLevel + setting_noise < actual_t[i] ) { // Local minimum found temppeakIndex = i; // This is now the latest maximum temppeakLevel = actual_t[i]; downslope = false; @@ -974,7 +981,7 @@ static bool sweep(bool break_on_operation) if (temppeakLevel < actual_t[i]) { // Follow up temppeakIndex = i; temppeakLevel = actual_t[i]; - } else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found + } else if (actual_t[i] < temppeakLevel - setting_noise) { // Local max found int j = 0; // Insertion index while (j= temppeakLevel) // Find where to insert @@ -1085,6 +1092,23 @@ static bool sweep(bool break_on_operation) } } else if (setting_measurement == M_PHASE_NOISE && markers[0].index > 10) { markers[1].index = markers[0].index + (setting_mode == M_LOW ? 290/4 : -290/4); // Position phase noise marker at requested offset + } else if (setting_measurement == M_STOP_BAND && markers[0].index > 10) { + markers[1].index = marker_search_left_min(markers[0].index); + if (markers[1].index < 0) markers[1].index = 0; + markers[2].index = marker_search_right_min(markers[0].index); + if (markers[2].index < 0) markers[1].index = POINTS_COUNT - 1; + } else if (setting_measurement == M_PASS_BAND && markers[0].index > 10) { + int t = markers[0].index; + float v = actual_t[t]; + while (t > 0 && actual_t[t] > v - 3.0) + t --; + if (t > 0) + markers[1].index = t; + t = markers[0].index; + while (t < POINTS_COUNT - 1 && actual_t[t] > v - 3.0) + t ++; + if (t < POINTS_COUNT - 1 ) + markers[2].index = t; } #endif peakIndex = max_index[0]; @@ -1116,7 +1140,130 @@ static bool sweep(bool break_on_operation) return true; } +//------------------------------- SEARCH --------------------------------------------- + +int +marker_search_left_max(int from) +{ + int i; + int found = -1; + if (uistat.current_trace == -1) + return -1; + + int value = actual_t[from]; + for (i = from - 1; i >= 0; i--) { + int new_value = actual_t[i]; + if (new_value < value) { + value = new_value; + found = i; + } else if (new_value > value + setting_noise ) + break; + } + + for (; i >= 0; i--) { + int new_value = actual_t[i]; + if (new_value > value) { + value = new_value; + found = i; + } else if (new_value < value - setting_noise ) + break; + } + return found; +} + +int +marker_search_right_max(int from) +{ + int i; + int found = -1; + + if (uistat.current_trace == -1) + return -1; + int value = actual_t[from]; + for (i = from + 1; i < sweep_points; i++) { + int new_value = actual_t[i]; + if (new_value < value) { // follow down + value = new_value; + found = i; + } else if (new_value > value + setting_noise) // larger then lowest value + noise + break; // past the minimum + } + for (; i < sweep_points; i++) { + int new_value = actual_t[i]; + if (new_value > value) { // follow up + value = new_value; + found = i; + } else if (new_value < value - setting_noise) + break; + } + return found; +} + +#define MINMAX_DELTA 10 + + +int +marker_search_left_min(int from) +{ + int i; + int found = from; + if (uistat.current_trace == -1) + return -1; + + int value = actual_t[from]; + for (i = from - 1; i >= 0; i--) { + int new_value = actual_t[i]; + if (new_value > value) { + value = new_value; // follow up +// found = i; + } else if (new_value < value - MINMAX_DELTA ) + break; // past the maximum + } + + for (; i >= 0; i--) { + int new_value = actual_t[i]; + if (new_value < value) { + value = new_value; // follow down + found = i; + } else if (new_value > value + MINMAX_DELTA ) + break; + } + return found; +} + +int +marker_search_right_min(int from) +{ + int i; + int found = from; + + if (uistat.current_trace == -1) + return -1; + int value = actual_t[from]; + for (i = from + 1; i < sweep_points; i++) { + int new_value = actual_t[i]; + if (new_value > value) { // follow up + value = new_value; +// found = i; + } else if (new_value < value - MINMAX_DELTA) // less then largest value - noise + break; // past the maximum + } + for (; i < sweep_points; i++) { + int new_value = actual_t[i]; + if (new_value < value) { // follow down + value = new_value; + found = i; + } else if (new_value > value + MINMAX_DELTA) // larger then smallest value + noise + break; + } + return found; +} + + + + +// -------------------------- CAL STATUS --------------------------------------------- const char *averageText[] = { "OFF", "MIN", "MAX", "MAXD", " A 4", "A 16"}; const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; diff --git a/ui.c b/ui.c index 290e3cd..8e809e8 100644 --- a/ui.c +++ b/ui.c @@ -781,16 +781,24 @@ menu_marker_search_cb(int item, uint8_t data) return; switch (data) { + case 0: /* search Left */ + i = marker_search_left_min(markers[active_marker].index); + break; + case 1: /* search right */ + i = marker_search_right_min(markers[active_marker].index); + break; +#if 0 case 0: /* maximum */ case 1: /* minimum */ set_marker_search(data); i = marker_search(); break; +#endif case 2: /* search Left */ - i = marker_search_left(markers[active_marker].index); + i = marker_search_left_max(markers[active_marker].index); break; case 3: /* search right */ - i = marker_search_right(markers[active_marker].index); + i = marker_search_right_max(markers[active_marker].index); break; case 4: /* tracking */ markers[active_marker].mtype ^= M_TRACKING; @@ -1651,7 +1659,10 @@ static void erase_menu_buttons(void) { // ili9341_fill(area_width, 0, 320 - area_width, area_height, DEFAULT_BG_COLOR); - ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR); + if (current_menu_is_form()) + ili9341_fill(5*5, 0,320-5*5, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR); + else + ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR); draw_frequencies(); } @@ -1843,15 +1854,15 @@ lever_move_marker(int status) if (active_marker >= 0 && markers[active_marker].enabled) { if ((status & EVT_DOWN) && markers[active_marker].index > 0) { markers[active_marker].index -= step; - if (markers[active_marker].index < 5) - markers[active_marker].index = 5 ; + if (markers[active_marker].index < 0) + markers[active_marker].index = 0 ; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } if ((status & EVT_UP) && markers[active_marker].index < sweep_points-1) { markers[active_marker].index += step; - if (markers[active_marker].index > POINTS_COUNT-5) - markers[active_marker].index = POINTS_COUNT-5 ; + if (markers[active_marker].index > POINTS_COUNT-1) + markers[active_marker].index = POINTS_COUNT-1 ; markers[active_marker].frequency = frequencies[markers[active_marker].index]; redraw_marker(active_marker); } diff --git a/ui_sa.c b/ui_sa.c index d50895a..64d3313 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -685,6 +685,36 @@ static void menu_measure_cb(int item, uint8_t data) set_measurement(M_PHASE_NOISE); SetAverage(4); + break; + case M_STOP_BAND: // STop band measurement + reset_settings(GetMode()); + markers[1].enabled = M_ENABLED; + markers[1].mtype = M_DELTA; + markers[2].enabled = M_ENABLED; + markers[2].mtype = M_DELTA; + ui_mode_keypad(KM_CENTER); + ui_process_keypad(); + ui_mode_keypad(KM_SPAN); + ui_process_keypad(); + set_sweep_frequency(ST_SPAN, uistat.value*4); + set_measurement(M_STOP_BAND); +// SetAverage(4); + + break; + case M_PASS_BAND: // STop band measurement + reset_settings(GetMode()); + markers[1].enabled = M_ENABLED; + markers[1].mtype = M_DELTA; + markers[2].enabled = M_ENABLED; + markers[2].mtype = M_DELTA; + ui_mode_keypad(KM_CENTER); + ui_process_keypad(); + ui_mode_keypad(KM_SPAN); + ui_process_keypad(); + set_sweep_frequency(ST_SPAN, uistat.value*2); + set_measurement(M_PASS_BAND); +// SetAverage(4); + break; } #endif @@ -1014,10 +1044,10 @@ static const menuitem_t menu_marker_type[] = { const menuitem_t menu_marker_search[] = { //{ MT_CALLBACK, "OFF", menu_marker_search_cb }, - { MT_CALLBACK, 0, "MAXIMUM", menu_marker_search_cb }, - { MT_CALLBACK, 1, "MINIMUM", menu_marker_search_cb }, - { MT_CALLBACK, 2, "\2SEARCH\0" S_LARROW" LEFT", menu_marker_search_cb }, - { MT_CALLBACK, 3, "\2SEARCH\0" S_RARROW" RIGHT", menu_marker_search_cb }, + { MT_CALLBACK, 0, "\2MIN\0" S_LARROW" LEFT", menu_marker_search_cb }, + { MT_CALLBACK, 1, "\2MIN\0" S_RARROW" RIGHT", menu_marker_search_cb }, + { MT_CALLBACK, 2, "\2MAX\0" S_LARROW" LEFT", menu_marker_search_cb }, + { MT_CALLBACK, 3, "\2MAX\0" S_RARROW" RIGHT", menu_marker_search_cb }, { MT_CALLBACK, 4, "TRACKING", menu_marker_search_cb }, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel @@ -1104,9 +1134,11 @@ static const menuitem_t menu_settings[] = static const menuitem_t menu_measure[] = { { MT_CALLBACK, M_OFF, "OFF", menu_measure_cb}, - { MT_CALLBACK, M_IMD, "IMD", menu_measure_cb}, + { MT_CALLBACK, M_IMD, "MARMONICS",menu_measure_cb}, { MT_CALLBACK, M_OIP3, "OIP3", menu_measure_cb}, { MT_CALLBACK, M_PHASE_NOISE, "\2PHASE\0NOISE",menu_measure_cb}, + { MT_CALLBACK, M_STOP_BAND, "\2STOP\0BAND",menu_measure_cb}, + { MT_CALLBACK, M_PASS_BAND, "\2PASS\0BAND",menu_measure_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 2d22122256fde69faabda76a8c0f20e45bf49003 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 15 Apr 2020 08:56:40 +0200 Subject: [PATCH 082/193] Help text for numeric input added --- ui.c | 18 +++++++++++++++--- ui_sa.c | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ui.c b/ui.c index 8e809e8..e508c71 100644 --- a/ui.c +++ b/ui.c @@ -81,6 +81,7 @@ static uint8_t keypad_mode; static uint8_t keypads_last_index; static char kp_buf[NUMINPUT_LEN+1]; static int8_t kp_index = 0; +static char *kp_help_text = NULL; static uint8_t menu_current_level = 0; static int8_t selection = 0; @@ -1390,9 +1391,9 @@ draw_numeric_input(const char *buf) int focused = FALSE; uint16_t xsim = 0b0010010000000000; + uint16_t fg = DEFAULT_MENU_TEXT_COLOR; + uint16_t bg = config.menu_normal_color; for (i = 0, x = 64; i < 10 && buf[i]; i++, xsim<<=1) { - uint16_t fg = DEFAULT_MENU_TEXT_COLOR; - uint16_t bg = config.menu_normal_color; int c = buf[i]; if (c == '.') c = KP_PERIOD; @@ -1419,7 +1420,18 @@ draw_numeric_input(const char *buf) x += xsim&0x8000 ? NUM_FONT_GET_WIDTH+2+8 : NUM_FONT_GET_WIDTH+2; } // erase last - ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color); +// ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color); + ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, 320-64, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color); + if (buf[0] == 0 && kp_help_text != NULL) { + ili9341_set_foreground(fg); + ili9341_set_background(bg); + const char *l1,*l2; + if (menu_is_multiline(kp_help_text, &l1, &l2)) { + ili9341_drawstring_7x13(l1, 64+NUM_FONT_GET_WIDTH+2, 240-NUM_INPUT_HEIGHT+1); + ili9341_drawstring_7x13(l2, 64+NUM_FONT_GET_WIDTH+2, 240-NUM_INPUT_HEIGHT/2 + 1); + } else + ili9341_drawstring_7x13(kp_help_text, 64+NUM_FONT_GET_WIDTH+2, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2); + } } static int diff --git a/ui_sa.c b/ui_sa.c index 64d3313..eaf102f 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -647,6 +647,7 @@ static void menu_measure_cb(int item, uint8_t data) markers[i].mtype = M_DELTA | M_TRACKING; } markers[0].mtype = M_REFERENCE | M_TRACKING; + kp_help_text = "Frequency of fundamental"; ui_mode_keypad(KM_CENTER); ui_process_keypad(); set_sweep_frequency(ST_START, 0); @@ -660,11 +661,16 @@ static void menu_measure_cb(int item, uint8_t data) markers[i].mtype = M_DELTA | M_TRACKING; } markers[0].mtype = M_REFERENCE | M_TRACKING; + kp_help_text = "Frequency of left signal"; ui_mode_keypad(KM_CENTER); ui_process_keypad(); - ui_mode_keypad(KM_SPAN); + int left = uistat.value; + kp_help_text = "Right signal"; + ui_mode_keypad(KM_CENTER); ui_process_keypad(); - set_sweep_frequency(ST_SPAN, uistat.value*4); + int right = uistat.value; + set_sweep_frequency(ST_CENTER, (left+right)/2); + set_sweep_frequency(ST_SPAN, (right - left)*4); set_measurement(M_OIP3); break; case M_PHASE_NOISE: // Phase noise @@ -677,8 +683,10 @@ static void menu_measure_cb(int item, uint8_t data) markers[0].mtype = M_REFERENCE | M_TRACKING; markers[1].enabled = M_ENABLED; markers[1].mtype = M_DELTA | M_NOISE; + kp_help_text = "Frequency of signal"; ui_mode_keypad(KM_CENTER); ui_process_keypad(); + kp_help_text = "Frequency offset"; ui_mode_keypad(KM_SPAN); ui_process_keypad(); set_sweep_frequency(ST_SPAN, uistat.value*4); @@ -692,8 +700,10 @@ static void menu_measure_cb(int item, uint8_t data) markers[1].mtype = M_DELTA; markers[2].enabled = M_ENABLED; markers[2].mtype = M_DELTA; + kp_help_text = "Frequency of signal"; ui_mode_keypad(KM_CENTER); ui_process_keypad(); + kp_help_text = "Width of signal"; ui_mode_keypad(KM_SPAN); ui_process_keypad(); set_sweep_frequency(ST_SPAN, uistat.value*4); @@ -707,8 +717,10 @@ static void menu_measure_cb(int item, uint8_t data) markers[1].mtype = M_DELTA; markers[2].enabled = M_ENABLED; markers[2].mtype = M_DELTA; + kp_help_text = "Frequency of signal"; ui_mode_keypad(KM_CENTER); ui_process_keypad(); + kp_help_text = "Width of signal"; ui_mode_keypad(KM_SPAN); ui_process_keypad(); set_sweep_frequency(ST_SPAN, uistat.value*2); @@ -717,6 +729,7 @@ static void menu_measure_cb(int item, uint8_t data) break; } + kp_help_text = NULL; #endif // selection = -1; ui_mode_normal(); From ac606f09e34c2eade103436b827be385c7f95f34 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 15 Apr 2020 09:12:16 +0200 Subject: [PATCH 083/193] Increase rows displayed in 7x13 --- ili9341.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ili9341.c b/ili9341.c index 99204fb..3b21d4e 100644 --- a/ili9341.c +++ b/ili9341.c @@ -609,7 +609,7 @@ void ili9341_drawstring_7x13(const char *str, int x, int y) while (*str) { uint8_t ch = *str++; const uint16_t *char_buf = &x7x13b_bits[(ch * 13)]; // All chars start at row 2 - blit16BitWidthBitmap(x, y, 7, 12, char_buf); // Only 'Q' has 12 rows + blit16BitWidthBitmap(x, y, 7, 13, char_buf); // Only 'Q' has 12 rows, 'g' requires 13 rows x += 7; } } From a7ae6d419751632abd442325147368fcf4c1875d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 15 Apr 2020 16:12:58 +0200 Subject: [PATCH 084/193] Serial experiements --- halconf.h | 2 +- main.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- mcuconf.h | 2 +- sa_core.c | 2 +- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/halconf.h b/halconf.h index 1450b9f..af6c283 100644 --- a/halconf.h +++ b/halconf.h @@ -132,7 +132,7 @@ * @brief Enables the SERIAL subsystem. */ #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL FALSE +#define HAL_USE_SERIAL TRUE #endif /** diff --git a/main.c b/main.c index bba6558..84a5b5f 100644 --- a/main.c +++ b/main.c @@ -16,9 +16,14 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ +//#define HAL_USE_SERIAL 1 +//#define STM32_SERIAL_USE_USART1 1 #include "ch.h" #include "hal.h" + +//#include "hal_serial.h" + #include "usbcfg.h" #ifdef __VNA__ #include "si5351.h" @@ -2591,6 +2596,39 @@ static DACConfig dac1cfg1 = { }; #endif +#if 0 +/* + * UART driver configuration structure. + */ +static UARTConfig uart_cfg_1 = { + NULL, //txend1, + NULL, //txend2, + NULL, //rxend, + NULL, //rxchar, + NULL, //rxerr, + 800000, + 0, + 0, //USART_CR2_LINEN, + 0 +}; +#endif + +#if 1 +static const SerialConfig default_config = +{ + 9600, + 0, + USART_CR2_STOP2_BITS, + 0 +}; +#endif + +myWrite(char *buf) +{ + int len = strlen(buf); + while(len-- > 0) + sdPut(&SD1,*buf++); +} // Main thread stack size defined in makefile USE_PROCESS_STACKSIZE = 0x200 // Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show: @@ -2625,7 +2663,35 @@ int main(void) usbStart(serusbcfg.usbp, &usbcfg); usbConnectBus(serusbcfg.usbp); -/* +#if 0 + /* + * UART initialize + */ + uartStart(&UARTD1, &uart_cfg_1); + + uartStartSend(&UARTD1, 1, "H"); + uartStartReceive(&UARTD1, 1, buf); +#endif + +#if 1 + palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(1)); // USART1 TX. + palSetPadMode(GPIOA,10, PAL_MODE_ALTERNATE(1)); // USART1 RX. + + uint8_t buf[10]; + sdStart(&SD1,&default_config); + osalThreadSleepMilliseconds(10); + myWrite("Hallo!?"); + + osalThreadSleepMilliseconds(10); + + sdReadTimeout(&SD1,buf,10, 10); + + sdWrite(&SD1,(const uint8_t *)"Test123",7); + osalThreadSleepMilliseconds(10); + sdReadTimeout(&SD1,buf,10, 10); +#endif + + /* * SPI LCD Initialize */ ili9341_init(); diff --git a/mcuconf.h b/mcuconf.h index 6d4550a..e04096c 100644 --- a/mcuconf.h +++ b/mcuconf.h @@ -201,7 +201,7 @@ /* * UART driver system settings. */ -#define STM32_UART_USE_USART1 TRUE +#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 diff --git a/sa_core.c b/sa_core.c index ebf9998..3175531 100644 --- a/sa_core.c +++ b/sa_core.c @@ -888,7 +888,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) return(0); float signal_path_loss; if (setting_mode == M_LOW) - signal_path_loss = -9.5; // Loss in dB + signal_path_loss = -9.5; // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 else signal_path_loss = 7; // Loss in dB (+ is gain) float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+ setting_attenuate - signal_path_loss; From 2d430a4f582a354c85b6c9c280060aca9a144a9d Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 16 Apr 2020 10:54:32 +0200 Subject: [PATCH 085/193] Small improvements --- ili9341.c | 4 +- main.c | 39 ++++++++++++++--- nanovna.h | 1 + plot.c | 22 ++++++++++ sa_core.c | 129 ++++++++++++++++++++++++++---------------------------- ui_sa.c | 2 +- 6 files changed, 120 insertions(+), 77 deletions(-) diff --git a/ili9341.c b/ili9341.c index 3b21d4e..bba3dd9 100644 --- a/ili9341.c +++ b/ili9341.c @@ -294,9 +294,11 @@ static const uint8_t ili9341_init_seq[] = { // POWER_CONTROL_2 ILI9341_POWER_CONTROL_2, 1, 0x11, // VCOM_CONTROL_1 - ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E, +// ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E, + ILI9341_VCOM_CONTROL_1, 2, 0x3e, 0x28, // VCOM_CONTROL_2 ILI9341_VCOM_CONTROL_2, 1, 0xBE, +// ILI9341_VCOM_CONTROL_2, 1, 0x86, // MEMORY_ACCESS_CONTROL //ILI9341_MEMORY_ACCESS_CONTROL, 1, 0x48, // portlait ILI9341_MEMORY_ACCESS_CONTROL, 1, DISPLAY_ROTATION_0, // landscape diff --git a/main.c b/main.c index 84a5b5f..78790ba 100644 --- a/main.c +++ b/main.c @@ -2613,7 +2613,7 @@ static UARTConfig uart_cfg_1 = { }; #endif -#if 1 +#if 0 static const SerialConfig default_config = { 9600, @@ -2621,14 +2621,34 @@ static const SerialConfig default_config = USART_CR2_STOP2_BITS, 0 }; -#endif -myWrite(char *buf) + +void myWrite(char *buf) { int len = strlen(buf); - while(len-- > 0) + while(len-- > 0) { sdPut(&SD1,*buf++); + osalThreadSleepMicroseconds(1000); + } +} + +static int serial_count = 0; +int mySerialReadline(unsigned char *buf, int len) +{ + int i; + do { + i = sdReadTimeout(&SD1,&buf[serial_count], 20-serial_count,TIME_IMMEDIATE); + serial_count += i; + if (i > 0) + osalThreadSleepMicroseconds(1000); + } while (serial_count < len && i > 0); + if (buf[serial_count-1] == '\n') { + serial_count = 0; + return(i); + } else + return 0; } +#endif // Main thread stack size defined in makefile USE_PROCESS_STACKSIZE = 0x200 // Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show: @@ -2673,22 +2693,27 @@ int main(void) uartStartReceive(&UARTD1, 1, buf); #endif -#if 1 +#if 0 palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(1)); // USART1 TX. palSetPadMode(GPIOA,10, PAL_MODE_ALTERNATE(1)); // USART1 RX. uint8_t buf[10]; sdStart(&SD1,&default_config); osalThreadSleepMilliseconds(10); - myWrite("Hallo!?"); + mySerialWrite("Hallo!?\n"); osalThreadSleepMilliseconds(10); + mySerialReadline(buf, 10); + sdReadTimeout(&SD1,buf,10, 10); sdWrite(&SD1,(const uint8_t *)"Test123",7); - osalThreadSleepMilliseconds(10); + osalThreadSleepMicroseconds(10); + sdReadTimeout(&SD1,buf,10,TIME_IMMEDIATE); sdReadTimeout(&SD1,buf,10, 10); + int i = sdReadTimeout(&SD1,buf,10,TIME_IMMEDIATE); + #endif /* diff --git a/nanovna.h b/nanovna.h index 0c3ee99..40ca6b3 100644 --- a/nanovna.h +++ b/nanovna.h @@ -29,6 +29,7 @@ #define __ICONS__ #define __MEASURE__ #define __SELFTEST__ +#define __CALIBRATE__ /* * main.c diff --git a/plot.c b/plot.c index 0f246fe..893fe6a 100644 --- a/plot.c +++ b/plot.c @@ -1534,7 +1534,28 @@ draw_all_cells(bool flush_markmap) g = 255 - b - r return r, g, b */ + int r,g,b; +#if 0 + int ratio = (int)(1024 * (actual_t[i] - w_min) / (w_max - w_min)); + + r = ratio - 512; + if (r<0) r=0; + b = (1024 - ratio*4) - 512; + if (b<0) b=0; + g = 512-r-b; + if (r>255) r=255; + if (g>255) g=255; + if (b>255) b=255; + +#define gamma_correct(X,L) X = (L + X * (255 - L)/255 ) + gamma_correct(r,160); + gamma_correct(g,160); + gamma_correct(b,160); + +#endif + +#if 1 float ratio = (int)(510.0 * (actual_t[i] - w_min) / (w_max - w_min)); // float ratio = (i*2); // Uncomment for testing the waterfall colors b = 255 - ratio; @@ -1549,6 +1570,7 @@ draw_all_cells(bool flush_markmap) gamma_correct(r,128); gamma_correct(g,128); gamma_correct(b,128); +#endif #if 0 int k = (actual_t[i]+120)* 2 * 8; k &= 255; diff --git a/sa_core.c b/sa_core.c index 3175531..2aa9f9b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -513,7 +513,11 @@ switch(m) { case M_LOW: // Mixed into 0 SI4432_Sel = 0; SI4432_Receive(); - SetSwitchReceive(); + if (setting_step_atten) { + SetSwitchTransmit(); + } else { + SetSwitchReceive(); + } SetAGCLNA(); SI4432_Sel = 1; @@ -1424,17 +1428,16 @@ void draw_cal_status(void) } // -------------------- Self testing ------------------------------------------------- -#ifdef __SELFTEST__ enum { TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT, TC_MEASURE, TC_SET, TC_END, }; enum { - TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ, TPH_30MHZ + TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_10MHZ_SWITCH, TP_30MHZ, TPH_30MHZ }; -#define TEST_COUNT 16 +#define TEST_COUNT 17 static const struct { int kind; @@ -1455,12 +1458,13 @@ static const struct { {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -13, 55, -60 }, // 7 BPF loss and stop band {TC_FLAT, TP_10MHZEXTRA, 10, 4, -18, 20, -60}, // 8 BPF pass band flatness {TC_BELOW, TP_30MHZ, 430, 60, -65, 0, -75}, // 9 LPF cutoff + {TC_SIGNAL, TP_10MHZ_SWITCH,20, 7, -58, 30, -90 }, // 10 Switch isolation {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 7, -22.5, 30, -70 }, // 11 Measure power level and noise - {TC_MEASURE, TP_30MHZ, 270, 4, -45, 30, -75 }, // 12 Measure powerlevel and noise - {TC_MEASURE, TPH_30MHZ, 270, 4, -45, 30, -75 }, // 13 Calibrate power high mode + {TC_MEASURE, TP_30MHZ, 30, 7, -22.5, 30, -70 }, // 12 Measure power level and noise + {TC_MEASURE, TP_30MHZ, 270, 4, -45, 30, -75 }, // 13 Measure powerlevel and noise + {TC_MEASURE, TPH_30MHZ, 270, 4, -45, 30, -65 }, // 14 Calibrate power high mode {TC_END, 0, 0, 0, 0, 0, 0}, - {TC_MEASURE, TP_30MHZ, 30, 1, -20, 30, -70 }, // 15 Measure RBW step time + {TC_MEASURE, TP_30MHZ, 30, 1, -20, 30, -70 }, // 16 Measure RBW step time {TC_END, 0, 0, 0, 0, 0, 0}, }; @@ -1539,20 +1543,29 @@ void cell_draw_test_info(int x0, int y0) #define fabs(X) ((X)<0?-(X):(X)) -int validate_peak_within(int i, float margin) +int validate_signal_within(int i, float margin) { - if (fabs(peakLevel-test_case[i].pass) > margin) - return false; - return(test_case[i].center * 1000000 - 100000 < peakFreq && peakFreq < test_case[i].center * 1000000 + 100000 ); + test_fail_cause[i] = "Signal level "; + if (fabs(peakLevel-test_case[i].pass) > 2*margin) { + return TS_FAIL; + } + if (fabs(peakLevel-test_case[i].pass) > margin) { + return TS_CRITICAL; + } + test_fail_cause[i] = "Frequency "; + if (peakFreq < test_case[i].center * 1000000 - 100000 || test_case[i].center * 1000000 + 100000 < peakFreq ) + return TS_FAIL; + test_fail_cause[i] = ""; + return TS_PASS; } int validate_peak_below(int i, float margin) { return(test_case[i].pass - peakLevel > margin); } -int validate_below(void) { +int validate_below(int tc, int from, int to) { int status = TS_PASS; - for (int j = 0; j < POINTS_COUNT; j++) { + for (int j = from; j < to; j++) { if (actual_t[j] > stored_t[j] - 5) status = TS_CRITICAL; else if (actual_t[j] > stored_t[j]) { @@ -1560,11 +1573,14 @@ int validate_below(void) { break; } } + if (status != TS_PASS) + test_fail_cause[tc] = "Above "; return(status); } int validate_flatness(int i) { volatile int j; + test_fail_cause[i] = "Passband "; for (j = peakIndex; j < POINTS_COUNT; j++) { if (actual_t[j] < peakLevel - 3) // Search right -3dB break; @@ -1577,10 +1593,11 @@ int validate_flatness(int i) { } if (peakIndex - j < test_case[i].width) return(TS_FAIL); + test_fail_cause[i] = ""; return(TS_PASS); } -int validate_above(void) { +int validate_above(int tc) { int status = TS_PASS; for (int j = 0; j < POINTS_COUNT; j++) { if (actual_t[j] < stored_t[j] + 5) @@ -1590,6 +1607,8 @@ int validate_above(void) { break; } } + if (status != TS_PASS) + test_fail_cause[tc] = "Below "; return(status); } @@ -1607,32 +1626,12 @@ int test_validate(int i) SetPowerLevel(test_case[i].pass); goto common; case TC_MEASURE: - case TC_SIGNAL: // Validate signal - common: - if (validate_peak_within(i, 5.0)) // Validate Peak - current_test_status = TS_PASS; - else if (validate_peak_within(i, 10.0)) - current_test_status = TS_CRITICAL; - else - current_test_status = TS_FAIL; - if (current_test_status != TS_PASS) - test_fail_cause[i] = "Peak "; + case TC_SIGNAL: // Validate signal + common: current_test_status = validate_signal_within(i, 5.0); if (current_test_status == TS_PASS) { // Validate noise floor - for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) { - if (actual_t[j] > test_case[i].stop - 5) - current_test_status = TS_CRITICAL; - else if (actual_t[j] > test_case[i].stop) { - current_test_status = TS_FAIL; - break; - } - } - for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) { - if (actual_t[j] > test_case[i].stop - 5) - current_test_status = TS_CRITICAL; - else if (actual_t[j] > test_case[i].stop) { - current_test_status = TS_FAIL; - break; - } + current_test_status = validate_below(i, 0, POINTS_COUNT/2 - test_case[i].width); + if (current_test_status == TS_PASS) { + current_test_status = validate_below(i, POINTS_COUNT/2 + test_case[i].width, POINTS_COUNT); } if (current_test_status != TS_PASS) test_fail_cause[i] = "Stopband "; @@ -1641,28 +1640,15 @@ int test_validate(int i) test_value = peakLevel; else test_value = 0; // Not valid - break; + break; case TC_ABOVE: // Validate signal above curve - for (int j = 0; j < POINTS_COUNT; j++) { - if (actual_t[j] < test_case[i].pass + 5) - current_test_status = TS_CRITICAL; - else if (actual_t[j] < test_case[i].pass) { - current_test_status = TS_FAIL; - break; - } - } - if (current_test_status != TS_PASS) - test_fail_cause[i] = "Above "; + current_test_status = validate_above(i); break; case TC_BELOW: // Validate signal below curve - current_test_status = validate_below(); - if (current_test_status != TS_PASS) - test_fail_cause[i] = "Above "; - break; + current_test_status = validate_below(i, 0, POINTS_COUNT); + break; case TC_FLAT: // Validate passband flatness current_test_status = validate_flatness(i); - if (current_test_status != TS_PASS) - test_fail_cause[i] = "Passband "; break; } @@ -1682,6 +1668,8 @@ int test_validate(int i) void test_prepare(int i) { setting_tracking = false; //Default test setup + setting_step_atten = false; + SetAttenuation(0); switch(test_case[i].setup) { // Prepare test conditions case TPH_SILENT: // No input signal SetMode(M_HIGH); @@ -1693,9 +1681,15 @@ common_silent: for (int j = 0; j < POINTS_COUNT; j++) stored_t[j] = test_case[i].pass; break; + case TP_10MHZ_SWITCH: + SetMode(M_LOW); + set_refer_output(2); + setting_step_atten = true; + goto common; case TP_10MHZEXTRA: // Swept receiver SetMode(M_LOW); setting_tracking = true; //Sweep BPF + frequency_IF = 434000000; // Center on SAW filters set_refer_output(2); goto common; case TP_10MHZ: // 10MHz input @@ -1719,11 +1713,12 @@ common_silent: set_refer_output(0); goto common; } + setting_auto_attenuation = false; + setting_attenuate = 0; trace[TRACE_STORED].enabled = true; SetReflevel(test_case[i].pass+10); set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000)); set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000)); - SetAttenuation(0); draw_cal_status(); } @@ -1745,11 +1740,10 @@ int add_spur(int f) } return 1; } -#endif + void self_test(void) { -#ifdef __SELFTEST__ #if 0 in_selftest = true; @@ -1800,7 +1794,7 @@ void self_test(void) int local_test_status; in_selftest = true; reset_settings(M_LOW); - int i = 14; // calibrate low mode power on 30 MHz; + int i = 15; // calibrate low mode power on 30 MHz; test_prepare(i); for (int j= 0; j < 32; j++ ) { test_prepare(i); @@ -1815,7 +1809,7 @@ void self_test(void) int local_test_status; in_selftest = true; reset_settings(M_LOW); - int i = 14; // calibrate low mode power on 30 MHz; + int i = 15; // calibrate low mode power on 30 MHz; test_prepare(i); setting_step_delay = 6000; for (int j= 0; j < 57; j++ ) { @@ -1845,7 +1839,7 @@ void self_test(void) } return; #else - + int old_IF = frequency_IF; in_selftest = true; menu_autosettings_cb(0); for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting @@ -1857,6 +1851,7 @@ void self_test(void) show_test_info = TRUE; int i=0; while (test_case[i].kind != TC_END) { + frequency_IF = old_IF; test_prepare(i); test_acquire(i); // Acquire test test_status[i] = test_validate(i); // Validate test @@ -1877,8 +1872,6 @@ void self_test(void) reset_settings(M_LOW); in_selftest = false; #endif - -#endif } void reset_calibration(void) @@ -1897,7 +1890,7 @@ void calibrate(void) in_selftest = true; SetPowerLevel(100); reset_settings(M_LOW); - int i = 10; // calibrate low mode power on 30 MHz; + int i = 11; // calibrate low mode power on 30 MHz; for (int j= 0; j < CALIBRATE_RBWS; j++ ) { SetRBW(power_rbw[j]); test_prepare(i); @@ -1913,7 +1906,7 @@ void calibrate(void) chThdSleepMilliseconds(1000); } } - i = 11; // Measure 270MHz in low mode + i = 12; // Measure 270MHz in low mode SetRBW(100); test_prepare(i); test_acquire(i); // Acquire test @@ -1923,7 +1916,7 @@ void calibrate(void) config.high_level_offset = 0; /// Preliminary setting - i = 12; // Calibrate 270MHz in high mode + i = 13; // Calibrate 270MHz in high mode for (int j = 0; j < CALIBRATE_RBWS; j++) { SetRBW(power_rbw[j]); test_prepare(i); diff --git a/ui_sa.c b/ui_sa.c index eaf102f..b21fa89 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1384,7 +1384,7 @@ static void menu_item_modify_attribute( mark = true; } - } else if (MT_MASK(menu[item].type) != MT_CALLBACK && (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3)) { + } else if (MT_MASK(menu[item].type) == MT_CALLBACK && (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3)) { if (data == setting_drive){ mark = true; } From 8bffd8ba369d813ad4f1283387064372484c5a58 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 17 Apr 2020 09:09:25 +0200 Subject: [PATCH 086/193] Added harmonic mixer --- main.c | 8 ++--- nanovna.h | 11 ++++-- sa_core.c | 105 ++++++++++++++++++++++++++++++++++++++---------------- ui.c | 2 +- ui_sa.c | 35 +++++++++++++++--- 5 files changed, 118 insertions(+), 43 deletions(-) diff --git a/main.c b/main.c index 78790ba..157e039 100644 --- a/main.c +++ b/main.c @@ -37,10 +37,10 @@ #include #include -extern uint32_t minFreq; -extern uint32_t maxFreq; -uint32_t frequencyStart; -uint32_t frequencyStop; +extern float minFreq; +extern float maxFreq; +float frequencyStart; +float frequencyStop; int32_t frequencyExtra; #define START_MIN minFreq #define STOP_MAX maxFreq diff --git a/nanovna.h b/nanovna.h index 40ca6b3..3c6b621 100644 --- a/nanovna.h +++ b/nanovna.h @@ -30,6 +30,7 @@ #define __MEASURE__ #define __SELFTEST__ #define __CALIBRATE__ +#define __ULTRA__ /* * main.c @@ -124,12 +125,12 @@ int shell_printf(const char *fmt, ...); void toggle_sweep(void); void load_default_properties(void); -extern float perform(bool b, int i, int32_t f, int e); +extern float perform(bool b, int i, uint32_t f, int e); enum { AV_OFF, AV_MIN, AV_MAX_HOLD, AV_MAX_DECAY, AV_4, AV_16 }; enum { - M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, + M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, M_ULTRA }; enum { @@ -137,7 +138,11 @@ enum { }; #define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH ) +#ifdef __ULTRA__ +#define MODE_INPUT(x) ((x) == M_LOW || (x) == M_HIGH || (x) == M_ULTRA ) +#else #define MODE_INPUT(x) ((x) == M_LOW || (x) == M_HIGH ) +#endif #define MODE_HIGH(x) ((x) == M_HIGH || (x) == M_GENHIGH ) #define MODE_LOW(x) ((x) == M_LOW || (x) == M_GENLOW ) #define MODE_SELECT(x) (MODE_HIGH(x) ? 1 : 0) @@ -575,7 +580,7 @@ typedef struct uistat { int8_t digit; /* 0~5 */ int8_t digit_mode; int8_t current_trace; /* 0..3 */ - int32_t value; // for editing at numeric input area + float value; // for editing at numeric input area // uint32_t previous_value; uint8_t lever_mode; uint8_t marker_delta; diff --git a/sa_core.c b/sa_core.c index 2aa9f9b..631c45e 100644 --- a/sa_core.c +++ b/sa_core.c @@ -33,9 +33,9 @@ int setting_measurement; int vbwSteps = 1; -//int setting_spur = 0; -uint32_t minFreq = 0; -uint32_t maxFreq = 520000000; +int setting_spur = 0; +float minFreq = 0; +float maxFreq = 520000000; int setting_refer = -1; // Off by default const int reffer_freq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; @@ -69,15 +69,24 @@ void reset_settings(int m) trace[TRACE_TEMP].enabled = false; setting_measurement = M_OFF; -// setting_spur = 0; + setting_spur = 0; switch(m) { case M_LOW: minFreq = 0; maxFreq = 520000000; - set_sweep_frequency(ST_START, (int32_t) 0); - set_sweep_frequency(ST_STOP, (int32_t) 350000000); + set_sweep_frequency(ST_START, (uint32_t) 0); + set_sweep_frequency(ST_STOP, (uint32_t) 350000000); setting_attenuate = 30; break; +#ifdef __ULTRA__ + case M_ULTRA: + minFreq = 770000000; + maxFreq = 4360000000; + set_sweep_frequency(ST_START, (uint32_t) 960000000); + set_sweep_frequency(ST_STOP, (uint32_t) 2100000000); + setting_attenuate = 30; + break; +#endif case M_GENLOW: setting_drive=8; minFreq = 0; @@ -290,6 +299,10 @@ void SetPowerLevel(int o) config.high_level_offset = new_offset; else if (setting_mode == M_LOW) config.low_level_offset = new_offset; +#ifdef __ULTRA__ + else if (setting_mode == M_ULTRA) + config.low_level_offset = new_offset; +#endif } else { config.low_level_offset = 100; @@ -338,13 +351,13 @@ int GetActualRBW(void) { return((int) actual_rbw); } -#if 0 + + void SetSpur(int v) { -// setting_spur = v; + setting_spur = v; dirty = true; } -#endif void SetStepDelay(int d) { @@ -422,6 +435,10 @@ void SetScale(int s) { //} void SetMode(int m) { +#ifdef __ULTRA__ + if (m == 6) + m = M_ULTRA; +#endif if (setting_mode == m) return; reset_settings(m); @@ -511,6 +528,9 @@ void SetRX(int m) { switch(m) { case M_LOW: // Mixed into 0 +#ifdef __ULTRA__ +case M_ULTRA: +#endif SI4432_Sel = 0; SI4432_Receive(); if (setting_step_atten) { @@ -821,14 +841,14 @@ static int modulation_counter = 0; char age[POINTS_COUNT]; -float perform(bool break_on_operation, int i, int32_t f, int tracking) +float perform(bool break_on_operation, int i, uint32_t f, int tracking) { - // long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0); long local_IF; if (MODE_HIGH(setting_mode)) local_IF = 0; else - local_IF = frequency_IF; + local_IF = frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw:0); +// local_IF = frequency_IF; if (i == 0 && dirty) { apply_settings(); @@ -865,7 +885,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) float RSSI = -150.0; int t = 0; do { - int lf = (uint32_t)(f + (int)((t * 500 - vbwSteps * 250) * actual_rbw)); + uint32_t lf = (uint32_t)(f + (int)((t * 500 - vbwSteps * 250) * actual_rbw)); if (lf < 0) lf = 0; if (setting_mode == M_LOW && tracking) { setFreq (0, frequency_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible @@ -874,11 +894,15 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) if (setting_mode == M_LOW && !in_selftest && avoid_spur(f)) { local_IF = spur_alternate_IF; } else { - local_IF = frequency_IF ; +// local_IF = frequency_IF ; } if (setting_mode == M_GENLOW && setting_modulation == MO_EXTERNAL) local_IF += lf; setFreq (0, local_IF); +#ifdef __ULTRA__ + } else if (setting_mode == M_ULTRA) { +// local_IF = frequency_IF; +#endif } else local_IF= 0; #if 0 @@ -887,13 +911,32 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking) break; } #endif - setFreq (1, local_IF + lf); +#ifdef __ULTRA__ + if (setting_mode == M_ULTRA) { +// if (lf > 3406000000 ) +// setFreq (1, local_IF/5 + lf/5); +// else + if (lf > 2446000000 ) + setFreq (1, local_IF/5 + lf/5); + else +// if (lf > 1486000000) + setFreq (1, local_IF/3 + lf/3); +// else +// setFreq (1, local_IF/2 + lf/2); + } else +#endif + setFreq (1, local_IF + lf); if (MODE_OUTPUT(setting_mode)) // No substepping in output mode return(0); float signal_path_loss; - if (setting_mode == M_LOW) - signal_path_loss = -9.5; // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 +#ifdef __ULTRA__ + if (setting_mode == M_ULTRA) + signal_path_loss = -15; // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 else +#endif + if (setting_mode == M_LOW) + signal_path_loss = -9.5; // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 + else signal_path_loss = 7; // Loss in dB (+ is gain) float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+ setting_attenuate - signal_path_loss; if (RSSI < subRSSI) @@ -918,7 +961,7 @@ static bool sweep(bool break_on_operation) temppeakLevel = -150; float temp_min_level = 100; // spur_old_stepdelay = 0; - //again: +again: for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking); @@ -930,12 +973,12 @@ static bool sweep(bool break_on_operation) } if (MODE_INPUT(setting_mode)) { - // if (setting_spur == 1) { // First pass - // temp_t[i] = RSSI; - // continue; // Skip all other processing - // } - // if (setting_spur == -1) // Second pass - // RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes + if (setting_spur == 1) { // First pass + temp_t[i] = RSSI; + continue; // Skip all other processing + } + if (setting_spur == -1) // Second pass + RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes temp_t[i] = RSSI; if (setting_subtract_stored) { RSSI = RSSI - stored_t[i] ; @@ -1023,11 +1066,11 @@ static bool sweep(bool break_on_operation) temp_min_level = actual_t[i]; } - // if (setting_spur == 1) { - // setting_spur = -1; - // goto again; - // } else if (setting_spur == -1) - // setting_spur = 1; + if (setting_spur == 1) { + setting_spur = -1; + goto again; + } else if (setting_spur == -1) + setting_spur = 1; if (scandirty) { scandirty = false; @@ -1335,7 +1378,7 @@ void draw_cal_status(void) buf[5]=0; ili9341_drawstring(buf, x, y); } -#if 0 +#if 1 if (setting_spur) { ili9341_set_foreground(BRIGHT_COLOR_BLUE); y += YSTEP*2; @@ -1383,7 +1426,7 @@ void draw_cal_status(void) ili9341_drawstring("Scan:", x, y); y += YSTEP; - int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 /* * (setting_spur ? 2 : 1) */; // in mS + int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 * (setting_spur ? 2 : 1); // in mS if (t>1000) plot_printf(buf, BLEN, "%dS",(t+500)/1000); else diff --git a/ui.c b/ui.c index e508c71..a665681 100644 --- a/ui.c +++ b/ui.c @@ -2051,7 +2051,7 @@ keypad_click(int key) /* numeric input done */ double value = my_atof(kp_buf) * scale; #if 1 - uistat.value = (int)value; + uistat.value = value; set_numeric_value(); #else switch (keypad_mode) { diff --git a/ui_sa.c b/ui_sa.c index b21fa89..a29ce65 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -23,7 +23,7 @@ void SetDrive(int d); void SetIF(int f); void SetStepDelay(int t); extern int setting_rbw; -void SetSpur(int); +extern int setting_spur; int GetSpur(void); void SetAverage(int); int GetAverage(void); @@ -473,6 +473,7 @@ extern const menuitem_t menu_highoutputmode[]; extern const menuitem_t menu_modulation[]; extern const menuitem_t menu_top[]; extern const menuitem_t menu_tophigh[]; +extern const menuitem_t menu_topultra[]; static void menu_mode_cb(int item, uint8_t data) { @@ -492,6 +493,9 @@ static void menu_mode_cb(int item, uint8_t data) case 4: menu_push_submenu(menu_highoutputmode); break; + case 7: + menu_push_submenu(menu_topultra); + break; } // draw_cal_status(); } @@ -614,13 +618,13 @@ static void menu_drive_cb(int item, uint8_t data) -#if 0 +#if 1 static void menu_spur_cb(int item, uint8_t data) { (void)data; (void)item; - if (GetSpur()) + if (setting_spur) SetSpur(0); else SetSpur(1); // must be 0 or 1 !!!! @@ -1250,6 +1254,7 @@ static const menuitem_t menu_stimulus[] = { { MT_KEYPAD, KM_SPAN, "SPAN", NULL}, { MT_KEYPAD, KM_CW, "\2ZERO\0SPAN", NULL}, { MT_SUBMENU,0, "RBW", menu_rbw}, + { MT_CALLBACK,0, "\2SPUR\0REMOVAL", menu_spur_cb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1264,10 +1269,29 @@ static const menuitem_t menu_mode[] = { { MT_FORM | MT_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "HIGH OUTPUT", menu_mode_cb}, { MT_FORM | MT_SUBMENU | MT_ICON, I_CONNECT+I_GEN, "CAL OUTPUT: %s", menu_reffer}, { MT_FORM | MT_SUBMENU | MT_ICON, I_EMPTY+I_CONFIG, "CONFIG", menu_config}, -// { MT_CANCEL, 0, S_LARROW" BACK", NULL }, +#ifdef __ULTRA__ + { MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "ULTRA HIGH INPUT",menu_mode_cb}, +#endif + // { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; #if 1 + +#ifdef __ULTRA__ +const menuitem_t menu_topultra[] = { + { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, + { MT_SUBMENU, 0, "FREQ", menu_stimulus}, + { MT_SUBMENU, 0, "LEVEL", menu_level}, + { MT_SUBMENU, 0, "DISPLAY", menu_display}, + { MT_SUBMENU, 0, "MARKER", menu_marker}, + { MT_SUBMENU, 0, "MEASURE", menu_measure}, + { MT_SUBMENU, 0, "SETTINGS", menu_settings}, + { MT_CANCEL, 0, S_LARROW" MODE",NULL}, + { MT_NONE, 0, NULL, NULL } // sentinel, + // MENUITEM_CLOSE, +}; +#endif + const menuitem_t menu_top[] = { { MT_CALLBACK, 0, "RESET", menu_autosettings_cb}, { MT_SUBMENU, 0, "FREQ", menu_stimulus}, @@ -1367,6 +1391,9 @@ static void menu_item_modify_attribute( if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_ENABLE)) { mark = true; } + if (item == 6 && setting_spur) { + mark = true; + } } else if (menu == menu_average) { if (item == GetAverage()){ mark = true; From feb6f5e81a54e53348e537d8bc4f67e3b9ae7fc7 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 17 Apr 2020 09:16:42 +0200 Subject: [PATCH 087/193] Harmonic made optional --- nanovna.h | 2 +- ui_sa.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/nanovna.h b/nanovna.h index 3c6b621..75b20f5 100644 --- a/nanovna.h +++ b/nanovna.h @@ -30,7 +30,7 @@ #define __MEASURE__ #define __SELFTEST__ #define __CALIBRATE__ -#define __ULTRA__ +//#define __ULTRA__ /* * main.c diff --git a/ui_sa.c b/ui_sa.c index a29ce65..502947f 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -24,7 +24,7 @@ void SetIF(int f); void SetStepDelay(int t); extern int setting_rbw; extern int setting_spur; -int GetSpur(void); +void SetSpur(int v); void SetAverage(int); int GetAverage(void); extern int setting_average; @@ -493,9 +493,11 @@ static void menu_mode_cb(int item, uint8_t data) case 4: menu_push_submenu(menu_highoutputmode); break; +#ifdef __ULTRA__ case 7: menu_push_submenu(menu_topultra); break; +#endif } // draw_cal_status(); } From aa6c0623410b4fa07bc0a78bbe461c0f19bb3406 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sat, 18 Apr 2020 18:15:50 +0200 Subject: [PATCH 088/193] Modify marker menu created adn ADF4351 core added --- NANOVNA_STM32_F072/board.h | 22 ++- main.c | 2 + nanovna.h | 3 +- sa_core.c | 32 +++- si4432.c | 362 ++++++++++++++++++++++++++++++++++++- si4432.h | 22 +++ ui.c | 17 +- ui_sa.c | 88 ++++++--- 8 files changed, 500 insertions(+), 48 deletions(-) diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index 5724a6c..7d5a539 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -56,6 +56,7 @@ #define GPIOA_XP 6 #define GPIOA_YP 7 #define GPIOA_MCO 8 +#define GPIOA_TX 9 #define GPIOA_USB_DISC 10 #define GPIOA_USB_DM 11 #define GPIOA_USB_DP 12 @@ -116,16 +117,23 @@ * PA13 - SWDIO (alternate 0). * PA14 - SWCLK (alternate 0). */ +#define __ULTRA_SA__ +#ifdef __ULTRA_SA__ +#define PIN_MOD_ULTRA(X) PIN_MODE_OUTPUT(X) +#else +#define PIN_MOD_ULTRA(X) PIN_MODE_INPUT(X) +#endif + #define VAL_GPIOA_MODER (PIN_MODE_OUTPUT(GPIOA_PE_SEL) | \ - PIN_MODE_INPUT(1U) | \ - PIN_MODE_INPUT(2U) | \ - PIN_MODE_INPUT(3U) | \ + PIN_MOD_ULTRA(1U) | \ + PIN_MOD_ULTRA(2U) | \ + PIN_MOD_ULTRA(3U) | \ PIN_MODE_OUTPUT(GPIOA_RX_SEL) | \ PIN_MODE_OUTPUT(GPIOA_LO_SEL) | \ PIN_MODE_ANALOG(GPIOA_XP) | \ PIN_MODE_ANALOG(GPIOA_YP) | \ PIN_MODE_ALTERNATE(GPIOA_MCO) | \ - PIN_MODE_INPUT(9U) | \ + PIN_MOD_ULTRA(9U) | \ PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \ PIN_MODE_INPUT(GPIOA_USB_DM) | \ PIN_MODE_INPUT(GPIOA_USB_DP) | \ @@ -149,9 +157,9 @@ PIN_OTYPE_PUSHPULL(GPIOA_JTCK) | \ PIN_OTYPE_PUSHPULL(GPIOA_LCD_RESET)) #define VAL_GPIOA_OSPEEDR (PIN_OSPEED_100M(GPIOA_PE_SEL) | \ - PIN_OSPEED_2M(1) | \ - PIN_OSPEED_2M(2) | \ - PIN_OSPEED_2M(3) | \ + PIN_OSPEED_100M(1) | \ + PIN_OSPEED_100M(2) | \ + PIN_OSPEED_100M(3) | \ PIN_OSPEED_100M(4) | \ PIN_OSPEED_100M(5) | \ PIN_OSPEED_2M(6) | \ diff --git a/main.c b/main.c index 157e039..acfac0c 100644 --- a/main.c +++ b/main.c @@ -2716,6 +2716,8 @@ int main(void) #endif + ADF4351_Setup(); + /* * SPI LCD Initialize */ diff --git a/nanovna.h b/nanovna.h index 75b20f5..2d2a230 100644 --- a/nanovna.h +++ b/nanovna.h @@ -31,6 +31,7 @@ #define __SELFTEST__ #define __CALIBRATE__ //#define __ULTRA__ +#define __ULTRA_SA__ /* * main.c @@ -329,7 +330,7 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]); #endif // marker enum { - M_NORMAL=0,M_REFERENCE=1, M_DELTA=2, M_NOISE=4, M_TRACKING=8 // Tracking must be last. + M_NORMAL=0,M_REFERENCE=1, M_DELTA=2, M_NOISE=4, M_TRACKING=8, M_DELETE=16 // Tracking must be last. }; enum { diff --git a/sa_core.c b/sa_core.c index 631c45e..446a4a0 100644 --- a/sa_core.c +++ b/sa_core.c @@ -32,8 +32,9 @@ int setting_tracking_output; int setting_measurement; int vbwSteps = 1; - +#ifdef __ULTRA__ int setting_spur = 0; +#endif float minFreq = 0; float maxFreq = 520000000; @@ -69,7 +70,9 @@ void reset_settings(int m) trace[TRACE_TEMP].enabled = false; setting_measurement = M_OFF; +#ifdef __ULTRA__ setting_spur = 0; +#endif switch(m) { case M_LOW: minFreq = 0; @@ -352,12 +355,13 @@ int GetActualRBW(void) return((int) actual_rbw); } - +#ifdef __ULTRA void SetSpur(int v) { setting_spur = v; dirty = true; } +#endif void SetStepDelay(int d) { @@ -847,8 +851,11 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) if (MODE_HIGH(setting_mode)) local_IF = 0; else - local_IF = frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw:0); -// local_IF = frequency_IF; + local_IF = frequency_IF +#ifdef __ULTRA__ + + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw:0) +#endif + ; if (i == 0 && dirty) { apply_settings(); @@ -961,7 +968,9 @@ static bool sweep(bool break_on_operation) temppeakLevel = -150; float temp_min_level = 100; // spur_old_stepdelay = 0; +#ifdef __ULTRA__ again: +#endif for (int i = 0; i < sweep_points; i++) { RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking); @@ -973,12 +982,14 @@ again: } if (MODE_INPUT(setting_mode)) { - if (setting_spur == 1) { // First pass +#ifdef __ULTRA__ + if (setting_spur == 1) { // First pass temp_t[i] = RSSI; continue; // Skip all other processing } if (setting_spur == -1) // Second pass RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes +#endif temp_t[i] = RSSI; if (setting_subtract_stored) { RSSI = RSSI - stored_t[i] ; @@ -1066,12 +1077,13 @@ again: temp_min_level = actual_t[i]; } +#ifdef __ULTRA__ if (setting_spur == 1) { setting_spur = -1; goto again; } else if (setting_spur == -1) setting_spur = 1; - +#endif if (scandirty) { scandirty = false; draw_cal_status(); @@ -1378,7 +1390,7 @@ void draw_cal_status(void) buf[5]=0; ili9341_drawstring(buf, x, y); } -#if 1 +#ifdef __ULTRA__ if (setting_spur) { ili9341_set_foreground(BRIGHT_COLOR_BLUE); y += YSTEP*2; @@ -1426,7 +1438,11 @@ void draw_cal_status(void) ili9341_drawstring("Scan:", x, y); y += YSTEP; - int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 * (setting_spur ? 2 : 1); // in mS + int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 +#ifdef __ULTRA__ + * (setting_spur ? 2 : 1) +#endif + ; // in mS if (t>1000) plot_printf(buf, BLEN, "%dS",(t+500)/1000); else diff --git a/si4432.c b/si4432.c index b79572c..b0492bf 100644 --- a/si4432.c +++ b/si4432.c @@ -19,7 +19,7 @@ #include "ch.h" #include "hal.h" #include "nanovna.h" - +#include #include "si4432.h" #define CS_SI0_HIGH palSetPad(GPIOA, GPIOA_RX_SEL) @@ -502,4 +502,364 @@ float Simulated_SI4432_RSSI(uint32_t i, int s) return(v); } +#endif +//------------------------------- ADF4351 ------------------------------------- + + +#ifdef __ULTRA_SA__ + + +#define bitClear(X,n) (X) ^= ((uint32_t)0xfffffffe) << (n) +#define bitSet(X,n) (X) |= ((uint32_t)1) << (n) +#define bitWrite(X,n,v) if (v) bitSet(X,n); else bitClear(X,n) + + + +#define CS_ADF0_HIGH palSetPad(GPIOA, 9) +#define CS_ADF1_HIGH palSetPad(GPIOA, 10) + +#define CS_ADF0_LOW palClearPad(GPIOA, 9) +#define CS_ADF1_LOW palClearPad(GPIOA, 10) + +#define SPI3_CLK_HIGH palSetPad(GPIOA, 1) +#define SPI3_CLK_LOW palClearPad(GPIOA, 1) + +#define SPI3_SDI_HIGH palSetPad(GPIOA, 2) +#define SPI3_SDI_LOW palClearPad(GPIOA, 2) + + +void ADF_shiftOut(uint8_t val) +{ + uint8_t i; + for (i = 0; i < 8; i++) { + if (val & (1 << (7 - i))) + SPI3_SDI_HIGH; + else + SPI3_SDI_LOW; + chThdSleepMicroseconds(1); + SPI3_CLK_HIGH; + SPI3_CLK_LOW; + } +} + +//unsigned long registers[6] = {0x4580A8, 0x80080C9, 0x4E42, 0x4B3, 0xBC803C, 0x580005} ; +//unsigned long registers[6] = {0x4C82C8, 0x80083E9, 0x6E42, 0x8004B3, 0x8C81FC, 0x580005} ; +unsigned long registers[6] = {0x320000, 0x8008011, 0x18004E42, 0x4B3,0x8C803C , 0x00580005} ; +int debug = 0; +int ADF4351_LE[2] = { 9, 10}; +int ADF4351_Mux = 7; + + +//#define DEBUG(X) // Serial.print( X ) +//#define DEBUGLN(X) Serial.println( X ) +//#define DEBUGFLN(X,Y) Serial.println( X,Y ) +//#define DEBUGF(X,Y) Serial.print( X,Y ) +#define DEBUG(X) +#define DEBUGLN(X) + + +double RFout, //Output freq in MHz +#if 1 //Black modules + PFDRFout[6] = {25.0,25.0,25.0,10.0,10.0,10.0}, //Reference freq in MHz + Chrystal[6] = {25.0,25.0,25.0,10.0,10.0,10.0}, +#else // Green modules + PFDRFout[6] = {10.0,10.0,10.0,10.0,10.0,10.0}, //Reference freq in MHz + Chrystal[6] = {10.0,10.0,10.0,10.0,10.0,10.0}, +#endif + + OutputChannelSpacing = 0.010, // = 0.01 + FRACF; // Temp + +unsigned int long RFint, // Output freq/10Hz + INTA, // Temp + RFcalc, //UI + MOD, //Temp + FRAC; //Temp + +byte OutputDivider; // Temp +byte lock=2; //Not used + +// Lock = A4 + +void ADF4351_Setup() +{ +// palSetPadMode(GPIOA, 1, PAL_MODE_OUTPUT_PUSHPULL ); +// palSetPadMode(GPIOA, 2, PAL_MODE_OUTPUT_PUSHPULL ); + + SPI3_CLK_HIGH; + SPI3_SDI_HIGH; + CS_ADF0_HIGH; + CS_ADF1_HIGH; +// bitSet (registers[2], 17); // R set to 8 +// bitClear (registers[2], 14); // R set to 8 + + ADF4351_R_counter(1); + ADF4351_level(3); + ADF4351_channel_spacing(10); + + while(1) { +// + ADF4351_set_frequency(1,100000000,0); +// ADF4351_set_frequency(1,150000000,0); +// ADF4351_Set(0); +// ADF4351_Set(1); + chThdSleepMilliseconds(1000); + } +// bitSet (registers[2], 17); // R set to 8 +// bitClear (registers[2], 14); // R set to 8 +// for (int i=0; i<6; i++) pinMode(ADF4351_LE[i], OUTPUT); // Setup pins +// for (int i=0; i<6; i++) digitalWrite(ADF4351_LE[i], HIGH); +// pinMode(ADF4351_Mux, INPUT); +// SPI.begin(); // Init SPI bus +// SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0)); + //SPI.setDataMode(SPI_MODE0); // CPHA = 0 Clock positive + //SPI.setBitOrder(MSBFIRST); +} + +void ADF4351_WriteRegister32(int channel, const uint32_t value) +{ + palClearPad(GPIOA, ADF4351_LE[channel]); +// chThdSleepMicroseconds(SELECT_DELAY); + for (int i = 3; i >= 0; i--) ADF_shiftOut((value >> 8 * i) & 0xFF); + palSetPad(GPIOA, ADF4351_LE[channel]); +// chThdSleepMicroseconds(SELECT_DELAY); + palClearPad(GPIOA, ADF4351_LE[channel]); +// chThdSleepMicroseconds(SELECT_DELAY); +} + +void ADF4351_disable_output() +{ + bitClear (registers[4], 5); // digital lock + ADF4351_Set(0); +} + +void ADF4351_enable_output() +{ + bitSet (registers[4], 5); // digital lock + ADF4351_Set(0); +} +void ADF4351_Set(int channel) +{ for (int i = 5; i >= 0; i--) { + ADF4351_WriteRegister32(channel, registers[i]); +// if (debug) Serial.println(registers[i],HEX); +} +} + +void ADF4351_set_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz +{ + ADF4351_prep_frequency(channel,freq, drive); + ADF4351_Set(channel); +} + +void ADF4351_spur_mode(int S) +{ + if (S & 1) + bitSet (registers[2], 29); // R set to 8 + else + bitClear (registers[2], 29); // R set to 8 + if (S & 2) + bitSet (registers[2], 30); // R set to 8 + else + bitClear (registers[2], 30); // R set to 8 +} + +void ADF4351_R_counter(int R) +{ + int dbl = false; + if (R < 0) { + dbl = true; + R = -R; + } + if (R<1) + return; + if (dbl) { + bitSet (registers[2], 25); // Reference doubler + } else { + bitClear (registers[2], 25); // Reference doubler + } + for (int channel=0; channel < 6; channel++) { + PFDRFout[channel] = Chrystal[channel] * (dbl?2:1) / R; + } + registers[2] &= ~ (((unsigned long)0x3FF) << 14); + registers[2] |= (((unsigned long)R) << 14); +} + +void ADF4351_CP(int p) +{ + registers[2] &= ~ (((unsigned long)0xF) << 9); + registers[2] |= (((unsigned long)p) << 9); +} + +void ADF4351_level(int p) +{ + registers[4] &= ~ (((unsigned long)0x3) << 3); + registers[4] |= (((unsigned long)p) << 3); +} + +void ADF4351_channel_spacing(int spacing) +{ + OutputChannelSpacing = 0.001 * spacing; +} + +static uint32_t gcd(uint32_t x, uint32_t y) +{ + uint32_t z; + while (y != 0) { + z = x % y; + x = y; + y = z; + } + return x; +} + +void ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz +{ + (void)drive; +// if (channel == 0) + RFout=freq/1000000.0; // To MHz +// else + // RFout=freq/1000002.764; // To MHz + + if (RFout >= 2200) { + OutputDivider = 1; + bitWrite (registers[4], 22, 0); + bitWrite (registers[4], 21, 0); + bitWrite (registers[4], 20, 0); + } else if (RFout >= 1100) { + OutputDivider = 2; + bitWrite (registers[4], 22, 0); + bitWrite (registers[4], 21, 0); + bitWrite (registers[4], 20, 1); + } else if (RFout >= 550) { + OutputDivider = 4; + bitWrite (registers[4], 22, 0); + bitWrite (registers[4], 21, 1); + bitWrite (registers[4], 20, 0); + } else if (RFout >= 275) { + OutputDivider = 8; + bitWrite (registers[4], 22, 0); + bitWrite (registers[4], 21, 1); + bitWrite (registers[4], 20, 1); + } else if (RFout >= 137.5) { + OutputDivider = 16; + bitWrite (registers[4], 22, 1); + bitWrite (registers[4], 21, 0); + bitWrite (registers[4], 20, 0); + } else if (RFout >= 68.75) { + OutputDivider = 32; + bitWrite (registers[4], 22, 1); + bitWrite (registers[4], 21, 0); + bitWrite (registers[4], 20, 1); + } else { + OutputDivider = 64; + bitWrite (registers[4], 22, 1); + bitWrite (registers[4], 21, 1); + bitWrite (registers[4], 20, 0); + } + + INTA = (RFout * OutputDivider) / PFDRFout[channel]; + MOD = (PFDRFout[channel] / OutputChannelSpacing) + 0.01; +// MOD = 3125; + FRACF = (((RFout * OutputDivider) / PFDRFout[channel]) - INTA) * MOD; + FRAC = round(FRACF); + + while (FRAC > 4095 || MOD > 4095) { + FRAC = FRAC >> 1; + MOD = MOD >> 1; + // Serial.println( "MOD/FRAC reduced"); + } + + int32_t k = gcd(FRAC, MOD); + if (k > 1) { + FRAC /= k; + MOD /= k; +// Serial.print( "MOD/FRAC gcd reduced"); + } +// while (denom >= (1<<20)) { +// num >>= 1; +// denom >>= 1; +// } + + +// if (INTA <= 75) Serial.println( "INTA <= 75"); +// if (FRAC > 4095) Serial.println( "FRAC > 4095"); +// if (MOD > 4095) Serial.println( "MOD > 4095"); + + +// if (FRAC > 4095) Serial.println( "FRAC > 4095"); +// if (MOD > 4095) Serial.println( "MOD > 4095"); +// if (INTA > 4095) Serial.println( "INT > 4095"); + + if (debug) { + DEBUG(" ODIV="); + DEBUG(OutputDivider); + DEBUG(" INT="); + DEBUG(INTA); + DEBUG(" FRAC="); + DEBUG(FRAC); + DEBUG(" MOD="); + DEBUG(MOD); + DEBUG( " CalF="); +// DEBUGFLN(PFDRFout[channel] *(INTA + ((double)FRAC)/MOD)/OutputDivider,6); + +// DEBUG(" FRACF="); +// DEBUGF(FRACF,6); + } + registers[0] = 0; + registers[0] = INTA << 15; // OK + FRAC = FRAC << 3; + registers[0] = registers[0] + FRAC; + //if (MOD == 1) MOD = 2; + registers[1] = 0; + registers[1] = MOD << 3; + registers[1] = registers[1] + 1 ; // restore address "001" + bitSet (registers[1], 27); // Prescaler at 8/9 +/* + drive = 1; + if (drive == 0) { + bitClear (registers[4], 3); // +5dBm + out + bitClear (registers[4], 4); // +5dBm + bitClear (registers[4], 6); // +5dBm - out + bitClear (registers[4], 7); // +5dBm + } else if (drive == 1) { + bitSet (registers[4], 6); // +5dBm + bitClear (registers[4], 7); // +5dBm - out + bitSet (registers[4], 3); // +5dBm + bitClear (registers[4], 4); // +5dBm + out + } else if (drive == 2) { + bitClear (registers[4], 6); // +5dBm - out + bitSet (registers[4], 7); // +5dBm + bitClear (registers[4], 3); // +5dBm + out + bitSet (registers[4], 4); // +5dBm + } + else { + bitSet (registers[4], 6); // +5dBm - out + bitSet (registers[4], 7); // +5dBm + bitSet (registers[4], 3); // +5dBm + out + bitSet (registers[4], 4); // +5dBm + } +*/ + bitSet (registers[4], 5); // enable + output + bitClear (registers[4], 8); // enable B output + +#if 0 + if (FRAC == 0) + bitSet (registers[2], 8); // INT mode + else + bitClear (registers[2], 8); // INT mode + bitSet (registers[2], 13); // Double buffered + + bitSet (registers[2], 28); // Digital lock == "110" sur b28 b27 b26 + bitSet (registers[2], 27); // digital lock + bitClear (registers[2], 26); // digital lock + + //bitSet (registers[4], 10); // Mute till lock + bitSet (registers[3], 23); // Fast lock + #endif + bitSet (registers[4], 10); // Mute till lock +// ADF4351_Set(channel); +} + + + #endif diff --git a/si4432.h b/si4432.h index 8b2774e..8473302 100644 --- a/si4432.h +++ b/si4432.h @@ -19,4 +19,26 @@ float SI4432_SET_RBW(float WISH); void PE4302_Write_Byte(unsigned char DATA ); void PE4302_init(void); +#ifdef __ULTRA_SA__ +extern int ADF4351_LE[]; +extern int debug; +void ADF4351_Setup(void); + + +void ADF4351_WriteRegister32(int channel, const uint32_t value); +void ADF4351_set_frequency(int channel, uint32_t freq, int drive_strength); +void ADF4351_prep_frequency(int channel, uint32_t freq, int drive_strength); +//int ADF4351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength); +void ADF4351_Set(int channel); +void ADF4351_enable_output(void); +void ADF4351_disable_output(void); +void ADF4351_spur_mode(int S); +void ADF4351_R_counter(int R); +void ADF4351_channel_spacing(int spacing); +void ADF4351_CP(int p); +void ADF4351_level(int p); +int ADF4351_locked(void); +#endif + + #endif //__SI4432_H__ diff --git a/ui.c b/ui.c index a665681..899d0d0 100644 --- a/ui.c +++ b/ui.c @@ -53,7 +53,11 @@ uistat_t uistat = { #define BIT_DOWN1 1 #define READ_PORT() palReadPort(GPIOA) +#ifdef __ULTRA_SA__ +#define BUTTON_MASK 0 +#else #define BUTTON_MASK 0b1110 +#endif static uint16_t last_button = 0b0000; static uint32_t last_button_down_ticks; @@ -128,7 +132,7 @@ static void choose_active_marker(void); static void menu_move_back(void); static void menu_push_submenu(const menuitem_t *submenu); -static const menuitem_t menu_marker_type[]; +//static const menuitem_t menu_marker_type[]; static int btn_check(void) { @@ -1109,7 +1113,7 @@ const menuitem_t menu_top[] = { #include "ui_sa.c" -#define MENU_STACK_DEPTH_MAX 4 +#define MENU_STACK_DEPTH_MAX 5 const menuitem_t *menu_stack[MENU_STACK_DEPTH_MAX] = { menu_mode, NULL, NULL, NULL }; @@ -1784,7 +1788,7 @@ static void draw_numeric_area(void) { char buf[10]; - plot_printf(buf, sizeof buf, "%9d", uistat.value); + plot_printf(buf, sizeof buf, "%9d", ((int32_t)uistat.value)); draw_numeric_input(buf); } @@ -2497,8 +2501,13 @@ static void extcb1(EXTDriver *extp, expchannel_t channel) static const EXTConfig extcfg = { { {EXT_CH_MODE_DISABLED, NULL}, +#ifdef __ULTRA_SA__ + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, +#else {EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1}, {EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1}, +#endif {EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1}, {EXT_CH_MODE_DISABLED, NULL}, {EXT_CH_MODE_DISABLED, NULL}, @@ -2556,8 +2565,8 @@ ui_init() /* * Activates the EXT driver 1. */ - extStart(&EXTD1, &extcfg); + extStart(&EXTD1, &extcfg); #if 1 gptStart(&GPTD3, &gpt3cfg); gptPolledDelay(&GPTD3, 10); /* Small delay.*/ diff --git a/ui_sa.c b/ui_sa.c index 502947f..745bf81 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1,6 +1,6 @@ void markmap_all_markers(void); -static void menu_marker_type_cb(int item, uint8_t data); - +static void menu_marker_modify_cb(int item, uint8_t data); +extern const menuitem_t menu_marker_modify[]; void set_sweep_frequency(int type, uint32_t frequency); uint32_t get_sweep_frequency(int type); void clearDisplay(void); @@ -23,8 +23,10 @@ void SetDrive(int d); void SetIF(int f); void SetStepDelay(int t); extern int setting_rbw; +#ifdef __ULTRA__ extern int setting_spur; void SetSpur(int v); +#endif void SetAverage(int); int GetAverage(void); extern int setting_average; @@ -620,8 +622,7 @@ static void menu_drive_cb(int item, uint8_t data) -#if 1 - +#ifdef __ULTRA__ static void menu_spur_cb(int item, uint8_t data) { (void)data; @@ -791,12 +792,31 @@ static void menu_average_cb(int item, uint8_t data) draw_cal_status(); } -static void menu_marker_type_cb(int item, uint8_t data) +static void +menu_marker_select_cb(int item, uint8_t data) +{ + (void)data; +// int t; + if (item >= 0 && item < MARKERS_MAX) { + markers[item].enabled = true; + active_marker_select(item); + menu_push_submenu(menu_marker_modify); + redraw_marker(active_marker); + draw_menu(); + } +} + +static void menu_marker_modify_cb(int item, uint8_t data) { (void)item; if (markers[active_marker].enabled == M_ENABLED) { - if (data == M_NORMAL) { + if (data == M_DELETE) { + markers[active_marker].enabled = false; + menu_move_back(); +// ui_mode_normal(); +// return; + } else if (data == M_NORMAL) { markers[active_marker].mtype = M_NORMAL; } else if (data == M_REFERENCE) { for (int i = 0; i= 0 && markers[active_marker].enabled == M_ENABLED) { + } else if (menu == menu_marker_modify && active_marker >= 0 && markers[active_marker].enabled == M_ENABLED) { if (data & markers[active_marker].mtype) mark = true; else if (item < 5 && data==markers[active_marker].mtype) // This catches the M_NORMAL case @@ -1460,8 +1494,8 @@ static void menu_item_modify_attribute( mark = true; if (item == 4 && markers[active_marker].mtype & M_TRACKING) mark = true; - } else if (menu == menu_marker_sel) { - if (item < MARKERS_MAX && markers[item].enabled) + } else if (menu == menu_marker_sel || menu == menu_marker_select) { + if (item < 4 && markers[item].enabled) mark = true; else if (item == 4 && uistat.marker_delta) mark = true; @@ -1516,19 +1550,19 @@ static void fetch_numeric_target(void) break; case KM_SCALE: uistat.value = setting_scale; - plot_printf(uistat.text, sizeof uistat.text, "%ddB/", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%ddB/", ((int32_t)uistat.value)); break; case KM_REFPOS: uistat.value = setting_reflevel; - plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value)); break; case KM_ATTENUATION: uistat.value = GetAttenuation(); - plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value)); break; case KM_ACTUALPOWER: uistat.value = settingLevelOffset(); - plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value)); break; case KM_IF: uistat.value = frequency_IF; @@ -1536,23 +1570,23 @@ static void fetch_numeric_target(void) break; case KM_SAMPLETIME: uistat.value = setting_step_delay; - plot_printf(uistat.text, sizeof uistat.text, "%3duS", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%3duS", ((int32_t)uistat.value)); break; case KM_DRIVE: uistat.value = setting_drive; - plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%3ddB", ((int32_t)uistat.value)); break; case KM_LOWOUTLEVEL: uistat.value = GetAttenuation(); // compensation for dB offset during low output mode - plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value)); break; case KM_DECAY: uistat.value = setting_decay; - plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%3d", ((int32_t)uistat.value)); break; case KM_NOISE: uistat.value = setting_noise; - plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value); + plot_printf(uistat.text, sizeof uistat.text, "%3d", ((int32_t)uistat.value)); break; case KM_10MHZ: uistat.value = setting_10mhz; From 20d9c2bbd6687fd7a236b76e0a9f580fb72366de Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 21 Apr 2020 10:34:46 +0200 Subject: [PATCH 089/193] Harmonic mode implemented --- .cproject | 17 ++++++-- main.c | 56 +++++++++++++++++++++---- nanovna.h | 2 +- sa_core.c | 120 +++++++++++++++++++++++++++++++----------------------- si4432.c | 35 ++++++++-------- ui_sa.c | 26 ++++++++++++ 6 files changed, 178 insertions(+), 78 deletions(-) diff --git a/.cproject b/.cproject index ec54bde..4714753 100644 --- a/.cproject +++ b/.cproject @@ -21,12 +21,21 @@