mirror of
https://github.com/ttrftech/NanoVNA.git
synced 2025-12-06 03:31:59 +01:00
Compare commits
70 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d02db797a7 | ||
|
|
4d64ef6e48 | ||
|
|
bc1b57c3f0 | ||
|
|
64de4d5d87 | ||
|
|
e57292ea01 | ||
|
|
fb57511f9a | ||
|
|
56b0d3ad8a | ||
|
|
ba7d358d35 | ||
|
|
d7c7d8faeb | ||
|
|
fe7a1ac4de | ||
|
|
5a10105b1a | ||
|
|
1656342eeb | ||
|
|
0d407577f8 | ||
|
|
a4821604a5 | ||
|
|
597c2c2958 | ||
|
|
23c765b719 | ||
|
|
3eb8a4cfe9 | ||
|
|
fdb3886b0f | ||
|
|
45dfd7d970 | ||
|
|
8a11eaa764 | ||
|
|
ec81a01226 | ||
|
|
922b66abdb | ||
|
|
88617a31fe | ||
|
|
8bdb650212 | ||
|
|
6f25d0d43f | ||
|
|
51b5cce016 | ||
|
|
10ae59e786 | ||
|
|
3714e05395 | ||
|
|
eebb625b9d | ||
|
|
04fb661b1a | ||
|
|
f9074149bb | ||
|
|
19121b3371 | ||
|
|
2d273a5548 | ||
|
|
a19722cdc3 | ||
|
|
90407d5730 | ||
|
|
5cf86ee1a6 | ||
|
|
a2d90a5e91 | ||
|
|
77b5d0bcc8 | ||
|
|
c40d78d80f | ||
|
|
608482a970 | ||
|
|
ba5bf9c1ad | ||
|
|
6befd57bc1 | ||
|
|
7c2e4364e6 | ||
|
|
45f04420cb | ||
|
|
fc6e090595 | ||
|
|
bb7127fdd0 | ||
|
|
e896f32803 | ||
|
|
12d53738bc | ||
|
|
a43b6e3acc | ||
|
|
b77e1d6680 | ||
|
|
f1cc60e99e | ||
|
|
f6b28c2c14 | ||
|
|
18c5ca9157 | ||
|
|
7f5948c4b8 | ||
|
|
153585ff1f | ||
|
|
ccb3693516 | ||
|
|
cc3370c962 | ||
|
|
a164a5765a | ||
|
|
0116c529ea | ||
|
|
cb587d05a4 | ||
|
|
95b3f6f7d0 | ||
|
|
17734f257d | ||
|
|
d386b0823c | ||
|
|
b7934745ca | ||
|
|
a4e9b7a139 | ||
|
|
48ff4893d3 | ||
|
|
d2431f0cdc | ||
|
|
5ee23be06f | ||
|
|
c92987c52e | ||
|
|
1177d87498 |
156
.clang-format
Normal file
156
.clang-format
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
---
|
||||
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
Normal file
31
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"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,3 +1,4 @@
|
|||
{
|
||||
"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",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "make",
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "make",
|
||||
"group": "build"
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "flash",
|
||||
"type": "shell",
|
||||
"command": "make dfu flash",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -9,9 +9,10 @@
|
|||
* Check 1 byte of char bitmap data for get width
|
||||
*/
|
||||
|
||||
#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7])
|
||||
#define FONT_GET_WIDTH(ch) (8-x5x7_bits[ch*7]&7)
|
||||
#define FONT_GET_HEIGHT 7
|
||||
#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7])
|
||||
#define FONT_GET_WIDTH(ch) (8-x5x7_bits[ch*7]&7)
|
||||
#define FONT_MAX_WIDTH 7
|
||||
#define FONT_GET_HEIGHT 7
|
||||
|
||||
#define CHAR5x7_WIDTH_1px 0x07
|
||||
#define CHAR5x7_WIDTH_2px 0x06
|
||||
|
|
|
|||
23
Makefile
23
Makefile
|
|
@ -81,6 +81,10 @@ endif
|
|||
# Project, sources and paths
|
||||
#
|
||||
|
||||
# Dvice node to flash
|
||||
DEVICE = /dev/cu.usbmodem401
|
||||
#DEVICE = /dev/ttyACM0
|
||||
|
||||
# Define project name here
|
||||
PROJECT = ch
|
||||
|
||||
|
|
@ -100,9 +104,9 @@ include $(CHIBIOS)/os/hal/osal/rt/osal.mk
|
|||
include $(CHIBIOS)/os/rt/rt.mk
|
||||
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk
|
||||
# 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/various/shell/shell.mk
|
||||
#include $(CHIBIOS)/os/various/shell/shell.mk
|
||||
|
||||
# Define linker script file here
|
||||
#LDSCRIPT= $(STARTUPLD)/STM32F072xB.ld
|
||||
|
|
@ -118,12 +122,9 @@ CSRC = $(STARTUPSRC) \
|
|||
$(PLATFORMSRC) \
|
||||
$(BOARDSRC) \
|
||||
$(STREAMSSRC) \
|
||||
$(SHELLSRC) \
|
||||
usbcfg.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
|
||||
# setting.
|
||||
CPPSRC =
|
||||
|
|
@ -153,8 +154,7 @@ ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
|
|||
|
||||
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
|
||||
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
|
||||
$(STREAMSINC) $(SHELLINC)
|
||||
# $(TESTINC)
|
||||
$(STREAMSINC)
|
||||
|
||||
#
|
||||
# Project, sources and paths
|
||||
|
|
@ -176,7 +176,7 @@ CPPC = $(TRGT)g++
|
|||
LD = $(TRGT)gcc
|
||||
#LD = $(TRGT)g++
|
||||
CP = $(TRGT)objcopy
|
||||
AS = $(TRGT)gcc -x assembler-with-cpp
|
||||
AS = $(TRGT)gcc -x assembler-with-cpp -ggdb
|
||||
AR = $(TRGT)ar
|
||||
OD = $(TRGT)objdump
|
||||
SZ = $(TRGT)size
|
||||
|
|
@ -229,9 +229,4 @@ flash: build/ch.bin
|
|||
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
|
||||
|
||||
dfu:
|
||||
-@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
|
||||
|
||||
-printf "reset dfu\r" >$(DEVICE) && sleep 1
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@
|
|||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
/*
|
||||
* Setup for the Strawberry Linux STbee
|
||||
*/
|
||||
|
||||
/*
|
||||
* Board identifier.
|
||||
*/
|
||||
|
|
@ -130,8 +126,8 @@
|
|||
PIN_MODE_ALTERNATE(GPIOA_MCO) | \
|
||||
PIN_MODE_INPUT(9U) | \
|
||||
PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \
|
||||
PIN_MODE_INPUT(GPIOA_USB_DM) | \
|
||||
PIN_MODE_INPUT(GPIOA_USB_DP) | \
|
||||
PIN_MODE_ALTERNATE(GPIOA_USB_DM) | \
|
||||
PIN_MODE_ALTERNATE(GPIOA_USB_DP) | \
|
||||
PIN_MODE_ALTERNATE(GPIOA_JTMS) | \
|
||||
PIN_MODE_ALTERNATE(GPIOA_JTCK) | \
|
||||
PIN_MODE_OUTPUT(GPIOA_LCD_RESET))
|
||||
|
|
@ -161,7 +157,7 @@
|
|||
PIN_OSPEED_2M(7) | \
|
||||
PIN_OSPEED_100M(GPIOA_MCO) | \
|
||||
PIN_OSPEED_100M(9) | \
|
||||
PIN_OSPEED_100M(10) | \
|
||||
PIN_OSPEED_100M(GPIOA_USB_DISC) | \
|
||||
PIN_OSPEED_100M(GPIOA_USB_DM) | \
|
||||
PIN_OSPEED_100M(GPIOA_USB_DP) | \
|
||||
PIN_OSPEED_100M(GPIOA_JTMS) | \
|
||||
|
|
@ -177,7 +173,7 @@
|
|||
PIN_PUPDR_FLOATING(7) | \
|
||||
PIN_PUPDR_PULLUP(GPIOA_MCO) | \
|
||||
PIN_PUPDR_PULLUP(9) | \
|
||||
PIN_PUPDR_PULLUP(GPIOA_USB_DISC) | \
|
||||
PIN_PUPDR_FLOATING(GPIOA_USB_DISC) | \
|
||||
PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \
|
||||
PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \
|
||||
PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ There are seveal numbers of great companion PC tools from third-party.
|
|||
|
||||
## Documentation
|
||||
|
||||
* [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
|
||||
* [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)
|
||||
|
||||
## Reference
|
||||
|
||||
|
|
@ -105,6 +105,7 @@ Hardware design material is disclosed to prevent bad quality clone. Please let m
|
|||
## Authorized Distributor
|
||||
|
||||
* [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
|
||||
|
||||
|
|
|
|||
124
adc.c
124
adc.c
|
|
@ -28,80 +28,82 @@
|
|||
#define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */
|
||||
#define ADC_CFGR1_RES_12BIT (0U << 3U)
|
||||
|
||||
#define VNA_ADC ADC1
|
||||
|
||||
void adc_init(void)
|
||||
{
|
||||
rccEnableADC1(FALSE);
|
||||
|
||||
/* Ensure flag states */
|
||||
ADC1->IER = 0;
|
||||
VNA_ADC->IER = 0;
|
||||
|
||||
/* Calibration procedure.*/
|
||||
ADC->CCR = 0;
|
||||
if (ADC1->CR & ADC_CR_ADEN) {
|
||||
ADC1->CR |= ~ADC_CR_ADDIS; /* Disable ADC */
|
||||
if (VNA_ADC->CR & ADC_CR_ADEN) {
|
||||
VNA_ADC->CR |= ~ADC_CR_ADDIS; /* Disable ADC */
|
||||
}
|
||||
while (ADC1->CR & ADC_CR_ADEN)
|
||||
while (VNA_ADC->CR & ADC_CR_ADEN)
|
||||
;
|
||||
ADC1->CFGR1 &= ~ADC_CFGR1_DMAEN;
|
||||
ADC1->CR |= ADC_CR_ADCAL;
|
||||
while (ADC1->CR & ADC_CR_ADCAL)
|
||||
VNA_ADC->CFGR1 &= ~ADC_CFGR1_DMAEN;
|
||||
VNA_ADC->CR |= ADC_CR_ADCAL;
|
||||
while (VNA_ADC->CR & ADC_CR_ADCAL)
|
||||
;
|
||||
|
||||
if (ADC1->ISR & ADC_ISR_ADRDY) {
|
||||
ADC1->ISR |= ADC_ISR_ADRDY; /* clear ADRDY */
|
||||
if (VNA_ADC->ISR & ADC_ISR_ADRDY) {
|
||||
VNA_ADC->ISR |= ADC_ISR_ADRDY; /* clear ADRDY */
|
||||
}
|
||||
/* Enable ADC */
|
||||
ADC1->CR |= ADC_CR_ADEN;
|
||||
while (!(ADC1->ISR & ADC_ISR_ADRDY))
|
||||
VNA_ADC->CR |= ADC_CR_ADEN;
|
||||
while (!(VNA_ADC->ISR & ADC_ISR_ADRDY))
|
||||
;
|
||||
}
|
||||
|
||||
uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel)
|
||||
uint16_t adc_single_read(uint32_t chsel)
|
||||
{
|
||||
/* ADC setup */
|
||||
adc->ISR = adc->ISR;
|
||||
adc->IER = 0;
|
||||
adc->TR = ADC_TR(0, 0);
|
||||
adc->SMPR = ADC_SMPR_SMP_239P5;
|
||||
adc->CFGR1 = ADC_CFGR1_RES_12BIT;
|
||||
adc->CHSELR = chsel;
|
||||
VNA_ADC->ISR = VNA_ADC->ISR;
|
||||
VNA_ADC->IER = 0;
|
||||
VNA_ADC->TR = ADC_TR(0, 0);
|
||||
VNA_ADC->SMPR = ADC_SMPR_SMP_239P5;
|
||||
VNA_ADC->CFGR1 = ADC_CFGR1_RES_12BIT;
|
||||
VNA_ADC->CHSELR = chsel;
|
||||
|
||||
/* ADC conversion start.*/
|
||||
adc->CR |= ADC_CR_ADSTART;
|
||||
VNA_ADC->CR |= ADC_CR_ADSTART;
|
||||
|
||||
while (adc->CR & ADC_CR_ADSTART)
|
||||
while (VNA_ADC->CR & ADC_CR_ADSTART)
|
||||
;
|
||||
|
||||
return adc->DR;
|
||||
return VNA_ADC->DR;
|
||||
}
|
||||
|
||||
int16_t adc_vbat_read(ADC_TypeDef *adc)
|
||||
int16_t adc_vbat_read(void)
|
||||
{
|
||||
// 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 VBAT_DIODE_VF 500
|
||||
#define VREFINT_CAL (*((uint16_t*)0x1FFFF7BA))
|
||||
float vbat = 0;
|
||||
float vrefint = 0;
|
||||
|
||||
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN;
|
||||
// VREFINT == ADC_IN17
|
||||
vrefint = adc_single_read(adc, ADC_CHSELR_CHSEL17);
|
||||
// VBAT == ADC_IN18
|
||||
// VBATEN enables resiter devider circuit. It consume vbat power.
|
||||
vbat = adc_single_read(adc, ADC_CHSELR_CHSEL18);
|
||||
ADC->CCR &= ~(ADC_CCR_VREFEN | ADC_CCR_VBATEN);
|
||||
|
||||
uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * vbat * 2 / (vrefint * ((1<<12)-1)));
|
||||
if (vbat_raw < 100) {
|
||||
// maybe D2 is not installed
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vbat_raw + VBAT_DIODE_VF;
|
||||
|
||||
adc_stop();
|
||||
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN;
|
||||
// VREFINT == ADC_IN17
|
||||
uint32_t vrefint = adc_single_read(ADC_CHSELR_CHSEL17);
|
||||
// VBAT == ADC_IN18
|
||||
// VBATEN enables resiter devider circuit. It consume vbat power.
|
||||
uint32_t vbat = adc_single_read(ADC_CHSELR_CHSEL18);
|
||||
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 * (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) {
|
||||
// maybe D2 is not installed
|
||||
return -1;
|
||||
}
|
||||
return vbat_raw + config.vbat_offset;
|
||||
}
|
||||
|
||||
void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel)
|
||||
void adc_start_analog_watchdogd(uint32_t chsel)
|
||||
{
|
||||
uint32_t cfgr1;
|
||||
|
||||
|
|
@ -111,38 +113,38 @@ void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel)
|
|||
|
||||
/* ADC setup, if it is defined a callback for the analog watch dog then it
|
||||
is enabled.*/
|
||||
adc->ISR = adc->ISR;
|
||||
adc->IER = ADC_IER_AWDIE;
|
||||
adc->TR = ADC_TR(0, TOUCH_THRESHOLD);
|
||||
adc->SMPR = ADC_SMPR_SMP_1P5;
|
||||
adc->CHSELR = chsel;
|
||||
VNA_ADC->ISR = VNA_ADC->ISR;
|
||||
VNA_ADC->IER = ADC_IER_AWDIE;
|
||||
VNA_ADC->TR = ADC_TR(0, TOUCH_THRESHOLD);
|
||||
VNA_ADC->SMPR = ADC_SMPR_SMP_1P5;
|
||||
VNA_ADC->CHSELR = chsel;
|
||||
|
||||
/* ADC configuration and start.*/
|
||||
adc->CFGR1 = cfgr1;
|
||||
VNA_ADC->CFGR1 = cfgr1;
|
||||
|
||||
/* ADC conversion start.*/
|
||||
adc->CR |= ADC_CR_ADSTART;
|
||||
VNA_ADC->CR |= ADC_CR_ADSTART;
|
||||
}
|
||||
|
||||
void adc_stop(ADC_TypeDef *adc)
|
||||
void adc_stop(void)
|
||||
{
|
||||
if (adc->CR & ADC_CR_ADEN) {
|
||||
if (adc->CR & ADC_CR_ADSTART) {
|
||||
adc->CR |= ADC_CR_ADSTP;
|
||||
while (adc->CR & ADC_CR_ADSTP)
|
||||
if (VNA_ADC->CR & ADC_CR_ADEN) {
|
||||
if (VNA_ADC->CR & ADC_CR_ADSTART) {
|
||||
VNA_ADC->CR |= ADC_CR_ADSTP;
|
||||
while (VNA_ADC->CR & ADC_CR_ADSTP)
|
||||
;
|
||||
}
|
||||
|
||||
/* adc->CR |= ADC_CR_ADDIS;
|
||||
while (adc->CR & ADC_CR_ADDIS)
|
||||
/* VNA_ADC->CR |= ADC_CR_ADDIS;
|
||||
while (VNA_ADC->CR & ADC_CR_ADDIS)
|
||||
;*/
|
||||
}
|
||||
}
|
||||
|
||||
void adc_interrupt(ADC_TypeDef *adc)
|
||||
void adc_interrupt(void)
|
||||
{
|
||||
uint32_t isr = adc->ISR;
|
||||
adc->ISR = isr;
|
||||
uint32_t isr = VNA_ADC->ISR;
|
||||
VNA_ADC->ISR = isr;
|
||||
|
||||
if (isr & ADC_ISR_OVR) {
|
||||
/* ADC overflow condition, this could happen only if the DMA is unable
|
||||
|
|
@ -159,7 +161,7 @@ OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER)
|
|||
{
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
|
||||
adc_interrupt(ADC1);
|
||||
adc_interrupt();
|
||||
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
|
|
|
|||
10
chconf.h
10
chconf.h
|
|
@ -156,7 +156,7 @@
|
|||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_WAITEXIT TRUE
|
||||
#define CH_CFG_USE_WAITEXIT FALSE
|
||||
|
||||
/**
|
||||
* @brief Semaphores APIs.
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_MUTEXES TRUE
|
||||
#define CH_CFG_USE_MUTEXES FALSE
|
||||
|
||||
/**
|
||||
* @brief Enables recursive behavior on mutexes.
|
||||
|
|
@ -193,7 +193,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||
*/
|
||||
#define CH_CFG_USE_MUTEXES_RECURSIVE TRUE
|
||||
#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
|
||||
|
||||
/**
|
||||
* @brief Conditional Variables APIs.
|
||||
|
|
@ -221,7 +221,7 @@
|
|||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_EVENTS TRUE
|
||||
#define CH_CFG_USE_EVENTS FALSE
|
||||
|
||||
/**
|
||||
* @brief Events Flags APIs with timeout.
|
||||
|
|
@ -231,7 +231,7 @@
|
|||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_EVENTS.
|
||||
*/
|
||||
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
|
||||
#define CH_CFG_USE_EVENTS_TIMEOUT FALSE
|
||||
|
||||
/**
|
||||
* @brief Synchronous Messages APIs.
|
||||
|
|
|
|||
220
chprintf.c
220
chprintf.c
|
|
@ -29,13 +29,16 @@
|
|||
|
||||
#include "hal.h"
|
||||
#include "chprintf.h"
|
||||
#include "memstreams.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
|
||||
|
||||
|
|
@ -46,24 +49,23 @@ static const uint32_t pow10[FLOAT_PRECISION+1] = {
|
|||
};
|
||||
// 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};
|
||||
static char bigPrefix[] = {' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0};
|
||||
// Prefixes for values less then 1.0
|
||||
// 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18, 1e-21, 1e-24
|
||||
static char smallPrefix[]= { 'm', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0};
|
||||
static char smallPrefix[] = {'m', 0x1d, 'n', 'p', 'f', 'a', 'z', 'y', 0};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//86066 5116 11456 102622 190de build/ch.elf
|
||||
static char *long_to_string_with_divisor(char *p,
|
||||
uint32_t num,
|
||||
uint32_t radix,
|
||||
uint32_t precision) {
|
||||
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;
|
||||
num /= radix;
|
||||
*--q = c + ((c > 9) ? ('A'-10) : '0');
|
||||
}while((precision && --precision) || num);
|
||||
// copy string at begin
|
||||
|
|
@ -76,12 +78,14 @@ static char *long_to_string_with_divisor(char *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
|
||||
#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){
|
||||
static char *
|
||||
ulong_freq(char *p, uint32_t freq, uint32_t precision)
|
||||
{
|
||||
uint8_t flag = FREQ_PSET;
|
||||
if (precision == 0)
|
||||
flag|=FREQ_PREFIX_SPACE;
|
||||
|
|
@ -92,7 +96,7 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){
|
|||
// Prefix counter
|
||||
uint32_t s = 0;
|
||||
// Set format (every 3 digits add ' ' up to GHz)
|
||||
uint32_t format=0b00100100100;
|
||||
uint32_t format = 0b00100100100;
|
||||
do {
|
||||
#if 0
|
||||
uint8_t c = freq % 10;
|
||||
|
|
@ -102,21 +106,27 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){
|
|||
// 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;}
|
||||
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;
|
||||
*--q = c + '0';
|
||||
if (freq == 0) break;
|
||||
// Add spaces, calculate prefix
|
||||
if (format & 1) {
|
||||
*--q = ' ';
|
||||
s++;
|
||||
}
|
||||
format >>= 1;
|
||||
} while (1);
|
||||
s = bigPrefix[s];
|
||||
|
||||
|
|
@ -124,34 +134,33 @@ static char *ulong_freq(char *p, uint32_t freq, uint32_t precision){
|
|||
uint32_t i = (b - q);
|
||||
// Limit string size, max size is - precision
|
||||
if (precision && i > precision) {
|
||||
i = precision;
|
||||
flag|=FREQ_NO_SPACE;
|
||||
i = precision;
|
||||
flag |= FREQ_NO_SPACE;
|
||||
}
|
||||
// copy string
|
||||
// Replace first ' ' by '.', remove ' ' if size too big
|
||||
do{
|
||||
do {
|
||||
char c = *q++;
|
||||
// replace first ' ' on '.'
|
||||
if (c == ' ') {
|
||||
if (flag&FREQ_PSET){
|
||||
if (flag & FREQ_PSET) {
|
||||
c = '.';
|
||||
flag&=~FREQ_PSET;
|
||||
}
|
||||
else if (flag&FREQ_NO_SPACE)
|
||||
flag &= ~FREQ_PSET;
|
||||
} else if (flag & FREQ_NO_SPACE)
|
||||
c = *q++;
|
||||
}
|
||||
*p++ = c;
|
||||
}while (--i);
|
||||
} while (--i);
|
||||
// Put pref (amd space before it if need)
|
||||
if (flag&FREQ_PREFIX_SPACE && s!=' ')
|
||||
*p++ = ' ';
|
||||
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
|
||||
// Check precision limit
|
||||
if (precision > FLOAT_PRECISION)
|
||||
precision = FLOAT_PRECISION;
|
||||
uint32_t multi = pow10[precision];
|
||||
|
|
@ -161,12 +170,14 @@ static char *ftoa(char *p, float num, uint32_t precision) {
|
|||
// Fix rounding error if get
|
||||
if (k>=multi){k-=multi;l++;}
|
||||
p = long_to_string_with_divisor(p, l, 10, 0);
|
||||
if (precision && k){
|
||||
*p++ = '.';
|
||||
p=long_to_string_with_divisor(p, k, 10, precision);
|
||||
// remove zeros at end
|
||||
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;
|
||||
}
|
||||
|
|
@ -175,14 +186,14 @@ 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];
|
||||
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;
|
||||
for (ptr = smallPrefix; *ptr && num < 1.0; num*=1000, ptr++)
|
||||
;
|
||||
prefix = num > 1e-3 ? ptr[-1] : 0;
|
||||
}
|
||||
// Auto set prescision
|
||||
uint32_t l = num;
|
||||
|
|
@ -223,23 +234,23 @@ static char *ftoaS(char *p, float num, uint32_t precision) {
|
|||
*
|
||||
* @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
|
||||
#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;
|
||||
uint32_t state;
|
||||
union {
|
||||
uint32_t u;
|
||||
int32_t l;
|
||||
float f;
|
||||
uint32_t u;
|
||||
int32_t l;
|
||||
float f;
|
||||
}value;
|
||||
#if CHPRINTF_USE_FLOAT
|
||||
char tmpbuf[2*MAX_FILLER + 1];
|
||||
|
|
@ -274,13 +285,13 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
|||
else if (*fmt == '+')
|
||||
state|=POSITIVE;
|
||||
else if (*fmt == '0')
|
||||
state|=PAD_ZERO;
|
||||
state|=PAD_ZERO;
|
||||
#ifdef CHPRINTF_USE_SPACE_FLAG
|
||||
else if (*fmt == ' ')
|
||||
state|=PLUS_SPACE;
|
||||
state|=PLUS_SPACE;
|
||||
#endif
|
||||
else
|
||||
break;
|
||||
break;
|
||||
fmt++;
|
||||
}
|
||||
// Get [width] - The Width field specifies a minimum number of characters to output
|
||||
|
|
@ -309,7 +320,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
|||
}
|
||||
}
|
||||
else
|
||||
state|=DEFAULT_PRESCISION;
|
||||
state|=DEFAULT_PRESCISION;
|
||||
//Get [length]
|
||||
/*
|
||||
if (c == 'l' || c == 'L') {
|
||||
|
|
@ -317,8 +328,8 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
|||
if (*fmt)
|
||||
c = *fmt++;
|
||||
}
|
||||
else if((c >= 'A') && (c <= 'Z'))
|
||||
state|=IS_LONG;
|
||||
else if ((c >= 'A') && (c <= 'Z'))
|
||||
state|=IS_LONG;
|
||||
*/
|
||||
// Parse type
|
||||
switch (c) {
|
||||
|
|
@ -342,42 +353,42 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
|||
if (state & IS_LONG)
|
||||
value.l = va_arg(ap, long);
|
||||
else*/
|
||||
value.l = va_arg(ap, uint32_t);
|
||||
value.l = va_arg(ap, uint32_t);
|
||||
if (value.l < 0) {
|
||||
state|=NEGATIVE;
|
||||
state|=NEGATIVE;
|
||||
*p++ = '-';
|
||||
value.l = -value.l;
|
||||
}
|
||||
else if (state & POSITIVE)
|
||||
*p++ = '+';
|
||||
*p++ = '+';
|
||||
#ifdef CHPRINTF_USE_SPACE_FLAG
|
||||
else if (state & PLUS_SPACE)
|
||||
*p++ = ' ';
|
||||
*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;
|
||||
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;
|
||||
state|=NEGATIVE;
|
||||
*p++ = '-';
|
||||
value.f = -value.f;
|
||||
}
|
||||
else if (state & POSITIVE)
|
||||
*p++ = '+';
|
||||
*p++ = '+';
|
||||
#ifdef CHPRINTF_USE_SPACE_FLAG
|
||||
else if (state & PLUS_SPACE)
|
||||
*p++ = ' ';
|
||||
*p++ = ' ';
|
||||
#endif
|
||||
if (value.f == INFINITY){
|
||||
*p++ = 0x19;
|
||||
break;
|
||||
*p++ = 0x19;
|
||||
break;
|
||||
}
|
||||
p = (c=='F') ? ftoaS(p, value.f, precision) : ftoa(p, value.f, state&DEFAULT_PRESCISION ? FLOAT_PRECISION : precision);
|
||||
break;
|
||||
|
|
@ -422,7 +433,7 @@ unsigned_common:/*
|
|||
while (width){
|
||||
streamPut(chp, (uint8_t)filler);
|
||||
n++;
|
||||
width--;
|
||||
width--;
|
||||
}
|
||||
}
|
||||
// put data
|
||||
|
|
@ -462,6 +473,7 @@ unsigned_common:/*
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
#if 0
|
||||
int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
int formatted_bytes;
|
||||
|
|
@ -472,7 +484,7 @@ int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
|
|||
|
||||
return formatted_bytes;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @brief System formatted output function.
|
||||
* @details This function implements a minimal @p vprintf()-like functionality
|
||||
|
|
@ -501,6 +513,7 @@ int chprintf(BaseSequentialStream *chp, const char *fmt, ...) {
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
#if 0
|
||||
int chsnprintf(char *str, size_t size, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
MemoryStream ms;
|
||||
|
|
@ -530,5 +543,52 @@ int chsnprintf(char *str, size_t size, const char *fmt, ...) {
|
|||
/* 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 }
|
||||
};
|
||||
|
||||
int32_t acc_samp_s;
|
||||
int32_t acc_samp_c;
|
||||
int32_t acc_ref_s;
|
||||
int32_t acc_ref_c;
|
||||
float acc_samp_s;
|
||||
float acc_samp_c;
|
||||
float acc_ref_s;
|
||||
float acc_ref_c;
|
||||
|
||||
void
|
||||
dsp_process(int16_t *capture, size_t length)
|
||||
|
|
@ -79,10 +79,10 @@ dsp_process(int16_t *capture, size_t length)
|
|||
ref_c = __SMLATT(sr, sc, ref_c);
|
||||
#endif
|
||||
}
|
||||
acc_samp_s = samp_s;
|
||||
acc_samp_c = samp_c;
|
||||
acc_ref_s = ref_s;
|
||||
acc_ref_c = ref_c;
|
||||
acc_samp_s += samp_s;
|
||||
acc_samp_c += samp_c;
|
||||
acc_ref_s += ref_s;
|
||||
acc_ref_c += ref_c;
|
||||
}
|
||||
|
||||
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;
|
||||
for (j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
|
||||
uint16_t l = j + halfsize;
|
||||
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 * M_PI * k / 256) + array[l][imag] * cos(2 * M_PI * k / 256);
|
||||
float tpre = array[l][real] * cos(2 * VNA_PI * k / 256) + array[l][imag] * sin(2 * VNA_PI * k / 256);
|
||||
float tpim = -array[l][real] * sin(2 * VNA_PI * k / 256) + array[l][imag] * cos(2 * VNA_PI * k / 256);
|
||||
array[l][real] = array[j][real] - tpre;
|
||||
array[l][imag] = array[j][imag] - tpim;
|
||||
array[j][real] += tpre;
|
||||
|
|
|
|||
58
flash.c
58
flash.c
|
|
@ -32,12 +32,12 @@ static int flash_wait_for_last_operation(void)
|
|||
|
||||
static void flash_erase_page0(uint32_t page_address)
|
||||
{
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR |= FLASH_CR_PER;
|
||||
FLASH->AR = page_address;
|
||||
FLASH->CR |= FLASH_CR_STRT;
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR &= ~FLASH_CR_PER;
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR |= FLASH_CR_PER;
|
||||
FLASH->AR = page_address;
|
||||
FLASH->CR |= FLASH_CR_STRT;
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR &= ~FLASH_CR_PER;
|
||||
}
|
||||
|
||||
int flash_erase_page(uint32_t page_address)
|
||||
|
|
@ -50,11 +50,11 @@ int flash_erase_page(uint32_t page_address)
|
|||
|
||||
void flash_program_half_word(uint32_t address, uint16_t data)
|
||||
{
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
*(__IO uint16_t*)address = data;
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR &= ~FLASH_CR_PG;
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
*(__IO uint16_t*)address = data;
|
||||
flash_wait_for_last_operation();
|
||||
FLASH->CR &= ~FLASH_CR_PG;
|
||||
}
|
||||
|
||||
void flash_unlock(void)
|
||||
|
|
@ -64,8 +64,6 @@ void flash_unlock(void)
|
|||
FLASH->KEYR = 0xCDEF89AB;
|
||||
}
|
||||
|
||||
#define rotate(x) (((x)<<1) | ((x)&(1<<31)?1:0))
|
||||
|
||||
static uint32_t
|
||||
checksum(const void *start, size_t len)
|
||||
{
|
||||
|
|
@ -73,14 +71,14 @@ checksum(const void *start, size_t len)
|
|||
uint32_t *tail = (uint32_t*)(start + len);
|
||||
uint32_t value = 0;
|
||||
while (p < tail)
|
||||
value = rotate(value) + *p++;
|
||||
value = __ROR(value, 31) + *p++;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
#define FLASH_PAGESIZE 0x800
|
||||
|
||||
const uint32_t save_config_area = 0x08018000;
|
||||
const uint32_t save_config_area = SAVE_CONFIG_ADDR;
|
||||
|
||||
int
|
||||
config_save(void)
|
||||
|
|
@ -98,7 +96,7 @@ config_save(void)
|
|||
flash_erase_page((uint32_t)dst);
|
||||
|
||||
/* write to flahs */
|
||||
while(count-- > 0) {
|
||||
while (count-- > 0) {
|
||||
flash_program_half_word((uint32_t)dst, *src++);
|
||||
dst++;
|
||||
}
|
||||
|
|
@ -122,14 +120,15 @@ config_recall(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define SAVEAREA_MAX 5
|
||||
|
||||
const uint32_t saveareas[] =
|
||||
{ 0x08018800, 0x0801a000, 0x0801b800, 0x0801d000, 0x0801e800 };
|
||||
const uint32_t saveareas[SAVEAREA_MAX] = {
|
||||
SAVE_PROP_CONFIG_0_ADDR,
|
||||
SAVE_PROP_CONFIG_1_ADDR,
|
||||
SAVE_PROP_CONFIG_2_ADDR,
|
||||
SAVE_PROP_CONFIG_3_ADDR,
|
||||
SAVE_PROP_CONFIG_4_ADDR };
|
||||
|
||||
int16_t lastsaveid = 0;
|
||||
|
||||
|
||||
int
|
||||
caldata_save(int id)
|
||||
{
|
||||
|
|
@ -142,7 +141,8 @@ caldata_save(int id)
|
|||
dst = (uint16_t*)saveareas[id];
|
||||
|
||||
current_props.magic = CONFIG_MAGIC;
|
||||
current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum);
|
||||
current_props.checksum = checksum(
|
||||
¤t_props, sizeof current_props - sizeof current_props.checksum);
|
||||
|
||||
flash_unlock();
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ caldata_save(int id)
|
|||
}
|
||||
|
||||
/* write to flahs */
|
||||
while(count-- > 0) {
|
||||
while (count-- > 0) {
|
||||
flash_program_half_word((uint32_t)dst, *src++);
|
||||
dst++;
|
||||
}
|
||||
|
|
@ -174,15 +174,15 @@ caldata_recall(int id)
|
|||
void *dst = ¤t_props;
|
||||
|
||||
if (id < 0 || id >= SAVEAREA_MAX)
|
||||
return -1;
|
||||
goto load_default;
|
||||
|
||||
// point to saved area on the flash memory
|
||||
src = (properties_t*)saveareas[id];
|
||||
|
||||
if (src->magic != CONFIG_MAGIC)
|
||||
return -1;
|
||||
goto load_default;
|
||||
if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum)
|
||||
return -1;
|
||||
goto load_default;
|
||||
|
||||
/* active configuration points to save data on flash memory */
|
||||
active_props = src;
|
||||
|
|
@ -190,8 +190,10 @@ caldata_recall(int id)
|
|||
|
||||
/* duplicated saved data onto sram to be able to modify marker/trace */
|
||||
memcpy(dst, src, sizeof(properties_t));
|
||||
|
||||
return 0;
|
||||
load_default:
|
||||
load_default_properties();
|
||||
return -1;
|
||||
}
|
||||
|
||||
const properties_t *
|
||||
|
|
@ -209,7 +211,7 @@ caldata_ref(int id)
|
|||
return src;
|
||||
}
|
||||
|
||||
const uint32_t save_config_prop_area_size = 0x8000;
|
||||
const uint32_t save_config_prop_area_size = SAVE_CONFIG_AREA_SIZE;
|
||||
|
||||
void
|
||||
clear_all_config_prop_data(void)
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
* @brief Enables the RTC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_RTC TRUE
|
||||
#define HAL_USE_RTC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@
|
|||
#define STM32_ADCSW STM32_ADCSW_HSI14
|
||||
#define STM32_USBSW STM32_USBSW_HSI48
|
||||
#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_RTCSEL STM32_RTCSEL_LSI
|
||||
|
||||
|
|
@ -95,7 +96,7 @@
|
|||
#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
|
||||
#define STM32_EXT_EXTI21_22_IRQ_PRIORITY 3
|
||||
|
||||
#define STM32_DISABLE_EXTI2122_HANDLER TRUE
|
||||
#define STM32_DISABLE_EXTI2122_HANDLER TRUE
|
||||
|
||||
/*
|
||||
* GPT driver system settings.
|
||||
|
|
|
|||
190
nanovna.h
190
nanovna.h
|
|
@ -26,6 +26,17 @@
|
|||
* main.c
|
||||
*/
|
||||
|
||||
// Minimum frequency set
|
||||
#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];
|
||||
|
||||
|
|
@ -71,8 +82,9 @@ extern float measured[2][POINTS_COUNT][2];
|
|||
void cal_collect(int type);
|
||||
void cal_done(void);
|
||||
|
||||
enum {
|
||||
ST_START, ST_STOP, ST_CENTER, ST_SPAN, ST_CW
|
||||
#define MAX_FREQ_TYPE 5
|
||||
enum stimulus_type {
|
||||
ST_START=0, ST_STOP, ST_CENTER, ST_SPAN, ST_CW
|
||||
};
|
||||
|
||||
void set_sweep_frequency(int type, uint32_t frequency);
|
||||
|
|
@ -81,17 +93,12 @@ uint32_t get_sweep_frequency(int type);
|
|||
double my_atof(const char *p);
|
||||
|
||||
void toggle_sweep(void);
|
||||
void load_default_properties(void);
|
||||
|
||||
extern int8_t sweep_enabled;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
#define SWEEP_ENABLE 0x01
|
||||
#define SWEEP_ONCE 0x02
|
||||
extern int8_t sweep_mode;
|
||||
extern const char *info_about[];
|
||||
|
||||
/*
|
||||
* dsp.c
|
||||
|
|
@ -115,9 +122,6 @@ void calculate_gamma(float *gamma);
|
|||
void fetch_amplitude(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
|
||||
*/
|
||||
|
|
@ -144,7 +148,7 @@ extern void tlv320aic3204_select(int channel);
|
|||
|
||||
#define FREQUENCIES_XPOS1 OFFSETX
|
||||
#define FREQUENCIES_XPOS2 200
|
||||
#define FREQUENCIES_YPOS (HEIGHT+1)
|
||||
#define FREQUENCIES_YPOS (240-7)
|
||||
|
||||
// GRIDX calculated depends from frequency span
|
||||
//#define GRIDY 29
|
||||
|
|
@ -165,14 +169,15 @@ extern int16_t area_height;
|
|||
|
||||
// font
|
||||
extern const uint8_t x5x7_bits [];
|
||||
#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7])
|
||||
#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7))
|
||||
#define FONT_GET_HEIGHT 7
|
||||
#define FONT_GET_DATA(ch) (&x5x7_bits[ch*7])
|
||||
#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[ch*7]&7))
|
||||
#define FONT_MAX_WIDTH 7
|
||||
#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 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"
|
||||
|
|
@ -187,11 +192,12 @@ extern const uint16_t numfont16x22[];
|
|||
|
||||
#define TRACES_MAX 4
|
||||
|
||||
enum {
|
||||
TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF
|
||||
#define MAX_TRACE_TYPE 12
|
||||
enum trace_type {
|
||||
TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_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))
|
||||
#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
|
||||
// PHASE: SCALE, REFPOS, REFVAL
|
||||
|
|
@ -203,7 +209,7 @@ enum {
|
|||
// Electrical Delay
|
||||
// Phase
|
||||
|
||||
typedef struct {
|
||||
typedef struct trace {
|
||||
uint8_t enabled;
|
||||
uint8_t type;
|
||||
uint8_t channel;
|
||||
|
|
@ -212,25 +218,26 @@ typedef struct {
|
|||
float refpos;
|
||||
} trace_t;
|
||||
|
||||
typedef struct {
|
||||
#define FREQ_MODE_START_STOP 0x0
|
||||
#define FREQ_MODE_CENTER_SPAN 0x1
|
||||
#define FREQ_MODE_DOTTED_GRID 0x2
|
||||
|
||||
typedef struct config {
|
||||
int32_t magic;
|
||||
uint16_t dac_value;
|
||||
uint16_t grid_color;
|
||||
uint16_t menu_normal_color;
|
||||
uint16_t menu_active_color;
|
||||
uint16_t trace_color[TRACES_MAX];
|
||||
int16_t touch_cal[4];
|
||||
int8_t default_loadcal;
|
||||
int16_t touch_cal[4];
|
||||
uint32_t harmonic_freq_threshold;
|
||||
|
||||
uint8_t _reserved[24];
|
||||
uint16_t vbat_offset;
|
||||
uint8_t _reserved[22];
|
||||
uint32_t checksum;
|
||||
} config_t;
|
||||
|
||||
extern config_t config;
|
||||
|
||||
//extern trace_t trace[TRACES_MAX];
|
||||
|
||||
void set_trace_type(int t, int type);
|
||||
void set_trace_channel(int t, int channel);
|
||||
void set_trace_scale(int t, float scale);
|
||||
|
|
@ -238,7 +245,6 @@ void set_trace_refpos(int t, float refpos);
|
|||
float get_trace_scale(int t);
|
||||
float get_trace_refpos(int t);
|
||||
const char *get_trace_typename(int t);
|
||||
void draw_battery_status(void);
|
||||
|
||||
void set_electrical_delay(float picoseconds);
|
||||
float get_electrical_delay(void);
|
||||
|
|
@ -248,7 +254,7 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]);
|
|||
|
||||
#define MARKERS_MAX 4
|
||||
|
||||
typedef struct {
|
||||
typedef struct marker {
|
||||
int8_t enabled;
|
||||
int16_t index;
|
||||
uint32_t frequency;
|
||||
|
|
@ -264,7 +270,7 @@ void redraw_frame(void);
|
|||
//void redraw_all(void);
|
||||
void request_to_draw_cells_behind_menu(void);
|
||||
void request_to_draw_cells_behind_numeric_input(void);
|
||||
void redraw_marker(int marker, int update_info);
|
||||
void redraw_marker(int marker);
|
||||
void plot_into_index(float measured[2][POINTS_COUNT][2]);
|
||||
void force_set_markmap(void);
|
||||
void draw_frequencies(void);
|
||||
|
|
@ -281,14 +287,14 @@ int marker_search(void);
|
|||
int marker_search_left(int from);
|
||||
int marker_search_right(int from);
|
||||
|
||||
extern uint16_t redraw_request;
|
||||
|
||||
// _request flag for update screen
|
||||
#define REDRAW_CELLS (1<<0)
|
||||
#define REDRAW_FREQUENCY (1<<1)
|
||||
#define REDRAW_CAL_STATUS (1<<2)
|
||||
#define REDRAW_MARKER (1<<3)
|
||||
|
||||
extern int16_t vbat;
|
||||
#define REDRAW_BATTERY (1<<4)
|
||||
#define REDRAW_AREA (1<<5)
|
||||
extern volatile uint8_t redraw_request;
|
||||
|
||||
/*
|
||||
* ili9341.c
|
||||
|
|
@ -298,34 +304,36 @@ extern int16_t vbat;
|
|||
#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 DEFAULT_FG_COLOR RGB565(255,255,255)
|
||||
#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);
|
||||
// Define size of screen buffer in pixels (one pixel 16bit size)
|
||||
#define SPI_BUFFER_SIZE 2048
|
||||
|
||||
#define DEFAULT_FG_COLOR RGB565(255,255,255)
|
||||
#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 background_color;
|
||||
|
||||
extern uint16_t spi_buffer[2048];
|
||||
extern uint16_t spi_buffer[SPI_BUFFER_SIZE];
|
||||
|
||||
void ili9341_init(void);
|
||||
//void ili9341_setRotation(uint8_t r);
|
||||
void ili9341_test(int mode);
|
||||
void ili9341_bulk(int x, int y, int w, int h);
|
||||
void ili9341_fill(int x, int y, int w, int h, int color);
|
||||
void setForegroundColor(uint16_t fg);
|
||||
void setBackgroundColor(uint16_t fg);
|
||||
void ili9341_set_foreground(uint16_t fg);
|
||||
void ili9341_set_background(uint16_t fg);
|
||||
void ili9341_clear_screen(void);
|
||||
void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap);
|
||||
void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *bitmap);
|
||||
void ili9341_drawchar(uint8_t ch, int x, int y);
|
||||
void ili9341_drawstring(const char *str, int x, int y);
|
||||
void ili9341_drawstringV(const char *str, int x, int y);
|
||||
|
|
@ -341,8 +349,18 @@ void show_logo(void);
|
|||
* flash.c
|
||||
*/
|
||||
#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 {
|
||||
typedef struct properties {
|
||||
uint32_t magic;
|
||||
uint32_t _frequency0;
|
||||
uint32_t _frequency1;
|
||||
|
|
@ -360,7 +378,9 @@ typedef struct {
|
|||
int8_t _active_marker;
|
||||
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */
|
||||
uint8_t _marker_smith_format;
|
||||
uint8_t _reserved[50];
|
||||
uint8_t _bandwidth;
|
||||
int8_t _freq_mode;
|
||||
uint8_t _reserved[49];
|
||||
uint32_t checksum;
|
||||
} properties_t;
|
||||
|
||||
|
|
@ -386,14 +406,12 @@ extern properties_t current_props;
|
|||
#define domain_mode current_props._domain_mode
|
||||
#define velocity_factor current_props._velocity_factor
|
||||
#define marker_smith_format current_props._marker_smith_format
|
||||
#define bandwidth current_props._bandwidth
|
||||
#define freq_mode current_props._freq_mode
|
||||
|
||||
#define FREQ_IS_STARTSTOP() (frequency0 < frequency1)
|
||||
#define FREQ_IS_CENTERSPAN() (frequency0 > frequency1)
|
||||
#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)
|
||||
#define FREQ_START() (frequency0)
|
||||
#define FREQ_STOP() (frequency1)
|
||||
#define FREQ_CENTER() (frequency0/2 + frequency1/2)
|
||||
#define FREQ_SPAN() (frequency0 - frequency1)
|
||||
|
||||
int caldata_save(int id);
|
||||
int caldata_recall(int id);
|
||||
|
|
@ -407,29 +425,38 @@ void clear_all_config_prop_data(void);
|
|||
/*
|
||||
* 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
|
||||
enum {
|
||||
LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN
|
||||
enum lever_mode {
|
||||
LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN, LM_EDELAY
|
||||
};
|
||||
|
||||
// marker smith value format
|
||||
enum {
|
||||
enum marker_smithvalue {
|
||||
MS_LIN, MS_LOG, MS_REIM, MS_RX, MS_RLC
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct uistat {
|
||||
int8_t digit; /* 0~5 */
|
||||
int8_t digit_mode;
|
||||
int8_t current_trace; /* 0..3 */
|
||||
uint32_t value; // for editing at numeric input area
|
||||
uint32_t previous_value;
|
||||
// uint32_t previous_value;
|
||||
uint8_t lever_mode;
|
||||
bool marker_delta;
|
||||
uint8_t marker_delta;
|
||||
uint8_t marker_tracking;
|
||||
} uistat_t;
|
||||
|
||||
extern uistat_t uistat;
|
||||
|
||||
void ui_init(void);
|
||||
void ui_show(void);
|
||||
void ui_hide(void);
|
||||
|
|
@ -449,15 +476,22 @@ void enter_dfu(void);
|
|||
*/
|
||||
|
||||
void adc_init(void);
|
||||
uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel);
|
||||
void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel);
|
||||
void adc_stop(ADC_TypeDef *adc);
|
||||
void adc_interrupt(ADC_TypeDef *adc);
|
||||
int16_t adc_vbat_read(ADC_TypeDef *adc);
|
||||
uint16_t adc_single_read(uint32_t chsel);
|
||||
void adc_start_analog_watchdogd(uint32_t chsel);
|
||||
void adc_stop(void);
|
||||
void adc_interrupt(void);
|
||||
int16_t adc_vbat_read(void);
|
||||
|
||||
/*
|
||||
* misclinous
|
||||
*/
|
||||
int plot_printf(char *str, int, const char *fmt, ...);
|
||||
#define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0)
|
||||
|
||||
// Speed profile definition
|
||||
#define START_PROFILE systime_t time = chVTGetSystemTimeX();
|
||||
#define STOP_PROFILE {char string_buf[12];plot_printf(string_buf, sizeof string_buf, "T:%06d", chVTGetSystemTimeX() - time);ili9341_drawstringV(string_buf, 1, 60);}
|
||||
// Macros for convert define value to string
|
||||
#define STR1(x) #x
|
||||
#define define_to_STR(x) STR1(x)
|
||||
/*EOF*/
|
||||
|
|
|
|||
1013
numfont20x22.c
1013
numfont20x22.c
File diff suppressed because it is too large
Load diff
602
si5351.c
602
si5351.c
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
|
||||
* Modified by DiSlord dislordlive@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
|
|
@ -21,40 +22,100 @@
|
|||
#include "nanovna.h"
|
||||
#include "si5351.h"
|
||||
|
||||
#define SI5351_I2C_ADDR (0x60<<1)
|
||||
// Enable cache for SI5351 CLKX_CONTROL register, little speedup exchange
|
||||
#define USE_CLK_CONTROL_CACHE TRUE
|
||||
|
||||
static void
|
||||
si5351_write(uint8_t reg, uint8_t dat)
|
||||
// XTAL frequency on si5351
|
||||
#define XTALFREQ 26000000U
|
||||
// MCLK (processor clock if set, audio codec) frequency clock
|
||||
#define CLK2_FREQUENCY 8000000U
|
||||
|
||||
// Fixed PLL mode multiplier (used in band 1)
|
||||
#define PLL_N 32
|
||||
|
||||
// I2C address on bus (only 0x60 for Si5351A in 10-Pin MSOP)
|
||||
#define SI5351_I2C_ADDR 0x60
|
||||
|
||||
static uint8_t current_band = 0;
|
||||
static uint32_t current_freq = 0;
|
||||
static int32_t current_offset = FREQUENCY_OFFSET;
|
||||
|
||||
// Minimum value is 2, freq change apply at next dsp measure, and need skip it
|
||||
#define DELAY_NORMAL 2
|
||||
// Delay for bands (depend set band 1 more fast (can change before next dsp buffer ready, need wait additional interval)
|
||||
#define DELAY_BAND_1 3
|
||||
#define DELAY_BAND_2 2
|
||||
// Band changes need set delay after reset PLL
|
||||
#define DELAY_BANDCHANGE_1 3
|
||||
#define DELAY_BANDCHANGE_2 3
|
||||
// Delay after set new PLL values, and send reset (on band 1 unstable if less then 900, on 4000-5000 no amplitude spike on change)
|
||||
#define DELAY_RESET_PLL 5000
|
||||
|
||||
uint32_t si5351_get_frequency(void)
|
||||
{
|
||||
int addr = SI5351_I2C_ADDR>>1;
|
||||
uint8_t buf[] = { reg, dat };
|
||||
i2cAcquireBus(&I2CD1);
|
||||
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, 2, NULL, 0, 1000);
|
||||
i2cReleaseBus(&I2CD1);
|
||||
return current_freq;
|
||||
}
|
||||
|
||||
void si5351_set_frequency_offset(int32_t offset)
|
||||
{
|
||||
current_offset = offset;
|
||||
current_freq = 0; // reset freq, for
|
||||
}
|
||||
|
||||
static void
|
||||
si5351_bulk_write(const uint8_t *buf, int len)
|
||||
{
|
||||
int addr = SI5351_I2C_ADDR>>1;
|
||||
i2cAcquireBus(&I2CD1);
|
||||
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
|
||||
(void)i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, buf, len, NULL, 0, 1000);
|
||||
i2cReleaseBus(&I2CD1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool si5351_bulk_read(uint8_t reg, uint8_t* buf, int len)
|
||||
{
|
||||
i2cAcquireBus(&I2CD1);
|
||||
msg_t mr = i2cMasterTransmitTimeout(&I2CD1, SI5351_I2C_ADDR, ®, 1, buf, len, 1000);
|
||||
i2cReleaseBus(&I2CD1);
|
||||
return mr == MSG_OK;
|
||||
}
|
||||
|
||||
static void si5351_wait_pll_lock(void)
|
||||
{
|
||||
uint8_t status;
|
||||
int count = 100;
|
||||
do{
|
||||
status=0xFF;
|
||||
si5351_bulk_read(0, &status, 1);
|
||||
if ((status & 0x60) == 0) // PLLA and PLLB locked
|
||||
return;
|
||||
}while (--count);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
si5351_write(uint8_t reg, uint8_t dat)
|
||||
{
|
||||
uint8_t buf[] = { reg, dat };
|
||||
si5351_bulk_write(buf, 2);
|
||||
}
|
||||
|
||||
// register addr, length, data, ...
|
||||
const uint8_t si5351_configs[] = {
|
||||
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff,
|
||||
4, SI5351_REG_16_CLK0_CONTROL, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN,
|
||||
2, SI5351_REG_183_CRYSTAL_LOAD, SI5351_CRYSTAL_LOAD_8PF,
|
||||
// All of this init code run late on sweep
|
||||
#if 0
|
||||
// setup PLL (26MHz * 32 = 832MHz, 32/2-2=14)
|
||||
9, SI5351_REG_26_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
|
||||
9, SI5351_REG_PLL_A, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
|
||||
9, SI5351_REG_PLL_B, /*P3*/0, 1, /*P1*/0, 14, 0, /*P3/P2*/0, 0, 0,
|
||||
// RESET PLL
|
||||
2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B,
|
||||
2, SI5351_REG_177_PLL_RESET, SI5351_PLL_RESET_A | SI5351_PLL_RESET_B | 0x0C, //
|
||||
// setup multisynth (832MHz / 104 = 8MHz, 104/2-2=50)
|
||||
9, SI5351_REG_58_MULTISYNTH2, /*P3*/0, 1, /*P1*/0, 50, 0, /*P2|P3*/0, 0, 0,
|
||||
2, SI5351_REG_18_CLK2_CONTROL, SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_INPUT_MULTISYNTH_N | SI5351_CLK_INTEGER_MODE,
|
||||
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0,
|
||||
#endif
|
||||
2, SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN),
|
||||
0 // sentinel
|
||||
};
|
||||
|
||||
|
|
@ -69,230 +130,211 @@ 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)
|
||||
{
|
||||
uint8_t reg[4];
|
||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xff);
|
||||
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);
|
||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0xFF);
|
||||
si5351_bulk_write(disable_output, sizeof(disable_output));
|
||||
current_band = 0;
|
||||
}
|
||||
|
||||
void si5351_enable_output(void)
|
||||
{
|
||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, 0x00);
|
||||
si5351_write(SI5351_REG_3_OUTPUT_ENABLE_CONTROL, ~(SI5351_CLK0_EN|SI5351_CLK1_EN|SI5351_CLK2_EN));
|
||||
//si5351_reset_pll(SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
|
||||
current_freq = 0;
|
||||
current_band = 0;
|
||||
}
|
||||
|
||||
void si5351_reset_pll(void)
|
||||
// Set PLL freq = XTALFREQ * (mult + num/denom)
|
||||
static void si5351_setupPLL(uint8_t pllSource, /* SI5351_REG_PLL_A or SI5351_REG_PLL_B */
|
||||
uint32_t mult,
|
||||
uint32_t num,
|
||||
uint32_t denom)
|
||||
{
|
||||
//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 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
|
||||
* where: a = mult, b = num and c = denom
|
||||
* P1 register is an 18-bit value using following formula:
|
||||
* P1[17:0] = 128 * mult + floor(128*(num/denom)) - 512
|
||||
* P1[17:0] = 128 * mult + int((128*num)/denom) - 512
|
||||
* P2 register is a 20-bit value using the following formula:
|
||||
* P2[19:0] = 128 * num - denom * floor(128*(num/denom))
|
||||
* P2[19:0] = (128 * num) % denom
|
||||
* 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 */
|
||||
if (num == 0)
|
||||
{
|
||||
/* Integer mode */
|
||||
P1 = 128 * mult - 512;
|
||||
P2 = 0;
|
||||
P3 = 1;
|
||||
}
|
||||
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);
|
||||
mult <<= 7;
|
||||
num <<= 7;
|
||||
uint32_t P1 = mult - 512; // Integer mode
|
||||
uint32_t P2 = 0;
|
||||
uint32_t P3 = 1;
|
||||
if (num) { // Fractional mode
|
||||
P1+= num / denom;
|
||||
P2 = num % denom;
|
||||
P3 = denom;
|
||||
}
|
||||
|
||||
/* The datasheet is a nightmare of typos and inconsistencies here! */
|
||||
// Pll MSN(A|B) registers Datasheet
|
||||
uint8_t reg[9];
|
||||
reg[0] = pllreg_base[pll];
|
||||
reg[1] = (P3 & 0x0000FF00) >> 8;
|
||||
reg[2] = (P3 & 0x000000FF);
|
||||
reg[3] = (P1 & 0x00030000) >> 16;
|
||||
reg[4] = (P1 & 0x0000FF00) >> 8;
|
||||
reg[5] = (P1 & 0x000000FF);
|
||||
reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
|
||||
reg[7] = (P2 & 0x0000FF00) >> 8;
|
||||
reg[8] = (P2 & 0x000000FF);
|
||||
reg[0] = pllSource; // SI5351_REG_PLL_A or SI5351_REG_PLL_B
|
||||
reg[1] = (P3 & 0x0FF00) >> 8; // MSN_P3[15: 8]
|
||||
reg[2] = (P3 & 0x000FF); // MSN_P3[ 7: 0]
|
||||
reg[3] = (P1 & 0x30000) >> 16; // MSN_P1[17:16]
|
||||
reg[4] = (P1 & 0x0FF00) >> 8; // MSN_P1[15: 8]
|
||||
reg[5] = (P1 & 0x000FF); // MSN_P1[ 7: 0]
|
||||
reg[6] = ((P3 & 0xF0000) >> 12) | ((P2 & 0xF0000) >> 16); // MSN_P3[19:16] | MSN_P2[19:16]
|
||||
reg[7] = (P2 & 0x0FF00) >> 8; // MSN_P2[15: 8]
|
||||
reg[8] = (P2 & 0x000FF); // MSN_P2[ 7: 0]
|
||||
si5351_bulk_write(reg, 9);
|
||||
}
|
||||
|
||||
void
|
||||
si5351_setupMultisynth(uint8_t output,
|
||||
uint8_t pllSource,
|
||||
uint32_t div, // 4,6,8, 8+ ~ 900
|
||||
uint32_t num,
|
||||
uint32_t denom,
|
||||
uint32_t rdiv, // SI5351_R_DIV_1~128
|
||||
uint8_t drive_strength)
|
||||
// Set Multisynth divider = (div + num/denom) * rdiv
|
||||
static void
|
||||
si5351_setupMultisynth(uint8_t channel,
|
||||
uint32_t div, // 4,6,8, 8+ ~ 900
|
||||
uint32_t num,
|
||||
uint32_t denom,
|
||||
uint32_t rdiv, // SI5351_R_DIV_1~128
|
||||
uint8_t chctrl) // SI5351_REG_16_CLKX_CONTROL settings
|
||||
{
|
||||
/* 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
|
||||
* where: a = div, b = num and c = denom
|
||||
* P1 register is an 18-bit value using following formula:
|
||||
* P1[17:0] = 128 * a + floor(128*(b/c)) - 512
|
||||
* P1[17:0] = 128 * a + int((128*b)/c) - 512
|
||||
* P2 register is a 20-bit value using the following formula:
|
||||
* P2[19:0] = 128 * b - c * floor(128*(b/c))
|
||||
* P2[19:0] = (128 * b) % c
|
||||
* 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 */
|
||||
if (div == 4) {
|
||||
div4 = SI5351_DIVBY4;
|
||||
P1 = P2 = 0;
|
||||
P3 = 1;
|
||||
} else if (num == 0) {
|
||||
/* Integer mode */
|
||||
P1 = 128 * div - 512;
|
||||
P2 = 0;
|
||||
P3 = 1;
|
||||
} else {
|
||||
/* Fractional mode */
|
||||
P1 = 128 * div + ((128 * num) / denom) - 512;
|
||||
P2 = 128 * num - denom * ((128 * num) / denom);
|
||||
P3 = denom;
|
||||
uint32_t P1 = 0;
|
||||
uint32_t P2 = 0;
|
||||
uint32_t P3 = 1;
|
||||
if (div == 4)
|
||||
rdiv|= SI5351_DIVBY4;
|
||||
else {
|
||||
num<<=7;
|
||||
div<<=7;
|
||||
P1 = div - 512; // Integer mode
|
||||
if (num) { // Fractional mode
|
||||
P1+= num / denom;
|
||||
P2 = num % denom;
|
||||
P3 = denom;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the MSx config registers */
|
||||
uint8_t reg[9];
|
||||
reg[0] = msreg_base[output];
|
||||
reg[1] = (P3 & 0x0000FF00) >> 8;
|
||||
reg[2] = (P3 & 0x000000FF);
|
||||
reg[3] = ((P1 & 0x00030000) >> 16) | div4 | rdiv;
|
||||
reg[4] = (P1 & 0x0000FF00) >> 8;
|
||||
reg[5] = (P1 & 0x000000FF);
|
||||
reg[6] = ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16);
|
||||
reg[7] = (P2 & 0x0000FF00) >> 8;
|
||||
reg[8] = (P2 & 0x000000FF);
|
||||
reg[0] = msreg_base[channel]; // SI5351_REG_42_MULTISYNTH0, SI5351_REG_50_MULTISYNTH1, SI5351_REG_58_MULTISYNTH2
|
||||
reg[1] = (P3 & 0x0FF00)>>8; // MSx_P3[15: 8]
|
||||
reg[2] = (P3 & 0x000FF); // MSx_P3[ 7: 0]
|
||||
reg[3] = ((P1 & 0x30000)>>16)| rdiv; // Rx_DIV[2:0] | MSx_DIVBY4[1:0] | MSx_P1[17:16]
|
||||
reg[4] = (P1 & 0x0FF00)>> 8; // MSx_P1[15: 8]
|
||||
reg[5] = (P1 & 0x000FF); // MSx_P1[ 7: 0]
|
||||
reg[6] = ((P3 & 0xF0000)>>12)|((P2 & 0xF0000)>>16); // MSx_P3[19:16] | MSx_P2[19:16]
|
||||
reg[7] = (P2 & 0x0FF00)>>8; // MSx_P2[15: 8]
|
||||
reg[8] = (P2 & 0x000FF); // MSx_P2[ 7: 0]
|
||||
si5351_bulk_write(reg, 9);
|
||||
|
||||
/* Configure the clk control and enable the output */
|
||||
dat = drive_strength | SI5351_CLK_INPUT_MULTISYNTH_N;
|
||||
if (pllSource == SI5351_PLL_B)
|
||||
dat |= SI5351_CLK_PLL_SELECT_B;
|
||||
uint8_t dat = chctrl | SI5351_CLK_INPUT_MULTISYNTH_N;
|
||||
if (num == 0)
|
||||
dat |= SI5351_CLK_INTEGER_MODE;
|
||||
si5351_write(clkctrl[output], dat);
|
||||
|
||||
#if USE_CLK_CONTROL_CACHE == TRUE
|
||||
// Use cache for this reg, not update if not change
|
||||
static uint8_t clk_cache[3];
|
||||
if (clk_cache[channel]!=dat) {
|
||||
si5351_write(clkctrl[channel], dat);
|
||||
clk_cache[channel]=dat;
|
||||
}
|
||||
#else
|
||||
si5351_write(clkctrl[channel], dat);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define XTALFREQ 26000000L
|
||||
#define PLL_N 32
|
||||
#define PLLFREQ (XTALFREQ * PLL_N)
|
||||
|
||||
void
|
||||
si5351_set_frequency_fixedpll(int channel, int pll, uint32_t pllfreq, uint32_t freq,
|
||||
int rdiv, uint8_t drive_strength, int mul)
|
||||
// Find better approximate values for n/d
|
||||
#define MAX_DENOMINATOR ((1 << 20) - 1)
|
||||
static inline void approximate_fraction(uint32_t *n, uint32_t *d)
|
||||
{
|
||||
int denom = freq;
|
||||
int div = (pllfreq * mul) / denom; // range: 8 ~ 1800
|
||||
int num = (pllfreq * mul) - denom * div;
|
||||
|
||||
// cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227
|
||||
int max_denominator = (1 << 20) - 1;
|
||||
if (denom > max_denominator) {
|
||||
int p0 = 0, q0 = 1, p1 = 1, q1 = 0;
|
||||
while (denom != 0) {
|
||||
int a = num / denom;
|
||||
int q2 = q0 + a*q1;
|
||||
if (q2 > max_denominator)
|
||||
break;
|
||||
int p2 = p0 + a*p1;
|
||||
p0 = p1; q0 = q1; p1 = p2; q1 = q2;
|
||||
int new_denom = num - a * denom;
|
||||
num = denom; denom = new_denom;
|
||||
}
|
||||
num = p1;
|
||||
denom = q1;
|
||||
// cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227
|
||||
uint32_t denom = *d;
|
||||
if (denom > MAX_DENOMINATOR) {
|
||||
uint32_t num = *n;
|
||||
uint32_t p0 = 0, q0 = 1, p1 = 1, q1 = 0;
|
||||
while (denom != 0) {
|
||||
uint32_t a = num / denom;
|
||||
uint32_t b = num % denom;
|
||||
uint32_t q2 = q0 + a*q1;
|
||||
if (q2 > MAX_DENOMINATOR)
|
||||
break;
|
||||
uint32_t p2 = p0 + a*p1;
|
||||
p0 = p1; q0 = q1; p1 = p2; q1 = q2;
|
||||
num = denom; denom = b;
|
||||
}
|
||||
|
||||
si5351_setupMultisynth(channel, pll, div, num, denom, rdiv, drive_strength);
|
||||
*n = p1;
|
||||
*d = q1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
si5351_set_frequency_fixeddiv(int channel, int pll, uint32_t freq, int div,
|
||||
uint8_t drive_strength, int mul)
|
||||
// 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)
|
||||
{
|
||||
int denom = XTALFREQ * mul;
|
||||
int64_t pllfreq = (int64_t)freq * div;
|
||||
int multi = pllfreq / denom;
|
||||
int num = pllfreq - denom * multi;
|
||||
|
||||
// cf. https://github.com/python/cpython/blob/master/Lib/fractions.py#L227
|
||||
int max_denominator = (1 << 20) - 1;
|
||||
if (denom > max_denominator) {
|
||||
int p0 = 0, q0 = 1, p1 = 1, q1 = 0;
|
||||
while (denom != 0) {
|
||||
int a = num / denom;
|
||||
int q2 = q0 + a*q1;
|
||||
if (q2 > max_denominator)
|
||||
break;
|
||||
int p2 = p0 + a*p1;
|
||||
p0 = p1; q0 = q1; p1 = p2; q1 = q2;
|
||||
int new_denom = num - a * denom;
|
||||
num = denom; denom = new_denom;
|
||||
}
|
||||
num = p1;
|
||||
denom = q1;
|
||||
}
|
||||
|
||||
si5351_setupPLL(pll, multi, num, denom);
|
||||
si5351_setupMultisynth(channel, pll, div, 0, 1, SI5351_R_DIV_1, drive_strength);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
si5351_set_frequency(int channel, uint32_t freq, uint8_t drive_strength)
|
||||
{
|
||||
if (freq <= 100000000) {
|
||||
si5351_setupPLL(SI5351_PLL_B, 32, 0, 1);
|
||||
|
|
@ -303,119 +345,129 @@ si5351_set_frequency(int channel, int freq, uint8_t drive_strength)
|
|||
si5351_set_frequency_fixeddiv(channel, SI5351_PLL_B, freq, 4, drive_strength, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int current_band = -1;
|
||||
|
||||
#define DELAY_NORMAL 3
|
||||
#define DELAY_BANDCHANGE 1
|
||||
#define DELAY_LOWBAND 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Frequency generation divide on 3 band
|
||||
* Band 1
|
||||
* 1~100MHz fixed PLL = XTALFREQ * PLL_N, fractional divider
|
||||
* Band 2
|
||||
* 100~150MHz fractional PLL = 600- 900MHz, fixed divider 'fdiv = 6'
|
||||
* Band 3
|
||||
* 150~300MHz fractional PLL = 600-1200MHz, fixed divider 'fdiv = 4'
|
||||
*
|
||||
* For FREQ_HARMONICS = 300MHz - band range is:
|
||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
||||
* | Band 1 | Band 2 | Band 3 | Band 2 | Band 3 |
|
||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
||||
* | Direct mode x1 : x1 | x3 : x5 | x5-x7 | x7-x9 | x9-x11 |
|
||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
||||
* | 50kHz - 100MHz | 100 - 150MHz | 150 - 300MHz | 300-450MHz | 450-900MHz | 900-1500MHz | 1500-2100MHz | 2100-2700MHz |
|
||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
||||
* | f = 50kHz-300MHz | f=100-150 | f=150-300 | f=150-300 | f=214-300 | f=233-300 |
|
||||
* | of = 50kHz-300MHz |of= 60- 90 |of= 90-180 |of=128-215 |of=166-234 |of=190-246 |
|
||||
* +-----------------------------------------------------------------------------------------------------------------------+
|
||||
*/
|
||||
static inline uint8_t
|
||||
si5351_get_band(uint32_t freq)
|
||||
{
|
||||
if (freq < 100000000U) return 1;
|
||||
if (freq < 150000000U) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maximum supported frequency = FREQ_HARMONICS * 9U
|
||||
* configure output as follows:
|
||||
* CLK0: frequency + offset
|
||||
* CLK1: frequency
|
||||
* CLK2: fixed 8MHz
|
||||
*/
|
||||
#define CLK2_FREQUENCY 8000000L
|
||||
int
|
||||
si5351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength)
|
||||
si5351_set_frequency(uint32_t freq, uint8_t drive_strength)
|
||||
{
|
||||
int band;
|
||||
uint8_t band;
|
||||
int delay = DELAY_NORMAL;
|
||||
uint32_t ofreq = freq + offset;
|
||||
if (freq == current_freq)
|
||||
return delay;
|
||||
else if (current_freq > freq) // Reset band on sweep begin (if set range 150-600, fix error then 600 MHz band 2 or 3 go back)
|
||||
current_band = 0;
|
||||
current_freq = freq;
|
||||
uint32_t ofreq = freq + current_offset;
|
||||
uint32_t mul = 1, omul = 1;
|
||||
uint32_t rdiv = SI5351_R_DIV_1;
|
||||
uint32_t fdiv;
|
||||
// Fix possible incorrect input
|
||||
drive_strength&=SI5351_CLK_DRIVE_STRENGTH_MASK;
|
||||
|
||||
if (freq >= config.harmonic_freq_threshold * 7U) {
|
||||
mul = 9;
|
||||
mul = 9;
|
||||
omul = 11;
|
||||
} else if (freq >= config.harmonic_freq_threshold * 5U) {
|
||||
mul = 7;
|
||||
mul = 7;
|
||||
omul = 9;
|
||||
} else if (freq >= config.harmonic_freq_threshold * 3U) {
|
||||
mul = 5;
|
||||
mul = 5;
|
||||
omul = 7;
|
||||
} else if (freq >= config.harmonic_freq_threshold) {
|
||||
mul = 3;
|
||||
mul = 3;
|
||||
omul = 5;
|
||||
}
|
||||
if ((freq / mul) < 100000000U) {
|
||||
band = 0;
|
||||
} else if ((freq / mul) < 150000000U) {
|
||||
band = 1;
|
||||
} else {
|
||||
band = 2;
|
||||
}
|
||||
if (freq <= 500000U) {
|
||||
} else if (freq <= 500000U) {
|
||||
rdiv = SI5351_R_DIV_64;
|
||||
freq<<= 6;
|
||||
ofreq<<= 6;
|
||||
} else if (freq <= 4000000U) {
|
||||
rdiv = SI5351_R_DIV_8;
|
||||
freq<<= 3;
|
||||
ofreq<<= 3;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (current_band != band)
|
||||
si5351_disable_output();
|
||||
#endif
|
||||
|
||||
band = si5351_get_band(freq / mul);
|
||||
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, omul);
|
||||
si5351_set_frequency_fixedpll(1, SI5351_PLL_A, PLLFREQ, freq,
|
||||
rdiv, drive_strength, mul);
|
||||
//if (current_band != 0)
|
||||
si5351_set_frequency_fixedpll(2, SI5351_PLL_A, PLLFREQ, CLK2_FREQUENCY,
|
||||
SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA, 1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Set PLL twice on changing from band 2
|
||||
if (current_band == 2) {
|
||||
si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 6, drive_strength, omul);
|
||||
si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength, mul);
|
||||
}
|
||||
|
||||
// div by 6 mode. both PLL A and B are dedicated for CLK0, CLK1
|
||||
si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 6, drive_strength, omul);
|
||||
si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 6, drive_strength, mul);
|
||||
si5351_set_frequency_fixedpll(2, SI5351_PLL_B, freq / mul * 6, CLK2_FREQUENCY,
|
||||
SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA, 1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// div by 4 mode. both PLL A and B are dedicated for CLK0, CLK1
|
||||
si5351_set_frequency_fixeddiv(0, SI5351_PLL_A, ofreq, 4, drive_strength, omul);
|
||||
si5351_set_frequency_fixeddiv(1, SI5351_PLL_B, freq, 4, drive_strength, mul);
|
||||
si5351_set_frequency_fixedpll(2, SI5351_PLL_B, freq / mul * 4, CLK2_FREQUENCY,
|
||||
SI5351_R_DIV_1, SI5351_CLK_DRIVE_STRENGTH_2MA, 1);
|
||||
break;
|
||||
case 1:
|
||||
// Setup CH0 and CH1 constant PLLA freq at band change, and set CH2 freq =
|
||||
// CLK2_FREQUENCY
|
||||
if (current_band != 1) {
|
||||
si5351_setupPLL(SI5351_REG_PLL_A, PLL_N, 0, 1);
|
||||
si5351_set_frequency_fixedpll(
|
||||
2, XTALFREQ * PLL_N, CLK2_FREQUENCY, SI5351_R_DIV_1,
|
||||
SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_PLL_SELECT_A);
|
||||
delay = DELAY_BANDCHANGE_1;
|
||||
} else {
|
||||
delay = DELAY_BAND_1;
|
||||
}
|
||||
// Calculate and set CH0 and CH1 divider
|
||||
si5351_set_frequency_fixedpll(0, (uint64_t)omul * XTALFREQ * PLL_N, ofreq, rdiv,
|
||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
||||
si5351_set_frequency_fixedpll(1, (uint64_t)mul * XTALFREQ * PLL_N, freq, rdiv,
|
||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
||||
break;
|
||||
case 2: // fdiv = 6
|
||||
case 3: // fdiv = 4;
|
||||
fdiv = (band == 2) ? 6 : 4;
|
||||
// Setup CH0 and CH1 constant fdiv divider at change
|
||||
if (current_band != band) {
|
||||
si5351_setupMultisynth(0, fdiv, 0, 1, SI5351_R_DIV_1,
|
||||
drive_strength | SI5351_CLK_PLL_SELECT_A);
|
||||
si5351_setupMultisynth(1, fdiv, 0, 1, SI5351_R_DIV_1,
|
||||
drive_strength | SI5351_CLK_PLL_SELECT_B);
|
||||
delay = DELAY_BANDCHANGE_2;
|
||||
} else {
|
||||
delay = DELAY_BAND_2;
|
||||
}
|
||||
// Calculate and set CH0 and CH1 PLL freq
|
||||
si5351_setupPLL_freq(SI5351_REG_PLL_A, ofreq, fdiv,
|
||||
omul); // set PLLA freq = (ofreq/omul)*fdiv
|
||||
si5351_setupPLL_freq(SI5351_REG_PLL_B, freq, fdiv,
|
||||
mul); // set PLLB freq = ( freq/ mul)*fdiv
|
||||
// Calculate CH2 freq = CLK2_FREQUENCY, depend from calculated before CH1 PLLB = (freq/mul)*fdiv
|
||||
si5351_set_frequency_fixedpll(
|
||||
2, (uint64_t)freq * fdiv, CLK2_FREQUENCY * mul, SI5351_R_DIV_1,
|
||||
SI5351_CLK_DRIVE_STRENGTH_2MA | SI5351_CLK_PLL_SELECT_B);
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_band != band) {
|
||||
si5351_reset_pll();
|
||||
#if 1
|
||||
si5351_enable_output();
|
||||
#endif
|
||||
delay += DELAY_BANDCHANGE;
|
||||
si5351_reset_pll(SI5351_PLL_RESET_A|SI5351_PLL_RESET_B);
|
||||
current_band = band;
|
||||
}
|
||||
if (band == 0)
|
||||
delay += DELAY_LOWBAND;
|
||||
|
||||
current_band = band;
|
||||
return delay;
|
||||
}
|
||||
|
|
|
|||
108
si5351.h
108
si5351.h
|
|
@ -17,73 +17,61 @@
|
|||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#define SI5351_PLL_A 0
|
||||
#define SI5351_PLL_B 1
|
||||
|
||||
#define SI5351_MULTISYNTH_DIV_4 4
|
||||
#define SI5351_MULTISYNTH_DIV_6 6
|
||||
#define SI5351_MULTISYNTH_DIV_8 8
|
||||
#define SI5351_R_DIV_1 (0<<4)
|
||||
#define SI5351_R_DIV_2 (1<<4)
|
||||
#define SI5351_R_DIV_4 (2<<4)
|
||||
#define SI5351_R_DIV_8 (3<<4)
|
||||
#define SI5351_R_DIV_16 (4<<4)
|
||||
#define SI5351_R_DIV_32 (5<<4)
|
||||
#define SI5351_R_DIV_64 (6<<4)
|
||||
#define SI5351_R_DIV_128 (7<<4)
|
||||
#define SI5351_DIVBY4 (3<<2)
|
||||
#define SI5351_REG_3_OUTPUT_ENABLE_CONTROL 3
|
||||
#define SI5351_CLK0_EN (1<<0)
|
||||
#define SI5351_CLK1_EN (1<<1)
|
||||
#define SI5351_CLK2_EN (1<<2)
|
||||
|
||||
#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
|
||||
// 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_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_REG_PLL_A 26
|
||||
#define SI5351_REG_PLL_B 34
|
||||
|
||||
#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_REG_42_MULTISYNTH0 42
|
||||
#define SI5351_REG_50_MULTISYNTH1 50
|
||||
#define SI5351_REG_58_MULTISYNTH2 58
|
||||
#define SI5351_DIVBY4 (3<<2)
|
||||
#define SI5351_R_DIV_1 (0<<4)
|
||||
#define SI5351_R_DIV_2 (1<<4)
|
||||
#define SI5351_R_DIV_4 (2<<4)
|
||||
#define SI5351_R_DIV_8 (3<<4)
|
||||
#define SI5351_R_DIV_16 (4<<4)
|
||||
#define SI5351_R_DIV_32 (5<<4)
|
||||
#define SI5351_R_DIV_64 (6<<4)
|
||||
#define SI5351_R_DIV_128 (7<<4)
|
||||
|
||||
#define SI5351_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_PLL_RESET_B (1<<7)
|
||||
#define SI5351_PLL_RESET_A (1<<5)
|
||||
#define SI5351_REG_177_PLL_RESET 177
|
||||
#define SI5351_PLL_RESET_B (1<<7)
|
||||
#define SI5351_PLL_RESET_A (1<<5)
|
||||
|
||||
#define SI5351_REG_183_CRYSTAL_LOAD 183
|
||||
#define SI5351_CRYSTAL_LOAD_6PF (1<<6)
|
||||
#define SI5351_CRYSTAL_LOAD_8PF (2<<6)
|
||||
#define SI5351_CRYSTAL_LOAD_10PF (3<<6)
|
||||
|
||||
#define SI5351_CRYSTAL_FREQ_25MHZ 25000000
|
||||
#define SI5351_CRYSTAL_LOAD_6PF (1<<6)
|
||||
#define SI5351_CRYSTAL_LOAD_8PF (2<<6)
|
||||
#define SI5351_CRYSTAL_LOAD_10PF (3<<6)
|
||||
|
||||
void si5351_init(void);
|
||||
void si5351_disable_output(void);
|
||||
void si5351_enable_output(void);
|
||||
|
||||
void si5351_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);
|
||||
void si5351_set_frequency_offset(int32_t offset);
|
||||
int si5351_set_frequency(uint32_t freq, uint8_t drive_strength);
|
||||
uint32_t si5351_get_frequency(void);
|
||||
|
|
|
|||
159
tlv320aic3204.c
159
tlv320aic3204.c
|
|
@ -25,74 +25,78 @@
|
|||
|
||||
#define wait_ms(ms) chThdSleepMilliseconds(ms)
|
||||
|
||||
static const uint8_t conf_data_pll[] = {
|
||||
// len, ( reg, data ),
|
||||
2, 0x00, 0x00, /* Initialize to Page 0 */
|
||||
2, 0x01, 0x01, /* Initialize the device through software reset */
|
||||
2, 0x04, 0x43, /* PLL Clock High, MCLK, PLL */
|
||||
static const uint8_t conf_data[] = {
|
||||
// reg, data,
|
||||
// PLL clock config
|
||||
0x00, 0x00, /* Initialize to Page 0 */
|
||||
0x01, 0x01, /* Initialize the device through software reset */
|
||||
0x04, 0x43, /* PLL Clock High, MCLK, PLL */
|
||||
#ifdef REFCLK_8000KHZ
|
||||
/* 8.000MHz*10.7520 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
|
||||
2, 0x05, 0x91, /* Power up PLL, P=1,R=1 */
|
||||
2, 0x06, 0x0a, /* J=10 */
|
||||
2, 0x07, 29, /* D=7520 = (29<<8) + 96 */
|
||||
2, 0x08, 96,
|
||||
0x05, 0x91, /* Power up PLL, P=1,R=1 */
|
||||
0x06, 0x0a, /* J=10 */
|
||||
0x07, 29, /* D=7520 = (29<<8) + 96 */
|
||||
0x08, 96,
|
||||
#endif
|
||||
0 // sentinel
|
||||
// Clock config, default fs=48kHz
|
||||
0x0b, 0x82, /* Power up the NDAC divider with value 2 */
|
||||
0x0c, 0x87, /* Power up the MDAC divider with value 7 */
|
||||
0x0d, 0x00, /* Program the OSR of DAC to 128 */
|
||||
0x0e, 0x80,
|
||||
0x3c, 0x08, /* Set the DAC Mode to PRB_P8 */
|
||||
//0x3c, 25, /* Set the DAC Mode to PRB_P25 */
|
||||
0x1b, 0x0c, /* Set the BCLK,WCLK as output */
|
||||
0x1e, 0x80 + 28, /* Enable the BCLKN divider with value 28 */
|
||||
0x25, 0xee, /* DAC power up */
|
||||
|
||||
0x12, 0x82, /* Power up the NADC divider with value 2 */
|
||||
0x13, 0x87, /* Power up the MADC divider with value 7 */
|
||||
0x14, 0x80, /* Program the OSR of ADC to 128 */
|
||||
0x3d, 0x01, /* Select ADC PRB_R1 */
|
||||
// Data routing
|
||||
0x00, 0x01, /* Select Page 1 */
|
||||
0x01, 0x08, /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/
|
||||
0x02, 0x01, /* Enable Master Analog Power Control */
|
||||
0x7b, 0x01, /* Set the REF charging time to 40ms */
|
||||
0x14, 0x25, /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */
|
||||
0x0a, 0x33, /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */
|
||||
|
||||
0x3d, 0x00, /* Select ADC PTM_R4 */
|
||||
0x47, 0x32, /* Set MicPGA startup delay to 3.1ms */
|
||||
0x7b, 0x01, /* Set the REF charging time to 40ms */
|
||||
0x34, 0x10, /* Route IN2L to LEFT_P with 10K */
|
||||
0x36, 0x10, /* Route IN2R to LEFT_N with 10K */
|
||||
//0x37, 0x04, /* Route IN3R to RIGHT_P with 10K */
|
||||
//0x39, 0x04, /* Route IN3L to RIGHT_N with 10K */
|
||||
//0x3b, 0x00, /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
|
||||
//0x3c, 0x00, /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
|
||||
};
|
||||
|
||||
// default fs=48kHz
|
||||
static const uint8_t conf_data_clk[] = {
|
||||
2, 0x0b, 0x82, /* Power up the NDAC divider with value 2 */
|
||||
2, 0x0c, 0x87, /* Power up the MDAC divider with value 7 */
|
||||
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_unmute[] = {
|
||||
// reg, data,
|
||||
0x00, 0x00, /* Select Page 0 */
|
||||
0x51, 0xc0, /* Power up Left and Right ADC Channels */
|
||||
0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */
|
||||
};
|
||||
|
||||
static const uint8_t conf_data_routing[] = {
|
||||
2, 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*/
|
||||
2, 0x02, 0x01, /* Enable Master Analog Power Control */
|
||||
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_ch3_select[] = {
|
||||
// reg, data,
|
||||
0x00, 0x01, /* Select Page 1 */
|
||||
0x37, 0x04, /* Route IN3R to RIGHT_P with input impedance of 10K */
|
||||
0x39, 0x04, /* Route IN3L to RIGHT_N with input impedance of 10K */
|
||||
};
|
||||
|
||||
const uint8_t conf_data_unmute[] = {
|
||||
2, 0x00, 0x00, /* Select Page 0 */
|
||||
2, 0x51, 0xc0, /* Power up Left and Right ADC Channels */
|
||||
2, 0x52, 0x00, /* Unmute Left and Right ADC Digital Volume Control */
|
||||
0 // sentinel
|
||||
static const uint8_t conf_data_ch1_select[] = {
|
||||
// reg, data,
|
||||
0x00, 0x01, /* Select Page 1 */
|
||||
0x37, 0x40, /* Route IN1R to RIGHT_P with input impedance of 10K */
|
||||
0x39, 0x10, /* Route IN1L to RIGHT_N with input impedance of 10K */
|
||||
};
|
||||
|
||||
static void
|
||||
static inline void
|
||||
tlv320aic3204_bulk_write(const uint8_t *buf, int len)
|
||||
{
|
||||
int addr = AIC3204_ADDR;
|
||||
i2cAcquireBus(&I2CD1);
|
||||
(void)i2cMasterTransmitTimeout(&I2CD1, addr, buf, len, NULL, 0, 1000);
|
||||
i2cReleaseBus(&I2CD1);
|
||||
(void)i2cMasterTransmitTimeout(&I2CD1, AIC3204_ADDR, buf, len, NULL, 0, 1000);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -109,49 +113,32 @@ tlv320aic3204_read(uint8_t d0)
|
|||
#endif
|
||||
|
||||
static void
|
||||
tlv320aic3204_config(const uint8_t *data)
|
||||
tlv320aic3204_config(const uint8_t *data, int len)
|
||||
{
|
||||
const uint8_t *p = data;
|
||||
while (*p) {
|
||||
uint8_t len = *p++;
|
||||
tlv320aic3204_bulk_write(p, len);
|
||||
p += len;
|
||||
}
|
||||
i2cAcquireBus(&I2CD1);
|
||||
for (; len--; data += 2)
|
||||
tlv320aic3204_bulk_write(data, 2);
|
||||
i2cReleaseBus(&I2CD1);
|
||||
}
|
||||
|
||||
void tlv320aic3204_init(void)
|
||||
{
|
||||
tlv320aic3204_config(conf_data_pll);
|
||||
tlv320aic3204_config(conf_data_clk);
|
||||
tlv320aic3204_config(conf_data_routing);
|
||||
tlv320aic3204_config(conf_data, sizeof(conf_data)/2);
|
||||
wait_ms(40);
|
||||
tlv320aic3204_config(conf_data_unmute);
|
||||
tlv320aic3204_config(conf_data_unmute, sizeof(conf_data_unmute)/2);
|
||||
}
|
||||
|
||||
void tlv320aic3204_select(int channel)
|
||||
{
|
||||
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);
|
||||
tlv320aic3204_config(channel ? conf_data_ch1_select : conf_data_ch3_select, sizeof(conf_data_ch3_select)/2);
|
||||
}
|
||||
|
||||
void tlv320aic3204_set_gain(int lgain, int rgain)
|
||||
{
|
||||
uint8_t data[] = {
|
||||
2, 0x00, 0x01, /* Select Page 1 */
|
||||
2, 0x3b, lgain, /* Unmute Left MICPGA, set gain */
|
||||
2, 0x3c, rgain, /* Unmute Right MICPGA, set gain */
|
||||
0 // sentinel
|
||||
};
|
||||
tlv320aic3204_config(data);
|
||||
uint8_t data[] = {
|
||||
0x00, 0x01, /* Select Page 1 */
|
||||
0x3b, lgain, /* Unmute Left MICPGA, set gain */
|
||||
0x3c, rgain, /* Unmute Right MICPGA, set gain */
|
||||
};
|
||||
tlv320aic3204_config(data, sizeof(data)/2);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue