mirror of
https://github.com/ttrftech/NanoVNA.git
synced 2025-12-06 03:31:59 +01:00
Compare commits
No commits in common. "master" and "0.5.1" have entirely different histories.
156
.clang-format
156
.clang-format
|
|
@ -1,156 +0,0 @@
|
||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
# BasedOnStyle: Google
|
|
||||||
AccessModifierOffset: -1
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignEscapedNewlines: Left
|
|
||||||
AlignOperands: true
|
|
||||||
AlignTrailingComments: true
|
|
||||||
AllowAllArgumentsOnNextLine: true
|
|
||||||
AllowAllConstructorInitializersOnNextLine: true
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
|
||||||
AllowShortBlocksOnASingleLine: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: All
|
|
||||||
AllowShortLambdasOnASingleLine: All
|
|
||||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
|
||||||
AllowShortLoopsOnASingleLine: true
|
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
BinPackArguments: true
|
|
||||||
BinPackParameters: true
|
|
||||||
BraceWrapping:
|
|
||||||
AfterCaseLabel: false
|
|
||||||
AfterClass: true
|
|
||||||
AfterControlStatement: false
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: true
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterObjCDeclaration: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
AfterExternBlock: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
IndentBraces: false
|
|
||||||
SplitEmptyFunction: true
|
|
||||||
SplitEmptyRecord: true
|
|
||||||
SplitEmptyNamespace: true
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
BreakBeforeInheritanceComma: false
|
|
||||||
BreakInheritanceList: BeforeColon
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
BreakConstructorInitializers: BeforeColon
|
|
||||||
BreakAfterJavaFieldAnnotations: false
|
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 90
|
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
|
||||||
CompactNamespaces: false
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
|
||||||
ConstructorInitializerIndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
DerivePointerAlignment: true
|
|
||||||
DisableFormat: false
|
|
||||||
ExperimentalAutoDetectBinPacking: false
|
|
||||||
FixNamespaceComments: true
|
|
||||||
ForEachMacros:
|
|
||||||
- foreach
|
|
||||||
- Q_FOREACH
|
|
||||||
- BOOST_FOREACH
|
|
||||||
IncludeBlocks: Regroup
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^<ext/.*\.h>'
|
|
||||||
Priority: 2
|
|
||||||
- Regex: '^<.*\.h>'
|
|
||||||
Priority: 1
|
|
||||||
- Regex: '^<.*'
|
|
||||||
Priority: 2
|
|
||||||
- Regex: '.*'
|
|
||||||
Priority: 3
|
|
||||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentPPDirectives: None
|
|
||||||
IndentWidth: 2
|
|
||||||
IndentWrappedFunctionNames: false
|
|
||||||
JavaScriptQuotes: Leave
|
|
||||||
JavaScriptWrapImports: true
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
|
||||||
MacroBlockBegin: ''
|
|
||||||
MacroBlockEnd: ''
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: None
|
|
||||||
ObjCBinPackProtocolList: Never
|
|
||||||
ObjCBlockIndentWidth: 2
|
|
||||||
ObjCSpaceAfterProperty: false
|
|
||||||
ObjCSpaceBeforeProtocolList: true
|
|
||||||
PenaltyBreakAssignment: 2
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 1
|
|
||||||
PenaltyBreakComment: 300
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyBreakTemplateDeclaration: 10
|
|
||||||
PenaltyExcessCharacter: 1000000
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 200
|
|
||||||
PointerAlignment: Left
|
|
||||||
RawStringFormats:
|
|
||||||
- Language: Cpp
|
|
||||||
Delimiters:
|
|
||||||
- cc
|
|
||||||
- CC
|
|
||||||
- cpp
|
|
||||||
- Cpp
|
|
||||||
- CPP
|
|
||||||
- 'c++'
|
|
||||||
- 'C++'
|
|
||||||
CanonicalDelimiter: ''
|
|
||||||
BasedOnStyle: google
|
|
||||||
- Language: TextProto
|
|
||||||
Delimiters:
|
|
||||||
- pb
|
|
||||||
- PB
|
|
||||||
- proto
|
|
||||||
- PROTO
|
|
||||||
EnclosingFunctions:
|
|
||||||
- EqualsProto
|
|
||||||
- EquivToProto
|
|
||||||
- PARSE_PARTIAL_TEXT_PROTO
|
|
||||||
- PARSE_TEST_PROTO
|
|
||||||
- PARSE_TEXT_PROTO
|
|
||||||
- ParseTextOrDie
|
|
||||||
- ParseTextProtoOrDie
|
|
||||||
CanonicalDelimiter: ''
|
|
||||||
BasedOnStyle: google
|
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: true
|
|
||||||
SortUsingDeclarations: true
|
|
||||||
SpaceAfterCStyleCast: false
|
|
||||||
SpaceAfterLogicalNot: false
|
|
||||||
SpaceAfterTemplateKeyword: true
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeCpp11BracedList: false
|
|
||||||
SpaceBeforeCtorInitializerColon: true
|
|
||||||
SpaceBeforeInheritanceColon: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 2
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
Standard: Auto
|
|
||||||
StatementMacros:
|
|
||||||
- Q_UNUSED
|
|
||||||
- QT_REQUIRE_VERSION
|
|
||||||
TabWidth: 4
|
|
||||||
UseTab: Never
|
|
||||||
...
|
|
||||||
|
|
||||||
31
.vscode/launch.json
vendored
31
.vscode/launch.json
vendored
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "OpenOCD-Debug",
|
|
||||||
"type": "cortex-debug",
|
|
||||||
"request": "launch",
|
|
||||||
"servertype": "openocd",
|
|
||||||
"executable": "build/ch.elf",
|
|
||||||
"configFiles": [
|
|
||||||
"interface/stlink.cfg",
|
|
||||||
"target/stm32f0x.cfg"
|
|
||||||
],
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"svdFile": "STM32F0x2.svd",
|
|
||||||
"device": "stm32f0x",
|
|
||||||
"preLaunchTask": "build",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "STLink-Debug",
|
|
||||||
"type": "cortex-debug",
|
|
||||||
"request": "launch",
|
|
||||||
"servertype": "stutil",
|
|
||||||
"executable": "build/ch.elf",
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"svdFile": "STM32F0x2.svd",
|
|
||||||
"device": "stm32f0x",
|
|
||||||
"preLaunchTask": "build",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -1,4 +1,3 @@
|
||||||
{
|
{
|
||||||
"C_Cpp.errorSquiggles": "Disabled",
|
"C_Cpp.errorSquiggles": "Disabled"
|
||||||
"cpplint.filters": ["-build/include_subdir", "-build/include_order", "-readability/casting", "-whitespace/comments"]
|
|
||||||
}
|
}
|
||||||
12
.vscode/tasks.json
vendored
12
.vscode/tasks.json
vendored
|
|
@ -2,19 +2,19 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"label": "build",
|
"label": "make",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "make",
|
"command": "make",
|
||||||
"group": {
|
"group": "build"
|
||||||
"kind": "build",
|
|
||||||
"isDefault": true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "flash",
|
"label": "flash",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "make dfu flash",
|
"command": "make dfu flash",
|
||||||
"group": "build"
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
23
Makefile
23
Makefile
|
|
@ -81,10 +81,6 @@ endif
|
||||||
# Project, sources and paths
|
# Project, sources and paths
|
||||||
#
|
#
|
||||||
|
|
||||||
# Dvice node to flash
|
|
||||||
DEVICE = /dev/cu.usbmodem401
|
|
||||||
#DEVICE = /dev/ttyACM0
|
|
||||||
|
|
||||||
# Define project name here
|
# Define project name here
|
||||||
PROJECT = ch
|
PROJECT = ch
|
||||||
|
|
||||||
|
|
@ -104,9 +100,9 @@ include $(CHIBIOS)/os/hal/osal/rt/osal.mk
|
||||||
include $(CHIBIOS)/os/rt/rt.mk
|
include $(CHIBIOS)/os/rt/rt.mk
|
||||||
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk
|
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk
|
||||||
# Other files (optional).
|
# Other files (optional).
|
||||||
#include $(CHIBIOS)/test/rt/test.mk
|
include $(CHIBIOS)/test/rt/test.mk
|
||||||
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
||||||
#include $(CHIBIOS)/os/various/shell/shell.mk
|
include $(CHIBIOS)/os/various/shell/shell.mk
|
||||||
|
|
||||||
# Define linker script file here
|
# Define linker script file here
|
||||||
#LDSCRIPT= $(STARTUPLD)/STM32F072xB.ld
|
#LDSCRIPT= $(STARTUPLD)/STM32F072xB.ld
|
||||||
|
|
@ -122,9 +118,12 @@ CSRC = $(STARTUPSRC) \
|
||||||
$(PLATFORMSRC) \
|
$(PLATFORMSRC) \
|
||||||
$(BOARDSRC) \
|
$(BOARDSRC) \
|
||||||
$(STREAMSSRC) \
|
$(STREAMSSRC) \
|
||||||
|
$(SHELLSRC) \
|
||||||
usbcfg.c \
|
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 si5351.c tlv320aic3204.c dsp.c plot.c ui.c ili9341.c numfont20x22.c Font5x7.c flash.c adc.c
|
||||||
|
|
||||||
|
# $(TESTSRC) \
|
||||||
|
|
||||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||||
# setting.
|
# setting.
|
||||||
CPPSRC =
|
CPPSRC =
|
||||||
|
|
@ -154,7 +153,8 @@ ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
|
||||||
|
|
||||||
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
|
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
|
||||||
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
|
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
|
||||||
$(STREAMSINC)
|
$(STREAMSINC) $(SHELLINC)
|
||||||
|
# $(TESTINC)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Project, sources and paths
|
# Project, sources and paths
|
||||||
|
|
@ -176,7 +176,7 @@ CPPC = $(TRGT)g++
|
||||||
LD = $(TRGT)gcc
|
LD = $(TRGT)gcc
|
||||||
#LD = $(TRGT)g++
|
#LD = $(TRGT)g++
|
||||||
CP = $(TRGT)objcopy
|
CP = $(TRGT)objcopy
|
||||||
AS = $(TRGT)gcc -x assembler-with-cpp -ggdb
|
AS = $(TRGT)gcc -x assembler-with-cpp
|
||||||
AR = $(TRGT)ar
|
AR = $(TRGT)ar
|
||||||
OD = $(TRGT)objdump
|
OD = $(TRGT)objdump
|
||||||
SZ = $(TRGT)size
|
SZ = $(TRGT)size
|
||||||
|
|
@ -229,4 +229,9 @@ flash: build/ch.bin
|
||||||
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
|
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
|
||||||
|
|
||||||
dfu:
|
dfu:
|
||||||
-printf "reset dfu\r" >$(DEVICE) && sleep 1
|
-@printf "reset dfu\r" >/dev/cu.usbmodem401
|
||||||
|
|
||||||
|
TAGS: Makefile
|
||||||
|
@etags *.[ch] NANOVNA_STM32_F072/*.[ch] $(shell find ChibiOS/os/hal/ports/STM32/STM32F0xx ChibiOS/os -name \*.\[ch\] -print)
|
||||||
|
@ls -l TAGS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@
|
||||||
#ifndef _BOARD_H_
|
#ifndef _BOARD_H_
|
||||||
#define _BOARD_H_
|
#define _BOARD_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup for the Strawberry Linux STbee
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Board identifier.
|
* Board identifier.
|
||||||
*/
|
*/
|
||||||
|
|
@ -126,8 +130,8 @@
|
||||||
PIN_MODE_ALTERNATE(GPIOA_MCO) | \
|
PIN_MODE_ALTERNATE(GPIOA_MCO) | \
|
||||||
PIN_MODE_INPUT(9U) | \
|
PIN_MODE_INPUT(9U) | \
|
||||||
PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \
|
PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \
|
||||||
PIN_MODE_ALTERNATE(GPIOA_USB_DM) | \
|
PIN_MODE_INPUT(GPIOA_USB_DM) | \
|
||||||
PIN_MODE_ALTERNATE(GPIOA_USB_DP) | \
|
PIN_MODE_INPUT(GPIOA_USB_DP) | \
|
||||||
PIN_MODE_ALTERNATE(GPIOA_JTMS) | \
|
PIN_MODE_ALTERNATE(GPIOA_JTMS) | \
|
||||||
PIN_MODE_ALTERNATE(GPIOA_JTCK) | \
|
PIN_MODE_ALTERNATE(GPIOA_JTCK) | \
|
||||||
PIN_MODE_OUTPUT(GPIOA_LCD_RESET))
|
PIN_MODE_OUTPUT(GPIOA_LCD_RESET))
|
||||||
|
|
@ -157,7 +161,7 @@
|
||||||
PIN_OSPEED_2M(7) | \
|
PIN_OSPEED_2M(7) | \
|
||||||
PIN_OSPEED_100M(GPIOA_MCO) | \
|
PIN_OSPEED_100M(GPIOA_MCO) | \
|
||||||
PIN_OSPEED_100M(9) | \
|
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_DM) | \
|
||||||
PIN_OSPEED_100M(GPIOA_USB_DP) | \
|
PIN_OSPEED_100M(GPIOA_USB_DP) | \
|
||||||
PIN_OSPEED_100M(GPIOA_JTMS) | \
|
PIN_OSPEED_100M(GPIOA_JTMS) | \
|
||||||
|
|
@ -173,7 +177,7 @@
|
||||||
PIN_PUPDR_FLOATING(7) | \
|
PIN_PUPDR_FLOATING(7) | \
|
||||||
PIN_PUPDR_PULLUP(GPIOA_MCO) | \
|
PIN_PUPDR_PULLUP(GPIOA_MCO) | \
|
||||||
PIN_PUPDR_PULLUP(9) | \
|
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_DM) | \
|
||||||
PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \
|
PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \
|
||||||
PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \
|
PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ Install cross tools and firmware updating tool.
|
||||||
Download arm cross tools from [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads).
|
Download arm cross tools from [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads).
|
||||||
|
|
||||||
$ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2
|
$ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2
|
||||||
$ sudo tar xfj gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 -C /usr/local
|
$ sudo tar xfj -C /usr/local gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2
|
||||||
$ PATH=/usr/local/gcc-arm-none-eabi-8-2018-q4-major/bin:$PATH
|
$ PATH=/usr/local/gcc-arm-none-eabi-8-2018-q4-major/bin:$PATH
|
||||||
$ sudo apt install -y dfu-util
|
$ sudo apt install -y dfu-util
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ There are seveal numbers of great companion PC tools from third-party.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
* [NanoVNA User Guide(ja)](https://cho45.github.io/NanoVNA-manual/) by cho45. [(en:google translate)](https://translate.google.com/translate?sl=ja&tl=en&u=https%3A%2F%2Fcho45.github.io%2FNanoVNA-manual%2F)
|
* [NanoVNA User Guide](https://cho45.github.io/NanoVNA-manual/) [(google translate)](https://translate.google.com/translate?sl=ja&tl=en&u=https%3A%2F%2Fcho45.github.io%2FNanoVNA-manual%2F) by cho45
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
|
|
@ -105,7 +105,6 @@ Hardware design material is disclosed to prevent bad quality clone. Please let m
|
||||||
## Authorized Distributor
|
## Authorized Distributor
|
||||||
|
|
||||||
* [Nooelec](https://www.nooelec.com/store/nanovna-bundle.html)
|
* [Nooelec](https://www.nooelec.com/store/nanovna-bundle.html)
|
||||||
* Switch Science(ja) [NanoVNA-H](https://www.switch-science.com/catalog/6405/) [NanoVNA-H4](https://www.switch-science.com/catalog/6406/)
|
|
||||||
|
|
||||||
## Credit
|
## Credit
|
||||||
|
|
||||||
|
|
@ -115,4 +114,3 @@ Hardware design material is disclosed to prevent bad quality clone. Please let m
|
||||||
|
|
||||||
* [@hugen79](https://github.com/hugen79)
|
* [@hugen79](https://github.com/hugen79)
|
||||||
* [@cho45](https://github.com/cho45)
|
* [@cho45](https://github.com/cho45)
|
||||||
* [@DiSlord](https://github.com/DiSlord/)
|
|
||||||
|
|
|
||||||
106
adc.c
106
adc.c
|
|
@ -28,82 +28,80 @@
|
||||||
#define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */
|
#define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */
|
||||||
#define ADC_CFGR1_RES_12BIT (0U << 3U)
|
#define ADC_CFGR1_RES_12BIT (0U << 3U)
|
||||||
|
|
||||||
#define VNA_ADC ADC1
|
|
||||||
|
|
||||||
void adc_init(void)
|
void adc_init(void)
|
||||||
{
|
{
|
||||||
rccEnableADC1(FALSE);
|
rccEnableADC1(FALSE);
|
||||||
|
|
||||||
/* Ensure flag states */
|
/* Ensure flag states */
|
||||||
VNA_ADC->IER = 0;
|
ADC1->IER = 0;
|
||||||
|
|
||||||
/* Calibration procedure.*/
|
/* Calibration procedure.*/
|
||||||
ADC->CCR = 0;
|
ADC->CCR = 0;
|
||||||
if (VNA_ADC->CR & ADC_CR_ADEN) {
|
if (ADC1->CR & ADC_CR_ADEN) {
|
||||||
VNA_ADC->CR |= ~ADC_CR_ADDIS; /* Disable ADC */
|
ADC1->CR |= ~ADC_CR_ADDIS; /* Disable ADC */
|
||||||
}
|
}
|
||||||
while (VNA_ADC->CR & ADC_CR_ADEN)
|
while (ADC1->CR & ADC_CR_ADEN)
|
||||||
;
|
;
|
||||||
VNA_ADC->CFGR1 &= ~ADC_CFGR1_DMAEN;
|
ADC1->CFGR1 &= ~ADC_CFGR1_DMAEN;
|
||||||
VNA_ADC->CR |= ADC_CR_ADCAL;
|
ADC1->CR |= ADC_CR_ADCAL;
|
||||||
while (VNA_ADC->CR & ADC_CR_ADCAL)
|
while (ADC1->CR & ADC_CR_ADCAL)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (VNA_ADC->ISR & ADC_ISR_ADRDY) {
|
if (ADC1->ISR & ADC_ISR_ADRDY) {
|
||||||
VNA_ADC->ISR |= ADC_ISR_ADRDY; /* clear ADRDY */
|
ADC1->ISR |= ADC_ISR_ADRDY; /* clear ADRDY */
|
||||||
}
|
}
|
||||||
/* Enable ADC */
|
/* Enable ADC */
|
||||||
VNA_ADC->CR |= ADC_CR_ADEN;
|
ADC1->CR |= ADC_CR_ADEN;
|
||||||
while (!(VNA_ADC->ISR & ADC_ISR_ADRDY))
|
while (!(ADC1->ISR & ADC_ISR_ADRDY))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t adc_single_read(uint32_t chsel)
|
uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel)
|
||||||
{
|
{
|
||||||
/* ADC setup */
|
/* ADC setup */
|
||||||
VNA_ADC->ISR = VNA_ADC->ISR;
|
adc->ISR = adc->ISR;
|
||||||
VNA_ADC->IER = 0;
|
adc->IER = 0;
|
||||||
VNA_ADC->TR = ADC_TR(0, 0);
|
adc->TR = ADC_TR(0, 0);
|
||||||
VNA_ADC->SMPR = ADC_SMPR_SMP_239P5;
|
adc->SMPR = ADC_SMPR_SMP_239P5;
|
||||||
VNA_ADC->CFGR1 = ADC_CFGR1_RES_12BIT;
|
adc->CFGR1 = ADC_CFGR1_RES_12BIT;
|
||||||
VNA_ADC->CHSELR = chsel;
|
adc->CHSELR = chsel;
|
||||||
|
|
||||||
/* ADC conversion start.*/
|
/* ADC conversion start.*/
|
||||||
VNA_ADC->CR |= ADC_CR_ADSTART;
|
adc->CR |= ADC_CR_ADSTART;
|
||||||
|
|
||||||
while (VNA_ADC->CR & ADC_CR_ADSTART)
|
while (adc->CR & ADC_CR_ADSTART)
|
||||||
;
|
;
|
||||||
|
|
||||||
return VNA_ADC->DR;
|
return adc->DR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t adc_vbat_read(void)
|
int16_t adc_vbat_read(ADC_TypeDef *adc)
|
||||||
{
|
{
|
||||||
// 13.9 Temperature sensor and internal reference voltage
|
|
||||||
// VREFINT_CAL calibrated on 3.3V, need get value in mV
|
|
||||||
#define ADC_FULL_SCALE 3300
|
#define ADC_FULL_SCALE 3300
|
||||||
|
#define VBAT_DIODE_VF 500
|
||||||
#define VREFINT_CAL (*((uint16_t*)0x1FFFF7BA))
|
#define VREFINT_CAL (*((uint16_t*)0x1FFFF7BA))
|
||||||
adc_stop();
|
float vbat = 0;
|
||||||
|
float vrefint = 0;
|
||||||
|
|
||||||
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN;
|
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN;
|
||||||
// VREFINT == ADC_IN17
|
// VREFINT == ADC_IN17
|
||||||
uint32_t vrefint = adc_single_read(ADC_CHSELR_CHSEL17);
|
vrefint = adc_single_read(adc, ADC_CHSELR_CHSEL17);
|
||||||
// VBAT == ADC_IN18
|
// VBAT == ADC_IN18
|
||||||
// VBATEN enables resiter devider circuit. It consume vbat power.
|
// VBATEN enables resiter devider circuit. It consume vbat power.
|
||||||
uint32_t vbat = adc_single_read(ADC_CHSELR_CHSEL18);
|
vbat = adc_single_read(adc, ADC_CHSELR_CHSEL18);
|
||||||
ADC->CCR &= ~(ADC_CCR_VREFEN | ADC_CCR_VBATEN);
|
ADC->CCR &= ~(ADC_CCR_VREFEN | ADC_CCR_VBATEN);
|
||||||
touch_start_watchdog();
|
|
||||||
// vbat_raw = (3300 * 2 * vbat / 4095) * (VREFINT_CAL / vrefint)
|
uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * vbat * 2 / (vrefint * ((1<<12)-1)));
|
||||||
// uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * (float)vbat * 2 / (vrefint * ((1<<12)-1)));
|
|
||||||
// For speed divide not on 4095, divide on 4096, get little error, but no matter
|
|
||||||
uint16_t vbat_raw = ((ADC_FULL_SCALE * 2 * vbat)>>12) * VREFINT_CAL / vrefint;
|
|
||||||
if (vbat_raw < 100) {
|
if (vbat_raw < 100) {
|
||||||
// maybe D2 is not installed
|
// maybe D2 is not installed
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return vbat_raw + config.vbat_offset;
|
|
||||||
|
return vbat_raw + VBAT_DIODE_VF;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_start_analog_watchdogd(uint32_t chsel)
|
void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel)
|
||||||
{
|
{
|
||||||
uint32_t cfgr1;
|
uint32_t cfgr1;
|
||||||
|
|
||||||
|
|
@ -113,38 +111,38 @@ void adc_start_analog_watchdogd(uint32_t chsel)
|
||||||
|
|
||||||
/* ADC setup, if it is defined a callback for the analog watch dog then it
|
/* ADC setup, if it is defined a callback for the analog watch dog then it
|
||||||
is enabled.*/
|
is enabled.*/
|
||||||
VNA_ADC->ISR = VNA_ADC->ISR;
|
adc->ISR = adc->ISR;
|
||||||
VNA_ADC->IER = ADC_IER_AWDIE;
|
adc->IER = ADC_IER_AWDIE;
|
||||||
VNA_ADC->TR = ADC_TR(0, TOUCH_THRESHOLD);
|
adc->TR = ADC_TR(0, TOUCH_THRESHOLD);
|
||||||
VNA_ADC->SMPR = ADC_SMPR_SMP_1P5;
|
adc->SMPR = ADC_SMPR_SMP_1P5;
|
||||||
VNA_ADC->CHSELR = chsel;
|
adc->CHSELR = chsel;
|
||||||
|
|
||||||
/* ADC configuration and start.*/
|
/* ADC configuration and start.*/
|
||||||
VNA_ADC->CFGR1 = cfgr1;
|
adc->CFGR1 = cfgr1;
|
||||||
|
|
||||||
/* ADC conversion start.*/
|
/* ADC conversion start.*/
|
||||||
VNA_ADC->CR |= ADC_CR_ADSTART;
|
adc->CR |= ADC_CR_ADSTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_stop(void)
|
void adc_stop(ADC_TypeDef *adc)
|
||||||
{
|
{
|
||||||
if (VNA_ADC->CR & ADC_CR_ADEN) {
|
if (adc->CR & ADC_CR_ADEN) {
|
||||||
if (VNA_ADC->CR & ADC_CR_ADSTART) {
|
if (adc->CR & ADC_CR_ADSTART) {
|
||||||
VNA_ADC->CR |= ADC_CR_ADSTP;
|
adc->CR |= ADC_CR_ADSTP;
|
||||||
while (VNA_ADC->CR & ADC_CR_ADSTP)
|
while (adc->CR & ADC_CR_ADSTP)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VNA_ADC->CR |= ADC_CR_ADDIS;
|
/* adc->CR |= ADC_CR_ADDIS;
|
||||||
while (VNA_ADC->CR & ADC_CR_ADDIS)
|
while (adc->CR & ADC_CR_ADDIS)
|
||||||
;*/
|
;*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_interrupt(void)
|
void adc_interrupt(ADC_TypeDef *adc)
|
||||||
{
|
{
|
||||||
uint32_t isr = VNA_ADC->ISR;
|
uint32_t isr = adc->ISR;
|
||||||
VNA_ADC->ISR = isr;
|
adc->ISR = isr;
|
||||||
|
|
||||||
if (isr & ADC_ISR_OVR) {
|
if (isr & ADC_ISR_OVR) {
|
||||||
/* ADC overflow condition, this could happen only if the DMA is unable
|
/* ADC overflow condition, this could happen only if the DMA is unable
|
||||||
|
|
@ -161,7 +159,7 @@ OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER)
|
||||||
{
|
{
|
||||||
OSAL_IRQ_PROLOGUE();
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
adc_interrupt();
|
adc_interrupt(ADC1);
|
||||||
|
|
||||||
OSAL_IRQ_EPILOGUE();
|
OSAL_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
chconf.h
18
chconf.h
|
|
@ -147,7 +147,7 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_REGISTRY FALSE
|
#define CH_CFG_USE_REGISTRY TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Threads synchronization APIs.
|
* @brief Threads synchronization APIs.
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_WAITEXIT FALSE
|
#define CH_CFG_USE_WAITEXIT TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Semaphores APIs.
|
* @brief Semaphores APIs.
|
||||||
|
|
@ -183,7 +183,7 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_MUTEXES FALSE
|
#define CH_CFG_USE_MUTEXES TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables recursive behavior on mutexes.
|
* @brief Enables recursive behavior on mutexes.
|
||||||
|
|
@ -193,7 +193,7 @@
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
|
#define CH_CFG_USE_MUTEXES_RECURSIVE TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Conditional Variables APIs.
|
* @brief Conditional Variables APIs.
|
||||||
|
|
@ -221,7 +221,7 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_EVENTS FALSE
|
#define CH_CFG_USE_EVENTS TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Events Flags APIs with timeout.
|
* @brief Events Flags APIs with timeout.
|
||||||
|
|
@ -231,7 +231,7 @@
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_CFG_USE_EVENTS.
|
* @note Requires @p CH_CFG_USE_EVENTS.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_EVENTS_TIMEOUT FALSE
|
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Synchronous Messages APIs.
|
* @brief Synchronous Messages APIs.
|
||||||
|
|
@ -269,7 +269,7 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#define CH_CFG_USE_QUEUES FALSE
|
#define CH_CFG_USE_QUEUES TRUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Core Memory Manager APIs.
|
* @brief Core Memory Manager APIs.
|
||||||
|
|
@ -530,11 +530,11 @@
|
||||||
* ChibiOS/os/various/shell/shell_cmd.c
|
* ChibiOS/os/various/shell/shell_cmd.c
|
||||||
*/
|
*/
|
||||||
#define SHELL_CMD_EXIT_ENABLED TRUE
|
#define SHELL_CMD_EXIT_ENABLED TRUE
|
||||||
#define SHELL_CMD_INFO_ENABLED FALSE
|
#define SHELL_CMD_INFO_ENABLED TRUE
|
||||||
#define SHELL_CMD_ECHO_ENABLED FALSE
|
#define SHELL_CMD_ECHO_ENABLED FALSE
|
||||||
#define SHELL_CMD_SYSTIME_ENABLED FALSE
|
#define SHELL_CMD_SYSTIME_ENABLED FALSE
|
||||||
#define SHELL_CMD_MEM_ENABLED FALSE
|
#define SHELL_CMD_MEM_ENABLED FALSE
|
||||||
#define SHELL_CMD_THREADS_ENABLED FALSE
|
#define SHELL_CMD_THREADS_ENABLED TRUE
|
||||||
#define SHELL_CMD_TEST_ENABLED FALSE
|
#define SHELL_CMD_TEST_ENABLED FALSE
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
594
chprintf.c
594
chprintf.c
|
|
@ -1,594 +0,0 @@
|
||||||
/*
|
|
||||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Concepts and parts of this file have been contributed by Fabio Utzig,
|
|
||||||
chvprintf() added by Brent Roman.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file chprintf.c
|
|
||||||
* @brief Mini printf-like functionality.
|
|
||||||
*
|
|
||||||
* @addtogroup chprintf
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "chprintf.h"
|
|
||||||
//#include "memstreams.h"
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
// Enable [flags], support:
|
|
||||||
// ' ' Prepends a space for positive signed-numeric types. positive = ' ', negative = '-'. This flag is ignored if the + flag exists.
|
|
||||||
//#define CHPRINTF_USE_SPACE_FLAG
|
|
||||||
|
|
||||||
// Force putting trailing zeros on float value
|
|
||||||
#define CHPRINTF_FORCE_TRAILING_ZEROS
|
|
||||||
|
|
||||||
#define MAX_FILLER 11
|
|
||||||
#define FLOAT_PRECISION 9
|
|
||||||
|
|
||||||
#pragma pack(push, 2)
|
|
||||||
|
|
||||||
static const uint32_t pow10[FLOAT_PRECISION+1] = {
|
|
||||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
|
|
||||||
};
|
|
||||||
// Prefixes for values bigger then 1000.0
|
|
||||||
// 1 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24
|
|
||||||
static char bigPrefix[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0};
|
|
||||||
// Prefixes for values less then 1.0
|
|
||||||
// 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18, 1e-21, 1e-24
|
|
||||||
static char smallPrefix[] = {'m', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0};
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
static char *long_to_string_with_divisor(char *p,
|
|
||||||
uint32_t num,
|
|
||||||
uint32_t radix,
|
|
||||||
uint32_t precision) {
|
|
||||||
char *q = p + MAX_FILLER;
|
|
||||||
char *b = q;
|
|
||||||
// convert to string from end buffer to begin
|
|
||||||
do {
|
|
||||||
uint8_t c = num % radix;
|
|
||||||
num /= radix;
|
|
||||||
*--q = c + ((c > 9) ? ('A'-10) : '0');
|
|
||||||
}while((precision && --precision) || num);
|
|
||||||
// copy string at begin
|
|
||||||
int i = (int)(b - q);
|
|
||||||
do
|
|
||||||
*p++ = *q++;
|
|
||||||
while (--i);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// default prescision = 13
|
|
||||||
// g.mmm kkk hhh
|
|
||||||
#define MAX_FREQ_PRESCISION 13
|
|
||||||
#define FREQ_PSET 1
|
|
||||||
#define FREQ_NO_SPACE 2
|
|
||||||
#define FREQ_PREFIX_SPACE 4
|
|
||||||
|
|
||||||
static char *
|
|
||||||
ulong_freq(char *p, uint32_t freq, uint32_t precision)
|
|
||||||
{
|
|
||||||
uint8_t flag = FREQ_PSET;
|
|
||||||
if (precision == 0)
|
|
||||||
flag|=FREQ_PREFIX_SPACE;
|
|
||||||
if (precision == 0 || precision > MAX_FREQ_PRESCISION)
|
|
||||||
precision = MAX_FREQ_PRESCISION;
|
|
||||||
char *q = p + MAX_FREQ_PRESCISION;
|
|
||||||
char *b = q;
|
|
||||||
// Prefix counter
|
|
||||||
uint32_t s = 0;
|
|
||||||
// Set format (every 3 digits add ' ' up to GHz)
|
|
||||||
uint32_t format = 0b00100100100;
|
|
||||||
do {
|
|
||||||
#if 0
|
|
||||||
uint8_t c = freq % 10;
|
|
||||||
freq/= 10;
|
|
||||||
#else
|
|
||||||
// Fast and compact division uint32_t on 10, using shifts, result:
|
|
||||||
// c = freq % 10
|
|
||||||
// freq = freq / 10;
|
|
||||||
uint32_t c = freq;
|
|
||||||
freq >>= 1;
|
|
||||||
freq += freq >> 1;
|
|
||||||
freq += freq >> 4;
|
|
||||||
freq += freq >> 8;
|
|
||||||
freq += freq >> 16; // freq = 858993459*freq/1073741824 = freq *
|
|
||||||
// 0,799999999813735485076904296875
|
|
||||||
freq >>= 3; // freq/=8; freq = freq * 0,09999999997671693563461303710938
|
|
||||||
c -= freq * 10; // freq*10 = (freq*4+freq)*2 = ((freq<<2)+freq)<<1
|
|
||||||
while (c >= 10) {
|
|
||||||
freq++;
|
|
||||||
c -= 10;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*--q = c + '0';
|
|
||||||
if (freq == 0) break;
|
|
||||||
// Add spaces, calculate prefix
|
|
||||||
if (format & 1) {
|
|
||||||
*--q = ' ';
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
format >>= 1;
|
|
||||||
} while (1);
|
|
||||||
s = bigPrefix[s];
|
|
||||||
|
|
||||||
// Get string size
|
|
||||||
uint32_t i = (b - q);
|
|
||||||
// Limit string size, max size is - precision
|
|
||||||
if (precision && i > precision) {
|
|
||||||
i = precision;
|
|
||||||
flag |= FREQ_NO_SPACE;
|
|
||||||
}
|
|
||||||
// copy string
|
|
||||||
// Replace first ' ' by '.', remove ' ' if size too big
|
|
||||||
do {
|
|
||||||
char c = *q++;
|
|
||||||
// replace first ' ' on '.'
|
|
||||||
if (c == ' ') {
|
|
||||||
if (flag & FREQ_PSET) {
|
|
||||||
c = '.';
|
|
||||||
flag &= ~FREQ_PSET;
|
|
||||||
} else if (flag & FREQ_NO_SPACE)
|
|
||||||
c = *q++;
|
|
||||||
}
|
|
||||||
*p++ = c;
|
|
||||||
} while (--i);
|
|
||||||
// Put pref (amd space before it if need)
|
|
||||||
if (flag & FREQ_PREFIX_SPACE && s != ' ')
|
|
||||||
*p++ = ' ';
|
|
||||||
*p++ = s;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CHPRINTF_USE_FLOAT
|
|
||||||
static char *ftoa(char *p, float num, uint32_t precision) {
|
|
||||||
// Check precision limit
|
|
||||||
if (precision > FLOAT_PRECISION)
|
|
||||||
precision = FLOAT_PRECISION;
|
|
||||||
uint32_t multi = pow10[precision];
|
|
||||||
uint32_t l = num;
|
|
||||||
// Round value
|
|
||||||
uint32_t k = ((num-l)*multi+0.5);
|
|
||||||
// Fix rounding error if get
|
|
||||||
if (k>=multi){k-=multi;l++;}
|
|
||||||
p = long_to_string_with_divisor(p, l, 10, 0);
|
|
||||||
if (precision) {
|
|
||||||
*p++ = '.';
|
|
||||||
p=long_to_string_with_divisor(p, k, 10, precision);
|
|
||||||
#ifndef CHPRINTF_FORCE_TRAILING_ZEROS
|
|
||||||
// remove zeros at end
|
|
||||||
while (p[-1]=='0') p--;
|
|
||||||
if (p[-1]=='.') p--;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *ftoaS(char *p, float num, uint32_t precision) {
|
|
||||||
char prefix=0;
|
|
||||||
char *ptr;
|
|
||||||
if (num > 1000.0){
|
|
||||||
for (ptr = bigPrefix+1; *ptr && num > 1000.0; num/=1000, ptr++)
|
|
||||||
;
|
|
||||||
prefix = ptr[-1];
|
|
||||||
}
|
|
||||||
else if (num < 1){
|
|
||||||
for (ptr = smallPrefix; *ptr && num < 1.0; num*=1000, ptr++)
|
|
||||||
;
|
|
||||||
prefix = num > 1e-3 ? ptr[-1] : 0;
|
|
||||||
}
|
|
||||||
// Auto set prescision
|
|
||||||
uint32_t l = num;
|
|
||||||
if (l < 10)
|
|
||||||
precision+=2;
|
|
||||||
else if (l < 100)
|
|
||||||
precision+=1;
|
|
||||||
p=ftoa(p, num, precision);
|
|
||||||
if (prefix)
|
|
||||||
*p++ = prefix;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief System formatted output function.
|
|
||||||
* @details This function implements a minimal @p vprintf()-like functionality
|
|
||||||
* with output on a @p BaseSequentialStream.
|
|
||||||
* The general parameters format is: %[-][width|*][.precision|*][l|L]p.
|
|
||||||
* The following parameter types (p) are supported:
|
|
||||||
* - <b>x</b> hexadecimal integer.
|
|
||||||
* - <b>X</b> hexadecimal long.
|
|
||||||
* - <b>o</b> octal integer.
|
|
||||||
* - <b>O</b> octal long.
|
|
||||||
* - <b>d</b> decimal signed integer.
|
|
||||||
* - <b>D</b> decimal signed long.
|
|
||||||
* - <b>u</b> decimal unsigned integer.
|
|
||||||
* - <b>U</b> decimal unsigned long.
|
|
||||||
* - <b>c</b> character.
|
|
||||||
* - <b>s</b> string.
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* @param[in] chp pointer to a @p BaseSequentialStream implementing object
|
|
||||||
* @param[in] fmt formatting string
|
|
||||||
* @param[in] ap list of parameters
|
|
||||||
* @return The number of bytes that would have been
|
|
||||||
* written to @p chp if no stream error occurs
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define IS_LONG 1
|
|
||||||
#define LEFT_ALIGN 2
|
|
||||||
#define POSITIVE 4
|
|
||||||
#define NEGATIVE 8
|
|
||||||
#define PAD_ZERO 16
|
|
||||||
#define PLUS_SPACE 32
|
|
||||||
#define DEFAULT_PRESCISION 64
|
|
||||||
|
|
||||||
int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
|
||||||
char *p, *s, c, filler=' ';
|
|
||||||
int precision, width;
|
|
||||||
int n = 0;
|
|
||||||
uint32_t state;
|
|
||||||
union {
|
|
||||||
uint32_t u;
|
|
||||||
int32_t l;
|
|
||||||
float f;
|
|
||||||
}value;
|
|
||||||
#if CHPRINTF_USE_FLOAT
|
|
||||||
char tmpbuf[2*MAX_FILLER + 1];
|
|
||||||
#else
|
|
||||||
char tmpbuf[MAX_FREQ_PRESCISION + 1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
c = *fmt++;
|
|
||||||
if (c == 0)
|
|
||||||
return n;
|
|
||||||
if (c != '%') {
|
|
||||||
streamPut(chp, (uint8_t)c);
|
|
||||||
n++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Parse %[flags][width][.precision][length]type
|
|
||||||
p = tmpbuf;
|
|
||||||
s = tmpbuf;
|
|
||||||
state = 0;
|
|
||||||
width = 0;
|
|
||||||
precision = 0;
|
|
||||||
|
|
||||||
// Get [flags], support:
|
|
||||||
// '-' Left-align the output of this placeholder. (The default is to right-align the output.)
|
|
||||||
// '+' Prepends a plus for positive signed-numeric types. positive = '+', negative = '-'.
|
|
||||||
// ' ' Prepends a space for positive signed-numeric types. positive = ' ', negative = '-'. This flag is ignored if the + flag exists.
|
|
||||||
// '0' When the 'width' option is specified, prepends zeros for numeric types. (The default prepends spaces.)
|
|
||||||
while (true){
|
|
||||||
if (*fmt == '-')
|
|
||||||
state|=LEFT_ALIGN;
|
|
||||||
else if (*fmt == '+')
|
|
||||||
state|=POSITIVE;
|
|
||||||
else if (*fmt == '0')
|
|
||||||
state|=PAD_ZERO;
|
|
||||||
#ifdef CHPRINTF_USE_SPACE_FLAG
|
|
||||||
else if (*fmt == ' ')
|
|
||||||
state|=PLUS_SPACE;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
fmt++;
|
|
||||||
}
|
|
||||||
// Get [width] - The Width field specifies a minimum number of characters to output
|
|
||||||
// if set *, get width as argument
|
|
||||||
while (true) {
|
|
||||||
c = *fmt++;
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
c -= '0';
|
|
||||||
else if (c == '*')
|
|
||||||
c = va_arg(ap, int);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
width = width * 10 + c;
|
|
||||||
}
|
|
||||||
// Get [.precision]
|
|
||||||
if (c == '.') {
|
|
||||||
while (true) {
|
|
||||||
c = *fmt++;
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
c -= '0';
|
|
||||||
else if (c == '*')
|
|
||||||
c = va_arg(ap, int);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
precision = precision * 10 + c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
state|=DEFAULT_PRESCISION;
|
|
||||||
//Get [length]
|
|
||||||
/*
|
|
||||||
if (c == 'l' || c == 'L') {
|
|
||||||
state|=IS_LONG;
|
|
||||||
if (*fmt)
|
|
||||||
c = *fmt++;
|
|
||||||
}
|
|
||||||
else if ((c >= 'A') && (c <= 'Z'))
|
|
||||||
state|=IS_LONG;
|
|
||||||
*/
|
|
||||||
// Parse type
|
|
||||||
switch (c) {
|
|
||||||
case 'c':
|
|
||||||
state&=~PAD_ZERO;
|
|
||||||
*p++ = va_arg(ap, int);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
state&=~PAD_ZERO;
|
|
||||||
if ((s = va_arg(ap, char *)) == 0)
|
|
||||||
s = "(null)";
|
|
||||||
if (state&DEFAULT_PRESCISION)
|
|
||||||
precision = 32767;
|
|
||||||
for (p = s; *p && (--precision >= 0); p++)
|
|
||||||
;
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
case 'd':
|
|
||||||
case 'I':
|
|
||||||
case 'i':/*
|
|
||||||
if (state & IS_LONG)
|
|
||||||
value.l = va_arg(ap, long);
|
|
||||||
else*/
|
|
||||||
value.l = va_arg(ap, uint32_t);
|
|
||||||
if (value.l < 0) {
|
|
||||||
state|=NEGATIVE;
|
|
||||||
*p++ = '-';
|
|
||||||
value.l = -value.l;
|
|
||||||
}
|
|
||||||
else if (state & POSITIVE)
|
|
||||||
*p++ = '+';
|
|
||||||
#ifdef CHPRINTF_USE_SPACE_FLAG
|
|
||||||
else if (state & PLUS_SPACE)
|
|
||||||
*p++ = ' ';
|
|
||||||
#endif
|
|
||||||
p = long_to_string_with_divisor(p, value.l, 10, 0);
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
value.u = va_arg(ap, uint32_t);
|
|
||||||
p=ulong_freq(p, value.u, precision);
|
|
||||||
break;
|
|
||||||
#if CHPRINTF_USE_FLOAT
|
|
||||||
case 'F':
|
|
||||||
case 'f':
|
|
||||||
value.f = va_arg(ap, double);
|
|
||||||
if (value.f < 0) {
|
|
||||||
state|=NEGATIVE;
|
|
||||||
*p++ = '-';
|
|
||||||
value.f = -value.f;
|
|
||||||
}
|
|
||||||
else if (state & POSITIVE)
|
|
||||||
*p++ = '+';
|
|
||||||
#ifdef CHPRINTF_USE_SPACE_FLAG
|
|
||||||
else if (state & PLUS_SPACE)
|
|
||||||
*p++ = ' ';
|
|
||||||
#endif
|
|
||||||
if (value.f == INFINITY){
|
|
||||||
*p++ = 0x19;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = (c=='F') ? ftoaS(p, value.f, precision) : ftoa(p, value.f, state&DEFAULT_PRESCISION ? FLOAT_PRECISION : precision);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 'X':
|
|
||||||
case 'x':
|
|
||||||
c = 16;
|
|
||||||
goto unsigned_common;
|
|
||||||
case 'U':
|
|
||||||
case 'u':
|
|
||||||
c = 10;
|
|
||||||
goto unsigned_common;
|
|
||||||
case 'O':
|
|
||||||
case 'o':
|
|
||||||
c = 8;
|
|
||||||
unsigned_common:/*
|
|
||||||
if (state & IS_LONG)
|
|
||||||
value.u = va_arg(ap, unsigned long);
|
|
||||||
else*/
|
|
||||||
value.u = va_arg(ap, uint32_t);
|
|
||||||
p = long_to_string_with_divisor(p, value.u, c, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*p++ = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Now need print buffer s[{sign}XXXXXXXXXXXX]p and align it on width
|
|
||||||
// Check filler width (if buffer less then width) and prepare filler if need fill
|
|
||||||
if ((width -=(int)(p - s)) < 0)
|
|
||||||
width = 0;
|
|
||||||
else
|
|
||||||
filler = (state&PAD_ZERO) ? '0' : ' ';
|
|
||||||
// if left align, put sign digit, and fill
|
|
||||||
// [{sign}ffffffXXXXXXXXXXXX]
|
|
||||||
if (!(state&LEFT_ALIGN)) {
|
|
||||||
// Put '+' or '-' or ' ' first if need
|
|
||||||
if ((state&(NEGATIVE|POSITIVE|PLUS_SPACE)) && (state&PAD_ZERO)) {
|
|
||||||
streamPut(chp, (uint8_t)*s++);
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
// fill from left
|
|
||||||
while (width){
|
|
||||||
streamPut(chp, (uint8_t)filler);
|
|
||||||
n++;
|
|
||||||
width--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// put data
|
|
||||||
while (s < p) {
|
|
||||||
streamPut(chp, (uint8_t)*s++);
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
// Put filler from right (if need)
|
|
||||||
while (width) {
|
|
||||||
streamPut(chp, (uint8_t)filler);
|
|
||||||
n++;
|
|
||||||
width--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief System formatted output function.
|
|
||||||
* @details This function implements a minimal @p printf() like functionality
|
|
||||||
* with output on a @p BaseSequentialStream.
|
|
||||||
* The general parameters format is: %[-][width|*][.precision|*][l|L]p.
|
|
||||||
* The following parameter types (p) are supported:
|
|
||||||
* - <b>x</b> hexadecimal integer.
|
|
||||||
* - <b>X</b> hexadecimal long.
|
|
||||||
* - <b>o</b> octal integer.
|
|
||||||
* - <b>O</b> octal long.
|
|
||||||
* - <b>d</b> decimal signed integer.
|
|
||||||
* - <b>D</b> decimal signed long.
|
|
||||||
* - <b>u</b> decimal unsigned integer.
|
|
||||||
* - <b>U</b> decimal unsigned long.
|
|
||||||
* - <b>c</b> character.
|
|
||||||
* - <b>s</b> string.
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* @param[in] chp pointer to a @p BaseSequentialStream implementing object
|
|
||||||
* @param[in] fmt formatting string
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
int formatted_bytes;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
formatted_bytes = chvprintf(chp, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return formatted_bytes;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* @brief System formatted output function.
|
|
||||||
* @details This function implements a minimal @p vprintf()-like functionality
|
|
||||||
* with output on a @p BaseSequentialStream.
|
|
||||||
* The general parameters format is: %[-][width|*][.precision|*][l|L]p.
|
|
||||||
* The following parameter types (p) are supported:
|
|
||||||
* - <b>x</b> hexadecimal integer.
|
|
||||||
* - <b>X</b> hexadecimal long.
|
|
||||||
* - <b>o</b> octal integer.
|
|
||||||
* - <b>O</b> octal long.
|
|
||||||
* - <b>d</b> decimal signed integer.
|
|
||||||
* - <b>D</b> decimal signed long.
|
|
||||||
* - <b>u</b> decimal unsigned integer.
|
|
||||||
* - <b>U</b> decimal unsigned long.
|
|
||||||
* - <b>c</b> character.
|
|
||||||
* - <b>s</b> string.
|
|
||||||
* .
|
|
||||||
* @post @p str is NUL-terminated, unless @p size is 0.
|
|
||||||
*
|
|
||||||
* @param[in] str pointer to a buffer
|
|
||||||
* @param[in] size maximum size of the buffer
|
|
||||||
* @param[in] fmt formatting string
|
|
||||||
* @return The number of characters (excluding the
|
|
||||||
* terminating NUL byte) that would have been
|
|
||||||
* stored in @p str if there was room.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
int chsnprintf(char *str, size_t size, const char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
MemoryStream ms;
|
|
||||||
BaseSequentialStream *chp;
|
|
||||||
size_t size_wo_nul;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
size_wo_nul = size - 1;
|
|
||||||
else
|
|
||||||
size_wo_nul = 0;
|
|
||||||
|
|
||||||
/* Memory stream object to be used as a string writer, reserving one
|
|
||||||
byte for the final zero.*/
|
|
||||||
msObjectInit(&ms, (uint8_t *)str, size_wo_nul, 0);
|
|
||||||
|
|
||||||
/* Performing the print operation using the common code.*/
|
|
||||||
chp = (BaseSequentialStream *)(void *)&ms;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
retval = chvprintf(chp, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
/* Terminate with a zero, unless size==0.*/
|
|
||||||
if (ms.eos < size)
|
|
||||||
str[ms.eos] = 0;
|
|
||||||
|
|
||||||
/* Return number of bytes that would have been written.*/
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Small memory stream object, only put function
|
|
||||||
//
|
|
||||||
struct printStreamVMT {
|
|
||||||
_base_sequential_stream_methods
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const struct printStreamVMT *vmt;
|
|
||||||
uint8_t *buffer;
|
|
||||||
uint16_t size;
|
|
||||||
} printStream;
|
|
||||||
|
|
||||||
static msg_t put(void *ip, uint8_t b) {
|
|
||||||
printStream *ps = ip;
|
|
||||||
if (ps->size > 1){
|
|
||||||
*(ps->buffer++) = b;
|
|
||||||
ps->size--;
|
|
||||||
}
|
|
||||||
return MSG_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct printStreamVMT vmt = {NULL, NULL, put, NULL};
|
|
||||||
void printObjectInit(printStream *ps, int size, uint8_t *buffer){
|
|
||||||
ps->vmt = &vmt;
|
|
||||||
ps->buffer = buffer;
|
|
||||||
ps->size = size;
|
|
||||||
}
|
|
||||||
// Simple print in buffer function
|
|
||||||
int plot_printf(char *str, int size, const char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
printStream ps;
|
|
||||||
int retval;
|
|
||||||
if (size <= 0) return 0;
|
|
||||||
// Init small memory stream for print
|
|
||||||
printObjectInit(&ps, size, (uint8_t *)str);
|
|
||||||
// Performing the print operation using the common code.
|
|
||||||
va_start(ap, fmt);
|
|
||||||
retval = chvprintf((BaseSequentialStream *)(void *)&ps, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
*(ps.buffer)=0;
|
|
||||||
if (retval > size-1) retval = size-1;
|
|
||||||
// Return number of bytes that would have been written.
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
16
dsp.c
16
dsp.c
|
|
@ -41,10 +41,10 @@ const int16_t sincos_tbl[48][2] = {
|
||||||
{-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 }
|
{-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 }
|
||||||
};
|
};
|
||||||
|
|
||||||
float acc_samp_s;
|
int32_t acc_samp_s;
|
||||||
float acc_samp_c;
|
int32_t acc_samp_c;
|
||||||
float acc_ref_s;
|
int32_t acc_ref_s;
|
||||||
float acc_ref_c;
|
int32_t acc_ref_c;
|
||||||
|
|
||||||
void
|
void
|
||||||
dsp_process(int16_t *capture, size_t length)
|
dsp_process(int16_t *capture, size_t length)
|
||||||
|
|
@ -79,10 +79,10 @@ dsp_process(int16_t *capture, size_t length)
|
||||||
ref_c = __SMLATT(sr, sc, ref_c);
|
ref_c = __SMLATT(sr, sc, ref_c);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
acc_samp_s += samp_s;
|
acc_samp_s = samp_s;
|
||||||
acc_samp_c += samp_c;
|
acc_samp_c = samp_c;
|
||||||
acc_ref_s += ref_s;
|
acc_ref_s = ref_s;
|
||||||
acc_ref_c += ref_c;
|
acc_ref_c = ref_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
4
fft.h
4
fft.h
|
|
@ -68,8 +68,8 @@ static void fft256(float array[][2], const uint8_t dir) {
|
||||||
uint16_t j, k;
|
uint16_t j, k;
|
||||||
for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
|
for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
|
||||||
uint16_t l = j + halfsize;
|
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 tpre = array[l][real] * cos(2 * M_PI * k / 256) + array[l][imag] * sin(2 * M_PI * k / 256);
|
||||||
float tpim = -array[l][real] * sin(2 * VNA_PI * k / 256) + array[l][imag] * cos(2 * VNA_PI * k / 256);
|
float tpim = -array[l][real] * sin(2 * M_PI * k / 256) + array[l][imag] * cos(2 * M_PI * k / 256);
|
||||||
array[l][real] = array[j][real] - tpre;
|
array[l][real] = array[j][real] - tpre;
|
||||||
array[l][imag] = array[j][imag] - tpim;
|
array[l][imag] = array[j][imag] - tpim;
|
||||||
array[j][real] += tpre;
|
array[j][real] += tpre;
|
||||||
|
|
|
||||||
45
flash.c
45
flash.c
|
|
@ -64,6 +64,7 @@ void flash_unlock(void)
|
||||||
FLASH->KEYR = 0xCDEF89AB;
|
FLASH->KEYR = 0xCDEF89AB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
checksum(const void *start, size_t len)
|
checksum(const void *start, size_t len)
|
||||||
{
|
{
|
||||||
|
|
@ -71,14 +72,14 @@ checksum(const void *start, size_t len)
|
||||||
uint32_t *tail = (uint32_t*)(start + len);
|
uint32_t *tail = (uint32_t*)(start + len);
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
while (p < tail)
|
while (p < tail)
|
||||||
value = __ROR(value, 31) + *p++;
|
value ^= *p++;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define FLASH_PAGESIZE 0x800
|
#define FLASH_PAGESIZE 0x800
|
||||||
|
|
||||||
const uint32_t save_config_area = SAVE_CONFIG_ADDR;
|
const uint32_t save_config_area = 0x08018000;
|
||||||
|
|
||||||
int
|
int
|
||||||
config_save(void)
|
config_save(void)
|
||||||
|
|
@ -88,7 +89,8 @@ config_save(void)
|
||||||
int count = sizeof(config_t) / sizeof(uint16_t);
|
int count = sizeof(config_t) / sizeof(uint16_t);
|
||||||
|
|
||||||
config.magic = CONFIG_MAGIC;
|
config.magic = CONFIG_MAGIC;
|
||||||
config.checksum = checksum(&config, sizeof config - sizeof config.checksum);
|
config.checksum = 0;
|
||||||
|
config.checksum = checksum(&config, sizeof config);
|
||||||
|
|
||||||
flash_unlock();
|
flash_unlock();
|
||||||
|
|
||||||
|
|
@ -96,7 +98,7 @@ config_save(void)
|
||||||
flash_erase_page((uint32_t)dst);
|
flash_erase_page((uint32_t)dst);
|
||||||
|
|
||||||
/* write to flahs */
|
/* write to flahs */
|
||||||
while (count-- > 0) {
|
while(count-- > 0) {
|
||||||
flash_program_half_word((uint32_t)dst, *src++);
|
flash_program_half_word((uint32_t)dst, *src++);
|
||||||
dst++;
|
dst++;
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +114,7 @@ config_recall(void)
|
||||||
|
|
||||||
if (src->magic != CONFIG_MAGIC)
|
if (src->magic != CONFIG_MAGIC)
|
||||||
return -1;
|
return -1;
|
||||||
if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum)
|
if (checksum(src, sizeof(config_t)) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* duplicated saved data onto sram to be able to modify marker/trace */
|
/* duplicated saved data onto sram to be able to modify marker/trace */
|
||||||
|
|
@ -120,15 +122,14 @@ config_recall(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t saveareas[SAVEAREA_MAX] = {
|
#define SAVEAREA_MAX 5
|
||||||
SAVE_PROP_CONFIG_0_ADDR,
|
|
||||||
SAVE_PROP_CONFIG_1_ADDR,
|
const uint32_t saveareas[] =
|
||||||
SAVE_PROP_CONFIG_2_ADDR,
|
{ 0x08018800, 0x0801a000, 0x0801b800, 0x0801d000, 0x0801e800 };
|
||||||
SAVE_PROP_CONFIG_3_ADDR,
|
|
||||||
SAVE_PROP_CONFIG_4_ADDR };
|
|
||||||
|
|
||||||
int16_t lastsaveid = 0;
|
int16_t lastsaveid = 0;
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
caldata_save(int id)
|
caldata_save(int id)
|
||||||
{
|
{
|
||||||
|
|
@ -141,8 +142,8 @@ caldata_save(int id)
|
||||||
dst = (uint16_t*)saveareas[id];
|
dst = (uint16_t*)saveareas[id];
|
||||||
|
|
||||||
current_props.magic = CONFIG_MAGIC;
|
current_props.magic = CONFIG_MAGIC;
|
||||||
current_props.checksum = checksum(
|
current_props.checksum = 0;
|
||||||
¤t_props, sizeof current_props - sizeof current_props.checksum);
|
current_props.checksum = checksum(¤t_props, sizeof current_props);
|
||||||
|
|
||||||
flash_unlock();
|
flash_unlock();
|
||||||
|
|
||||||
|
|
@ -155,7 +156,7 @@ caldata_save(int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write to flahs */
|
/* write to flahs */
|
||||||
while (count-- > 0) {
|
while(count-- > 0) {
|
||||||
flash_program_half_word((uint32_t)dst, *src++);
|
flash_program_half_word((uint32_t)dst, *src++);
|
||||||
dst++;
|
dst++;
|
||||||
}
|
}
|
||||||
|
|
@ -174,15 +175,15 @@ caldata_recall(int id)
|
||||||
void *dst = ¤t_props;
|
void *dst = ¤t_props;
|
||||||
|
|
||||||
if (id < 0 || id >= SAVEAREA_MAX)
|
if (id < 0 || id >= SAVEAREA_MAX)
|
||||||
goto load_default;
|
return -1;
|
||||||
|
|
||||||
// point to saved area on the flash memory
|
// point to saved area on the flash memory
|
||||||
src = (properties_t*)saveareas[id];
|
src = (properties_t*)saveareas[id];
|
||||||
|
|
||||||
if (src->magic != CONFIG_MAGIC)
|
if (src->magic != CONFIG_MAGIC)
|
||||||
goto load_default;
|
return -1;
|
||||||
if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum)
|
if (checksum(src, sizeof(properties_t)) != 0)
|
||||||
goto load_default;
|
return -1;
|
||||||
|
|
||||||
/* active configuration points to save data on flash memory */
|
/* active configuration points to save data on flash memory */
|
||||||
active_props = src;
|
active_props = src;
|
||||||
|
|
@ -190,10 +191,8 @@ caldata_recall(int id)
|
||||||
|
|
||||||
/* duplicated saved data onto sram to be able to modify marker/trace */
|
/* duplicated saved data onto sram to be able to modify marker/trace */
|
||||||
memcpy(dst, src, sizeof(properties_t));
|
memcpy(dst, src, sizeof(properties_t));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
load_default:
|
|
||||||
load_default_properties();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const properties_t *
|
const properties_t *
|
||||||
|
|
@ -206,12 +205,12 @@ caldata_ref(int id)
|
||||||
|
|
||||||
if (src->magic != CONFIG_MAGIC)
|
if (src->magic != CONFIG_MAGIC)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum)
|
if (checksum(src, sizeof(properties_t)) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t save_config_prop_area_size = SAVE_CONFIG_AREA_SIZE;
|
const uint32_t save_config_prop_area_size = 0x8000;
|
||||||
|
|
||||||
void
|
void
|
||||||
clear_all_config_prop_data(void)
|
clear_all_config_prop_data(void)
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@
|
||||||
* @brief Enables the RTC subsystem.
|
* @brief Enables the RTC subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||||
#define HAL_USE_RTC FALSE
|
#define HAL_USE_RTC TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -132,7 +132,7 @@
|
||||||
* @brief Enables the SERIAL subsystem.
|
* @brief Enables the SERIAL subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
||||||
#define HAL_USE_SERIAL FALSE
|
#define HAL_USE_SERIAL TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
825
ili9341.c
825
ili9341.c
|
|
@ -21,120 +21,6 @@
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "nanovna.h"
|
#include "nanovna.h"
|
||||||
|
|
||||||
uint16_t spi_buffer[SPI_BUFFER_SIZE];
|
|
||||||
// Default foreground & background colors
|
|
||||||
uint16_t foreground_color = 0;
|
|
||||||
uint16_t background_color = 0;
|
|
||||||
|
|
||||||
// Display width and height definition
|
|
||||||
#define ILI9341_WIDTH 320
|
|
||||||
#define ILI9341_HEIGHT 240
|
|
||||||
|
|
||||||
// Display commands list
|
|
||||||
#define ILI9341_NOP 0x00
|
|
||||||
#define ILI9341_SOFTWARE_RESET 0x01
|
|
||||||
#define ILI9341_READ_IDENTIFICATION 0x04
|
|
||||||
#define ILI9341_READ_STATUS 0x09
|
|
||||||
#define ILI9341_READ_POWER_MODE 0x0A
|
|
||||||
#define ILI9341_READ_MADCTL 0x0B
|
|
||||||
#define ILI9341_READ_PIXEL_FORMAT 0x0C
|
|
||||||
#define ILI9341_READ_IMAGE_FORMAT 0x0D
|
|
||||||
#define ILI9341_READ_SIGNAL_MODE 0x0E
|
|
||||||
#define ILI9341_READ_SELF_DIAGNOSTIC 0x0F
|
|
||||||
#define ILI9341_SLEEP_IN 0x10
|
|
||||||
#define ILI9341_SLEEP_OUT 0x11
|
|
||||||
#define ILI9341_PARTIAL_MODE_ON 0x12
|
|
||||||
#define ILI9341_NORMAL_DISPLAY_MODE_ON 0x13
|
|
||||||
#define ILI9341_INVERSION_OFF 0x20
|
|
||||||
#define ILI9341_INVERSION_ON 0x21
|
|
||||||
#define ILI9341_GAMMA_SET 0x26
|
|
||||||
#define ILI9341_DISPLAY_OFF 0x28
|
|
||||||
#define ILI9341_DISPLAY_ON 0x29
|
|
||||||
#define ILI9341_COLUMN_ADDRESS_SET 0x2A
|
|
||||||
#define ILI9341_PAGE_ADDRESS_SET 0x2B
|
|
||||||
#define ILI9341_MEMORY_WRITE 0x2C
|
|
||||||
#define ILI9341_COLOR_SET 0x2D
|
|
||||||
#define ILI9341_MEMORY_READ 0x2E
|
|
||||||
#define ILI9341_PARTIAL_AREA 0x30
|
|
||||||
#define ILI9341_VERTICAL_SCROLLING_DEF 0x33
|
|
||||||
#define ILI9341_TEARING_LINE_OFF 0x34
|
|
||||||
#define ILI9341_TEARING_LINE_ON 0x35
|
|
||||||
#define ILI9341_MEMORY_ACCESS_CONTROL 0x36
|
|
||||||
#define ILI9341_VERTICAL_SCROLLING 0x37
|
|
||||||
#define ILI9341_IDLE_MODE_OFF 0x38
|
|
||||||
#define ILI9341_IDLE_MODE_ON 0x39
|
|
||||||
#define ILI9341_PIXEL_FORMAT_SET 0x3A
|
|
||||||
#define ILI9341_WRITE_MEMORY_CONTINUE 0x3C
|
|
||||||
#define ILI9341_READ_MEMORY_CONTINUE 0x3E
|
|
||||||
#define ILI9341_SET_TEAR_SCANLINE 0x44
|
|
||||||
#define ILI9341_GET_SCANLINE 0x45
|
|
||||||
#define ILI9341_WRITE_BRIGHTNESS 0x51
|
|
||||||
#define ILI9341_READ_BRIGHTNESS 0x52
|
|
||||||
#define ILI9341_WRITE_CTRL_DISPLAY 0x53
|
|
||||||
#define ILI9341_READ_CTRL_DISPLAY 0x54
|
|
||||||
#define ILI9341_WRITE_CA_BRIGHTNESS 0x55
|
|
||||||
#define ILI9341_READ_CA_BRIGHTNESS 0x56
|
|
||||||
#define ILI9341_WRITE_CA_MIN_BRIGHTNESS 0x5E
|
|
||||||
#define ILI9341_READ_CA_MIN_BRIGHTNESS 0x5F
|
|
||||||
#define ILI9341_READ_ID1 0xDA
|
|
||||||
#define ILI9341_READ_ID2 0xDB
|
|
||||||
#define ILI9341_READ_ID3 0xDC
|
|
||||||
#define ILI9341_RGB_INTERFACE_CONTROL 0xB0
|
|
||||||
#define ILI9341_FRAME_RATE_CONTROL_1 0xB1
|
|
||||||
#define ILI9341_FRAME_RATE_CONTROL_2 0xB2
|
|
||||||
#define ILI9341_FRAME_RATE_CONTROL_3 0xB3
|
|
||||||
#define ILI9341_DISPLAY_INVERSION_CONTROL 0xB4
|
|
||||||
#define ILI9341_BLANKING_PORCH_CONTROL 0xB5
|
|
||||||
#define ILI9341_DISPLAY_FUNCTION_CONTROL 0xB6
|
|
||||||
#define ILI9341_ENTRY_MODE_SET 0xB7
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_1 0xB8
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_2 0xB9
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_3 0xBA
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_4 0xBB
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_5 0xBC
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_7 0xBE
|
|
||||||
#define ILI9341_BACKLIGHT_CONTROL_8 0xBF
|
|
||||||
#define ILI9341_POWER_CONTROL_1 0xC0
|
|
||||||
#define ILI9341_POWER_CONTROL_2 0xC1
|
|
||||||
#define ILI9341_VCOM_CONTROL_1 0xC5
|
|
||||||
#define ILI9341_VCOM_CONTROL_2 0xC7
|
|
||||||
#define ILI9341_POWERA 0xCB
|
|
||||||
#define ILI9341_POWERB 0xCF
|
|
||||||
#define ILI9341_NV_MEMORY_WRITE 0xD0
|
|
||||||
#define ILI9341_NV_PROTECTION_KEY 0xD1
|
|
||||||
#define ILI9341_NV_STATUS_READ 0xD2
|
|
||||||
#define ILI9341_READ_ID4 0xD3
|
|
||||||
#define ILI9341_POSITIVE_GAMMA_CORRECTION 0xE0
|
|
||||||
#define ILI9341_NEGATIVE_GAMMA_CORRECTION 0xE1
|
|
||||||
#define ILI9341_DIGITAL_GAMMA_CONTROL_1 0xE2
|
|
||||||
#define ILI9341_DIGITAL_GAMMA_CONTROL_2 0xE3
|
|
||||||
#define ILI9341_DTCA 0xE8
|
|
||||||
#define ILI9341_DTCB 0xEA
|
|
||||||
#define ILI9341_POWER_SEQ 0xED
|
|
||||||
#define ILI9341_3GAMMA_EN 0xF2
|
|
||||||
#define ILI9341_INTERFACE_CONTROL 0xF6
|
|
||||||
#define ILI9341_PUMP_RATIO_CONTROL 0xF7
|
|
||||||
|
|
||||||
//
|
|
||||||
// ILI9341_MEMORY_ACCESS_CONTROL registers
|
|
||||||
//
|
|
||||||
#define ILI9341_MADCTL_MY 0x80
|
|
||||||
#define ILI9341_MADCTL_MX 0x40
|
|
||||||
#define ILI9341_MADCTL_MV 0x20
|
|
||||||
#define ILI9341_MADCTL_ML 0x10
|
|
||||||
#define ILI9341_MADCTL_BGR 0x08
|
|
||||||
#define ILI9341_MADCTL_MH 0x04
|
|
||||||
#define ILI9341_MADCTL_RGB 0x00
|
|
||||||
|
|
||||||
#define DISPLAY_ROTATION_270 (ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR)
|
|
||||||
#define DISPLAY_ROTATION_90 (ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR)
|
|
||||||
#define DISPLAY_ROTATION_0 (ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR)
|
|
||||||
#define DISPLAY_ROTATION_180 (ILI9341_MADCTL_MX | ILI9341_MADCTL_MY \
|
|
||||||
| ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Pin macros
|
|
||||||
//
|
|
||||||
#define RESET_ASSERT palClearPad(GPIOA, 15)
|
#define RESET_ASSERT palClearPad(GPIOA, 15)
|
||||||
#define RESET_NEGATE palSetPad(GPIOA, 15)
|
#define RESET_NEGATE palSetPad(GPIOA, 15)
|
||||||
#define CS_LOW palClearPad(GPIOB, 6)
|
#define CS_LOW palClearPad(GPIOB, 6)
|
||||||
|
|
@ -142,512 +28,380 @@ uint16_t background_color = 0;
|
||||||
#define DC_CMD palClearPad(GPIOB, 7)
|
#define DC_CMD palClearPad(GPIOB, 7)
|
||||||
#define DC_DATA palSetPad(GPIOB, 7)
|
#define DC_DATA palSetPad(GPIOB, 7)
|
||||||
|
|
||||||
//*****************************************************************************
|
uint16_t spi_buffer[1024];
|
||||||
//********************************** SPI bus **********************************
|
|
||||||
//*****************************************************************************
|
|
||||||
// STM32 SPI transfer mode:
|
|
||||||
// in 8 bit mode:
|
|
||||||
// if you write *(uint8_t*)(&SPI1->DR) = (uint8_t) data, then data send as << data
|
|
||||||
// if you write *(uint16_t*)(&SPI1->DR) =(uint16_t) data, then data send as << dataLoByte, after send dataHiByte
|
|
||||||
// in 16 bit mode
|
|
||||||
// if you write *(uint16_t*)(&SPI1->DR) =(uint16_t) data, then data send as << data
|
|
||||||
|
|
||||||
// SPI init in 8 bit mode
|
void
|
||||||
#define SPI_CR2_8BIT 0x0700
|
ssp_wait(void)
|
||||||
#define SPI_CR2_16BIT 0x0F00
|
|
||||||
|
|
||||||
// SPI bus activity macros
|
|
||||||
|
|
||||||
// The RXNE flag is set depending on the FRXTH bit value in the SPIx_CR2 register:
|
|
||||||
// • If FRXTH is set, RXNE goes high and stays high until the RXFIFO level is greater or equal to 1/4 (8-bit).
|
|
||||||
#define SPI_RX_IS_NOT_EMPTY (SPI1->SR&SPI_SR_RXNE)
|
|
||||||
#define SPI_RX_IS_EMPTY (((SPI1->SR&SPI_SR_RXNE) == 0))
|
|
||||||
|
|
||||||
// The TXE flag is set when transmission TXFIFO has enough space to store data to send.
|
|
||||||
// 0: Tx buffer not empty, bit is cleared automatically when the TXFIFO level becomes greater than 1/2
|
|
||||||
// 1: Tx buffer empty, flag goes high and stays high until the TXFIFO level is lower or equal to 1/2 of the FIFO depth
|
|
||||||
#define SPI_TX_IS_NOT_EMPTY (((SPI1->SR&(SPI_SR_TXE)) == 0))
|
|
||||||
#define SPI_TX_IS_EMPTY (SPI1->SR&SPI_SR_TXE)
|
|
||||||
|
|
||||||
// When BSY is set, it indicates that a data transfer is in progress on the SPI (the SPI bus is busy).
|
|
||||||
#define SPI_IS_BUSY (SPI1->SR & SPI_SR_BSY)
|
|
||||||
|
|
||||||
// SPI send data macros
|
|
||||||
#define SPI_WRITE_8BIT(data) *(__IO uint8_t*)(&SPI1->DR) = (uint8_t) data
|
|
||||||
#define SPI_WRITE_16BIT(data) SPI1->DR = data
|
|
||||||
|
|
||||||
// SPI read data macros
|
|
||||||
#define SPI_READ_DATA SPI1->DR
|
|
||||||
|
|
||||||
#ifdef __USE_DISPLAY_DMA__
|
|
||||||
static const stm32_dma_stream_t *dmatx =
|
|
||||||
STM32_DMA_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM);
|
|
||||||
static uint32_t txdmamode =
|
|
||||||
STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) // Select SPI1 Tx DMA
|
|
||||||
| STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) // Set priority
|
|
||||||
| STM32_DMA_CR_DIR_M2P // Memory to Spi
|
|
||||||
| STM32_DMA_CR_DMEIE //
|
|
||||||
| STM32_DMA_CR_TEIE;
|
|
||||||
|
|
||||||
static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags)
|
|
||||||
{
|
{
|
||||||
|
while (SPI1->SR & SPI_SR_BSY)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ssp_wait_slot(void)
|
||||||
|
{
|
||||||
|
while ((SPI1->SR & 0x1800) == 0x1800)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ssp_senddata(uint8_t x)
|
||||||
|
{
|
||||||
|
*(uint8_t*)(&SPI1->DR) = x;
|
||||||
|
while (SPI1->SR & SPI_SR_BSY)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
ssp_sendrecvdata(uint8_t x)
|
||||||
|
{
|
||||||
|
while (!(SPI1->SR & SPI_SR_TXE));
|
||||||
|
// clear OVR
|
||||||
|
while (SPI1->SR & SPI_SR_RXNE) (void)SPI1->DR;
|
||||||
|
|
||||||
|
*(uint8_t*)(&SPI1->DR) = x;
|
||||||
|
while (!(SPI1->SR & SPI_SR_RXNE));
|
||||||
|
return SPI1->DR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ssp_senddata16(uint16_t x)
|
||||||
|
{
|
||||||
|
ssp_wait_slot();
|
||||||
|
SPI1->DR = x;
|
||||||
|
//while (SPI1->SR & SPI_SR_BSY)
|
||||||
|
// ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ssp_databit8(void)
|
||||||
|
{
|
||||||
|
SPI1->CR2 = (SPI1->CR2 & 0xf0ff) | 0x0700;
|
||||||
|
//LPC_SSP1->CR0 = (LPC_SSP1->CR0 & 0xf0) | SSP_DATABIT_8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ssp_databit16(void)
|
||||||
|
{
|
||||||
|
SPI1->CR2 = (SPI1->CR2 & 0xf0ff) | 0x0f00;
|
||||||
|
//LPC_SSP1->CR0 = (LPC_SSP1->CR0 & 0xf0) | SSP_DATABIT_16;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const stm32_dma_stream_t *dmatx;
|
||||||
|
uint32_t txdmamode;
|
||||||
|
|
||||||
|
static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
|
||||||
(void)spip;
|
(void)spip;
|
||||||
(void)flags;
|
(void)flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const stm32_dma_stream_t *dmarx = STM32_DMA_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM);
|
void
|
||||||
static uint32_t rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL)
|
spi_init(void)
|
||||||
| STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY)
|
|
||||||
| STM32_DMA_CR_DIR_P2M
|
|
||||||
| STM32_DMA_CR_TCIE
|
|
||||||
| STM32_DMA_CR_DMEIE
|
|
||||||
| STM32_DMA_CR_TEIE;
|
|
||||||
|
|
||||||
static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags)
|
|
||||||
{
|
|
||||||
(void)spip;
|
|
||||||
(void)flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dmaStreamFlush(uint32_t len)
|
|
||||||
{
|
|
||||||
while (len) {
|
|
||||||
// DMA data transfer limited by 65535
|
|
||||||
uint16_t tx_size = len > 65535 ? 65535 : len;
|
|
||||||
dmaStreamSetTransactionSize(dmatx, tx_size);
|
|
||||||
dmaStreamEnable(dmatx);
|
|
||||||
len -= tx_size;
|
|
||||||
dmaWaitCompletion(dmatx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void spi_init(void)
|
|
||||||
{
|
{
|
||||||
rccEnableSPI1(FALSE);
|
rccEnableSPI1(FALSE);
|
||||||
SPI1->CR1 = 0;
|
|
||||||
SPI1->CR1 = SPI_CR1_MSTR // SPI is MASTER
|
|
||||||
| SPI_CR1_SSM // Software slave management (The external NSS pin is free for other application uses)
|
|
||||||
| SPI_CR1_SSI; // Internal slave select (This bit has an effect only when the SSM bit is set. Allow use NSS pin as I/O)
|
|
||||||
// | SPI_CR1_BR_1; // Baud rate control
|
|
||||||
|
|
||||||
SPI1->CR2 = SPI_CR2_8BIT // SPI data size, set to 8 bit
|
dmatx = STM32_DMA_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM);
|
||||||
| SPI_CR2_FRXTH; // SPI_SR_RXNE generated every 8 bit data
|
txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) |
|
||||||
// | SPI_CR2_SSOE; //
|
STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
|
||||||
|
STM32_DMA_CR_DIR_M2P |
|
||||||
#ifdef __USE_DISPLAY_DMA__
|
STM32_DMA_CR_DMEIE |
|
||||||
// Tx DMA init
|
STM32_DMA_CR_TEIE |
|
||||||
dmaStreamAllocate(dmatx, STM32_SPI_SPI1_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, NULL);
|
STM32_DMA_CR_PSIZE_HWORD |
|
||||||
|
STM32_DMA_CR_MSIZE_HWORD;
|
||||||
|
dmaStreamAllocate(dmatx,
|
||||||
|
STM32_SPI_SPI1_IRQ_PRIORITY,
|
||||||
|
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||||
|
NULL);
|
||||||
dmaStreamSetPeripheral(dmatx, &SPI1->DR);
|
dmaStreamSetPeripheral(dmatx, &SPI1->DR);
|
||||||
// Rx DMA init
|
|
||||||
dmaStreamAllocate(dmarx, STM32_SPI_SPI1_IRQ_PRIORITY, (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, NULL);
|
SPI1->CR1 = 0;
|
||||||
dmaStreamSetPeripheral(dmarx, &SPI1->DR);
|
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;// | SPI_CR1_BR_1;
|
||||||
// Enable DMA on SPI
|
SPI1->CR2 = 0x0700 | SPI_CR2_TXDMAEN | SPI_CR2_FRXTH;
|
||||||
SPI1->CR2|= SPI_CR2_TXDMAEN // Tx DMA enable
|
SPI1->CR1 |= SPI_CR1_SPE;
|
||||||
| SPI_CR2_RXDMAEN; // Rx DMA enable
|
|
||||||
#endif
|
|
||||||
SPI1->CR1|= SPI_CR1_SPE; //SPI enable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable inline for this function
|
void
|
||||||
static void __attribute__ ((noinline)) send_command(uint8_t cmd, uint8_t len, const uint8_t *data)
|
send_command(uint8_t cmd, int len, const uint8_t *data)
|
||||||
{
|
{
|
||||||
CS_LOW;
|
CS_LOW;
|
||||||
//while (SPI_TX_IS_NOT_EMPTY);
|
|
||||||
DC_CMD;
|
DC_CMD;
|
||||||
SPI_WRITE_8BIT(cmd);
|
ssp_databit8();
|
||||||
// Need wait transfer complete and set data bit
|
ssp_senddata(cmd);
|
||||||
while (SPI_IS_BUSY)
|
|
||||||
;
|
|
||||||
// Send command data (if need)
|
|
||||||
DC_DATA;
|
DC_DATA;
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
while (SPI_TX_IS_NOT_EMPTY)
|
ssp_senddata(*data++);
|
||||||
;
|
|
||||||
SPI_WRITE_8BIT(*data++);
|
|
||||||
}
|
}
|
||||||
//CS_HIGH;
|
//CS_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t ili9341_init_seq[] = {
|
void
|
||||||
|
send_command16(uint8_t cmd, int data)
|
||||||
|
{
|
||||||
|
CS_LOW;
|
||||||
|
DC_CMD;
|
||||||
|
ssp_databit8();
|
||||||
|
ssp_senddata(cmd);
|
||||||
|
DC_DATA;
|
||||||
|
ssp_databit16();
|
||||||
|
ssp_senddata16(data);
|
||||||
|
CS_HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t ili9341_init_seq[] = {
|
||||||
// cmd, len, data...,
|
// cmd, len, data...,
|
||||||
// SW reset
|
|
||||||
ILI9341_SOFTWARE_RESET, 0,
|
|
||||||
// display off
|
|
||||||
ILI9341_DISPLAY_OFF, 0,
|
|
||||||
// Power control B
|
// Power control B
|
||||||
ILI9341_POWERB, 3, 0x00, 0x83, 0x30,
|
0xCF, 3, 0x00, 0x83, 0x30,
|
||||||
// Power on sequence control
|
// Power on sequence control
|
||||||
ILI9341_POWER_SEQ, 4, 0x64, 0x03, 0x12, 0x81,
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
||||||
//ILI9341_POWER_SEQ, 4, 0x55, 0x01, 0x23, 0x01,
|
//0xED, 4, 0x55, 0x01, 0x23, 0x01,
|
||||||
// Driver timing control A
|
// Driver timing control A
|
||||||
ILI9341_DTCA, 3, 0x85, 0x01, 0x79,
|
0xE8, 3, 0x85, 0x01, 0x79,
|
||||||
//ILI9341_DTCA, 3, 0x84, 0x11, 0x7a,
|
//0xE8, 3, 0x84, 0x11, 0x7a,
|
||||||
// Power control A
|
// Power control A
|
||||||
ILI9341_POWERA, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||||
// Pump ratio control
|
// Pump ratio control
|
||||||
ILI9341_PUMP_RATIO_CONTROL, 1, 0x20,
|
0xF7, 1, 0x20,
|
||||||
// Driver timing control B
|
// Driver timing control B
|
||||||
ILI9341_DTCB, 2, 0x00, 0x00,
|
0xEA, 2, 0x00, 0x00,
|
||||||
// POWER_CONTROL_1
|
// POWER_CONTROL_1
|
||||||
ILI9341_POWER_CONTROL_1, 1, 0x26,
|
0xC0, 1, 0x26,
|
||||||
// POWER_CONTROL_2
|
// POWER_CONTROL_2
|
||||||
ILI9341_POWER_CONTROL_2, 1, 0x11,
|
0xC1, 1, 0x11,
|
||||||
// VCOM_CONTROL_1
|
// VCOM_CONTROL_1
|
||||||
ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E,
|
0xC5, 2, 0x35, 0x3E,
|
||||||
// VCOM_CONTROL_2
|
// VCOM_CONTROL_2
|
||||||
ILI9341_VCOM_CONTROL_2, 1, 0xBE,
|
0xC7, 1, 0xBE,
|
||||||
// MEMORY_ACCESS_CONTROL
|
// MEMORY_ACCESS_CONTROL
|
||||||
//ILI9341_MEMORY_ACCESS_CONTROL, 1, 0x48, // portlait
|
//0x36, 1, 0x48, // portlait
|
||||||
ILI9341_MEMORY_ACCESS_CONTROL, 1, DISPLAY_ROTATION_0, // landscape
|
0x36, 1, 0x28, // landscape
|
||||||
// COLMOD_PIXEL_FORMAT_SET : 16 bit pixel
|
// COLMOD_PIXEL_FORMAT_SET : 16 bit pixel
|
||||||
ILI9341_PIXEL_FORMAT_SET, 1, 0x55,
|
0x3A, 1, 0x55,
|
||||||
// Frame Rate
|
// Frame Rate
|
||||||
ILI9341_FRAME_RATE_CONTROL_1, 2, 0x00, 0x1B,
|
0xB1, 2, 0x00, 0x1B,
|
||||||
// Gamma Function Disable
|
// Gamma Function Disable
|
||||||
ILI9341_3GAMMA_EN, 1, 0x08,
|
0xF2, 1, 0x08,
|
||||||
// gamma set for curve 01/2/04/08
|
// gamma set for curve 01/2/04/08
|
||||||
ILI9341_GAMMA_SET, 1, 0x01,
|
0x26, 1, 0x01,
|
||||||
// positive gamma correction
|
// positive gamma correction
|
||||||
//ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00,
|
0xE0, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00,
|
||||||
// negativ gamma correction
|
// negativ gamma correction
|
||||||
//ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F,
|
0xE1, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F,
|
||||||
|
|
||||||
// Column Address Set
|
// Column Address Set
|
||||||
//ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
|
0x2A, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
|
||||||
// Page Address Set
|
// Page Address Set
|
||||||
//ILI9341_PAGE_ADDRESS_SET, 4, 0x00, 0x00, 0x00, 0xef, // height 240
|
0x2B, 4, 0x00, 0x00, 0x00, 0xef, // height 240
|
||||||
|
|
||||||
// entry mode
|
// entry mode
|
||||||
ILI9341_ENTRY_MODE_SET, 1, 0x06,
|
0xB7, 1, 0x06,
|
||||||
// display function control
|
// display function control
|
||||||
ILI9341_DISPLAY_FUNCTION_CONTROL, 4, 0x0A, 0x82, 0x27, 0x00,
|
0xB6, 4, 0x0A, 0x82, 0x27, 0x00,
|
||||||
// Interface Control (set WEMODE=0)
|
|
||||||
ILI9341_INTERFACE_CONTROL, 3, 0x00, 0x00, 0x00,
|
|
||||||
// control display
|
// control display
|
||||||
//ILI9341_WRITE_CTRL_DISPLAY, 1, 0x0c,
|
//0x53, 1, 0x0c,
|
||||||
// diaplay brightness
|
// diaplay brightness
|
||||||
//ILI9341_WRITE_BRIGHTNESS, 1, 0xff,
|
//0x51, 1, 0xff,
|
||||||
|
|
||||||
// sleep out
|
// sleep out
|
||||||
ILI9341_SLEEP_OUT, 0,
|
0x11, 0,
|
||||||
// display on
|
|
||||||
ILI9341_DISPLAY_ON, 0,
|
|
||||||
0 // sentinel
|
0 // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
void ili9341_init(void)
|
void
|
||||||
|
ili9341_init(void)
|
||||||
{
|
{
|
||||||
spi_init();
|
spi_init();
|
||||||
|
|
||||||
DC_DATA;
|
DC_DATA;
|
||||||
RESET_ASSERT;
|
RESET_ASSERT;
|
||||||
chThdSleepMilliseconds(10);
|
chThdSleepMilliseconds(10);
|
||||||
RESET_NEGATE;
|
RESET_NEGATE;
|
||||||
|
|
||||||
|
send_command(0x01, 0, NULL); // SW reset
|
||||||
|
chThdSleepMilliseconds(5);
|
||||||
|
send_command(0x28, 0, NULL); // display off
|
||||||
|
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
for (p = ili9341_init_seq; *p; ) {
|
for (p = ili9341_init_seq; *p; ) {
|
||||||
send_command(p[0], p[1], &p[2]);
|
send_command(p[0], p[1], &p[2]);
|
||||||
p += 2 + p[1];
|
p += 2 + p[1];
|
||||||
chThdSleepMilliseconds(5);
|
chThdSleepMilliseconds(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chThdSleepMilliseconds(100);
|
||||||
|
send_command(0x29, 0, NULL); // display on
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __USE_DISPLAY_DMA__
|
void ili9341_pixel(int x, int y, int color)
|
||||||
|
{
|
||||||
|
uint8_t xx[4] = { x >> 8, x, (x+1) >> 8, (x+1) };
|
||||||
|
uint8_t yy[4] = { y >> 8, y, (y+1) >> 8, (y+1) };
|
||||||
|
uint8_t cc[2] = { color >> 8, color };
|
||||||
|
send_command(0x2A, 4, xx);
|
||||||
|
send_command(0x2B, 4, yy);
|
||||||
|
send_command(0x2C, 2, cc);
|
||||||
|
//send_command16(0x2C, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ili9341_fill(int x, int y, int w, int h, int color)
|
void ili9341_fill(int x, int y, int w, int h, int color)
|
||||||
{
|
{
|
||||||
//uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
|
uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
|
||||||
//uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
|
uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
|
||||||
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
|
int len = w * h;
|
||||||
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
|
send_command(0x2A, 4, xx);
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx);
|
send_command(0x2B, 4, yy);
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy);
|
send_command(0x2C, 0, NULL);
|
||||||
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
while (len-- > 0)
|
||||||
int32_t len = w * h;
|
ssp_senddata16(color);
|
||||||
while (len-- > 0) {
|
|
||||||
while (SPI_TX_IS_NOT_EMPTY)
|
|
||||||
;
|
|
||||||
SPI_WRITE_16BIT(color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void ili9341_bulk(int x, int y, int w, int h)
|
void ili9341_bulk(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
// uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
|
uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
|
||||||
// uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
|
uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
|
||||||
uint16_t *buf = spi_buffer;
|
uint16_t *buf = spi_buffer;
|
||||||
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
|
int len = w * h;
|
||||||
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
|
send_command(0x2A, 4, xx);
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx);
|
send_command(0x2B, 4, yy);
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy);
|
send_command(0x2C, 0, NULL);
|
||||||
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
while (len-- > 0)
|
||||||
int32_t len = w * h;
|
ssp_senddata16(*buf++);
|
||||||
while (len-- > 0) {
|
|
||||||
while (SPI_TX_IS_NOT_EMPTY)
|
|
||||||
;
|
|
||||||
SPI_WRITE_16BIT(*buf++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t ssp_sendrecvdata(void)
|
|
||||||
{
|
|
||||||
// Start RX clock (by sending data)
|
|
||||||
SPI_WRITE_8BIT(0);
|
|
||||||
while (SPI_RX_IS_EMPTY && SPI_IS_BUSY)
|
|
||||||
;
|
|
||||||
return SPI_READ_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
#else
|
||||||
//
|
|
||||||
// Use DMA for send data
|
|
||||||
//
|
|
||||||
|
|
||||||
// Fill region by some color
|
|
||||||
void ili9341_fill(int x, int y, int w, int h, int color)
|
|
||||||
{
|
|
||||||
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
|
|
||||||
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
|
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx);
|
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
|
|
||||||
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
||||||
|
|
||||||
dmaStreamSetMemory0(dmatx, &color);
|
|
||||||
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD);
|
|
||||||
dmaStreamFlush(w * h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ili9341_bulk_8bit(int x, int y, int w, int h, uint16_t *palette)
|
|
||||||
{
|
|
||||||
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
|
|
||||||
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
|
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx);
|
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
|
|
||||||
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
||||||
|
|
||||||
uint8_t *buf = (uint8_t *)spi_buffer;
|
|
||||||
int32_t len = w * h;
|
|
||||||
while (len-- > 0) {
|
|
||||||
uint16_t color = palette[*buf++];
|
|
||||||
while (SPI_TX_IS_NOT_EMPTY)
|
|
||||||
;
|
|
||||||
SPI_WRITE_16BIT(color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy spi_buffer to region
|
|
||||||
void ili9341_bulk(int x, int y, int w, int h)
|
void ili9341_bulk(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
|
uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
|
||||||
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
|
uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx);
|
int len = w * h;
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
|
|
||||||
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
send_command(0x2A, 4, xx);
|
||||||
|
send_command(0x2B, 4, yy);
|
||||||
|
send_command(0x2C, 0, NULL);
|
||||||
|
|
||||||
// Init Tx DMA mem->spi, set size, mode (spi and mem data size is 16 bit)
|
|
||||||
dmaStreamSetMemory0(dmatx, spi_buffer);
|
dmaStreamSetMemory0(dmatx, spi_buffer);
|
||||||
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD |
|
dmaStreamSetTransactionSize(dmatx, len);
|
||||||
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC);
|
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_MINC);
|
||||||
dmaStreamFlush(w * h);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy screen data to buffer
|
|
||||||
// Warning!!! buffer size must be greater then 3*len + 1 bytes
|
|
||||||
void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out)
|
|
||||||
{
|
|
||||||
uint8_t dummy_tx = 0;
|
|
||||||
uint8_t *rgbbuf = (uint8_t *)out;
|
|
||||||
uint16_t data_size = len * 3 + 1;
|
|
||||||
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
|
|
||||||
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
|
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx);
|
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
|
|
||||||
send_command(ILI9341_MEMORY_READ, 0, NULL);
|
|
||||||
// Skip SPI rx buffer
|
|
||||||
while (SPI_RX_IS_NOT_EMPTY) (void)SPI_READ_DATA;
|
|
||||||
// Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit)
|
|
||||||
dmaStreamSetMemory0(dmarx, rgbbuf);
|
|
||||||
dmaStreamSetTransactionSize(dmarx, data_size);
|
|
||||||
dmaStreamSetMode(dmarx, rxdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
|
||||||
STM32_DMA_CR_MINC);
|
|
||||||
// Init dummy Tx DMA (for rx clock), size, mode (spi and mem data size is 8 bit)
|
|
||||||
dmaStreamSetMemory0(dmatx, &dummy_tx);
|
|
||||||
dmaStreamSetTransactionSize(dmatx, data_size);
|
|
||||||
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE);
|
|
||||||
|
|
||||||
// Start DMA exchange
|
|
||||||
dmaStreamEnable(dmatx);
|
dmaStreamEnable(dmatx);
|
||||||
dmaStreamEnable(dmarx);
|
|
||||||
// Wait DMA completion
|
|
||||||
dmaWaitCompletion(dmatx);
|
dmaWaitCompletion(dmatx);
|
||||||
dmaWaitCompletion(dmarx);
|
|
||||||
CS_HIGH;
|
|
||||||
|
|
||||||
// Parce recived data
|
|
||||||
// Skip dummy 8-bit read
|
|
||||||
rgbbuf++;
|
|
||||||
while (len-- > 0) {
|
|
||||||
uint8_t r, g, b;
|
|
||||||
// read data is always 18bit
|
|
||||||
r = rgbbuf[0];
|
|
||||||
g = rgbbuf[1];
|
|
||||||
b = rgbbuf[2];
|
|
||||||
*out++ = RGB565(r, g, b);
|
|
||||||
rgbbuf += 3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ili9341_clear_screen(void)
|
void
|
||||||
|
ili9341_read_memory_raw(uint8_t cmd, int len, uint16_t* out)
|
||||||
{
|
{
|
||||||
ili9341_fill(0, 0, ILI9341_WIDTH, ILI9341_HEIGHT, background_color);
|
uint8_t r, g, b;
|
||||||
|
send_command(cmd, 0, NULL);
|
||||||
|
ssp_databit8();
|
||||||
|
|
||||||
|
// consume old data
|
||||||
|
while (!(SPI1->SR & SPI_SR_TXE));
|
||||||
|
// clear OVR
|
||||||
|
while (SPI1->SR & SPI_SR_RXNE) r = SPI1->DR;
|
||||||
|
|
||||||
|
// require 8bit dummy clock
|
||||||
|
r = ssp_sendrecvdata(0);
|
||||||
|
|
||||||
|
while (len-- > 0) {
|
||||||
|
// read data is always 18bit
|
||||||
|
r = ssp_sendrecvdata(0);
|
||||||
|
g = ssp_sendrecvdata(0);
|
||||||
|
b = ssp_sendrecvdata(0);
|
||||||
|
*out++ = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
CS_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_set_foreground(uint16_t fg)
|
void
|
||||||
|
ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out)
|
||||||
{
|
{
|
||||||
foreground_color = fg;
|
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) };
|
||||||
|
|
||||||
|
send_command(0x2A, 4, xx);
|
||||||
|
send_command(0x2B, 4, yy);
|
||||||
|
|
||||||
|
ili9341_read_memory_raw(0x2E, len, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_set_background(uint16_t bg)
|
void
|
||||||
|
ili9341_read_memory_continue(int len, uint16_t* out)
|
||||||
{
|
{
|
||||||
background_color = bg;
|
ili9341_read_memory_raw(0x3E, len, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_set_rotation(uint8_t r)
|
void
|
||||||
{
|
ili9341_drawchar_5x7(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg)
|
||||||
// static const uint8_t rotation_const[]={DISPLAY_ROTATION_0, DISPLAY_ROTATION_90,
|
|
||||||
// DISPLAY_ROTATION_180, DISPLAY_ROTATION_270};
|
|
||||||
send_command(ILI9341_MEMORY_ACCESS_CONTROL, 1, &r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
|
||||||
const uint8_t *bitmap)
|
|
||||||
{
|
{
|
||||||
uint16_t *buf = spi_buffer;
|
uint16_t *buf = spi_buffer;
|
||||||
for (uint16_t c = 0; c < height; c++) {
|
uint8_t bits;
|
||||||
uint8_t bits = *bitmap++;
|
int c, r;
|
||||||
for (uint16_t r = 0; r < width; r++) {
|
for(c = 0; c < 7; c++) {
|
||||||
*buf++ = (0x80 & bits) ? foreground_color : background_color;
|
bits = x5x7_bits[(ch * 7) + c];
|
||||||
|
for (r = 0; r < 5; r++) {
|
||||||
|
*buf++ = (0x80 & bits) ? fg : bg;
|
||||||
bits <<= 1;
|
bits <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ili9341_bulk(x, y, width, height);
|
ili9341_bulk(x, y, 5, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
void
|
||||||
const uint16_t *bitmap)
|
ili9341_drawstring_5x7(const char *str, int x, int y, uint16_t fg, uint16_t bg)
|
||||||
{
|
|
||||||
uint16_t *buf = spi_buffer;
|
|
||||||
for (uint16_t c = 0; c < height; c++) {
|
|
||||||
uint16_t bits = *bitmap++;
|
|
||||||
for (uint16_t r = 0; r < width; r++) {
|
|
||||||
*buf++ = (0x8000 & bits) ? foreground_color : background_color;
|
|
||||||
bits <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ili9341_bulk(x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ili9341_drawchar(uint8_t ch, int x, int y)
|
|
||||||
{
|
|
||||||
blit8BitWidthBitmap(x, y, FONT_GET_WIDTH(ch), FONT_GET_HEIGHT, FONT_GET_DATA(ch));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ili9341_drawstring(const char *str, int x, int y)
|
|
||||||
{
|
{
|
||||||
while (*str) {
|
while (*str) {
|
||||||
uint8_t ch = *str++;
|
ili9341_drawchar_5x7(*str, x, y, fg, bg);
|
||||||
const uint8_t *char_buf = FONT_GET_DATA(ch);
|
x += 5;
|
||||||
uint16_t w = FONT_GET_WIDTH(ch);
|
str++;
|
||||||
blit8BitWidthBitmap(x, y, w, FONT_GET_HEIGHT, char_buf);
|
|
||||||
x += w;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_drawstringV(const char *str, int x, int y)
|
void
|
||||||
|
ili9341_drawstring_5x7_inv(const char *str, int x, int y, uint16_t fg, uint16_t bg, bool invert)
|
||||||
{
|
{
|
||||||
ili9341_set_rotation(DISPLAY_ROTATION_270);
|
if (invert)
|
||||||
ili9341_drawstring(str, ILI9341_HEIGHT-y, x);
|
ili9341_drawstring_5x7(str, x, y, bg, fg);
|
||||||
ili9341_set_rotation(DISPLAY_ROTATION_0);
|
else
|
||||||
|
ili9341_drawstring_5x7(str, x, y, fg, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size)
|
void
|
||||||
|
ili9341_drawchar_size(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg, uint8_t size)
|
||||||
{
|
{
|
||||||
uint16_t *buf = spi_buffer;
|
uint16_t *buf = spi_buffer;
|
||||||
const uint8_t *char_buf = FONT_GET_DATA(ch);
|
uint8_t bits;
|
||||||
uint16_t w = FONT_GET_WIDTH(ch);
|
int c, r;
|
||||||
for (int c = 0; c < FONT_GET_HEIGHT; c++, char_buf++) {
|
for(c = 0; c < 7*size; c++) {
|
||||||
for (int i = 0; i < size; i++) {
|
bits = x5x7_bits[(ch * 7) + (c / size)];
|
||||||
uint8_t bits = *char_buf;
|
for (r = 0; r < 5*size; r++) {
|
||||||
for (int r = 0; r < w; r++, bits <<= 1)
|
*buf++ = (0x80 & bits) ? fg : bg;
|
||||||
for (int j = 0; j < size; j++)
|
if (r % size == (size-1)) {
|
||||||
*buf++ = (0x80 & bits) ? foreground_color : background_color;
|
bits <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ili9341_bulk(x, y, w * size, FONT_GET_HEIGHT * size);
|
|
||||||
return w*size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ili9341_drawfont(uint8_t ch, int x, int y)
|
|
||||||
{
|
|
||||||
blit16BitWidthBitmap(x, y, NUM_FONT_GET_WIDTH, NUM_FONT_GET_HEIGHT,
|
|
||||||
NUM_FONT_GET_DATA(ch));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size)
|
|
||||||
{
|
|
||||||
while (*str)
|
|
||||||
x += ili9341_drawchar_size(*str++, x, y, size);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
static void ili9341_pixel(int x, int y, uint16_t color)
|
|
||||||
{
|
|
||||||
uint32_t xx = __REV16(x|((x)<<16));
|
|
||||||
uint32_t yy = __REV16(y|((y)<<16));
|
|
||||||
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t*)&xx);
|
|
||||||
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t*)&yy);
|
|
||||||
send_command(ILI9341_MEMORY_WRITE, 2, &color);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SWAP(x, y) { int z = x; x = y; y = z; }
|
|
||||||
|
|
||||||
void ili9341_line(int x0, int y0, int x1, int y1)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
// modifed Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
|
||||||
int dx = x1 - x0, sx = 1; if (dx < 0) {dx = -dx; sx = -1;}
|
|
||||||
int dy = y1 - y0, sy = 1; if (dy < 0) {dy = -dy; sy = -1;}
|
|
||||||
int err = (dx > dy ? dx : -dy) / 2;
|
|
||||||
while (1) {
|
|
||||||
ili9341_pixel(x0, y0, DEFAULT_FG_COLOR);
|
|
||||||
if (x0 == x1 && y0 == y1)
|
|
||||||
break;
|
|
||||||
int e2 = err;
|
|
||||||
if (e2 > -dx) { err -= dy; x0 += sx; }
|
|
||||||
if (e2 < dy) { err += dx; y0 += sy; }
|
|
||||||
}
|
}
|
||||||
#endif
|
ili9341_bulk(x, y, 5*size, 7*size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ili9341_drawstring_size(const char *str, int x, int y, uint16_t fg, uint16_t bg, uint8_t size)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
ili9341_drawchar_size(*str, x, y, fg, bg, size);
|
||||||
|
x += 5 * size;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SWAP(x,y) do { int z=x; x = y; y = z; } while(0)
|
||||||
|
|
||||||
|
void
|
||||||
|
ili9341_line(int x0, int y0, int x1, int y1, uint16_t fg)
|
||||||
|
{
|
||||||
if (x0 > x1) {
|
if (x0 > x1) {
|
||||||
SWAP(x0, x1);
|
SWAP(x0, x1);
|
||||||
SWAP(y0, y1);
|
SWAP(y0, y1);
|
||||||
|
|
@ -668,25 +422,52 @@ void ili9341_line(int x0, int y0, int x1, int y1)
|
||||||
if (-dy > dx) {
|
if (-dy > dx) {
|
||||||
dy /= dx; dx = 1;
|
dy /= dx; dx = 1;
|
||||||
} else {
|
} else {
|
||||||
dx /= -dy;dy = -1;
|
dx /= -dy; dy = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dy > 0)
|
if (dy > 0)
|
||||||
ili9341_fill(x0, y0, dx, dy, foreground_color);
|
ili9341_fill(x0, y0, dx, dy, fg);
|
||||||
else
|
else
|
||||||
ili9341_fill(x0, y0+dy, dx, -dy, foreground_color);
|
ili9341_fill(x0, y0+dy, dx, -dy, fg);
|
||||||
x0 += dx;
|
x0 += dx;
|
||||||
y0 += dy;
|
y0 += dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const font_t NF20x22 = { 20, 22, 1, 3*22, (const uint8_t *)numfont20x22 };
|
||||||
|
|
||||||
|
void
|
||||||
|
ili9341_drawfont(uint8_t ch, const font_t *font, int x, int y, uint16_t fg, uint16_t bg)
|
||||||
|
{
|
||||||
|
uint16_t *buf = spi_buffer;
|
||||||
|
const uint8_t *bitmap = &font->bitmap[font->slide * ch];
|
||||||
|
int c, r;
|
||||||
|
|
||||||
|
for (c = 0; c < font->height; c++) {
|
||||||
|
uint8_t bits = *bitmap++;
|
||||||
|
uint8_t m = 0x80;
|
||||||
|
for (r = 0; r < font->width; r++) {
|
||||||
|
*buf++ = (bits & m) ? fg : bg;
|
||||||
|
m >>= 1;
|
||||||
|
|
||||||
|
if (m == 0) {
|
||||||
|
bits = *bitmap++;
|
||||||
|
m = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ili9341_bulk(x, y, font->width, font->height);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static const uint16_t colormap[] = {
|
const uint16_t colormap[] = {
|
||||||
RGBHEX(0x00ff00), RGBHEX(0x0000ff), RGBHEX(0xff0000),
|
RGB565(255,0,0), RGB565(0,255,0), RGB565(0,0,255),
|
||||||
RGBHEX(0x00ffff), RGBHEX(0xff00ff), RGBHEX(0xffff00)
|
RGB565(255,255,0), RGB565(0,255,255), RGB565(255,0,255)
|
||||||
};
|
};
|
||||||
|
|
||||||
void ili9341_test(int mode)
|
void
|
||||||
|
ili9341_test(int mode)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -695,7 +476,7 @@ void ili9341_test(int mode)
|
||||||
#if 1
|
#if 1
|
||||||
ili9341_fill(0, 0, 320, 240, 0);
|
ili9341_fill(0, 0, 320, 240, 0);
|
||||||
for (y = 0; y < 240; y++) {
|
for (y = 0; y < 240; y++) {
|
||||||
ili9341_fill(0, y, 320, 1, RGB(240-y, y, (y + 120) % 256));
|
ili9341_fill(0, y, 320, 1, RGB565(y, (y + 120) % 256, 240-y));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
|
@ -714,7 +495,7 @@ void ili9341_test(int mode)
|
||||||
#if 1
|
#if 1
|
||||||
case 3:
|
case 3:
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
ili9341_drawfont(i, i*20, 120);
|
ili9341_drawfont(i, &NF20x22, i*20, 120, colormap[i%6], 0x0000);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -723,10 +504,10 @@ void ili9341_test(int mode)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 4:
|
case 4:
|
||||||
ili9341_line(0, 0, 15, 100);
|
ili9341_line(0, 0, 15, 100, 0xffff);
|
||||||
ili9341_line(0, 0, 100, 100);
|
ili9341_line(0, 0, 100, 100, 0xffff);
|
||||||
ili9341_line(0, 15, 100, 0);
|
ili9341_line(0, 15, 100, 0, 0xffff);
|
||||||
ili9341_line(0, 100, 100, 0);
|
ili9341_line(0, 100, 100, 0, 0xffff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,7 @@
|
||||||
#define STM32_ADCSW STM32_ADCSW_HSI14
|
#define STM32_ADCSW STM32_ADCSW_HSI14
|
||||||
#define STM32_USBSW STM32_USBSW_HSI48
|
#define STM32_USBSW STM32_USBSW_HSI48
|
||||||
#define STM32_CECSW STM32_CECSW_HSI
|
#define STM32_CECSW STM32_CECSW_HSI
|
||||||
//#define STM32_I2C1SW STM32_I2C1SW_HSI
|
#define STM32_I2C1SW STM32_I2C1SW_HSI
|
||||||
#define STM32_I2C1SW STM32_I2C1SW_SYSCLK
|
|
||||||
#define STM32_USART1SW STM32_USART1SW_PCLK
|
#define STM32_USART1SW STM32_USART1SW_PCLK
|
||||||
#define STM32_RTCSEL STM32_RTCSEL_LSI
|
#define STM32_RTCSEL STM32_RTCSEL_LSI
|
||||||
|
|
||||||
|
|
@ -118,9 +117,7 @@
|
||||||
#define STM32_I2C_BUSY_TIMEOUT 50
|
#define STM32_I2C_BUSY_TIMEOUT 50
|
||||||
#define STM32_I2C_I2C1_IRQ_PRIORITY 3
|
#define STM32_I2C_I2C1_IRQ_PRIORITY 3
|
||||||
#define STM32_I2C_I2C2_IRQ_PRIORITY 3
|
#define STM32_I2C_I2C2_IRQ_PRIORITY 3
|
||||||
|
#define STM32_I2C_USE_DMA TRUE
|
||||||
// I2C1 rx operation use DMA3, some as SPI1 DMA Tx used by LCD
|
|
||||||
#define STM32_I2C_USE_DMA FALSE
|
|
||||||
#define STM32_I2C_I2C1_DMA_PRIORITY 1
|
#define STM32_I2C_I2C1_DMA_PRIORITY 1
|
||||||
#define STM32_I2C_I2C2_DMA_PRIORITY 1
|
#define STM32_I2C_I2C2_DMA_PRIORITY 1
|
||||||
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
|
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
|
||||||
|
|
|
||||||
311
nanovna.h
311
nanovna.h
|
|
@ -19,26 +19,11 @@
|
||||||
*/
|
*/
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
|
||||||
// Need enable HAL_USE_SPI in halconf.h
|
|
||||||
#define __USE_DISPLAY_DMA__
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main.c
|
* main.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Minimum frequency set
|
extern float measured[2][101][2];
|
||||||
#define START_MIN 50000
|
|
||||||
// Maximum frequency set
|
|
||||||
#define STOP_MAX 2700000000U
|
|
||||||
// Frequency offset (sin_cos table in dsp.c generated for this offset, if change need create new table)
|
|
||||||
#define FREQUENCY_OFFSET 5000
|
|
||||||
// Speed of light const
|
|
||||||
#define SPEED_OF_LIGHT 299792458
|
|
||||||
// pi const
|
|
||||||
#define VNA_PI 3.14159265358979323846
|
|
||||||
|
|
||||||
#define POINTS_COUNT 101
|
|
||||||
extern float measured[2][POINTS_COUNT][2];
|
|
||||||
|
|
||||||
#define CAL_LOAD 0
|
#define CAL_LOAD 0
|
||||||
#define CAL_OPEN 1
|
#define CAL_OPEN 1
|
||||||
|
|
@ -82,23 +67,27 @@ extern float measured[2][POINTS_COUNT][2];
|
||||||
void cal_collect(int type);
|
void cal_collect(int type);
|
||||||
void cal_done(void);
|
void cal_done(void);
|
||||||
|
|
||||||
#define MAX_FREQ_TYPE 5
|
enum {
|
||||||
enum stimulus_type {
|
ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW
|
||||||
ST_START=0, ST_STOP, ST_CENTER, ST_SPAN, ST_CW
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_sweep_frequency(int type, uint32_t frequency);
|
void set_sweep_frequency(int type, int32_t frequency);
|
||||||
uint32_t get_sweep_frequency(int type);
|
uint32_t get_sweep_frequency(int type);
|
||||||
|
|
||||||
double my_atof(const char *p);
|
float my_atof(const char *p);
|
||||||
|
|
||||||
void toggle_sweep(void);
|
void toggle_sweep(void);
|
||||||
void load_default_properties(void);
|
|
||||||
|
|
||||||
#define SWEEP_ENABLE 0x01
|
extern int8_t sweep_enabled;
|
||||||
#define SWEEP_ONCE 0x02
|
|
||||||
extern int8_t sweep_mode;
|
/*
|
||||||
extern const char *info_about[];
|
* ui.c
|
||||||
|
*/
|
||||||
|
extern void ui_init(void);
|
||||||
|
extern void ui_process(void);
|
||||||
|
|
||||||
|
enum { OP_NONE = 0, OP_LEVER, OP_TOUCH, OP_FREQCHANGE };
|
||||||
|
extern uint8_t operation_requested;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dsp.c
|
* dsp.c
|
||||||
|
|
@ -122,6 +111,9 @@ void calculate_gamma(float *gamma);
|
||||||
void fetch_amplitude(float *gamma);
|
void fetch_amplitude(float *gamma);
|
||||||
void fetch_amplitude_ref(float *gamma);
|
void fetch_amplitude_ref(float *gamma);
|
||||||
|
|
||||||
|
int si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tlv320aic3204.c
|
* tlv320aic3204.c
|
||||||
*/
|
*/
|
||||||
|
|
@ -130,74 +122,42 @@ extern void tlv320aic3204_init(void);
|
||||||
extern void tlv320aic3204_set_gain(int lgain, int rgain);
|
extern void tlv320aic3204_set_gain(int lgain, int rgain);
|
||||||
extern void tlv320aic3204_select(int channel);
|
extern void tlv320aic3204_select(int channel);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* plot.c
|
* plot.c
|
||||||
*/
|
*/
|
||||||
|
#define OFFSETX 15
|
||||||
// Offset of plot area
|
|
||||||
#define OFFSETX 10
|
|
||||||
#define OFFSETY 0
|
#define OFFSETY 0
|
||||||
|
#define WIDTH 291
|
||||||
|
#define HEIGHT 233
|
||||||
|
|
||||||
// WIDTH better be n*(POINTS_COUNT-1)
|
|
||||||
#define WIDTH 300
|
|
||||||
// HEIGHT = 8*GRIDY
|
|
||||||
#define HEIGHT 232
|
|
||||||
|
|
||||||
//#define NGRIDY 10
|
|
||||||
#define NGRIDY 8
|
|
||||||
|
|
||||||
#define FREQUENCIES_XPOS1 OFFSETX
|
|
||||||
#define FREQUENCIES_XPOS2 200
|
|
||||||
#define FREQUENCIES_YPOS (240-7)
|
|
||||||
|
|
||||||
// GRIDX calculated depends from frequency span
|
|
||||||
//#define GRIDY 29
|
|
||||||
#define GRIDY (HEIGHT / NGRIDY)
|
|
||||||
|
|
||||||
//
|
|
||||||
#define CELLOFFSETX 5
|
#define CELLOFFSETX 5
|
||||||
#define AREA_WIDTH_NORMAL (CELLOFFSETX + WIDTH + 1 + 4)
|
#define AREA_WIDTH_NORMAL (WIDTH + CELLOFFSETX*2)
|
||||||
#define AREA_HEIGHT_NORMAL ( HEIGHT + 1)
|
|
||||||
|
|
||||||
// Smith/polar chart
|
extern int area_width;
|
||||||
#define P_CENTER_X (CELLOFFSETX + WIDTH/2)
|
extern int area_height;
|
||||||
#define P_CENTER_Y (HEIGHT/2)
|
|
||||||
#define P_RADIUS (HEIGHT/2)
|
|
||||||
|
|
||||||
extern int16_t area_width;
|
#define GRIDY 29
|
||||||
extern int16_t area_height;
|
|
||||||
|
|
||||||
// font
|
// font
|
||||||
|
|
||||||
extern const uint8_t x5x7_bits [];
|
extern const uint8_t x5x7_bits [];
|
||||||
#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7])
|
extern const uint8_t numfont20x22[][22 * 3];
|
||||||
#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7))
|
|
||||||
#define FONT_MAX_WIDTH 7
|
|
||||||
#define FONT_GET_HEIGHT 7
|
|
||||||
|
|
||||||
extern const uint16_t numfont16x22[];
|
|
||||||
#define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*22])
|
|
||||||
#define NUM_FONT_GET_WIDTH 16
|
|
||||||
#define NUM_FONT_GET_HEIGHT 22
|
|
||||||
|
|
||||||
#define S_DELTA "\004"
|
|
||||||
#define S_DEGREE "\037"
|
|
||||||
#define S_SARROW "\030"
|
|
||||||
#define S_INFINITY "\031"
|
|
||||||
#define S_LARROW "\032"
|
|
||||||
#define S_RARROW "\033"
|
|
||||||
#define S_PI "\034"
|
#define S_PI "\034"
|
||||||
#define S_MICRO "\035"
|
#define S_MICRO "\035"
|
||||||
#define S_OHM "\036"
|
#define S_OHM "\036"
|
||||||
|
#define S_DEGREE "\037"
|
||||||
|
#define S_LARROW "\032"
|
||||||
|
#define S_RARROW "\033"
|
||||||
|
|
||||||
// trace
|
// trace
|
||||||
|
|
||||||
#define TRACES_MAX 4
|
#define TRACES_MAX 4
|
||||||
|
|
||||||
#define MAX_TRACE_TYPE 12
|
enum {
|
||||||
enum trace_type {
|
TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF
|
||||||
TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_Q, TRC_OFF
|
|
||||||
};
|
};
|
||||||
// Mask for define rectangular plot
|
|
||||||
#define RECTANGULAR_GRID_MASK ((1<<TRC_LOGMAG)|(1<<TRC_PHASE)|(1<<TRC_DELAY)|(1<<TRC_LINEAR)|(1<<TRC_SWR)|(1<<TRC_REAL)|(1<<TRC_IMAG)|(1<<TRC_R)|(1<<TRC_X)|(1<<TRC_Q))
|
|
||||||
|
|
||||||
// LOGMAG: SCALE, REFPOS, REFVAL
|
// LOGMAG: SCALE, REFPOS, REFVAL
|
||||||
// PHASE: SCALE, REFPOS, REFVAL
|
// PHASE: SCALE, REFPOS, REFVAL
|
||||||
|
|
@ -209,20 +169,16 @@ enum trace_type {
|
||||||
// Electrical Delay
|
// Electrical Delay
|
||||||
// Phase
|
// Phase
|
||||||
|
|
||||||
typedef struct trace {
|
typedef struct {
|
||||||
uint8_t enabled;
|
uint8_t enabled;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t channel;
|
uint8_t channel;
|
||||||
uint8_t reserved;
|
uint8_t polar;
|
||||||
float scale;
|
float scale;
|
||||||
float refpos;
|
float refpos;
|
||||||
} trace_t;
|
} trace_t;
|
||||||
|
|
||||||
#define FREQ_MODE_START_STOP 0x0
|
typedef struct {
|
||||||
#define FREQ_MODE_CENTER_SPAN 0x1
|
|
||||||
#define FREQ_MODE_DOTTED_GRID 0x2
|
|
||||||
|
|
||||||
typedef struct config {
|
|
||||||
int32_t magic;
|
int32_t magic;
|
||||||
uint16_t dac_value;
|
uint16_t dac_value;
|
||||||
uint16_t grid_color;
|
uint16_t grid_color;
|
||||||
|
|
@ -230,14 +186,15 @@ typedef struct config {
|
||||||
uint16_t menu_active_color;
|
uint16_t menu_active_color;
|
||||||
uint16_t trace_color[TRACES_MAX];
|
uint16_t trace_color[TRACES_MAX];
|
||||||
int16_t touch_cal[4];
|
int16_t touch_cal[4];
|
||||||
|
int8_t default_loadcal;
|
||||||
uint32_t harmonic_freq_threshold;
|
uint32_t harmonic_freq_threshold;
|
||||||
uint16_t vbat_offset;
|
int32_t checksum;
|
||||||
uint8_t _reserved[22];
|
|
||||||
uint32_t checksum;
|
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
||||||
extern config_t config;
|
extern config_t config;
|
||||||
|
|
||||||
|
//extern trace_t trace[TRACES_MAX];
|
||||||
|
|
||||||
void set_trace_type(int t, int type);
|
void set_trace_type(int t, int type);
|
||||||
void set_trace_channel(int t, int channel);
|
void set_trace_channel(int t, int channel);
|
||||||
void set_trace_scale(int t, float scale);
|
void set_trace_scale(int t, float scale);
|
||||||
|
|
@ -245,23 +202,22 @@ void set_trace_refpos(int t, float refpos);
|
||||||
float get_trace_scale(int t);
|
float get_trace_scale(int t);
|
||||||
float get_trace_refpos(int t);
|
float get_trace_refpos(int t);
|
||||||
const char *get_trace_typename(int t);
|
const char *get_trace_typename(int t);
|
||||||
|
void draw_battery_status(void);
|
||||||
|
|
||||||
void set_electrical_delay(float picoseconds);
|
void set_electrical_delay(float picoseconds);
|
||||||
float get_electrical_delay(void);
|
float get_electrical_delay(void);
|
||||||
float groupdelay_from_array(int i, float array[POINTS_COUNT][2]);
|
float groupdelay_from_array(int i, float array[101][2]);
|
||||||
|
|
||||||
// marker
|
// marker
|
||||||
|
|
||||||
#define MARKERS_MAX 4
|
typedef struct {
|
||||||
|
|
||||||
typedef struct marker {
|
|
||||||
int8_t enabled;
|
int8_t enabled;
|
||||||
int16_t index;
|
int16_t index;
|
||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
} marker_t;
|
} marker_t;
|
||||||
|
|
||||||
extern int8_t previous_marker;
|
//extern marker_t markers[4];
|
||||||
extern int8_t marker_tracking;
|
//extern int active_marker;
|
||||||
|
|
||||||
void plot_init(void);
|
void plot_init(void);
|
||||||
void update_grid(void);
|
void update_grid(void);
|
||||||
|
|
@ -270,121 +226,87 @@ void redraw_frame(void);
|
||||||
//void redraw_all(void);
|
//void redraw_all(void);
|
||||||
void request_to_draw_cells_behind_menu(void);
|
void request_to_draw_cells_behind_menu(void);
|
||||||
void request_to_draw_cells_behind_numeric_input(void);
|
void request_to_draw_cells_behind_numeric_input(void);
|
||||||
void redraw_marker(int marker);
|
void redraw_marker(int marker, int update_info);
|
||||||
void plot_into_index(float measured[2][POINTS_COUNT][2]);
|
void trace_get_info(int t, char *buf, int len);
|
||||||
|
void plot_into_index(float measured[2][101][2]);
|
||||||
void force_set_markmap(void);
|
void force_set_markmap(void);
|
||||||
void draw_frequencies(void);
|
void draw_frequencies(void);
|
||||||
void draw_all(bool flush);
|
void draw_all(bool flush);
|
||||||
|
|
||||||
void draw_cal_status(void);
|
void draw_cal_status(void);
|
||||||
|
|
||||||
//void markmap_all_markers(void);
|
void markmap_all_markers(void);
|
||||||
|
|
||||||
void marker_position(int m, int t, int *x, int *y);
|
void marker_position(int m, int t, int *x, int *y);
|
||||||
int search_nearest_index(int x, int y, int t);
|
int search_nearest_index(int x, int y, int t);
|
||||||
void set_marker_search(int mode);
|
int marker_search(int mode);
|
||||||
int marker_search(void);
|
|
||||||
int marker_search_left(int from);
|
int marker_search_left(int from);
|
||||||
int marker_search_right(int from);
|
int marker_search_right(int from);
|
||||||
|
|
||||||
// _request flag for update screen
|
extern uint16_t redraw_request;
|
||||||
|
|
||||||
#define REDRAW_CELLS (1<<0)
|
#define REDRAW_CELLS (1<<0)
|
||||||
#define REDRAW_FREQUENCY (1<<1)
|
#define REDRAW_FREQUENCY (1<<1)
|
||||||
#define REDRAW_CAL_STATUS (1<<2)
|
#define REDRAW_CAL_STATUS (1<<2)
|
||||||
#define REDRAW_MARKER (1<<3)
|
#define REDRAW_MARKER (1<<3)
|
||||||
#define REDRAW_BATTERY (1<<4)
|
|
||||||
#define REDRAW_AREA (1<<5)
|
extern int16_t vbat;
|
||||||
extern volatile uint8_t redraw_request;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ili9341.c
|
* ili9341.c
|
||||||
*/
|
*/
|
||||||
// SPI bus revert byte order
|
#define RGB565(b,r,g) ( (((b)<<8)&0xfc00) | (((r)<<2)&0x03e0) | (((g)>>3)&0x001f) )
|
||||||
//gggBBBbb RRRrrGGG
|
|
||||||
#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)
|
typedef struct {
|
||||||
#define SPI_BUFFER_SIZE 2048
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
uint16_t scaley;
|
||||||
|
uint16_t slide;
|
||||||
|
const uint8_t *bitmap;
|
||||||
|
} font_t;
|
||||||
|
|
||||||
#define DEFAULT_FG_COLOR RGB565(255,255,255)
|
extern const font_t NF20x22;
|
||||||
#define DEFAULT_BG_COLOR RGB565( 0, 0, 0)
|
|
||||||
#define DEFAULT_GRID_COLOR RGB565(128,128,128)
|
|
||||||
#define DEFAULT_MENU_COLOR RGB565(255,255,255)
|
|
||||||
#define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0)
|
|
||||||
#define DEFAULT_MENU_ACTIVE_COLOR RGB565(180,255,180)
|
|
||||||
#define DEFAULT_TRACE_1_COLOR RGB565(255,255, 0)
|
|
||||||
#define DEFAULT_TRACE_2_COLOR RGB565( 0,255,255)
|
|
||||||
#define DEFAULT_TRACE_3_COLOR RGB565( 0,255, 0)
|
|
||||||
#define DEFAULT_TRACE_4_COLOR RGB565(255, 0,255)
|
|
||||||
#define DEFAULT_NORMAL_BAT_COLOR RGB565( 31,227, 0)
|
|
||||||
#define DEFAULT_LOW_BAT_COLOR RGB565(255, 0, 0)
|
|
||||||
#define DEFAULT_SPEC_INPUT_COLOR RGB565(128,255,128);
|
|
||||||
|
|
||||||
extern uint16_t foreground_color;
|
extern uint16_t spi_buffer[1024];
|
||||||
extern uint16_t background_color;
|
|
||||||
|
|
||||||
extern uint16_t spi_buffer[SPI_BUFFER_SIZE];
|
|
||||||
|
|
||||||
void ili9341_init(void);
|
void ili9341_init(void);
|
||||||
void ili9341_test(int mode);
|
void ili9341_test(int mode);
|
||||||
void ili9341_bulk(int x, int y, int w, int h);
|
void ili9341_bulk(int x, int y, int w, int h);
|
||||||
void ili9341_fill(int x, int y, int w, int h, int color);
|
void ili9341_fill(int x, int y, int w, int h, int color);
|
||||||
void ili9341_set_foreground(uint16_t fg);
|
void ili9341_drawchar_5x7(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg);
|
||||||
void ili9341_set_background(uint16_t fg);
|
void ili9341_drawstring_5x7(const char *str, int x, int y, uint16_t fg, uint16_t bg);
|
||||||
void ili9341_clear_screen(void);
|
void ili9341_drawstring_5x7_inv(const char *str, int x, int y, uint16_t fg, uint16_t bg, bool inv);
|
||||||
void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap);
|
void ili9341_drawchar_size(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg, uint8_t size);
|
||||||
void ili9341_drawchar(uint8_t ch, int x, int y);
|
void ili9341_drawstring_size(const char *str, int x, int y, uint16_t fg, uint16_t bg, uint8_t size);
|
||||||
void ili9341_drawstring(const char *str, int x, int y);
|
void ili9341_drawfont(uint8_t ch, const font_t *font, int x, int y, uint16_t fg, uint16_t bg);
|
||||||
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);
|
|
||||||
void ili9341_drawfont(uint8_t ch, int x, int y);
|
|
||||||
void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t* out);
|
void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t* out);
|
||||||
void ili9341_line(int x0, int y0, int x1, int y1);
|
void ili9341_read_memory_continue(int len, uint16_t* out);
|
||||||
void show_version(void);
|
|
||||||
void show_logo(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flash.c
|
* flash.c
|
||||||
*/
|
*/
|
||||||
#define SAVEAREA_MAX 5
|
#define SAVEAREA_MAX 5
|
||||||
// Begin addr 0x08018000
|
|
||||||
#define SAVE_CONFIG_AREA_SIZE 0x00008000
|
|
||||||
// config save area
|
|
||||||
#define SAVE_CONFIG_ADDR 0x08018000
|
|
||||||
// properties_t save area
|
|
||||||
#define SAVE_PROP_CONFIG_0_ADDR 0x08018800
|
|
||||||
#define SAVE_PROP_CONFIG_1_ADDR 0x0801a000
|
|
||||||
#define SAVE_PROP_CONFIG_2_ADDR 0x0801b800
|
|
||||||
#define SAVE_PROP_CONFIG_3_ADDR 0x0801d000
|
|
||||||
#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800
|
|
||||||
|
|
||||||
typedef struct properties {
|
typedef struct {
|
||||||
uint32_t magic;
|
int32_t magic;
|
||||||
uint32_t _frequency0;
|
int32_t _frequency0; // start or center
|
||||||
uint32_t _frequency1;
|
int32_t _frequency1; // stop or span
|
||||||
uint16_t _sweep_points;
|
int16_t _sweep_points;
|
||||||
uint16_t _cal_status;
|
uint16_t _cal_status;
|
||||||
|
|
||||||
uint32_t _frequencies[POINTS_COUNT];
|
uint32_t _frequencies[101];
|
||||||
float _cal_data[5][POINTS_COUNT][2];
|
float _cal_data[5][101][2];
|
||||||
float _electrical_delay; // picoseconds
|
float _electrical_delay; // picoseconds
|
||||||
|
|
||||||
trace_t _trace[TRACES_MAX];
|
trace_t _trace[TRACES_MAX];
|
||||||
marker_t _markers[MARKERS_MAX];
|
marker_t _markers[4];
|
||||||
|
int _active_marker;
|
||||||
float _velocity_factor; // %
|
|
||||||
int8_t _active_marker;
|
|
||||||
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */
|
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */
|
||||||
uint8_t _marker_smith_format;
|
uint8_t _velocity_factor; // %
|
||||||
uint8_t _bandwidth;
|
|
||||||
int8_t _freq_mode;
|
|
||||||
uint8_t _reserved[49];
|
|
||||||
uint32_t checksum;
|
|
||||||
} properties_t;
|
|
||||||
|
|
||||||
//sizeof(properties_t) == 0x1200
|
int32_t checksum;
|
||||||
|
} properties_t;
|
||||||
|
|
||||||
#define CONFIG_MAGIC 0x434f4e45 /* 'CONF' */
|
#define CONFIG_MAGIC 0x434f4e45 /* 'CONF' */
|
||||||
|
|
||||||
|
|
@ -392,6 +314,8 @@ extern int16_t lastsaveid;
|
||||||
extern properties_t *active_props;
|
extern properties_t *active_props;
|
||||||
extern properties_t current_props;
|
extern properties_t current_props;
|
||||||
|
|
||||||
|
extern int8_t previous_marker;
|
||||||
|
|
||||||
#define frequency0 current_props._frequency0
|
#define frequency0 current_props._frequency0
|
||||||
#define frequency1 current_props._frequency1
|
#define frequency1 current_props._frequency1
|
||||||
#define sweep_points current_props._sweep_points
|
#define sweep_points current_props._sweep_points
|
||||||
|
|
@ -405,13 +329,6 @@ extern properties_t current_props;
|
||||||
#define active_marker current_props._active_marker
|
#define active_marker current_props._active_marker
|
||||||
#define domain_mode current_props._domain_mode
|
#define domain_mode current_props._domain_mode
|
||||||
#define velocity_factor current_props._velocity_factor
|
#define velocity_factor current_props._velocity_factor
|
||||||
#define marker_smith_format current_props._marker_smith_format
|
|
||||||
#define bandwidth current_props._bandwidth
|
|
||||||
#define freq_mode current_props._freq_mode
|
|
||||||
|
|
||||||
#define FREQ_IS_STARTSTOP() (!(freq_mode & FREQ_MODE_CENTER_SPAN))
|
|
||||||
#define FREQ_IS_CENTERSPAN() (freq_mode & FREQ_MODE_CENTER_SPAN)
|
|
||||||
#define FREQ_IS_CW() (frequency0 == frequency1)
|
|
||||||
|
|
||||||
int caldata_save(int id);
|
int caldata_save(int id);
|
||||||
int caldata_recall(int id);
|
int caldata_recall(int id);
|
||||||
|
|
@ -425,42 +342,29 @@ void clear_all_config_prop_data(void);
|
||||||
/*
|
/*
|
||||||
* ui.c
|
* ui.c
|
||||||
*/
|
*/
|
||||||
extern void ui_init(void);
|
|
||||||
extern void ui_process(void);
|
|
||||||
|
|
||||||
// Irq operation process set
|
|
||||||
#define OP_NONE 0x00
|
|
||||||
#define OP_LEVER 0x01
|
|
||||||
#define OP_TOUCH 0x02
|
|
||||||
//#define OP_FREQCHANGE 0x04
|
|
||||||
extern volatile uint8_t operation_requested;
|
|
||||||
|
|
||||||
// lever_mode
|
// lever_mode
|
||||||
enum lever_mode {
|
enum {
|
||||||
LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN, LM_EDELAY
|
LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN
|
||||||
};
|
};
|
||||||
|
|
||||||
// marker smith value format
|
typedef struct {
|
||||||
enum marker_smithvalue {
|
|
||||||
MS_LIN, MS_LOG, MS_REIM, MS_RX, MS_RLC
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct uistat {
|
|
||||||
int8_t digit; /* 0~5 */
|
int8_t digit; /* 0~5 */
|
||||||
int8_t digit_mode;
|
int8_t digit_mode;
|
||||||
int8_t current_trace; /* 0..3 */
|
int8_t current_trace; /* 0..3 */
|
||||||
uint32_t value; // for editing at numeric input area
|
uint32_t value; // for editing at numeric input area
|
||||||
// uint32_t previous_value;
|
uint32_t previous_value;
|
||||||
uint8_t lever_mode;
|
uint8_t lever_mode;
|
||||||
uint8_t marker_delta;
|
|
||||||
uint8_t marker_tracking;
|
|
||||||
} uistat_t;
|
} uistat_t;
|
||||||
|
|
||||||
extern uistat_t uistat;
|
extern uistat_t uistat;
|
||||||
|
|
||||||
void ui_init(void);
|
void ui_init(void);
|
||||||
void ui_show(void);
|
void ui_show(void);
|
||||||
void ui_hide(void);
|
void ui_hide(void);
|
||||||
|
|
||||||
|
extern uint8_t operation_requested;
|
||||||
|
|
||||||
void touch_start_watchdog(void);
|
void touch_start_watchdog(void);
|
||||||
void touch_position(int *x, int *y);
|
void touch_position(int *x, int *y);
|
||||||
void handle_touch_interrupt(void);
|
void handle_touch_interrupt(void);
|
||||||
|
|
@ -476,22 +380,25 @@ void enter_dfu(void);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void adc_init(void);
|
void adc_init(void);
|
||||||
uint16_t adc_single_read(uint32_t chsel);
|
uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel);
|
||||||
void adc_start_analog_watchdogd(uint32_t chsel);
|
void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel);
|
||||||
void adc_stop(void);
|
void adc_stop(ADC_TypeDef *adc);
|
||||||
void adc_interrupt(void);
|
void adc_interrupt(ADC_TypeDef *adc);
|
||||||
int16_t adc_vbat_read(void);
|
int16_t adc_vbat_read(ADC_TypeDef *adc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* misclinous
|
* misclinous
|
||||||
*/
|
*/
|
||||||
int plot_printf(char *str, int, const char *fmt, ...);
|
|
||||||
#define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0)
|
#define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0)
|
||||||
|
|
||||||
// Speed profile definition
|
// convert vbat [mV] to battery indicator
|
||||||
#define START_PROFILE systime_t time = chVTGetSystemTimeX();
|
static inline uint8_t vbat2bati(int16_t vbat)
|
||||||
#define STOP_PROFILE {char string_buf[12];plot_printf(string_buf, sizeof string_buf, "T:%06d", chVTGetSystemTimeX() - time);ili9341_drawstringV(string_buf, 1, 60);}
|
{
|
||||||
// Macros for convert define value to string
|
if (vbat < 3200) return 0;
|
||||||
#define STR1(x) #x
|
if (vbat < 3450) return 25;
|
||||||
#define define_to_STR(x) STR1(x)
|
if (vbat < 3700) return 50;
|
||||||
|
if (vbat < 4100) return 75;
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
/*EOF*/
|
/*EOF*/
|
||||||
|
|
|
||||||
1087
numfont20x22.c
1087
numfont20x22.c
File diff suppressed because it is too large
Load diff
584
si5351.c
584
si5351.c
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
||||||
* Modified by DiSlord dislordlive@gmail.com
|
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This is free software; you can redistribute it and/or modify
|
* This is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -22,100 +21,40 @@
|
||||||
#include "nanovna.h"
|
#include "nanovna.h"
|
||||||
#include "si5351.h"
|
#include "si5351.h"
|
||||||
|
|
||||||
// Enable cache for SI5351 CLKX_CONTROL register, little speedup exchange
|
#define SI5351_I2C_ADDR (0x60<<1)
|
||||||
#define USE_CLK_CONTROL_CACHE TRUE
|
|
||||||
|
|
||||||
// XTAL frequency on si5351
|
static void
|
||||||
#define XTALFREQ 26000000U
|
si5351_write(uint8_t reg, uint8_t dat)
|
||||||
// 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;
|
int addr = SI5351_I2C_ADDR>>1;
|
||||||
}
|
uint8_t buf[] = { reg, dat };
|
||||||
|
i2cAcquireBus(&I2CD1);
|
||||||
void si5351_set_frequency_offset(int32_t offset)
|
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000);
|
||||||
{
|
i2cReleaseBus(&I2CD1);
|
||||||
current_offset = offset;
|
|
||||||
current_freq = 0; // reset freq, for
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
si5351_bulk_write(const uint8_t *buf, int len)
|
si5351_bulk_write(const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
|
int addr = SI5351_I2C_ADDR>>1;
|
||||||
i2cAcquireBus(&I2CD1);
|
i2cAcquireBus(&I2CD1);
|
||||||
(void)i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, buf, len, NULL, 0, 1000);
|
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
|
||||||
i2cReleaseBus(&I2CD1);
|
i2cReleaseBus(&I2CD1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len)
|
|
||||||
{
|
|
||||||
i2cAcquireBus(&I2CD1);
|
|
||||||
msg_t mr = i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, ®, 1, buf, len, 1000);
|
|
||||||
i2cReleaseBus(&I2CD1);
|
|
||||||
return mr == MSG_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void si5351_wait_pll_lock(void)
|
|
||||||
{
|
|
||||||
uint8_t status;
|
|
||||||
int count = 100;
|
|
||||||
do{
|
|
||||||
status=0xFF;
|
|
||||||
si5351_bulk_read(0, &status, 1);
|
|
||||||
if ((status & 0x60) == 0) // PLLA and PLLB locked
|
|
||||||
return;
|
|
||||||
}while (--count);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
si5351_write(uint8_t reg, uint8_t dat)
|
|
||||||
{
|
|
||||||
uint8_t buf[] = { reg, dat };
|
|
||||||
si5351_bulk_write(buf, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// register addr, length, data, ...
|
// register addr, length, data, ...
|
||||||
const uint8_t si5351_configs[] = {
|
const uint8_t si5351_configs[] = {
|
||||||
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff,
|
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff,
|
||||||
4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN,
|
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,
|
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)
|
// 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_26_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
|
// RESET PLL
|
||||||
2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B | 0x0C, //
|
2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B,
|
||||||
// setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50)
|
// 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,
|
9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0,
|
||||||
2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE,
|
2, SI5351_REG_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, 0,
|
||||||
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN),
|
|
||||||
0 // sentinel
|
0 // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -130,344 +69,335 @@ si5351_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
void si5351_disable_output(void)
|
||||||
{
|
{
|
||||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xFF);
|
uint8_t reg[4];
|
||||||
si5351_bulk_write(disable_output, sizeof(disable_output));
|
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff);
|
||||||
current_band = 0;
|
reg[0] = SI5351_REG_16_CLK0_CONTROL;
|
||||||
|
reg[1] = SI5351_CLK_POWERDOWN;
|
||||||
|
reg[2] = SI5351_CLK_POWERDOWN;
|
||||||
|
reg[3] = SI5351_CLK_POWERDOWN;
|
||||||
|
si5351_bulk_write(reg, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void si5351_enable_output(void)
|
void si5351_enable_output(void)
|
||||||
{
|
{
|
||||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN));
|
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0x00);
|
||||||
//si5351_reset_pll(SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
|
|
||||||
current_freq = 0;
|
|
||||||
current_band = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set PLL freq = XTALFREQ * (mult + num/denom)
|
void si5351_reset_pll(void)
|
||||||
static void si5351_setupPLL(uint8_t pllSource, /* SI5351_REG_PLL_A or SI5351_REG_PLL_B */
|
{
|
||||||
uint32_t mult,
|
//si5351_write(SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
|
||||||
|
si5351_write(SI5351_REG_177_PLL_RESET, 0xAC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */
|
||||||
|
uint8_t mult,
|
||||||
uint32_t num,
|
uint32_t num,
|
||||||
uint32_t denom)
|
uint32_t denom)
|
||||||
{
|
{
|
||||||
|
/* Get the appropriate starting point for the PLL registers */
|
||||||
|
const uint8_t pllreg_base[] = {
|
||||||
|
SI5351_REG_26_PLL_A,
|
||||||
|
SI5351_REG_34_PLL_B
|
||||||
|
};
|
||||||
|
uint32_t P1;
|
||||||
|
uint32_t P2;
|
||||||
|
uint32_t P3;
|
||||||
|
|
||||||
/* Feedback Multisynth Divider Equation
|
/* Feedback Multisynth Divider Equation
|
||||||
* where: a = mult, b = num and c = denom
|
* where: a = mult, b = num and c = denom
|
||||||
* P1 register is an 18-bit value using following formula:
|
* P1 register is an 18-bit value using following formula:
|
||||||
* P1[17:0] = 128 * mult + int((128*num)/denom) - 512
|
* P1[17:0] = 128 * mult + floor(128*(num/denom)) - 512
|
||||||
* P2 register is a 20-bit value using the following formula:
|
* P2 register is a 20-bit value using the following formula:
|
||||||
* P2[19:0] = (128 * num) % denom
|
* P2[19:0] = 128 * num - denom * floor(128*(num/denom))
|
||||||
* P3 register is a 20-bit value using the following formula:
|
* P3 register is a 20-bit value using the following formula:
|
||||||
* P3[19:0] = denom
|
* P3[19:0] = denom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Set the main PLL config registers */
|
/* Set the main PLL config registers */
|
||||||
mult <<= 7;
|
if (num == 0)
|
||||||
num <<= 7;
|
{
|
||||||
uint32_t P1 = mult - 512; // Integer mode
|
/* Integer mode */
|
||||||
uint32_t P2 = 0;
|
P1 = 128 * mult - 512;
|
||||||
uint32_t P3 = 1;
|
P2 = 0;
|
||||||
if (num) { // Fractional mode
|
P3 = 1;
|
||||||
P1+= num / denom;
|
}
|
||||||
P2 = num % denom;
|
else
|
||||||
|
{
|
||||||
|
/* Fractional mode */
|
||||||
|
//P1 = (uint32_t)(128 * mult + floor(128 * ((float)num/(float)denom)) - 512);
|
||||||
|
P1 = 128 * mult + ((128 * num) / denom) - 512;
|
||||||
|
//P2 = (uint32_t)(128 * num - denom * floor(128 * ((float)num/(float)denom)));
|
||||||
|
P2 = 128 * num - denom * ((128 * num) / denom);
|
||||||
P3 = denom;
|
P3 = denom;
|
||||||
}
|
}
|
||||||
// Pll MSN(A|B) registers Datasheet
|
|
||||||
|
/* The datasheet is a nightmare of typos and inconsistencies here! */
|
||||||
uint8_t reg[9];
|
uint8_t reg[9];
|
||||||
reg[0] = pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B
|
reg[0] = pllreg_base[pll];
|
||||||
reg[1] = (P3 & 0x0FF00) >> 8; // MSN_P3[15: 8]
|
reg[1] = (P3 & 0x0000FF00) >> 8;
|
||||||
reg[2] = (P3 & 0x000FF); // MSN_P3[ 7: 0]
|
reg[2] = (P3 & 0x000000FF);
|
||||||
reg[3] = (P1 & 0x30000) >> 16; // MSN_P1[17:16]
|
reg[3] = (P1 & 0x00030000) >> 16;
|
||||||
reg[4] = (P1 & 0x0FF00) >> 8; // MSN_P1[15: 8]
|
reg[4] = (P1 & 0x0000FF00) >> 8;
|
||||||
reg[5] = (P1 & 0x000FF); // MSN_P1[ 7: 0]
|
reg[5] = (P1 & 0x000000FF);
|
||||||
reg[6] = ((P3 & 0xF0000) >> 12) | ((P2 & 0xF0000) >> 16); // MSN_P3[19:16] | MSN_P2[19:16]
|
reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
|
||||||
reg[7] = (P2 & 0x0FF00) >> 8; // MSN_P2[15: 8]
|
reg[7] = (P2 & 0x0000FF00) >> 8;
|
||||||
reg[8] = (P2 & 0x000FF); // MSN_P2[ 7: 0]
|
reg[8] = (P2 & 0x000000FF);
|
||||||
si5351_bulk_write(reg, 9);
|
si5351_bulk_write(reg, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Multisynth divider = (div + num/denom) * rdiv
|
void
|
||||||
static void
|
si5351_setupMultisynth(uint8_t output,
|
||||||
si5351_setupMultisynth(uint8_t channel,
|
uint8_t pllSource,
|
||||||
uint32_t div, // 4,6,8, 8+ ~ 900
|
uint32_t div, // 4,6,8, 8+ ~ 900
|
||||||
uint32_t num,
|
uint32_t num,
|
||||||
uint32_t denom,
|
uint32_t denom,
|
||||||
uint32_t rdiv, // SI5351_R_DIV_1~128
|
uint32_t rdiv, // SI5351_R_DIV_1~128
|
||||||
uint8_t chctrl) // SI5351_REG_16_CLKX_CONTROL settings
|
uint8_t drive_strength)
|
||||||
{
|
{
|
||||||
|
/* Get the appropriate starting point for the PLL registers */
|
||||||
|
const uint8_t msreg_base[] = {
|
||||||
|
SI5351_REG_42_MULTISYNTH0,
|
||||||
|
SI5351_REG_50_MULTISYNTH1,
|
||||||
|
SI5351_REG_58_MULTISYNTH2,
|
||||||
|
};
|
||||||
|
const uint8_t clkctrl[] = {
|
||||||
|
SI5351_REG_16_CLK0_CONTROL,
|
||||||
|
SI5351_REG_17_CLK1_CONTROL,
|
||||||
|
SI5351_REG_18_CLK2_CONTROL
|
||||||
|
};
|
||||||
|
uint8_t dat;
|
||||||
|
|
||||||
|
uint32_t P1;
|
||||||
|
uint32_t P2;
|
||||||
|
uint32_t P3;
|
||||||
|
uint32_t div4 = 0;
|
||||||
|
|
||||||
/* Output Multisynth Divider Equations
|
/* Output Multisynth Divider Equations
|
||||||
* where: a = div, b = num and c = denom
|
* where: a = div, b = num and c = denom
|
||||||
* P1 register is an 18-bit value using following formula:
|
* P1 register is an 18-bit value using following formula:
|
||||||
* P1[17:0] = 128 * a + int((128*b)/c) - 512
|
* P1[17:0] = 128 * a + floor(128*(b/c)) - 512
|
||||||
* P2 register is a 20-bit value using the following formula:
|
* P2 register is a 20-bit value using the following formula:
|
||||||
* P2[19:0] = (128 * b) % c
|
* P2[19:0] = 128 * b - c * floor(128*(b/c))
|
||||||
* P3 register is a 20-bit value using the following formula:
|
* P3 register is a 20-bit value using the following formula:
|
||||||
* P3[19:0] = c
|
* P3[19:0] = c
|
||||||
*/
|
*/
|
||||||
/* Set the main PLL config registers */
|
/* Set the main PLL config registers */
|
||||||
uint32_t P1 = 0;
|
if (div == 4) {
|
||||||
uint32_t P2 = 0;
|
div4 = SI5351_DIVBY4;
|
||||||
uint32_t P3 = 1;
|
P1 = P2 = 0;
|
||||||
if (div == 4)
|
P3 = 1;
|
||||||
rdiv|= SI5351_DIVBY4;
|
} else if (num == 0) {
|
||||||
else {
|
/* Integer mode */
|
||||||
num<<=7;
|
P1 = 128 * div - 512;
|
||||||
div<<=7;
|
P2 = 0;
|
||||||
P1 = div - 512; // Integer mode
|
P3 = 1;
|
||||||
if (num) { // Fractional mode
|
} else {
|
||||||
P1+= num / denom;
|
/* Fractional mode */
|
||||||
P2 = num % denom;
|
P1 = 128 * div + ((128 * num) / denom) - 512;
|
||||||
|
P2 = 128 * num - denom * ((128 * num) / denom);
|
||||||
P3 = denom;
|
P3 = denom;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Set the MSx config registers */
|
/* Set the MSx config registers */
|
||||||
uint8_t reg[9];
|
uint8_t reg[9];
|
||||||
reg[0] = msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2
|
reg[0] = msreg_base[output];
|
||||||
reg[1] = (P3 & 0x0FF00)>>8; // MSx_P3[15: 8]
|
reg[1] = (P3 & 0x0000FF00) >> 8;
|
||||||
reg[2] = (P3 & 0x000FF); // MSx_P3[ 7: 0]
|
reg[2] = (P3 & 0x000000FF);
|
||||||
reg[3] = ((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16]
|
reg[3] = ((P1 & 0x00030000) >> 16) | div4 | rdiv;
|
||||||
reg[4] = (P1 & 0x0FF00)>> 8; // MSx_P1[15: 8]
|
reg[4] = (P1 & 0x0000FF00) >> 8;
|
||||||
reg[5] = (P1 & 0x000FF); // MSx_P1[ 7: 0]
|
reg[5] = (P1 & 0x000000FF);
|
||||||
reg[6] = ((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16]
|
reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
|
||||||
reg[7] = (P2 & 0x0FF00)>>8; // MSx_P2[15: 8]
|
reg[7] = (P2 & 0x0000FF00) >> 8;
|
||||||
reg[8] = (P2 & 0x000FF); // MSx_P2[ 7: 0]
|
reg[8] = (P2 & 0x000000FF);
|
||||||
si5351_bulk_write(reg, 9);
|
si5351_bulk_write(reg, 9);
|
||||||
|
|
||||||
/* Configure the clk control and enable the output */
|
/* Configure the clk control and enable the output */
|
||||||
uint8_t dat = chctrl | SI5351_CLK_INPUT_MULTISYNTH_N;
|
dat = drive_strength | SI5351_CLK_INPUT_MULTISYNTH_N;
|
||||||
|
if (pllSource == SI5351_PLL_B)
|
||||||
|
dat |= SI5351_CLK_PLL_SELECT_B;
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
dat |= SI5351_CLK_INTEGER_MODE;
|
dat |= SI5351_CLK_INTEGER_MODE;
|
||||||
|
si5351_write(clkctrl[output], dat);
|
||||||
|
}
|
||||||
|
|
||||||
#if USE_CLK_CONTROL_CACHE == TRUE
|
static uint32_t
|
||||||
// Use cache for this reg, not update if not change
|
gcd(uint32_t x, uint32_t y)
|
||||||
static uint8_t clk_cache[3];
|
{
|
||||||
if (clk_cache[channel]!=dat) {
|
uint32_t z;
|
||||||
si5351_write(clkctrl[channel], dat);
|
while (y != 0) {
|
||||||
clk_cache[channel]=dat;
|
z = x % y;
|
||||||
|
x = y;
|
||||||
|
y = z;
|
||||||
}
|
}
|
||||||
#else
|
return x;
|
||||||
si5351_write(clkctrl[channel], dat);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find better approximate values for n/d
|
#define XTALFREQ 26000000L
|
||||||
#define MAX_DENOMINATOR ((1 << 20) - 1)
|
#define PLL_N 32
|
||||||
static inline void approximate_fraction(uint32_t *n, uint32_t *d)
|
#define PLLFREQ (XTALFREQ * PLL_N)
|
||||||
|
|
||||||
|
void
|
||||||
|
si5351_set_frequency_fixedpll(int channel, int pll, int pllfreq, int freq,
|
||||||
|
uint32_t rdiv, uint8_t drive_strength)
|
||||||
{
|
{
|
||||||
// cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227
|
int32_t div = pllfreq / freq; // range: 8 ~ 1800
|
||||||
uint32_t denom = *d;
|
int32_t num = pllfreq - freq * div;
|
||||||
if (denom > MAX_DENOMINATOR) {
|
int32_t denom = freq;
|
||||||
uint32_t num = *n;
|
//int32_t k = freq / (1<<20) + 1;
|
||||||
uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0;
|
int32_t k = gcd(num, denom);
|
||||||
while (denom != 0) {
|
num /= k;
|
||||||
uint32_t a = num / denom;
|
denom /= k;
|
||||||
uint32_t b = num % denom;
|
while (denom >= (1<<20)) {
|
||||||
uint32_t q2 = q0 + a*q1;
|
num >>= 1;
|
||||||
if (q2 > MAX_DENOMINATOR)
|
denom >>= 1;
|
||||||
break;
|
|
||||||
uint32_t p2 = p0 + a*p1;
|
|
||||||
p0 = p1; q0 = q1; p1 = p2; q1 = q2;
|
|
||||||
num = denom; denom = b;
|
|
||||||
}
|
}
|
||||||
*n = p1;
|
si5351_setupMultisynth(channel, pll, div, num, denom, rdiv, drive_strength);
|
||||||
*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
|
void
|
||||||
si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength)
|
si5351_set_frequency_fixeddiv(int channel, int pll, int freq, int div,
|
||||||
|
uint8_t drive_strength)
|
||||||
|
{
|
||||||
|
int32_t pllfreq = freq * div;
|
||||||
|
int32_t multi = pllfreq / XTALFREQ;
|
||||||
|
int32_t num = pllfreq - multi * XTALFREQ;
|
||||||
|
int32_t denom = XTALFREQ;
|
||||||
|
int32_t k = gcd(num, denom);
|
||||||
|
num /= k;
|
||||||
|
denom /= k;
|
||||||
|
while (denom >= (1<<20)) {
|
||||||
|
num >>= 1;
|
||||||
|
denom >>= 1;
|
||||||
|
}
|
||||||
|
si5351_setupPLL(pll, multi, num, denom);
|
||||||
|
si5351_setupMultisynth(channel, pll, div, 0, 1, SI5351_R_DIV_1, drive_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1~100MHz fixed PLL 900MHz, fractional divider
|
||||||
|
* 100~150MHz fractional PLL 600-900MHz, fixed divider 6
|
||||||
|
* 150~200MHz fractional PLL 600-900MHz, fixed divider 4
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
si5351_set_frequency(int channel, int freq, uint8_t drive_strength)
|
||||||
{
|
{
|
||||||
if (freq <= 100000000) {
|
if (freq <= 100000000) {
|
||||||
si5351_setupPLL(SI5351_PLL_B, 32, 0, 1);
|
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);
|
si5351_set_frequency_fixedpll(channel, SI5351_PLL_B, PLLFREQ, freq, SI5351_R_DIV_1, drive_strength);
|
||||||
} else if (freq < 150000000) {
|
} else if (freq < 150000000) {
|
||||||
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 6, drive_strength, 1);
|
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 6, drive_strength);
|
||||||
} else {
|
} else {
|
||||||
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength, 1);
|
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
int current_band = -1;
|
||||||
|
|
||||||
|
#define DELAY_NORMAL 3
|
||||||
|
#define DELAY_BANDCHANGE 1
|
||||||
|
#define DELAY_LOWBAND 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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:
|
* configure output as follows:
|
||||||
* CLK0: frequency + offset
|
* CLK0: frequency + offset
|
||||||
* CLK1: frequency
|
* CLK1: frequency
|
||||||
* CLK2: fixed 8MHz
|
* CLK2: fixed 8MHz
|
||||||
*/
|
*/
|
||||||
|
#define CLK2_FREQUENCY 8000000L
|
||||||
int
|
int
|
||||||
si5351_set_frequency(uint32_t freq, uint8_t drive_strength)
|
si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength)
|
||||||
{
|
{
|
||||||
uint8_t band;
|
int band;
|
||||||
int delay = DELAY_NORMAL;
|
int delay = DELAY_NORMAL;
|
||||||
if (freq == current_freq)
|
uint32_t ofreq = freq + offset;
|
||||||
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 rdiv = SI5351_R_DIV_1;
|
||||||
uint32_t fdiv;
|
if (freq >= config.harmonic_freq_threshold * 3) {
|
||||||
// Fix possible incorrect input
|
freq /= 5;
|
||||||
drive_strength&=SI5351_CLK_DRIVE_STRENGTH_MASK;
|
ofreq /= 7;
|
||||||
|
|
||||||
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) {
|
} else if (freq >= config.harmonic_freq_threshold) {
|
||||||
mul = 3;
|
freq /= 3;
|
||||||
omul = 5;
|
ofreq /= 5;
|
||||||
} else if (freq <= 500000U) {
|
}
|
||||||
|
if (freq <= 100000000) {
|
||||||
|
band = 0;
|
||||||
|
} else if (freq < 150000000) {
|
||||||
|
band = 1;
|
||||||
|
} else {
|
||||||
|
band = 2;
|
||||||
|
}
|
||||||
|
if (freq <= 500000) {
|
||||||
rdiv = SI5351_R_DIV_64;
|
rdiv = SI5351_R_DIV_64;
|
||||||
freq<<= 6;
|
} else if (freq <= 4000000) {
|
||||||
ofreq<<= 6;
|
|
||||||
} else if (freq <= 4000000U) {
|
|
||||||
rdiv = SI5351_R_DIV_8;
|
rdiv = SI5351_R_DIV_8;
|
||||||
freq<<= 3;
|
|
||||||
ofreq<<= 3;
|
|
||||||
}
|
}
|
||||||
band = si5351_get_band(freq / mul);
|
|
||||||
|
#if 1
|
||||||
|
if (current_band != band)
|
||||||
|
si5351_disable_output();
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (band) {
|
switch (band) {
|
||||||
|
case 0:
|
||||||
|
// fractional divider mode. only PLL A is used.
|
||||||
|
if (current_band == 1 || current_band == 2)
|
||||||
|
si5351_setupPLL(SI5351_PLL_A, 32, 0, 1);
|
||||||
|
// Set PLL twice on changing from band 2
|
||||||
|
if (current_band == 2)
|
||||||
|
si5351_setupPLL(SI5351_PLL_A, 32, 0, 1);
|
||||||
|
|
||||||
|
if (rdiv == SI5351_R_DIV_8) {
|
||||||
|
freq *= 8;
|
||||||
|
ofreq *= 8;
|
||||||
|
} else if (rdiv == SI5351_R_DIV_64) {
|
||||||
|
freq *= 64;
|
||||||
|
ofreq *= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
si5351_set_frequency_fixedpll(0, SI5351_PLL_A, PLLFREQ, ofreq,
|
||||||
|
rdiv, drive_strength);
|
||||||
|
si5351_set_frequency_fixedpll(1, SI5351_PLL_A, PLLFREQ, freq,
|
||||||
|
rdiv, drive_strength);
|
||||||
|
//if (current_band != 0)
|
||||||
|
si5351_set_frequency_fixedpll(2, SI5351_PLL_A, PLLFREQ, CLK2_FREQUENCY,
|
||||||
|
SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA);
|
||||||
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq =
|
// Set PLL twice on changing from band 2
|
||||||
// CLK2_FREQUENCY
|
if (current_band == 2) {
|
||||||
if (current_band != 1) {
|
si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 6, drive_strength);
|
||||||
si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1);
|
si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength);
|
||||||
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,
|
// div by 6 mode. both PLL A and B are dedicated for CLK0, CLK1
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 6, drive_strength);
|
||||||
si5351_set_frequency_fixedpll(1, (uint64_t)mul * XTALFREQ * PLL_N, freq, rdiv,
|
si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength);
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
si5351_set_frequency_fixedpll(2, SI5351_PLL_B, freq * 6, CLK2_FREQUENCY,
|
||||||
|
SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA);
|
||||||
break;
|
break;
|
||||||
case 2: // fdiv = 6
|
|
||||||
case 3: // fdiv = 4;
|
case 2:
|
||||||
fdiv = (band == 2) ? 6 : 4;
|
// div by 4 mode. both PLL A and B are dedicated for CLK0, CLK1
|
||||||
// Setup CH0 and CH1 constant fdiv divider at change
|
si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 4, drive_strength);
|
||||||
if (current_band != band) {
|
si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 4, drive_strength);
|
||||||
si5351_setupMultisynth(0, fdiv, 0, 1, SI5351_R_DIV_1,
|
si5351_set_frequency_fixedpll(2, SI5351_PLL_B, freq * 4, CLK2_FREQUENCY,
|
||||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA);
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_band != band) {
|
if (current_band != band) {
|
||||||
si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B);
|
si5351_reset_pll();
|
||||||
|
#if 1
|
||||||
|
si5351_enable_output();
|
||||||
|
#endif
|
||||||
|
delay += DELAY_BANDCHANGE;
|
||||||
|
}
|
||||||
|
if (band == 0)
|
||||||
|
delay += DELAY_LOWBAND;
|
||||||
|
|
||||||
current_band = band;
|
current_band = band;
|
||||||
}
|
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
88
si5351.h
88
si5351.h
|
|
@ -17,39 +17,12 @@
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
#define SI5351_PLL_A 0
|
||||||
|
#define SI5351_PLL_B 1
|
||||||
|
|
||||||
#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3
|
#define SI5351_MULTISYNTH_DIV_4 4
|
||||||
#define SI5351_CLK0_EN (1<<0)
|
#define SI5351_MULTISYNTH_DIV_6 6
|
||||||
#define SI5351_CLK1_EN (1<<1)
|
#define SI5351_MULTISYNTH_DIV_8 8
|
||||||
#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_1 (0<<4)
|
||||||
#define SI5351_R_DIV_2 (1<<4)
|
#define SI5351_R_DIV_2 (1<<4)
|
||||||
#define SI5351_R_DIV_4 (2<<4)
|
#define SI5351_R_DIV_4 (2<<4)
|
||||||
|
|
@ -58,6 +31,35 @@
|
||||||
#define SI5351_R_DIV_32 (5<<4)
|
#define SI5351_R_DIV_32 (5<<4)
|
||||||
#define SI5351_R_DIV_64 (6<<4)
|
#define SI5351_R_DIV_64 (6<<4)
|
||||||
#define SI5351_R_DIV_128 (7<<4)
|
#define SI5351_R_DIV_128 (7<<4)
|
||||||
|
#define SI5351_DIVBY4 (3<<2)
|
||||||
|
|
||||||
|
#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3
|
||||||
|
#define SI5351_REG_16_CLK0_CONTROL 16
|
||||||
|
#define SI5351_REG_17_CLK1_CONTROL 17
|
||||||
|
#define SI5351_REG_18_CLK2_CONTROL 18
|
||||||
|
#define SI5351_REG_26_PLL_A 26
|
||||||
|
#define SI5351_REG_34_PLL_B 34
|
||||||
|
#define SI5351_REG_42_MULTISYNTH0 42
|
||||||
|
#define SI5351_REG_50_MULTISYNTH1 50
|
||||||
|
#define SI5351_REG_58_MULTISYNTH2 58
|
||||||
|
|
||||||
|
#define SI5351_CLK_POWERDOWN (1<<7)
|
||||||
|
#define SI5351_CLK_INTEGER_MODE (1<<6)
|
||||||
|
#define SI5351_CLK_PLL_SELECT_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_177_PLL_RESET 177
|
#define SI5351_REG_177_PLL_RESET 177
|
||||||
#define SI5351_PLL_RESET_B (1<<7)
|
#define SI5351_PLL_RESET_B (1<<7)
|
||||||
|
|
@ -68,10 +70,20 @@
|
||||||
#define SI5351_CRYSTAL_LOAD_8PF (2<<6)
|
#define SI5351_CRYSTAL_LOAD_8PF (2<<6)
|
||||||
#define SI5351_CRYSTAL_LOAD_10PF (3<<6)
|
#define SI5351_CRYSTAL_LOAD_10PF (3<<6)
|
||||||
|
|
||||||
void si5351_init(void);
|
#define SI5351_CRYSTAL_FREQ_25MHZ 25000000
|
||||||
void si5351_disable_output(void);
|
|
||||||
void si5351_enable_output(void);
|
|
||||||
|
|
||||||
void si5351_set_frequency_offset(int32_t offset);
|
void si5351_init(void);
|
||||||
int si5351_set_frequency(uint32_t freq, uint8_t drive_strength);
|
|
||||||
uint32_t si5351_get_frequency(void);
|
void si5351_setupPLL(uint8_t pll, /* SI5351_PLL_A or SI5351_PLL_B */
|
||||||
|
uint8_t mult,
|
||||||
|
uint32_t num,
|
||||||
|
uint32_t denom);
|
||||||
|
void si5351_setupMultisynth(uint8_t output,
|
||||||
|
uint8_t pllSource,
|
||||||
|
uint32_t div,
|
||||||
|
uint32_t num,
|
||||||
|
uint32_t denom,
|
||||||
|
uint32_t rdiv,
|
||||||
|
uint8_t drive_strength);
|
||||||
|
|
||||||
|
void si5351_set_frequency(int channel, int freq, uint8_t drive_strength);
|
||||||
|
|
|
||||||
155
tlv320aic3204.c
155
tlv320aic3204.c
|
|
@ -25,78 +25,74 @@
|
||||||
|
|
||||||
#define wait_ms(ms) chThdSleepMilliseconds(ms)
|
#define wait_ms(ms) chThdSleepMilliseconds(ms)
|
||||||
|
|
||||||
static const uint8_t conf_data[] = {
|
static const uint8_t conf_data_pll[] = {
|
||||||
// reg, data,
|
// len, ( reg, data ),
|
||||||
// PLL clock config
|
2, 0x00, 0x00, /* Initialize to Page 0 */
|
||||||
0x00, 0x00, /* Initialize to Page 0 */
|
2, 0x01, 0x01, /* Initialize the device through software reset */
|
||||||
0x01, 0x01, /* Initialize the device through software reset */
|
2, 0x04, 0x43, /* PLL Clock High, MCLK, PLL */
|
||||||
0x04, 0x43, /* PLL Clock High, MCLK, PLL */
|
|
||||||
#ifdef REFCLK_8000KHZ
|
#ifdef REFCLK_8000KHZ
|
||||||
/* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
|
/* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
|
||||||
0x05, 0x91, /* Power up PLL, P=1,R=1 */
|
2, 0x05, 0x91, /* Power up PLL, P=1,R=1 */
|
||||||
0x06, 0x0a, /* J=10 */
|
2, 0x06, 0x0a, /* J=10 */
|
||||||
0x07, 29, /* D=7520 = (29<<8) + 96 */
|
2, 0x07, 29, /* D=7520 = (29<<8) + 96 */
|
||||||
0x08, 96,
|
2, 0x08, 96,
|
||||||
#endif
|
#endif
|
||||||
// Clock config, default fs=48kHz
|
0 // sentinel
|
||||||
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[] = {
|
// default fs=48kHz
|
||||||
// reg, data,
|
static const uint8_t conf_data_clk[] = {
|
||||||
0x00, 0x00, /* Select Page 0 */
|
2, 0x0b, 0x82, /* Power up the NDAC divider with value 2 */
|
||||||
0x51, 0xc0, /* Power up Left and Right ADC Channels */
|
2, 0x0c, 0x87, /* Power up the MDAC divider with value 7 */
|
||||||
0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */
|
2, 0x0d, 0x00, /* Program the OSR of DAC to 128 */
|
||||||
|
2, 0x0e, 0x80,
|
||||||
|
2, 0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */
|
||||||
|
//2, 0x3c, 25, /* Set the DAC Mode to PRB_P25 */
|
||||||
|
2, 0x1b, 0x0c, /* Set the BCLK,WCLK as output */
|
||||||
|
2, 0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */
|
||||||
|
2, 0x25, 0xee, /* DAC power up */
|
||||||
|
|
||||||
|
2, 0x12, 0x82, /* Power up the NADC divider with value 2 */
|
||||||
|
2, 0x13, 0x87, /* Power up the MADC divider with value 7 */
|
||||||
|
2, 0x14, 0x80, /* Program the OSR of ADC to 128 */
|
||||||
|
2, 0x3d, 0x01, /* Select ADC PRB_R1 */
|
||||||
|
0 // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t conf_data_ch3_select[] = {
|
static const uint8_t conf_data_routing[] = {
|
||||||
// reg, data,
|
2, 0x00, 0x01, /* Select Page 1 */
|
||||||
0x00, 0x01, /* Select Page 1 */
|
2, 0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/
|
||||||
0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */
|
2, 0x02, 0x01, /* Enable Master Analog Power Control */
|
||||||
0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */
|
2, 0x7b, 0x01, /* Set the REF charging time to 40ms */
|
||||||
|
2, 0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */
|
||||||
|
2, 0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */
|
||||||
|
|
||||||
|
2, 0x3d, 0x00, /* Select ADC PTM_R4 */
|
||||||
|
2, 0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */
|
||||||
|
2, 0x7b, 0x01, /* Set the REF charging time to 40ms */
|
||||||
|
2, 0x34, 0x10, /* Route IN2L to LEFT_P with 10K */
|
||||||
|
2, 0x36, 0x10, /* Route IN2R to LEFT_N with 10K */
|
||||||
|
2, 0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */
|
||||||
|
2, 0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */
|
||||||
|
2, 0x3b, 0, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
|
||||||
|
2, 0x3c, 0, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
|
||||||
|
0 // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t conf_data_ch1_select[] = {
|
const uint8_t conf_data_unmute[] = {
|
||||||
// reg, data,
|
2, 0x00, 0x00, /* Select Page 0 */
|
||||||
0x00, 0x01, /* Select Page 1 */
|
2, 0x51, 0xc0, /* Power up Left and Right ADC Channels */
|
||||||
0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */
|
2, 0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */
|
||||||
0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */
|
0 // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void
|
static void
|
||||||
tlv320aic3204_bulk_write(const uint8_t *buf, int len)
|
tlv320aic3204_bulk_write(const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
(void)i2cMasterTransmitTimeout(&I2CD1, AIC3204_ADDR, buf, len, NULL, 0, 1000);
|
int addr = AIC3204_ADDR;
|
||||||
|
i2cAcquireBus(&I2CD1);
|
||||||
|
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
|
||||||
|
i2cReleaseBus(&I2CD1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -113,32 +109,49 @@ tlv320aic3204_read(uint8_t d0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tlv320aic3204_config(const uint8_t *data, int len)
|
tlv320aic3204_config(const uint8_t *data)
|
||||||
{
|
{
|
||||||
i2cAcquireBus(&I2CD1);
|
const uint8_t *p = data;
|
||||||
for (; len--; data += 2)
|
while (*p) {
|
||||||
tlv320aic3204_bulk_write(data, 2);
|
uint8_t len = *p++;
|
||||||
i2cReleaseBus(&I2CD1);
|
tlv320aic3204_bulk_write(p, len);
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlv320aic3204_init(void)
|
void tlv320aic3204_init(void)
|
||||||
{
|
{
|
||||||
tlv320aic3204_config(conf_data, sizeof(conf_data)/2);
|
tlv320aic3204_config(conf_data_pll);
|
||||||
|
tlv320aic3204_config(conf_data_clk);
|
||||||
|
tlv320aic3204_config(conf_data_routing);
|
||||||
wait_ms(40);
|
wait_ms(40);
|
||||||
tlv320aic3204_config(conf_data_unmute, sizeof(conf_data_unmute)/2);
|
tlv320aic3204_config(conf_data_unmute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlv320aic3204_select(int channel)
|
void tlv320aic3204_select(int channel)
|
||||||
{
|
{
|
||||||
tlv320aic3204_config(channel ? conf_data_ch1_select : conf_data_ch3_select, sizeof(conf_data_ch3_select)/2);
|
const uint8_t ch3[] = {
|
||||||
|
2, 0x00, 0x01, /* Select Page 1 */
|
||||||
|
2, 0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */
|
||||||
|
2, 0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */
|
||||||
|
0 // sentinel
|
||||||
|
};
|
||||||
|
const uint8_t ch1[] = {
|
||||||
|
2, 0x00, 0x01, /* Select Page 1 */
|
||||||
|
2, 0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */
|
||||||
|
2, 0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */
|
||||||
|
0 // sentinel
|
||||||
|
};
|
||||||
|
tlv320aic3204_config(channel ? ch1 : ch3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlv320aic3204_set_gain(int lgain, int rgain)
|
void tlv320aic3204_set_gain(int lgain, int rgain)
|
||||||
{
|
{
|
||||||
uint8_t data[] = {
|
uint8_t data[] = {
|
||||||
0x00, 0x01, /* Select Page 1 */
|
2, 0x00, 0x01, /* Select Page 1 */
|
||||||
0x3b, lgain, /* Unmute Left MICPGA, set gain */
|
2, 0x3b, lgain, /* Unmute Left MICPGA, set gain */
|
||||||
0x3c, rgain, /* Unmute Right MICPGA, set gain */
|
2, 0x3c, rgain, /* Unmute Right MICPGA, set gain */
|
||||||
|
0 // sentinel
|
||||||
};
|
};
|
||||||
tlv320aic3204_config(data, sizeof(data)/2);
|
tlv320aic3204_config(data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue