Merge branch 'tinySA-v0.2'

pull/4/head
erikkaashoek 6 years ago
commit 8852ba1384

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="0.632494471">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.632494471" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" description="" id="0.632494471" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.632494471." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.634936630" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.634936630.838183685" name=""/>
<builder autoBuildTarget="all" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.1821817659" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1098741703" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.827577975" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1071007085" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1654493752" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.58808415" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1096008220" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.846521722" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="tinySA.null.1625903942" name="tinySA"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="0.632494471">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="0.1682776706">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

4
.gitignore vendored

@ -10,3 +10,7 @@ python
TAGS
.emacs-dirvars
*png
*.bak
version.txt
dorelease.bat
ChibiOS

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>nanoVNA-Erik</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
</natures>
</projectDescription>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.cross.base.1097268449" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="834375144321394" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>

File diff suppressed because it is too large Load Diff

@ -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 = -Og -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).
@ -54,7 +55,7 @@ endif
##############################################################################
ifeq ($(VERSION),)
VERSION="$(shell git describe --tags)"
VERSION="tinySA_$(shell git describe --tags)"
endif
##############################################################################
@ -64,7 +65,7 @@ endif
# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
USE_PROCESS_STACKSIZE = 0x200
USE_PROCESS_STACKSIZE = 0x240
endif
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
@ -82,7 +83,7 @@ endif
#
# Define project name here
PROJECT = ch
PROJECT = tinySA
# Imported source files and paths
#CHIBIOS = ../ChibiOS-RT
@ -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 Font7x13b.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
@ -225,6 +226,7 @@ flash: build/ch.bin
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
dfu:
c:/work/dfu/HEX2DFU build/ch.hex build/ch.dfu
-@printf "reset dfu\r" >/dev/cu.usbmodem401

@ -21,8 +21,8 @@
* Board identifier.
*/
#define BOARD_NANOVNA_STM32_F072
#define BOARD_NAME "NanoVNA"
#define BOARD_NAME "tinySA v0.2"
#define BOARD_VERSION 0
/*
* Board frequencies.
*/
@ -47,14 +47,16 @@
/* on-board */
#define GPIOA_BUTTON 0
//#define GPIO_PE_SEL 0
#define GPIOA_LEVER1 1
#define GPIOA_LEVER2 2
#define GPIOA_PUSH 3
#define GPIOA_DAC2 5
//#define GPIO_RX_SEL 4
//#define GPIO_LO_SEL 5
#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
@ -71,14 +73,19 @@
#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_I2S2_WCLK 12
#define GPIOB_I2S2_BCLK 13
#define GPIOB_I2S2_MOSI 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
#define GPIOB_LED 11
#define GPIOF_OSC_IN 0
#define GPIOF_OSC_OUT 1
@ -115,19 +122,19 @@
* PA13 - SWDIO (alternate 0).
* PA14 - SWCLK (alternate 0).
*/
#define VAL_GPIOA_MODER (PIN_MODE_INPUT(0U) | \
#define VAL_GPIOA_MODER (PIN_MODE_INPUT(0U) | \
PIN_MODE_INPUT(1U) | \
PIN_MODE_INPUT(2U) | \
PIN_MODE_INPUT(3U) | \
PIN_MODE_INPUT(4U) | \
PIN_MODE_ANALOG(GPIOA_DAC2) | \
PIN_MODE_INPUT(4U) | \
PIN_MODE_INPUT(5U) | \
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))
@ -151,40 +158,40 @@
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(0) | \
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(0) | \
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) | \
@ -234,14 +241,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_ALTERNATE(GPIOB_I2S2_WCLK) | \
PIN_MODE_ALTERNATE(GPIOB_I2S2_BCLK) | \
PIN_MODE_ALTERNATE(14) | \
PIN_MODE_ALTERNATE(GPIOB_I2S2_MOSI))
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) | \
@ -250,14 +257,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_I2S2_WCLK) | \
PIN_OTYPE_PUSHPULL(GPIOB_I2S2_BCLK) | \
PIN_OTYPE_PUSHPULL(14) | \
PIN_OTYPE_PUSHPULL(GPIOB_I2S2_MOSI))
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) | \
@ -266,14 +273,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_I2S2_WCLK) | \
PIN_OSPEED_100M(GPIOB_I2S2_BCLK) | \
PIN_OSPEED_100M(12) | \
PIN_OSPEED_100M(13) | \
PIN_OSPEED_100M(14) | \
PIN_OSPEED_100M(GPIOB_I2S2_MOSI))
PIN_OSPEED_100M(15))
#define VAL_GPIOB_PUPDR (PIN_PUPDR_PULLUP(0) | \
PIN_PUPDR_PULLUP(1) | \
PIN_PUPDR_PULLUP(2) | \
@ -282,14 +289,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_I2S2_WCLK) | \
PIN_PUPDR_PULLUP(GPIOB_I2S2_BCLK) | \
PIN_PUPDR_PULLUP(12) | \
PIN_PUPDR_PULLUP(13) | \
PIN_PUPDR_PULLUP(14) | \
PIN_PUPDR_PULLUP(GPIOB_I2S2_MOSI))
PIN_PUPDR_PULLUP(14))
#define VAL_GPIOB_ODR (PIN_ODR_HIGH(0) | \
PIN_ODR_HIGH(1) | \
PIN_ODR_HIGH(2) | \
@ -298,14 +305,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_I2S2_WCLK) | \
PIN_ODR_HIGH(GPIOB_I2S2_BCLK) | \
PIN_ODR_HIGH(12) | \
PIN_ODR_HIGH(13) | \
PIN_ODR_HIGH(14) | \
PIN_ODR_HIGH(GPIOB_I2S2_MOSI))
PIN_ODR_HIGH(15))
#define VAL_GPIOB_AFRL (PIN_AFIO_AF(0, 0) | \
PIN_AFIO_AF(1, 0) | \
PIN_AFIO_AF(2, 0) | \
@ -314,20 +321,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_I2S2_WCLK, 0) | \
PIN_AFIO_AF(GPIOB_I2S2_BCLK, 0) | \
PIN_AFIO_AF(12, 0) | \
PIN_AFIO_AF(13, 0) | \
PIN_AFIO_AF(14, 0) | \
PIN_AFIO_AF(GPIOB_I2S2_MOSI, 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) | \
@ -341,9 +349,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) | \
@ -357,7 +365,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) | \
@ -373,7 +381,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) | \
@ -389,8 +397,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) | \
@ -405,7 +413,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) | \
@ -421,7 +429,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))
@ -743,6 +751,7 @@
PIN_AFIO_AF(14, 0) | \
PIN_AFIO_AF(15, 0))
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {

@ -19,14 +19,14 @@
*/
MEMORY
{
flash0 : org = 0x08000000, len = 96k
flash0 : org = 0x08000000, len = 108k
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 = 0x0801B000, len = 20k
ram0 : org = 0x20000000, len = 16k
ram1 : org = 0x00000000, len = 0
ram2 : org = 0x00000000, len = 0

@ -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.

@ -52,7 +52,7 @@ static const uint32_t pow10[FLOAT_PRECISION+1] = {
static char bigPrefix[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0};
// Prefixes for values less then 1.0
// 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18, 1e-21, 1e-24
static char smallPrefix[] = {'m', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0};
static char smallPrefix[] = {'m', 'u', 'n', 'p', 'f', 'a', 'z', 'y', 0};
#pragma pack(pop)
@ -195,12 +195,15 @@ static char *ftoaS(char *p, float num, uint32_t precision) {
;
prefix = num > 1e-3 ? ptr[-1] : 0;
}
// Auto set prescision
if (prefix)
precision--;
// Auto set precision
uint32_t l = num;
if (l < 10)
precision+=2;
else if (l < 100)
precision+=1;
if (l > 100)
precision-=2;
else if (l > 10)
precision-=1;
p=ftoa(p, num, precision);
if (prefix)
*p++ = prefix;

131
dsp.c

@ -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 <arm_math.h>
#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 }
};
float acc_samp_s;
float acc_samp_c;
float acc_ref_s;
float 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;
}

@ -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 */

90
fft.h

@ -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 <math.h>
#include <stdint.h>
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);
}

@ -120,48 +120,62 @@ config_recall(void)
return 0;
}
const uint32_t saveareas[SAVEAREA_MAX] = {
const uint32_t saveareas[SAVEAREA_MAX] =
{
SAVE_PROP_CONFIG_0_ADDR,
SAVE_PROP_CONFIG_1_ADDR,
SAVE_PROP_CONFIG_2_ADDR,
SAVE_PROP_CONFIG_3_ADDR,
SAVE_PROP_CONFIG_4_ADDR };
SAVE_PROP_CONFIG_4_ADDR,
SAVE_PROP_CONFIG_5_ADDR,
SAVE_PROP_CONFIG_6_ADDR,
SAVE_PROP_CONFIG_7_ADDR,
SAVE_PROP_CONFIG_8_ADDR,
};
int16_t lastsaveid = 0;
int
caldata_save(int id)
{
uint16_t *src = (uint16_t*)&current_props;
uint16_t *src = (uint16_t*)&setting;
uint16_t *dst;
int count = sizeof(properties_t) / sizeof(uint16_t);
int count = sizeof(setting_t) / sizeof(uint16_t);
if (id < 0 || id >= SAVEAREA_MAX)
return -1;
dst = (uint16_t*)saveareas[id];
current_props.magic = CONFIG_MAGIC;
current_props.checksum = checksum(
&current_props, sizeof current_props - sizeof current_props.checksum);
setting.magic = CONFIG_MAGIC;
setting.checksum = checksum(
&setting, sizeof setting - sizeof setting.checksum);
flash_unlock();
/* erase flash pages */
void *p = dst;
void *tail = p + sizeof(properties_t);
void *tail = p + sizeof(setting_t);
while (p < tail) {
flash_erase_page((uint32_t)p);
p += FLASH_PAGESIZE;
}
/* write to flahs */
/* write to flash */
while (count-- > 0) {
flash_program_half_word((uint32_t)dst, *src++);
dst++;
}
// Flash stored trace
count = sizeof(stored_t) / sizeof(uint16_t);
src = (uint16_t*)&stored_t[0];
while (count-- > 0) {
flash_program_half_word((uint32_t)dst, *src++);
dst++;
}
/* after saving data, make active configuration points to flash */
active_props = (properties_t*)saveareas[id];
// active_props = (setting_t*)saveareas[id];
lastsaveid = id;
return 0;
@ -170,39 +184,42 @@ caldata_save(int id)
int
caldata_recall(int id)
{
properties_t *src;
void *dst = &current_props;
setting_t *src;
void *dst = &setting;
if (id < 0 || id >= SAVEAREA_MAX)
goto load_default;
return -1;
// point to saved area on the flash memory
src = (properties_t*)saveareas[id];
src = (setting_t*)saveareas[id];
if (src->magic != CONFIG_MAGIC)
goto load_default;
if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum)
goto load_default;
return -1;
if (checksum(src, sizeof setting - sizeof src->checksum) != src->checksum)
return -1;
/* active configuration points to save data on flash memory */
active_props = src;
// active_props = src;
lastsaveid = id;
/* duplicated saved data onto sram to be able to modify marker/trace */
memcpy(dst, src, sizeof(properties_t));
memcpy(dst, src, sizeof(setting_t));
// Restore stored trace
memcpy(stored_t, &src[1], sizeof(stored_t));
update_frequencies();
set_scale(setting.scale);
set_reflevel(setting.reflevel);
return 0;
load_default:
load_default_properties();
return -1;
}
const properties_t *
#if 0
const setting_t *
caldata_ref(int id)
{
const properties_t *src;
const setting_t *src;
if (id < 0 || id >= SAVEAREA_MAX)
return NULL;
src = (const properties_t*)saveareas[id];
src = (const setting_t*)saveareas[id];
if (src->magic != CONFIG_MAGIC)
return NULL;
@ -210,6 +227,7 @@ caldata_ref(int id)
return NULL;
return src;
}
#endif
const uint32_t save_config_prop_area_size = SAVE_CONFIG_AREA_SIZE;

@ -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
/**
@ -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
/**

@ -27,8 +27,8 @@ uint16_t foreground_color = 0;
uint16_t background_color = 0;
// Display width and height definition
#define ILI9341_WIDTH 320
#define ILI9341_HEIGHT 240
#define ILI9341_WIDTH LCD_WIDTH
#define ILI9341_HEIGHT LCD_HEIGHT
// Display commands list
#define ILI9341_NOP 0x00
@ -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
@ -309,9 +311,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
@ -383,41 +385,8 @@ void ili9341_bulk(int x, int y, int w, int h)
SPI_WRITE_16BIT(*buf++);
}
}
static uint8_t ssp_sendrecvdata(void)
{
// Start RX clock (by sending data)
SPI_WRITE_8BIT(0);
while (SPI_RX_IS_EMPTY && SPI_IS_BUSY)
;
return SPI_READ_DATA;
}
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;
}
#else
//
// Use DMA for send data
//
@ -469,7 +438,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 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)
@ -485,6 +454,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 |
@ -499,7 +469,18 @@ 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 0
int count = 0;
while ((dmarx)->channel->CNDTR > 0U) {
chThdSleepMicroseconds(100);
if (count++ > 10)
break;
}
dmaStreamDisable(dmarx);
#else
dmaWaitCompletion(dmarx);
#endif
chSysUnlock();
CS_HIGH;
// Parce recived data
@ -515,13 +496,49 @@ 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
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;
@ -531,7 +548,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,
@ -553,7 +570,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;
@ -567,6 +584,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));
@ -583,6 +606,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)]; // All chars start at row 2
blit16BitWidthBitmap(x, y, 7, 13, char_buf); // Only 'Q' has 12 rows, 'g' requires 13 rows
x += 7;
}
}
void ili9341_drawstringV(const char *str, int x, int y)
{
ili9341_set_rotation(DISPLAY_ROTATION_270);
@ -693,15 +726,15 @@ void ili9341_test(int mode)
switch (mode) {
default:
#if 1
ili9341_fill(0, 0, 320, 240, 0);
for (y = 0; y < 240; y++) {
ili9341_fill(0, y, 320, 1, RGB(240-y, y, (y + 120) % 256));
ili9341_fill(0, 0, LCD_WIDTH, LCD_HEIGHT, 0);
for (y = 0; y < LCD_HEIGHT; y++) {
ili9341_fill(0, y, LCD_WIDTH, 1, RGB(LCD_HEIGHT-y, y, (y + 120) % 256));
}
break;
case 1:
ili9341_fill(0, 0, 320, 240, 0);
for (y = 0; y < 240; y++) {
for (x = 0; x < 320; x++) {
ili9341_fill(0, 0, LCD_WIDTH, LCD_HEIGHT, 0);
for (y = 0; y < LCD_HEIGHT; y++) {
for (x = 0; x < LCD_WIDTH; x++) {
ili9341_pixel(x, y, (y<<8)|x);
}
}

638
main.c

File diff suppressed because it is too large Load Diff

@ -104,7 +104,7 @@
#define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 TRUE
#define STM32_GPT_USE_TIM14 FALSE
#define STM32_GPT_USE_TIM14 TRUE
#define STM32_GPT_TIM1_IRQ_PRIORITY 2
#define STM32_GPT_TIM2_IRQ_PRIORITY 2
#define STM32_GPT_TIM3_IRQ_PRIORITY 2
@ -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 | \

@ -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
@ -22,10 +21,44 @@
// Need enable HAL_USE_SPI in halconf.h
#define __USE_DISPLAY_DMA__
#define __SA__
//#define __SIMULATION__
//#define __PIPELINE__
#define __SCROLL__
#define __ICONS__
#define __MEASURE__
#define __SELFTEST__
#define __CALIBRATE__
#define __FAST_SWEEP__ // Pre-fill SI4432 RSSI buffer to get fastest sweep in zero span mode
//#define __ULTRA__ // Add harmonics mode on low input.
//#define __ULTRA_SA__ // Adds ADF4351 control for extra high 1st IF stage
#define __SPUR__ // Does spur reduction by shifting IF
/*
* main.c
*/
#ifdef __SA__
#define POINTS_COUNT 290
#define MARKER_COUNT 4
#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]
#define CORRECTION_POINTS 10 // Frequency dependent level correction table entries
typedef float measurement_t[TRACES_MAX][POINTS_COUNT];
extern measurement_t measured;
#endif
#ifdef __VNA__
// Minimum frequency set
#define START_MIN 50000
// Maximum frequency set
@ -81,25 +114,120 @@ 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
};
void update_frequencies(void);
void set_sweep_frequency(int type, uint32_t frequency);
uint32_t get_sweep_frequency(int type);
void my_microsecond_delay(int t);
double my_atof(const char *p);
int shell_printf(const char *fmt, ...);
void toggle_sweep(void);
void toggle_mute(void);
void load_default_properties(void);
#define SWEEP_ENABLE 0x01
#define SWEEP_ONCE 0x02
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_ULTRA
};
enum {
MO_NONE, MO_AM_1kHz, MO_AM_10Hz, MO_NFM, MO_WFM, MO_EXTERNAL,
};
#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)
#define SWEEP_ENABLE 0x01
#define SWEEP_ONCE 0x02
#define SWEEP_CALIBRATE 0x04
#define SWEEP_SELFTEST 0x08
#define SWEEP_REMOTE 0x10
extern int8_t sweep_mode;
extern bool completed;
extern const char *info_about[];
// ------------------------------- sa_core.c ----------------------------------
void reset_settings(int);
//void ui_process_touch(void);
void SetPowerGrid(int);
void SetRefLevel(float);
void set_refer_output(int);
void toggle_below_IF(void);
int get_refer_output(void);
void set_attenuation(int);
int get_attenuation(void);
void set_harmonic(int);
//extern int setting.harmonic;
int search_is_greater(void);
void set_auto_attenuation(void);
void set_auto_reflevel(int);
int is_paused(void);
void set_actual_power(float);
void SetGenerate(int);
void set_RBW(int);
void set_drive(int d);
void set_IF(int f);
void set_step_delay(int t);
void set_repeat(int);
void set_level_sweep(float);
void set_level(float);
void set_sweep_time(float);
//extern int setting.repeat;
//extern int setting.rbw;
#ifdef __SPUR__
//extern int setting.spur;
void SetSpur(int v);
#endif
void set_average(int);
int GetAverage(void);
//extern int setting.average;
void set_storage(void);
void set_clear_storage(void);
void set_subtract_storage(void);
void toggle_waterfall(void);
void set_mode(int);
int GetMode(void);
void set_reflevel(float);
void user_set_reflevel(float);
#define REFLEVEL_MAX 9999.0
#define REFLEVEL_MIN 1.0e-12
void set_scale(float);
void user_set_scale(float);
void AllDirty(void);
void MenuDirty(void);
void toggle_LNA(void);
void toggle_AGC(void);
void redrawHisto(void);
void self_test(int);
void set_decay(int);
void set_noise(int);
void toggle_tracking_output(void);
extern int32_t frequencyExtra;
void set_10mhz(int);
void set_modulation(int);
//extern int setting.modulation;
void set_measurement(int);
// extern int settingSpeed;
//extern int setting.step_delay;
void sweep_remote(void);
#ifdef __VNA__
/*
* dsp.c
*/
@ -121,7 +249,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 +260,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 30
#define OFFSETY 0
#define BUTTON_WIDTH 60
#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 10
//#define NGRIDY 9
#define FREQUENCIES_XPOS1 OFFSETX
#define FREQUENCIES_XPOS2 200
@ -155,8 +296,8 @@ extern void tlv320aic3204_select(int channel);
#define GRIDY (HEIGHT / NGRIDY)
//
#define CELLOFFSETX 5
#define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH + 1 + 4)
#define CELLOFFSETX 0
#define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH)
#define AREA_HEIGHT_NORMAL ( HEIGHT + 1)
// Smith/polar chart
@ -169,6 +310,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
@ -190,8 +332,6 @@ extern const uint16_t numfont16x22[];
#define S_OHM "\036"
// trace
#define TRACES_MAX 4
#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
@ -209,6 +349,15 @@ enum trace_type {
// Electrical Delay
// Phase
#define MAX_UNIT_TYPE 4
enum unit_type {
U_DBM=0, U_DBMV, U_DBUV, U_VOLT, U_WATT, U_DBC // dBc only for displaying delta marker info
};
#define UNIT_IS_LINEAR(T) ( T >= U_VOLT ? true : false)
#define UNIT_IS_LOG(T) ( T >= U_VOLT ? false : true)
float value(float);
typedef struct trace {
uint8_t enabled;
uint8_t type;
@ -231,13 +380,21 @@ 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 low_level_offset;
int16_t high_level_offset;
uint32_t correction_frequency[CORRECTION_POINTS];
float correction_value[CORRECTION_POINTS];
// uint8_t _reserved[22];
uint32_t checksum;
} config_t;
extern config_t config;
//#define settingLevelOffset config.level_offset
int get_level_offset(void);
void set_trace_type(int t, int type);
void set_trace_channel(int t, int channel);
@ -246,21 +403,31 @@ 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);
float get_electrical_delay(void);
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, M_DELETE=16 // Tracking must be last.
};
#define MARKERS_MAX 4
enum {
M_DISABLED = false, M_ENABLED = true
};
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 +439,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);
@ -287,6 +454,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)
@ -302,25 +473,36 @@ 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)
#define SPI_BUFFER_SIZE 2048
#define SPI_BUFFER_SIZE 1024
#define LCD_WIDTH 320
#define LCD_HEIGHT 240
#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)
#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;
@ -331,12 +513,18 @@ 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);
void ili9341_drawstring(const char *str, int x, int y);
void ili9341_drawstring_7x13(const char *str, int x, int y);
void ili9341_drawstringV(const char *str, int x, int y);
int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size);
void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size);
@ -349,73 +537,192 @@ void show_logo(void);
/*
* flash.c
*/
#define SAVEAREA_MAX 5
// Begin addr 0x08018000
#define SAVE_CONFIG_AREA_SIZE 0x00008000
typedef struct setting
{
uint32_t magic;
// uint32_t _frequency0;
// uint32_t _frequency1;
int mode;
uint16_t _sweep_points;
int attenuate;
int auto_attenuation;
int step_atten;
int rbw;
int below_IF;
int average;
int show_stored;
int subtract_stored;
int drive; // 0-7 , 7=+20dBm, 3dB steps
int agc;
int lna;
int auto_reflevel;
float reflevel;
float scale;
int tracking;
int modulation;
int step_delay;
int frequency_step;
int test;
int harmonic;
int decay;
int noise;
float vbw;
int tracking_output;
int repeat;
uint32_t frequency0;
uint32_t frequency1;
uint32_t frequency_IF;
int freq_mode;
int measurement;
int refer;
int spur;
trace_t _trace[TRACES_MAX];
marker_t _markers[MARKERS_MAX];
int8_t _active_marker;
int8_t unit;
float offset;
float trigger_level;
int trigger;
int linearity_step;
float level;
float level_sweep;
float sweep_time;
float actual_sweep_time;
int test_argument;
int auto_IF;
unsigned int unit_scale_index;
float unit_scale;
int mute;
uint32_t checksum;
}setting_t;
extern setting_t setting;
extern int setting_frequency_10mhz;
void reset_settings(int m);
#define S_IS_AUTO(x) ((x)&2)
#define S_STATE(X) ((X)&1)
enum { S_OFF=0, S_ON=1, S_AUTO_OFF=2, S_AUTO_ON=3 };
#ifdef __FAST_SWEEP__
#define MINIMUM_SWEEP_TIME 3 // Minimum sweep time on zero span in miliseconds
#else
#define MINIMUM_SWEEP_TIME 15 // Minimum sweep time on zero span in miliseconds
#endif
#define REPEAT_TIME 134.0 // Time per extra repeat in uS
#define MEASURE_TIME 175.0 // Time per vbwstep without stepdelay in uS
extern uint32_t frequencies[POINTS_COUNT];
extern const float unit_scale_value[];
extern const char * const unit_scale_text[];
#if 1
#define SAVEAREA_MAX 9
// config save area
#define SAVE_CONFIG_ADDR 0x08018000
#define SAVE_CONFIG_ADDR 0x0801B000
// setting_t save area
#define SAVE_PROP_CONFIG_0_ADDR 0x0801B800
#define SAVE_PROP_CONFIG_1_ADDR 0x0801C000
#define SAVE_PROP_CONFIG_2_ADDR 0x0801C800
#define SAVE_PROP_CONFIG_3_ADDR 0x0801D000
#define SAVE_PROP_CONFIG_4_ADDR 0x0801D800
#define SAVE_PROP_CONFIG_5_ADDR 0x0801E000
#define SAVE_PROP_CONFIG_6_ADDR 0x0801E800
#define SAVE_PROP_CONFIG_7_ADDR 0x0801F000
#define SAVE_PROP_CONFIG_8_ADDR 0x0801F800
#define SAVE_CONFIG_AREA_SIZE (0x0801F800 - SAVE_CONFIG_ADDR) // Should include all save slots
#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 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_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
#if 0
typedef struct properties {
uint32_t magic;
uint32_t _frequency0;
uint32_t _frequency1;
preset_t setting;
// uint32_t _frequency0;
// uint32_t _frequency1;
uint16_t _sweep_points;
#ifdef __VNA__
uint16_t _cal_status;
uint32_t _frequencies[POINTS_COUNT];
#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__
float _velocity_factor; // %
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */
uint8_t _marker_smith_format;
uint8_t _bandwidth;
uint8_t _reserved[50];
#endif
uint8_t _reserved[2];
uint32_t checksum;
} properties_t;
#endif
//sizeof(properties_t) == 0x1200
#define CONFIG_MAGIC 0x434f4e45 /* 'CONF' */
extern int16_t lastsaveid;
extern properties_t *active_props;
extern properties_t current_props;
//extern properties_t *active_props;
//extern properties_t current_props;
#define frequency0 current_props._frequency0
#define frequency1 current_props._frequency1
#define sweep_points current_props._sweep_points
//#define frequency0 current_props._frequency0
//#define frequency1 current_props._frequency1
#define sweep_points setting._sweep_points
#ifdef __VNA__
#define cal_status current_props._cal_status
#define frequencies current_props._frequencies
#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
#define trace current_props._trace
#define markers current_props._markers
#define active_marker current_props._active_marker
#endif
#define trace setting._trace
#define markers setting._markers
#define active_marker setting._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
#define bandwidth current_props._bandwidth
#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)
int caldata_save(int id);
#define FREQ_IS_STARTSTOP() (!(setting.freq_mode&FREQ_MODE_CENTER_SPAN))
#define FREQ_IS_CENTERSPAN() (setting.freq_mode&FREQ_MODE_CENTER_SPAN)
#define FREQ_IS_CW() (setting.frequency0 == setting.frequency1)
int caldata_recall(int id);
const properties_t *caldata_ref(int id);
int caldata_save(int id);
//const properties_t *caldata_ref(int id);
int config_save(void);
int config_recall(void);
@ -426,11 +733,17 @@ void clear_all_config_prop_data(void);
*/
extern void ui_init(void);
extern void ui_process(void);
int current_menu_is_form(void);
void menu_mode_cb(int, uint8_t);
void ui_mode_normal(void);
void ui_mode_menu(void);
// Irq operation process set
#define OP_NONE 0x00
#define OP_LEVER 0x01
#define OP_TOUCH 0x02
#define OP_CONSOLE 0x04
//#define OP_FREQCHANGE 0x04
extern volatile uint8_t operation_requested;
@ -448,11 +761,13 @@ 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
float value; // for editing at numeric input area
// 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;
extern uistat_t uistat;
@ -486,11 +801,63 @@ 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 setting_attenuate;
//extern int settingPowerCal;
//extern int setting_step_delay;
//extern int actualStepDelay;
//extern int setting_mode;
void update_rbw(void);
int get_actual_RBW(void);
#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);
void SI4432_Drive(int);
float SI4432_RSSI(uint32_t i, int s);
#ifdef __FAST_SWEEP__
void SI4432_Fill(int s, int start);
#endif
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();
#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 RESTART_PROFILE 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, 180);}
// Macros for convert define value to string
#define STR1(x) #x
#define define_to_STR(x) STR1(x)
// sa_core.c
int get_waterfall(void);
void toggle_tracking(void);
void calibrate(void);
void reset_calibration(void);
void set_reflevel(float);
void set_offset(float);
void set_unit(int);
void set_RBW(int);
void set_switches(int);
void set_trigger_level(float);
void set_trigger(int);
//extern int setting_measurement;
void self_test(int);
//extern int setting_test;
void wait_user(void);
void calibrate(void);
float to_dBm(float);
float calc_min_sweep_time(void);
extern float actual_rbw;
enum {
M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_STOP_BAND, M_PASS_BAND, M_LINEARITY
};
enum {
T_AUTO, T_NORMAL, T_SINGLE, T_DONE
};
/*EOF*/

@ -507,6 +507,7 @@ const uint16_t numfont16x22[] = {
0b0000000000000000,
0b0000000000000000,
0b0000000000000000, // m
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
@ -514,6 +515,51 @@ const uint16_t numfont16x22[] = {
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b1111001100110000,
0b1111011111111100,
0b1111111111111110,
0b1111111111111110,
0b1111111111011111,
0b1111101111001111,
0b1111001111001111,
0b1111001111001111,
0b1111001111001111,
0b1111001111001111,
0b1111001111001111,
0b1111001111001111,
0b1111001111001111,
0b1111001111001111,
0b0000000000000000, // u
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000011111,
0b1111100000111111,
0b1111110001111111,
0b0111111111111111,
0b0011111111101111,
0b0001111111001111,
0b0000000000000000, // n
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b1111000111110000,
0b1111011111111100,
@ -530,7 +576,7 @@ const uint16_t numfont16x22[] = {
0b1111000000001111,
0b1111000000001111,
0b0000000000000000,
0b0000000000000000, // p
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,

707
plot.c

File diff suppressed because it is too large Load Diff

@ -0,0 +1,447 @@
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_mode)
{
static const char cmd_low_high[] = "low|high";
static const char cmd_in_out[] = "input|output";
if (argc != 2) {
usage:
shell_printf("usage: mode %s %s\r\n", cmd_low_high,cmd_in_out);
return;
}
int lh = get_str_index(argv[0], cmd_low_high);
int io = get_str_index(argv[1], cmd_in_out);
if (lh<0 || io<0)
goto usage;
switch(lh+io*2)
{
case 0:
set_mode(M_LOW);
break;
case 1:
set_mode(M_HIGH);
break;
case 2:
set_mode(M_GENLOW);
break;
case 3:
set_mode(M_GENHIGH);
break;
}
}
VNA_SHELL_FUNCTION(cmd_modulation )
{
static const char cmd_mod[] = "off|AM_1kHz|AM_10Hz|NFM|WFM|extern";
if (argc != 1) {
usage:
shell_printf("usage: modulation %s\r\n", cmd_mod);
return;
}
static const int cmd_mod_val[] = { MO_NONE, MO_AM_1kHz, MO_AM_10Hz, MO_NFM, MO_WFM, MO_EXTERNAL};
int m = get_str_index(argv[1], cmd_mod);
if (m<0)
goto usage;
set_modulation(cmd_mod_val[m]);
}
VNA_SHELL_FUNCTION(cmd_spur)
{
if (argc != 1) {
usage:
shell_printf("usage: spur on|off\r\n");
return;
}
if (strcmp(argv[0],"on") == 0) {
setting.spur = 1;
} else if (strcmp(argv[0],"off") == 0) {
setting.spur = 0;
} else
goto usage;
}
VNA_SHELL_FUNCTION(cmd_load)
{
if (argc != 1) {
usage:
shell_printf("usage: load 0..4\r\n");
return;
}
int a = my_atoi(argv[0]);
if (0 <= a && a <= 4) {
caldata_recall(a);
} else
goto usage;
}
VNA_SHELL_FUNCTION(cmd_attenuate)
{
if (argc != 1) {
usage:
shell_printf("usage: attenuate 0..31|auto\r\n");
return;
}
if (strcmp(argv[0],"auto") == 0) {
set_auto_attenuation();
} else {
int a = my_atoi(argv[0]);
if (a < 0 || a>31)
goto usage;
set_attenuation(a);
}
}
VNA_SHELL_FUNCTION(cmd_level)
{
if (argc != 1) {
shell_printf("usage: level -76..-6\r\n");
return;
}
float f = my_atof(argv[0]);
set_level(f);
}
VNA_SHELL_FUNCTION(cmd_levelsweep)
{
if (argc != 1) {
shell_printf("usage: levelsweep -76..+76\r\n");
return;
}
float f = my_atof(argv[0]);
set_level_sweep(f);
}
VNA_SHELL_FUNCTION(cmd_leveloffset)
{
if (argc == 0) {
shell_printf("leveloffset low %.1f\r\n", (float) config.low_level_offset);
shell_printf("leveloffset high %.1f\r\n", (float)config.high_level_offset);
return;
} else if (argc == 2) {
float v = my_atof(argv[1]);
if (strcmp(argv[0],"low") == 0)
config.low_level_offset = v;
else if (strcmp(argv[0],"high") == 0)
config.low_level_offset = v;
else
goto usage;
} else {
usage:
shell_printf("leveloffset [low|high] [<offset>]\r\n");
}
}
VNA_SHELL_FUNCTION(cmd_rbw)
{
if (argc != 1) {
usage:
shell_printf("usage: rbw 2..600|auto\r\n");
return;
}
if (strcmp(argv[0],"auto") == 0 || strcmp(argv[0],"0") == 0) {
set_RBW(0);
} else {
int a = my_atoi(argv[0]);
if (a < 2 || a>600)
goto usage;
set_RBW(a);
}
}
VNA_SHELL_FUNCTION(cmd_if)
{
if (argc != 1) {
usage:
shell_printf("usage: if {433M..435M}\r\n");
return;
} else {
int a = my_atoi(argv[0]);
if (a!= 0 &&( a < 433000000 || a>435000000))
goto usage;
setting.auto_IF = false;
set_IF(a);
}
}
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_y)
{
int rvalue;
int lvalue = 0;
if (argc != 1 && argc != 2) {
shell_printf("usage: y {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_selftest)
{
if (argc < 1 || argc > 2) {
shell_printf("usage: selftest (1-3) [arg]\r\n");
return;
}
setting.test = my_atoi(argv[0]);
if (argc == 1)
setting.test_argument = 0;
else
setting.test_argument = my_atoi(argv[1]);
sweep_mode = SWEEP_SELFTEST;
}
#ifdef __ULTRA_SA__
VNA_SHELL_FUNCTION(cmd_x)
{
uint32_t reg;
if (argc != 1) {
shell_printf("usage: x value(0-FFFFFFFF)\r\n");
return;
}
reg = xtoi(argv[0]);
if ((reg & 7) == 5) {
if (reg & (1<<22))
VFO = 1;
else
VFO = 0;
reg &= ~0xc00000; // Force led to show lock
reg |= 0x400000;
}
ADF4351_WriteRegister32(VFO, reg);
shell_printf("x=%x\r\n", reg);
}
#endif
VNA_SHELL_FUNCTION(cmd_i)
{
int rvalue;
return; // Don't use!!!!
SI4432_Init();
shell_printf("SI4432 init done\r\n");
if (argc == 1) {
rvalue = xtoi(argv[0]);
set_switches(rvalue);
set_mode(rvalue);
shell_printf("SI4432 mode %d set\r\n", rvalue);
}
}
VNA_SHELL_FUNCTION(cmd_o)
{
(void) argc;
uint32_t value = my_atoi(argv[0]);
if (VFO == 0)
setting.frequency_IF = value;
set_freq(VFO, value);
}
VNA_SHELL_FUNCTION(cmd_d)
{
(void) argc;
(void) argv;
// int32_t a = my_atoi(argv[0]);
// setting.drive = a;
}
VNA_SHELL_FUNCTION(cmd_a)
{
(void)argc;
if (argc != 1) {
shell_printf("a=%d\r\n", frequencyStart);
return;
}
int32_t value = my_atoi(argv[0]);
frequencyStart = value;
}
VNA_SHELL_FUNCTION(cmd_b)
{
(void)argc;
if (argc != 1) {
shell_printf("b=%d\r\n", frequencyStop);
return;
}
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;
if (argc != 1) {
shell_printf("e=%d\r\n", setting.tracking);
return;
}
setting.tracking = my_atoi(argv[0]);
if (setting.tracking == -1)
setting.tracking = false;
else
setting.tracking = true;
if (argc >1)
frequencyExtra = my_atoi(argv[1]);
}
VNA_SHELL_FUNCTION(cmd_s)
{
(void)argc;
if (argc != 1) {
shell_printf("s=%d\r\n", points);
return;
}
points = my_atoi(argv[0]);
}
void sweep_remote(void)
{
int old_step = setting.frequency_step;
uint32_t f_step = (frequencyStop-frequencyStart)/ points;
setting.frequency_step = f_step;
streamPut(shell_stream, '{');
dirty = true;
for (int i = 0; i<points; i++) {
if (operation_requested)
break;
float val = perform(false, i, frequencyStart - setting.frequency_IF + f_step * i, false);
streamPut(shell_stream, 'x');
int v = val*2 + 256;
streamPut(shell_stream, (uint8_t)(v & 0xFF));
streamPut(shell_stream, (uint8_t)((v>>8) & 0xFF));
// enable led
}
streamPut(shell_stream, '}');
setting.frequency_step = old_step;
sweep_mode = 0;
}
VNA_SHELL_FUNCTION(cmd_m)
{
(void)argc;
(void)argv;
// set_mode(0);
// setting.tracking = false; //Default test setup
// setting.step_atten = false;
// set_attenuation(0);
// set_reflevel(-10);
// set_sweep_frequency(ST_START,frequencyStart - setting.frequency_IF );
// set_sweep_frequency(ST_STOP, frequencyStop - setting.frequency_IF);
// draw_cal_status();
pause_sweep();
// update_rbw();
chThdSleepMilliseconds(10);
sweep_mode = SWEEP_REMOTE;
// update_rbw();
}
VNA_SHELL_FUNCTION(cmd_p)
{
(void)argc;
return;
int p = my_atoi(argv[0]);
int a = my_atoi(argv[1]);
if (p==5)
set_attenuation(-a);
if (p==6)
set_mode(a);
if (p==1)
if (get_refer_output() != a)
set_refer_output(a);
}
VNA_SHELL_FUNCTION(cmd_w)
{
(void)argc;
int p = my_atoi(argv[0]);
return;
set_RBW(p);
}
VNA_SHELL_FUNCTION(cmd_correction)
{
(void)argc;
if (argc == 0) {
shell_printf("index frequency value\r\n");
for (int i=0; i<CORRECTION_POINTS; i++) {
shell_printf("%d %d %.1f\r\n", i, config.correction_frequency[i], config.correction_value[i]);
}
return;
}
if (argc == 1 && (strcmp(argv[0],"reset") == 0)) {
for (int i=0; i<CORRECTION_POINTS; i++) {
config.correction_value[i] = 0.0;
}
shell_printf("correction table reset\r\n");
return;
}
if (argc != 3) {
shell_printf("usage: correction 0-9 frequency(Hz) value(dB)\r\n");
return;
}
int i = my_atoi(argv[0]);
uint32_t f = my_atoui(argv[1]);
float v = my_atof(argv[2]);
config.correction_frequency[i] = f;
config.correction_value[i] = v;
shell_printf("updated %d to %d %.1f\r\n", i, config.correction_frequency[i], config.correction_value[i]);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,995 @@
/* 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 <math.h>
#include "si4432.h"
#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 RF_POWER_HIGH palSetPad(GPIOB, GPIO_RF_PWR)
#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_CLK_HIGH palSetPad(GPIOB, GPIO_SPI2_CLK)
#define SPI2_CLK_LOW palClearPad(GPIOB, GPIO_SPI2_CLK)
#define SPI2_SDI_HIGH palSetPad(GPIOB, GPIO_SPI2_SDI)
#define SPI2_SDI_LOW palClearPad(GPIOB, GPIO_SPI2_SDI)
#define SPI2_SDO ((palReadPort(GPIOB) & (1<<GPIO_SPI2_SDO))?1:0)
//#define MAXLOG 1024
//unsigned char SI4432_logging[MAXLOG];
//volatile int log_index = 0;
//#define SI4432_log(X) { if (log_index < MAXLOG) SI4432_logging[log_index++] = X; }
#define SI4432_log(X)
void 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;
SPI2_CLK_HIGH;
SPI2_CLK_LOW;
}
}
uint8_t shiftIn(void) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
SPI2_CLK_HIGH;
value |= SPI2_SDO << (7 - i);
SPI2_CLK_LOW;
}
return value;
}
const int SI_nSEL[3] = { GPIO_RX_SEL, GPIO_LO_SEL, 0}; // #3 is dummy!!!!!!
volatile int SI4432_Sel = 0; // currently selected SI4432
// volatile int SI4432_guard = 0;
#ifdef __SI4432_H__
#define SELECT_DELAY 10
void SI4432_Write_Byte(byte ADR, byte DATA )
{
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
SPI2_CLK_LOW;
palClearPad(GPIOC, SI_nSEL[SI4432_Sel]);
// chThdSleepMicroseconds(SELECT_DELAY);
ADR |= 0x80 ; // RW = 1
shiftOut( ADR );
shiftOut( DATA );
palSetPad(GPIOC, SI_nSEL[SI4432_Sel]);
// SI4432_guard = 0;
}
void SI4432_Write_3_Byte(byte ADR, byte DATA1, byte DATA2, byte DATA3 )
{
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
SPI2_CLK_LOW;
palClearPad(GPIOC, SI_nSEL[SI4432_Sel]);
// chThdSleepMicroseconds(SELECT_DELAY);
ADR |= 0x80 ; // RW = 1
shiftOut( ADR );
shiftOut( DATA1 );
shiftOut( DATA2 );
shiftOut( DATA3 );
palSetPad(GPIOC, SI_nSEL[SI4432_Sel]);
// SI4432_guard = 0;
}
byte SI4432_Read_Byte( byte ADR )
{
byte DATA ;
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
SPI2_CLK_LOW;
palClearPad(GPIOC, SI_nSEL[SI4432_Sel]);
shiftOut( ADR );
DATA = shiftIn();
palSetPad(GPIOC, SI_nSEL[SI4432_Sel]);
// SI4432_guard = 0;
return DATA ;
}
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);
// wait for chiprdy bit
while (count++ < 100 && ( SI4432_Read_Byte ( 0x04 ) & 0x02 ) == 0) {
chThdSleepMilliseconds(10);
}
}
void SI4432_Drive(int d)
{
SI4432_Write_Byte(0x6D, (byte) (0x18+(d & 7)));
}
void SI4432_Transmit(int d)
{
int count = 0;
SI4432_Write_Byte(0x6D, (byte) (0x18+(d & 7)));
if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 2)
return; // Already in transmit mode
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);
}
}
void SI4432_Receive(void)
{
int count = 0;
if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 1)
return; // Already in receive mode
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);
}
}
// 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 quadrupple is: ndec, fils, WISH*10, corr*10
5,1,26,-5,
5,2,28,-5,
5,3,31,0,
5,4,32,0,
5,5,37,0,
5,6,42,0,
5,7,45,5,
4,1,49,5,
4,2,54,-5,
4,3,59,-5,
4,4,61,-5,
4,5,72,0,
4,6,82,0,
4,7,88,-5,
3,1,95,0,
3,2,106,0,
3,3,115,0,
3,4,121,-5,
3,5,142,0,
3,6,162,0,
3,7,175,0,
2,1,189,0,
2,2,210,-5,
2,3,227,0,
2,4,240,-5,
2,5,282,0,
2,6,322,0,
2,7,347,0,
1,1,377,0,
1,2,417,-5,
1,3,452,0,
1,4,479,-5,
1,5,562,0,
1,6,641,0,
1,7,692,0,
0,1,752,-5,
0,2,832,-5,
0,3,900,0,
0,4,953,-5,
0,5,1121,0,
0,6,1279,0,
0,7,1379,0,
1,4,1428,15,
1,5,1678,20,
1,9,1811,-55,
0,15,1915,-105,
0,1,2251,15,
0,2,2488,20,
0,3,2693,20,
0,4,2849,15,
0,8,3355,-15,
0,9,3618,-55,
0,10,4202,-15,
0,11,4684,-15,
0,12,5188,-20,
0,13,5770,-15,
0,14,6207,-10,
};
static float SI4432_RSSI_correction = -120.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)/sizeof(RBW_choices[0]); i+=4)
if (WISH <= RBW_choices[i-1]) break;
ndec = RBW_choices[i-3];
fils = RBW_choices[i-2];
WISH = RBW_choices[i-1]; // RBW achieved by Si4432 in Hz
SI4432_RSSI_correction = RBW_choices[i]/10.0 - 120.0;
uint8_t BW = (dwn3 << 7) | (ndec << 4) | fils ;
SI4432_Write_Byte(0x1C , BW ) ;
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){
if (i < 0)
return 0;
if (i * 4 >= (int)(sizeof RBW_choices) / 2 )
return 0;
return(RBW_choices[i*4-1]);
}
int setting_frequency_10mhz = 10000000;
void set_10mhz(int f)
{
setting_frequency_10mhz = f;
}
int SI4432_frequency_changed = false;
void SI4432_Set_Frequency ( long Freq ) {
int hbsel;
long Carrier;
if (Freq >= 480000000) {
hbsel = 1;
Freq = Freq / 2;
} else {
hbsel = 0;
}
int sbsel = 1;
long N = Freq / setting_frequency_10mhz;
Carrier = ( 4 * ( Freq - N * setting_frequency_10mhz )) / 625;
int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 );
#if 0
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
SI4432_frequency_changed = true;
}
int actualStepDelay = 1500;
//extern int setting.repeat;
#ifdef __FAST_SWEEP__
extern char age[POINTS_COUNT];
static int buf_index = 0;
static bool buf_read = false;
void SI4432_Fill(int s, int start)
{
SI4432_Sel = s;
int sel = SI_nSEL[SI4432_Sel];
float t = setting.sweep_time - calc_min_sweep_time(); // Time to delay in mS
if (t < 0)
t = 0;
int ti = t * 1000 / 290.0; // Now in uS per point if (t < 30000)
for (int i=start; i<POINTS_COUNT; ) {
SPI2_CLK_LOW;
palClearPad(GPIOC, sel);
shiftOut( 0x26 );
age[i++]=(char)shiftIn();
palSetPad(GPIOC, sel);
if (ti)
my_microsecond_delay(ti);
}
buf_index = start;
buf_read = true;
}
#endif
float SI4432_RSSI(uint32_t i, int s)
{
(void) i;
int32_t RSSI_RAW;
(void) i;
// SEE DATASHEET PAGE 61
#ifdef USE_SI4463
if (SI4432_Sel == 2) {
RSSI_RAW = Si446x_getRSSI();
} else
#endif
//START_PROFILE
#ifdef __FAST_SWEEP__
if (buf_read) {
float dBm = ((float)((unsigned char)age[buf_index++]))/2 + SI4432_RSSI_correction;
if (buf_index ==POINTS_COUNT) {
buf_read = false;
}
return dBm;
}
#endif
SI4432_Sel = s;
int stepdelay = actualStepDelay;
if (SI4432_frequency_changed) {
if (stepdelay < 280) {
stepdelay = 280;
}
SI4432_frequency_changed = false;
}
if (stepdelay)
my_microsecond_delay(stepdelay);
// chThdSleepMicroseconds(actualStepDelay);
i = setting.repeat;
RSSI_RAW = 0;
again:
RSSI_RAW += ((unsigned int)SI4432_Read_Byte( 0x26 )) << 4 ;
i--;
if (i > 0) {
my_microsecond_delay(100);
goto again;
}
if (setting.repeat > 1)
RSSI_RAW = RSSI_RAW / setting.repeat;
// if (MODE_INPUT(setting.mode) && RSSI_RAW == 0)
// SI4432_Init();
float dBm = ((float)RSSI_RAW)/32.0 + SI4432_RSSI_correction;
#ifdef __SIMULATION__
dBm = Simulated_SI4432_RSSI(i,s);
#endif
//STOP_PROFILE
// Serial.println(dBm,2);
return dBm ;
}
void SI4432_Sub_Init(void)
{
SI4432_Reset();
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
#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, 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
// 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<33>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_3_Byte(0x1C, 0x81, 0x3C, 0x02) ;
// 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_3_Byte(0x21, 0x01, 0x11, 0x11) ;
// 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_3_Byte(0x2C, 0x28, 0x0c, 0x28) ;
// 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()
{
palClearPad(GPIOB, GPIO_RF_PWR);
chThdSleepMilliseconds(20);
palSetPad(GPIOB, GPIO_RF_PWR);
chThdSleepMilliseconds(20);
//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(433800000);
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(443800000);
SI4432_Write_Byte(0x0D, 0x1F) ; // Set GPIO2 output to ground
// 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;
}
#define PE4302_DELAY 100
#if 0
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);
}
}
#endif
void PE4302_Write_Byte(unsigned char DATA )
{
// chThdSleepMicroseconds(PE4302_DELAY);
SPI2_CLK_LOW;
// chThdSleepMicroseconds(PE4302_DELAY);
// PE4302_shiftOut(DATA);
shiftOut(DATA);
// chThdSleepMicroseconds(PE4302_DELAY);
CS_PE_HIGH;
// chThdSleepMicroseconds(PE4302_DELAY);
CS_PE_LOW;
// chThdSleepMicroseconds(PE4302_DELAY);
}
#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
//------------------------------- ADF4351 -------------------------------------
#ifdef __ULTRA_SA__
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
#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(10);
SPI3_CLK_HIGH;
// chThdSleepMicroseconds(10);
SPI3_CLK_LOW;
// chThdSleepMicroseconds(10);
}
}
//unsigned long registers[6] = {0x4580A8, 0x80080C9, 0x4E42, 0x4B3, 0xBC803C, 0x580005} ;
//unsigned long registers[6] = {0x4C82C8, 0x80083E9, 0x6E42, 0x8004B3, 0x8C81FC, 0x580005} ;
//uint32_t registers[6] = {0x320000, 0x8008011, 0x4E42, 0x4B3,0x8C803C , 0x580005} ; //25 MHz ref
uint32_t registers[6] = {0xA00000, 0x8000011, 0x4E42, 0x4B3,0xDC003C , 0x580005} ; //10 MHz ref
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 0 //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
// while(1) {
//
ADF4351_set_frequency(0,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(10);
for (int i = 3; i >= 0; i--) ADF_shiftOut((value >> (8 * i)) & 0xFF);
// chThdSleepMicroseconds(10);
palSetPad(GPIOA, ADF4351_LE[channel]);
// chThdSleepMicroseconds(10);
palClearPad(GPIOA, ADF4351_LE[channel]);
// chThdSleepMicroseconds(10);
}
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

@ -0,0 +1,44 @@
#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);
#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__

@ -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, &reg, 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;
}

@ -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);

@ -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);
}

551
ui.c

File diff suppressed because it is too large Load Diff

1906
ui_sa.c

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save

Powered by TurnKey Linux.