├── .gitignore
├── hardware
├── ltdz-pcb.jpg
├── ltdz-mods-v1.png
├── ltdz-schematics.jpg
├── ltdz-130kHz-rbw-filter.pdf
├── ltdz-130kHz-rbw-filter.png
└── ltdz-new-and-original-120kHz-rbw-filters.png
├── images
└── ltdz_adc_reader_v0.0.png
├── pretty.sh
├── .astylerc
├── ltdz_log2_table.py
├── system_stm32f10x.h
├── stm32f10x_conf.h
├── ltdz_log2_table.inc
├── STM32F103C8Tx_FLASH.ld
├── Makefile
├── startup_stm32f10x_md.s
├── sintable_q15_1024.inc
├── costable_q15_1024.inc
├── README.md
├── system_stm32f10x.c
├── util
└── ltdz_adc_read.py
└── sintable_q15_4096.inc
/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /nbproject/
3 |
--------------------------------------------------------------------------------
/hardware/ltdz-pcb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/hardware/ltdz-pcb.jpg
--------------------------------------------------------------------------------
/hardware/ltdz-mods-v1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/hardware/ltdz-mods-v1.png
--------------------------------------------------------------------------------
/hardware/ltdz-schematics.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/hardware/ltdz-schematics.jpg
--------------------------------------------------------------------------------
/images/ltdz_adc_reader_v0.0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/images/ltdz_adc_reader_v0.0.png
--------------------------------------------------------------------------------
/hardware/ltdz-130kHz-rbw-filter.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/hardware/ltdz-130kHz-rbw-filter.pdf
--------------------------------------------------------------------------------
/hardware/ltdz-130kHz-rbw-filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/hardware/ltdz-130kHz-rbw-filter.png
--------------------------------------------------------------------------------
/hardware/ltdz-new-and-original-120kHz-rbw-filters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kalvin2021/ltdz-dsp/HEAD/hardware/ltdz-new-and-original-120kHz-rbw-filters.png
--------------------------------------------------------------------------------
/pretty.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Author: Kalvin
4 | #
5 | # File pretty.sh
6 | #
7 | # Helper shell script to run the astyle source code formatting utility.
8 | #
9 | # Usage:
10 | #
11 | # $ ./pretty.sh filename
12 | #
13 |
14 | ASTYLERC="$(dirname $0)/.astylerc"
15 |
16 | astyle --options="$ASTYLERC" $*
17 |
--------------------------------------------------------------------------------
/.astylerc:
--------------------------------------------------------------------------------
1 | #
2 | # Author: Kalvin
3 | #
4 | # File: .astylerc
5 | #
6 | # Configuration file for Astyle C source code formatting tool.
7 | #
8 | # Documentation: http://astyle.sourceforge.net/astyle.html
9 | #
10 |
11 | --suffix=none # Do not create backup
12 | --indent=spaces=4
13 | --convert-tabs
14 | --lineend=linux
15 | --add-one-line-braces
16 | --attach-extern-c
17 | #--break-blocks
18 | --indent-col1-comments
19 | --indent-labels
20 | #--indent-switches
21 | --indent-preproc-define
22 | --keep-one-line-blocks
23 | --keep-one-line-statements
24 | --max-continuation-indent=80
25 | --min-conditional-indent=0
26 | --pad-oper
27 | --pad-header
28 | #--unpad-paren
29 | --align-pointer=type
30 | --align-reference=type
31 | --max-code-length=160
32 |
33 |
--------------------------------------------------------------------------------
/ltdz_log2_table.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | #
3 | # Author: Kalvin
4 | #
5 | # Usage: python3 ./ltdz_log2_table.py
6 | #
7 | # Generates log2 lookup-table C include-file ltdz_log2_table.inc.
8 | #
9 |
10 | import os
11 | import math
12 |
13 | THISFILE = os.path.basename(__file__)
14 |
15 | # Output file name
16 | OUTFILE = "ltdz_log2_table.inc"
17 |
18 | # Log2 table size
19 | TABLE_SIZE = 256
20 |
21 | print("Generating log2 lookup-table C include file {}".format(OUTFILE))
22 |
23 | sep = ","
24 | with open(OUTFILE, 'w') as f:
25 | f.write("/**\n")
26 | f.write(" * Do not edit or modify manually.\n")
27 | f.write(" * Generated by python script file {}\n".format(THISFILE))
28 | f.write(" */\n")
29 | for n in range(0, TABLE_SIZE):
30 | man = round(math.log2(1.0 + n/TABLE_SIZE)*100.0)
31 | if n == TABLE_SIZE-1:
32 | sep = ""
33 | f.write("/* {:3} */ {}{}\n".format(n, man, sep))
34 | f.write("/* end of file */\n")
35 |
36 | print("Done.")
37 |
--------------------------------------------------------------------------------
/system_stm32f10x.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file system_stm32f10x.h
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 11-March-2011
7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 | *
18 | *
© COPYRIGHT 2011 STMicroelectronics
19 | ******************************************************************************
20 | */
21 |
22 | /** @addtogroup CMSIS
23 | * @{
24 | */
25 |
26 | /** @addtogroup stm32f10x_system
27 | * @{
28 | */
29 |
30 | /**
31 | * @brief Define to prevent recursive inclusion
32 | */
33 | #ifndef __SYSTEM_STM32F10X_H
34 | #define __SYSTEM_STM32F10X_H
35 |
36 | #ifdef __cplusplus
37 | extern "C" {
38 | #endif
39 |
40 | /** @addtogroup STM32F10x_System_Includes
41 | * @{
42 | */
43 |
44 | /**
45 | * @}
46 | */
47 |
48 |
49 | /** @addtogroup STM32F10x_System_Exported_types
50 | * @{
51 | */
52 |
53 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
54 |
55 | /**
56 | * @}
57 | */
58 |
59 | /** @addtogroup STM32F10x_System_Exported_Constants
60 | * @{
61 | */
62 |
63 | /**
64 | * @}
65 | */
66 |
67 | /** @addtogroup STM32F10x_System_Exported_Macros
68 | * @{
69 | */
70 |
71 | /**
72 | * @}
73 | */
74 |
75 | /** @addtogroup STM32F10x_System_Exported_Functions
76 | * @{
77 | */
78 |
79 | extern void SystemInit(void);
80 | extern void SystemCoreClockUpdate(void);
81 | /**
82 | * @}
83 | */
84 |
85 | #ifdef __cplusplus
86 | }
87 | #endif
88 |
89 | #endif /*__SYSTEM_STM32F10X_H */
90 |
91 | /**
92 | * @}
93 | */
94 |
95 | /**
96 | * @}
97 | */
98 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
99 |
--------------------------------------------------------------------------------
/stm32f10x_conf.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 08-April-2011
7 | * @brief Library configuration file.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 | *
18 | * © COPYRIGHT 2011 STMicroelectronics
19 | ******************************************************************************
20 | */
21 |
22 | /* Define to prevent recursive inclusion -------------------------------------*/
23 | #ifndef __STM32F10x_CONF_H
24 | #define __STM32F10x_CONF_H
25 |
26 | /* Includes ------------------------------------------------------------------*/
27 | /* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */
28 | #include "stm32f10x_adc.h"
29 | #include "stm32f10x_bkp.h"
30 | #include "stm32f10x_can.h"
31 | #include "stm32f10x_cec.h"
32 | #include "stm32f10x_crc.h"
33 | #include "stm32f10x_dac.h"
34 | #include "stm32f10x_dbgmcu.h"
35 | #include "stm32f10x_dma.h"
36 | #include "stm32f10x_exti.h"
37 | #include "stm32f10x_flash.h"
38 | #include "stm32f10x_fsmc.h"
39 | #include "stm32f10x_gpio.h"
40 | #include "stm32f10x_i2c.h"
41 | #include "stm32f10x_iwdg.h"
42 | #include "stm32f10x_pwr.h"
43 | #include "stm32f10x_rcc.h"
44 | #include "stm32f10x_rtc.h"
45 | #include "stm32f10x_sdio.h"
46 | #include "stm32f10x_spi.h"
47 | #include "stm32f10x_tim.h"
48 | #include "stm32f10x_usart.h"
49 | #include "stm32f10x_wwdg.h"
50 | #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
51 |
52 | /* Exported types ------------------------------------------------------------*/
53 | /* Exported constants --------------------------------------------------------*/
54 | /* Uncomment the line below to expanse the "assert_param" macro in the
55 | Standard Peripheral Library drivers code */
56 | /* #define USE_FULL_ASSERT 1 */
57 |
58 | /* Exported macro ------------------------------------------------------------*/
59 | #ifdef USE_FULL_ASSERT
60 |
61 | /**
62 | * @brief The assert_param macro is used for function's parameters check.
63 | * @param expr: If expr is false, it calls assert_failed function which reports
64 | * the name of the source file and the source line number of the call
65 | * that failed. If expr is true, it returns no value.
66 | * @retval None
67 | */
68 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
69 | /* Exported functions ------------------------------------------------------- */
70 | void assert_failed(uint8_t* file, uint32_t line);
71 | #else
72 | #define assert_param(expr) ((void)0)
73 | #endif /* USE_FULL_ASSERT */
74 |
75 | #endif /* __STM32F10x_CONF_H */
76 |
77 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
78 |
--------------------------------------------------------------------------------
/ltdz_log2_table.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * Do not edit or modify manually.
3 | * Generated by python script file ltdz_log2_table.py
4 | */
5 | /* 0 */ 0,
6 | /* 1 */ 1,
7 | /* 2 */ 1,
8 | /* 3 */ 2,
9 | /* 4 */ 2,
10 | /* 5 */ 3,
11 | /* 6 */ 3,
12 | /* 7 */ 4,
13 | /* 8 */ 4,
14 | /* 9 */ 5,
15 | /* 10 */ 6,
16 | /* 11 */ 6,
17 | /* 12 */ 7,
18 | /* 13 */ 7,
19 | /* 14 */ 8,
20 | /* 15 */ 8,
21 | /* 16 */ 9,
22 | /* 17 */ 9,
23 | /* 18 */ 10,
24 | /* 19 */ 10,
25 | /* 20 */ 11,
26 | /* 21 */ 11,
27 | /* 22 */ 12,
28 | /* 23 */ 12,
29 | /* 24 */ 13,
30 | /* 25 */ 13,
31 | /* 26 */ 14,
32 | /* 27 */ 14,
33 | /* 28 */ 15,
34 | /* 29 */ 15,
35 | /* 30 */ 16,
36 | /* 31 */ 16,
37 | /* 32 */ 17,
38 | /* 33 */ 17,
39 | /* 34 */ 18,
40 | /* 35 */ 18,
41 | /* 36 */ 19,
42 | /* 37 */ 19,
43 | /* 38 */ 20,
44 | /* 39 */ 20,
45 | /* 40 */ 21,
46 | /* 41 */ 21,
47 | /* 42 */ 22,
48 | /* 43 */ 22,
49 | /* 44 */ 23,
50 | /* 45 */ 23,
51 | /* 46 */ 24,
52 | /* 47 */ 24,
53 | /* 48 */ 25,
54 | /* 49 */ 25,
55 | /* 50 */ 26,
56 | /* 51 */ 26,
57 | /* 52 */ 27,
58 | /* 53 */ 27,
59 | /* 54 */ 28,
60 | /* 55 */ 28,
61 | /* 56 */ 29,
62 | /* 57 */ 29,
63 | /* 58 */ 29,
64 | /* 59 */ 30,
65 | /* 60 */ 30,
66 | /* 61 */ 31,
67 | /* 62 */ 31,
68 | /* 63 */ 32,
69 | /* 64 */ 32,
70 | /* 65 */ 33,
71 | /* 66 */ 33,
72 | /* 67 */ 34,
73 | /* 68 */ 34,
74 | /* 69 */ 34,
75 | /* 70 */ 35,
76 | /* 71 */ 35,
77 | /* 72 */ 36,
78 | /* 73 */ 36,
79 | /* 74 */ 37,
80 | /* 75 */ 37,
81 | /* 76 */ 38,
82 | /* 77 */ 38,
83 | /* 78 */ 38,
84 | /* 79 */ 39,
85 | /* 80 */ 39,
86 | /* 81 */ 40,
87 | /* 82 */ 40,
88 | /* 83 */ 41,
89 | /* 84 */ 41,
90 | /* 85 */ 41,
91 | /* 86 */ 42,
92 | /* 87 */ 42,
93 | /* 88 */ 43,
94 | /* 89 */ 43,
95 | /* 90 */ 43,
96 | /* 91 */ 44,
97 | /* 92 */ 44,
98 | /* 93 */ 45,
99 | /* 94 */ 45,
100 | /* 95 */ 46,
101 | /* 96 */ 46,
102 | /* 97 */ 46,
103 | /* 98 */ 47,
104 | /* 99 */ 47,
105 | /* 100 */ 48,
106 | /* 101 */ 48,
107 | /* 102 */ 48,
108 | /* 103 */ 49,
109 | /* 104 */ 49,
110 | /* 105 */ 50,
111 | /* 106 */ 50,
112 | /* 107 */ 50,
113 | /* 108 */ 51,
114 | /* 109 */ 51,
115 | /* 110 */ 52,
116 | /* 111 */ 52,
117 | /* 112 */ 52,
118 | /* 113 */ 53,
119 | /* 114 */ 53,
120 | /* 115 */ 54,
121 | /* 116 */ 54,
122 | /* 117 */ 54,
123 | /* 118 */ 55,
124 | /* 119 */ 55,
125 | /* 120 */ 55,
126 | /* 121 */ 56,
127 | /* 122 */ 56,
128 | /* 123 */ 57,
129 | /* 124 */ 57,
130 | /* 125 */ 57,
131 | /* 126 */ 58,
132 | /* 127 */ 58,
133 | /* 128 */ 58,
134 | /* 129 */ 59,
135 | /* 130 */ 59,
136 | /* 131 */ 60,
137 | /* 132 */ 60,
138 | /* 133 */ 60,
139 | /* 134 */ 61,
140 | /* 135 */ 61,
141 | /* 136 */ 61,
142 | /* 137 */ 62,
143 | /* 138 */ 62,
144 | /* 139 */ 63,
145 | /* 140 */ 63,
146 | /* 141 */ 63,
147 | /* 142 */ 64,
148 | /* 143 */ 64,
149 | /* 144 */ 64,
150 | /* 145 */ 65,
151 | /* 146 */ 65,
152 | /* 147 */ 65,
153 | /* 148 */ 66,
154 | /* 149 */ 66,
155 | /* 150 */ 67,
156 | /* 151 */ 67,
157 | /* 152 */ 67,
158 | /* 153 */ 68,
159 | /* 154 */ 68,
160 | /* 155 */ 68,
161 | /* 156 */ 69,
162 | /* 157 */ 69,
163 | /* 158 */ 69,
164 | /* 159 */ 70,
165 | /* 160 */ 70,
166 | /* 161 */ 70,
167 | /* 162 */ 71,
168 | /* 163 */ 71,
169 | /* 164 */ 71,
170 | /* 165 */ 72,
171 | /* 166 */ 72,
172 | /* 167 */ 72,
173 | /* 168 */ 73,
174 | /* 169 */ 73,
175 | /* 170 */ 73,
176 | /* 171 */ 74,
177 | /* 172 */ 74,
178 | /* 173 */ 74,
179 | /* 174 */ 75,
180 | /* 175 */ 75,
181 | /* 176 */ 75,
182 | /* 177 */ 76,
183 | /* 178 */ 76,
184 | /* 179 */ 76,
185 | /* 180 */ 77,
186 | /* 181 */ 77,
187 | /* 182 */ 77,
188 | /* 183 */ 78,
189 | /* 184 */ 78,
190 | /* 185 */ 78,
191 | /* 186 */ 79,
192 | /* 187 */ 79,
193 | /* 188 */ 79,
194 | /* 189 */ 80,
195 | /* 190 */ 80,
196 | /* 191 */ 80,
197 | /* 192 */ 81,
198 | /* 193 */ 81,
199 | /* 194 */ 81,
200 | /* 195 */ 82,
201 | /* 196 */ 82,
202 | /* 197 */ 82,
203 | /* 198 */ 83,
204 | /* 199 */ 83,
205 | /* 200 */ 83,
206 | /* 201 */ 84,
207 | /* 202 */ 84,
208 | /* 203 */ 84,
209 | /* 204 */ 85,
210 | /* 205 */ 85,
211 | /* 206 */ 85,
212 | /* 207 */ 85,
213 | /* 208 */ 86,
214 | /* 209 */ 86,
215 | /* 210 */ 86,
216 | /* 211 */ 87,
217 | /* 212 */ 87,
218 | /* 213 */ 87,
219 | /* 214 */ 88,
220 | /* 215 */ 88,
221 | /* 216 */ 88,
222 | /* 217 */ 89,
223 | /* 218 */ 89,
224 | /* 219 */ 89,
225 | /* 220 */ 89,
226 | /* 221 */ 90,
227 | /* 222 */ 90,
228 | /* 223 */ 90,
229 | /* 224 */ 91,
230 | /* 225 */ 91,
231 | /* 226 */ 91,
232 | /* 227 */ 92,
233 | /* 228 */ 92,
234 | /* 229 */ 92,
235 | /* 230 */ 92,
236 | /* 231 */ 93,
237 | /* 232 */ 93,
238 | /* 233 */ 93,
239 | /* 234 */ 94,
240 | /* 235 */ 94,
241 | /* 236 */ 94,
242 | /* 237 */ 95,
243 | /* 238 */ 95,
244 | /* 239 */ 95,
245 | /* 240 */ 95,
246 | /* 241 */ 96,
247 | /* 242 */ 96,
248 | /* 243 */ 96,
249 | /* 244 */ 97,
250 | /* 245 */ 97,
251 | /* 246 */ 97,
252 | /* 247 */ 97,
253 | /* 248 */ 98,
254 | /* 249 */ 98,
255 | /* 250 */ 98,
256 | /* 251 */ 99,
257 | /* 252 */ 99,
258 | /* 253 */ 99,
259 | /* 254 */ 99,
260 | /* 255 */ 100
261 | /* end of file */
262 |
--------------------------------------------------------------------------------
/STM32F103C8Tx_FLASH.ld:
--------------------------------------------------------------------------------
1 | /*
2 | ******************************************************************************
3 | **
4 | ** File : LinkerScript.ld
5 | **
6 | ** Author : Auto-generated by System Workbench for STM32
7 | **
8 | ** Abstract : Linker script for STM32F103C8Tx series
9 | ** 64Kbytes FLASH and 20Kbytes RAM
10 | **
11 | ** Set heap size, stack size and stack location according
12 | ** to application requirements.
13 | **
14 | ** Set memory bank area and size if external memory is used.
15 | **
16 | ** Target : STMicroelectronics STM32
17 | **
18 | ** Distribution: The file is distributed “as is,” without any warranty
19 | ** of any kind.
20 | **
21 | *****************************************************************************
22 | ** @attention
23 | **
24 | ** © COPYRIGHT(c) 2019 STMicroelectronics
25 | **
26 | ** Redistribution and use in source and binary forms, with or without modification,
27 | ** are permitted provided that the following conditions are met:
28 | ** 1. Redistributions of source code must retain the above copyright notice,
29 | ** this list of conditions and the following disclaimer.
30 | ** 2. Redistributions in binary form must reproduce the above copyright notice,
31 | ** this list of conditions and the following disclaimer in the documentation
32 | ** and/or other materials provided with the distribution.
33 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors
34 | ** may be used to endorse or promote products derived from this software
35 | ** without specific prior written permission.
36 | **
37 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
41 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 | **
48 | *****************************************************************************
49 | */
50 |
51 | /* Entry Point */
52 | ENTRY(Reset_Handler)
53 |
54 | /* Highest address of the user mode stack */
55 | _estack = 0x20005000; /* end of RAM */
56 | /* Generate a link error if heap and stack don't fit into RAM */
57 | _Min_Heap_Size = 0x200; /* required amount of heap */
58 | _Min_Stack_Size = 0x400; /* required amount of stack */
59 |
60 | /* Specify the memory areas */
61 | MEMORY
62 | {
63 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
64 | FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
65 | }
66 |
67 | /* Define output sections */
68 | SECTIONS
69 | {
70 | /* The startup code goes first into FLASH */
71 | .isr_vector :
72 | {
73 | . = ALIGN(4);
74 | KEEP(*(.isr_vector)) /* Startup code */
75 | . = ALIGN(4);
76 | } >FLASH
77 |
78 | /* The program code and other data goes into FLASH */
79 | .text :
80 | {
81 | . = ALIGN(4);
82 | *(.text) /* .text sections (code) */
83 | *(.text*) /* .text* sections (code) */
84 | *(.glue_7) /* glue arm to thumb code */
85 | *(.glue_7t) /* glue thumb to arm code */
86 | *(.eh_frame)
87 |
88 | KEEP (*(.init))
89 | KEEP (*(.fini))
90 |
91 | . = ALIGN(4);
92 | _etext = .; /* define a global symbols at end of code */
93 | } >FLASH
94 |
95 | /* Constant data goes into FLASH */
96 | .rodata :
97 | {
98 | . = ALIGN(4);
99 | *(.rodata) /* .rodata sections (constants, strings, etc.) */
100 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
101 | . = ALIGN(4);
102 | } >FLASH
103 |
104 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
105 | .ARM : {
106 | __exidx_start = .;
107 | *(.ARM.exidx*)
108 | __exidx_end = .;
109 | } >FLASH
110 |
111 | .preinit_array :
112 | {
113 | PROVIDE_HIDDEN (__preinit_array_start = .);
114 | KEEP (*(.preinit_array*))
115 | PROVIDE_HIDDEN (__preinit_array_end = .);
116 | } >FLASH
117 | .init_array :
118 | {
119 | PROVIDE_HIDDEN (__init_array_start = .);
120 | KEEP (*(SORT(.init_array.*)))
121 | KEEP (*(.init_array*))
122 | PROVIDE_HIDDEN (__init_array_end = .);
123 | } >FLASH
124 | .fini_array :
125 | {
126 | PROVIDE_HIDDEN (__fini_array_start = .);
127 | KEEP (*(SORT(.fini_array.*)))
128 | KEEP (*(.fini_array*))
129 | PROVIDE_HIDDEN (__fini_array_end = .);
130 | } >FLASH
131 |
132 | /* used by the startup to initialize data */
133 | _sidata = LOADADDR(.data);
134 |
135 | /* Initialized data sections goes into RAM, load LMA copy after code */
136 | .data :
137 | {
138 | . = ALIGN(4);
139 | _sdata = .; /* create a global symbol at data start */
140 | *(.data) /* .data sections */
141 | *(.data*) /* .data* sections */
142 |
143 | . = ALIGN(4);
144 | _edata = .; /* define a global symbol at data end */
145 | } >RAM AT> FLASH
146 |
147 |
148 | /* Uninitialized data section */
149 | . = ALIGN(4);
150 | .bss :
151 | {
152 | /* This is used by the startup in order to initialize the .bss secion */
153 | _sbss = .; /* define a global symbol at bss start */
154 | __bss_start__ = _sbss;
155 | *(.bss)
156 | *(.bss*)
157 | *(COMMON)
158 |
159 | . = ALIGN(4);
160 | _ebss = .; /* define a global symbol at bss end */
161 | __bss_end__ = _ebss;
162 | } >RAM
163 |
164 | /* User_heap_stack section, used to check that there is enough RAM left */
165 | ._user_heap_stack :
166 | {
167 | . = ALIGN(8);
168 | PROVIDE ( end = . );
169 | PROVIDE ( _end = . );
170 | . = . + _Min_Heap_Size;
171 | . = . + _Min_Stack_Size;
172 | . = ALIGN(8);
173 | } >RAM
174 |
175 |
176 |
177 | /* Remove information from the standard libraries */
178 | /DISCARD/ :
179 | {
180 | libc.a ( * )
181 | libm.a ( * )
182 | libgcc.a ( * )
183 | }
184 |
185 | .ARM.attributes 0 : { *(.ARM.attributes) }
186 | }
187 |
188 |
189 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # *****************************************************************************
2 | # Author: Kalvin
3 | #
4 | # File: Makefile
5 | #
6 | # The main Makefile for building the LTDZ firmware using GCC toolchain.
7 | #
8 | # Build the firmware:
9 | #
10 | # $ make
11 | #
12 | # Flash the firmware using st-link v2:
13 | #
14 | # $ make flash
15 | #
16 | # *****************************************************************************
17 |
18 | # Hardware IDs
19 | HARDWARE_LTDZ = 1
20 |
21 | # Target hardware
22 | HARDWARE = $(HARDWARE_LTDZ)
23 |
24 | # New firmware versions
25 | FIRMWARE_MAJOR = 0
26 | FIRMWARE_MINOR = 1
27 |
28 | ######################################
29 | # target
30 | ######################################
31 |
32 | TARGET = ltdz_firmware
33 |
34 | ######################################
35 | # building variables
36 | ######################################
37 |
38 | # Debug build option: 0 | 1
39 | DEBUG = 0
40 |
41 | # Optimization level depending on DEBUG option
42 | ifeq ($(DEBUG), 0)
43 | OPT = -O3
44 | else
45 | OPT = -g -O0 -gdwarf-2
46 | endif
47 |
48 | #######################################
49 | # paths
50 | #######################################
51 |
52 | # Build path
53 | BUILD_DIR = build
54 |
55 | # STM32 headers and source code
56 | BSP_ROOT = ${HOME}/STM32Cube/Repository
57 |
58 | # STM32Cube Firmware
59 | STM32CUBEFW = STM32CubeF1-1.8.3
60 |
61 | # STM32Cube StdPeriph Library
62 | STM32STDLIB = STM32F10x_StdPeriph_Lib_V3.5.0
63 |
64 | # GCC compiler toolchain
65 | GCC_PATH ?=
66 |
67 | # GCC target compiler prefix
68 | PREFIX = arm-none-eabi-
69 |
70 | # ST Flash tool
71 | ST_FLASH = st-flash
72 |
73 | ######################################
74 | # source
75 | ######################################
76 |
77 | # C includes
78 | C_INCLUDES = \
79 | -I./ \
80 | -I$(BSP_ROOT)/$(STM32STDLIB)/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x \
81 | -I$(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/inc \
82 | -I$(BSP_ROOT)/$(STM32CUBEFW)/Drivers/CMSIS/Include \
83 | -I$(BSP_ROOT)/$(STM32CUBEFW)/Drivers/CMSIS/Core/Include \
84 | -I$(BSP_ROOT)/$(STM32CUBEFW)/Drivers/CMSIS/Device/ST/STM32F1xx/Include \
85 | -I$(BSP_ROOT)/$(STM32CUBEFW)/Drivers/CMSIS/DSP/Include
86 |
87 | # C sources
88 | C_SOURCES = \
89 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_adc.c \
90 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c \
91 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c \
92 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c \
93 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c \
94 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.c \
95 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c \
96 | $(BSP_ROOT)/$(STM32STDLIB)/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c \
97 | $(BSP_ROOT)/$(STM32CUBEFW)/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c \
98 | $(BSP_ROOT)/$(STM32CUBEFW)/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c \
99 | system_stm32f10x.c \
100 | main.c
101 |
102 | # AS includes
103 | AS_INCLUDES =
104 |
105 | # ASM sources
106 | AS_SOURCES = \
107 | startup_stm32f10x_md.s
108 |
109 | #######################################
110 | # Compiler toolchain definitions
111 | #######################################
112 |
113 | # The GCC compiler bin path can be either defined in make command via GCC_PATH
114 | # variable (> make GCC_PATH=xxx) or it can be added to the PATH environment variable.
115 |
116 | ifdef GCC_PATH
117 | GCC_PREFIX = $(GCC_PATH)/$(PREFIX)
118 | else
119 | GCC_PREFIX = $(PREFIX)
120 | endif
121 |
122 | CC = $(GCC_PREFIX)gcc
123 | AS = $(GCC_PREFIX)gcc -x assembler-with-cpp
124 | CP = $(GCC_PREFIX)objcopy
125 | SZ = $(GCC_PREFIX)size
126 | HEX = $(CP) -O ihex
127 | BIN = $(CP) -O binary -S
128 |
129 | #######################################
130 | # CFLAGS
131 | #######################################
132 |
133 | # cpu
134 | CPU = -mcpu=cortex-m3
135 |
136 | # fpu
137 | # NONE for Cortex-M0/M0+/M3
138 |
139 | # float-abi
140 |
141 | # mcu
142 | MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
143 |
144 | # C defines
145 | C_DEFS = \
146 | -DUSE_STDPERIPH_DRIVER \
147 | -DSTM32F103xB \
148 | -DSTM32F10X_MD \
149 | -DARM_MATH_CM3 \
150 | -DHARDWARE=$(HARDWARE) \
151 | -DFIRMWARE_MAJOR=$(FIRMWARE_MAJOR) \
152 | -DFIRMWARE_MINOR=$(FIRMWARE_MINOR)
153 |
154 | # C compiler options
155 | CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT)
156 | CFLAGS += -Wall -Werror -Wextra -Wpedantic
157 | CFLAGS += -fdata-sections
158 | CFLAGS += -ffreestanding
159 | CFLAGS += -ffunction-sections
160 | CFLAGS += -fno-common
161 | CFLAGS += -fno-builtin
162 | CFLAGS += -nostdlib
163 |
164 | # Generate dependency information
165 | CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
166 |
167 | # AS defines
168 | AS_DEFS =
169 |
170 | # AS flags
171 | ASFLAGS += $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT)
172 | ASFLAGS += -Wall
173 | ASFLAGS += -fdata-sections
174 | ASFLAGS += -ffunction-sections
175 |
176 | #######################################
177 | # LDFLAGS
178 | #######################################
179 |
180 | # Linker script
181 | LDSCRIPT = STM32F103C8Tx_FLASH.ld
182 |
183 | # Libraries
184 | LIBS = -lc -lm -lnosys
185 |
186 | # Extra libraries
187 | LIBDIR =
188 |
189 | # Linker options
190 | LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
191 |
192 | #######################################
193 | # build the application
194 | #######################################
195 |
196 | # default action: build all
197 | all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
198 |
199 | # list of objects
200 | OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
201 | vpath %.c $(sort $(dir $(C_SOURCES)))
202 |
203 | # list of ASM program objects
204 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(AS_SOURCES:.s=.o)))
205 | vpath %.s $(sort $(dir $(AS_SOURCES)))
206 |
207 | $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
208 | $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
209 |
210 | $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
211 | $(AS) -c $(CFLAGS) $< -o $@
212 |
213 | $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
214 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@
215 | $(SZ) $@
216 |
217 | $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
218 | $(HEX) $< $@
219 |
220 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
221 | $(BIN) $< $@
222 |
223 | $(BUILD_DIR):
224 | mkdir $@
225 |
226 | #######################################
227 | # Clean up
228 | #######################################
229 |
230 | clean:
231 | -rm -fR $(BUILD_DIR)
232 |
233 | #######################################
234 | # Flash the binary using st-link v2
235 | #######################################
236 |
237 | flash:
238 | $(ST_FLASH) --reset write $(BUILD_DIR)/$(TARGET).bin 0x08000000
239 |
240 | #######################################
241 | # Dependencies
242 | #######################################
243 |
244 | -include $(wildcard $(BUILD_DIR)/*.d)
245 |
246 | # *** EOF ***
247 |
--------------------------------------------------------------------------------
/startup_stm32f10x_md.s:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file startup_stm32f10x_md.s
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 11-March-2011
7 | * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain.
8 | * This module performs:
9 | * - Set the initial SP
10 | * - Set the initial PC == Reset_Handler,
11 | * - Set the vector table entries with the exceptions ISR address
12 | * - Configure the clock system
13 | * - Branches to main in the C library (which eventually
14 | * calls main()).
15 | * After Reset the Cortex-M3 processor is in Thread mode,
16 | * priority is Privileged, and the Stack is set to Main.
17 | ******************************************************************************
18 | * @attention
19 | *
20 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
21 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
22 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
23 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
24 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
25 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
26 | *
27 | * © COPYRIGHT 2011 STMicroelectronics
28 | ******************************************************************************
29 | */
30 |
31 | .syntax unified
32 | .cpu cortex-m3
33 | .fpu softvfp
34 | .thumb
35 |
36 | .global g_pfnVectors
37 | .global Default_Handler
38 |
39 | /* start address for the initialization values of the .data section.
40 | defined in linker script */
41 | .word _sidata
42 | /* start address for the .data section. defined in linker script */
43 | .word _sdata
44 | /* end address for the .data section. defined in linker script */
45 | .word _edata
46 | /* start address for the .bss section. defined in linker script */
47 | .word _sbss
48 | /* end address for the .bss section. defined in linker script */
49 | .word _ebss
50 |
51 | .equ BootRAM, 0xF108F85F
52 | /**
53 | * @brief This is the code that gets called when the processor first
54 | * starts execution following a reset event. Only the absolutely
55 | * necessary set is performed, after which the application
56 | * supplied main() routine is called.
57 | * @param None
58 | * @retval : None
59 | */
60 |
61 | .section .text.Reset_Handler
62 | .weak Reset_Handler
63 | .type Reset_Handler, %function
64 | Reset_Handler:
65 |
66 | /* Copy the data segment initializers from flash to SRAM */
67 | movs r1, #0
68 | b LoopCopyDataInit
69 |
70 | CopyDataInit:
71 | ldr r3, =_sidata
72 | ldr r3, [r3, r1]
73 | str r3, [r0, r1]
74 | adds r1, r1, #4
75 |
76 | LoopCopyDataInit:
77 | ldr r0, =_sdata
78 | ldr r3, =_edata
79 | adds r2, r0, r1
80 | cmp r2, r3
81 | bcc CopyDataInit
82 | ldr r2, =_sbss
83 | b LoopFillZerobss
84 | /* Zero fill the bss segment. */
85 | FillZerobss:
86 | movs r3, #0
87 | str r3, [r2], #4
88 |
89 | LoopFillZerobss:
90 | ldr r3, = _ebss
91 | cmp r2, r3
92 | bcc FillZerobss
93 | /* Call the clock system intitialization function.*/
94 | bl SystemInit
95 | /* Call the application's entry point.*/
96 | bl main
97 | bx lr
98 | .size Reset_Handler, .-Reset_Handler
99 |
100 | /**
101 | * @brief This is the code that gets called when the processor receives an
102 | * unexpected interrupt. This simply enters an infinite loop, preserving
103 | * the system state for examination by a debugger.
104 | * @param None
105 | * @retval None
106 | */
107 | .section .text.Default_Handler,"ax",%progbits
108 | Default_Handler:
109 | Infinite_Loop:
110 | b Infinite_Loop
111 | .size Default_Handler, .-Default_Handler
112 | /******************************************************************************
113 | *
114 | * The minimal vector table for a Cortex M3. Note that the proper constructs
115 | * must be placed on this to ensure that it ends up at physical address
116 | * 0x0000.0000.
117 | *
118 | ******************************************************************************/
119 | .section .isr_vector,"a",%progbits
120 | .type g_pfnVectors, %object
121 | .size g_pfnVectors, .-g_pfnVectors
122 |
123 |
124 | g_pfnVectors:
125 | .word _estack
126 | .word Reset_Handler
127 | .word NMI_Handler
128 | .word HardFault_Handler
129 | .word MemManage_Handler
130 | .word BusFault_Handler
131 | .word UsageFault_Handler
132 | .word 0
133 | .word 0
134 | .word 0
135 | .word 0
136 | .word SVC_Handler
137 | .word DebugMon_Handler
138 | .word 0
139 | .word PendSV_Handler
140 | .word SysTick_Handler
141 | .word WWDG_IRQHandler
142 | .word PVD_IRQHandler
143 | .word TAMPER_IRQHandler
144 | .word RTC_IRQHandler
145 | .word FLASH_IRQHandler
146 | .word RCC_IRQHandler
147 | .word EXTI0_IRQHandler
148 | .word EXTI1_IRQHandler
149 | .word EXTI2_IRQHandler
150 | .word EXTI3_IRQHandler
151 | .word EXTI4_IRQHandler
152 | .word DMA1_Channel1_IRQHandler
153 | .word DMA1_Channel2_IRQHandler
154 | .word DMA1_Channel3_IRQHandler
155 | .word DMA1_Channel4_IRQHandler
156 | .word DMA1_Channel5_IRQHandler
157 | .word DMA1_Channel6_IRQHandler
158 | .word DMA1_Channel7_IRQHandler
159 | .word ADC1_2_IRQHandler
160 | .word USB_HP_CAN1_TX_IRQHandler
161 | .word USB_LP_CAN1_RX0_IRQHandler
162 | .word CAN1_RX1_IRQHandler
163 | .word CAN1_SCE_IRQHandler
164 | .word EXTI9_5_IRQHandler
165 | .word TIM1_BRK_IRQHandler
166 | .word TIM1_UP_IRQHandler
167 | .word TIM1_TRG_COM_IRQHandler
168 | .word TIM1_CC_IRQHandler
169 | .word TIM2_IRQHandler
170 | .word TIM3_IRQHandler
171 | .word TIM4_IRQHandler
172 | .word I2C1_EV_IRQHandler
173 | .word I2C1_ER_IRQHandler
174 | .word I2C2_EV_IRQHandler
175 | .word I2C2_ER_IRQHandler
176 | .word SPI1_IRQHandler
177 | .word SPI2_IRQHandler
178 | .word USART1_IRQHandler
179 | .word USART2_IRQHandler
180 | .word USART3_IRQHandler
181 | .word EXTI15_10_IRQHandler
182 | .word RTCAlarm_IRQHandler
183 | .word USBWakeUp_IRQHandler
184 | .word 0
185 | .word 0
186 | .word 0
187 | .word 0
188 | .word 0
189 | .word 0
190 | .word 0
191 | .word BootRAM /* @0x108. This is for boot in RAM mode for
192 | STM32F10x Medium Density devices. */
193 |
194 | /*******************************************************************************
195 | *
196 | * Provide weak aliases for each Exception handler to the Default_Handler.
197 | * As they are weak aliases, any function with the same name will override
198 | * this definition.
199 | *
200 | *******************************************************************************/
201 |
202 | .weak NMI_Handler
203 | .thumb_set NMI_Handler,Default_Handler
204 |
205 | .weak HardFault_Handler
206 | .thumb_set HardFault_Handler,Default_Handler
207 |
208 | .weak MemManage_Handler
209 | .thumb_set MemManage_Handler,Default_Handler
210 |
211 | .weak BusFault_Handler
212 | .thumb_set BusFault_Handler,Default_Handler
213 |
214 | .weak UsageFault_Handler
215 | .thumb_set UsageFault_Handler,Default_Handler
216 |
217 | .weak SVC_Handler
218 | .thumb_set SVC_Handler,Default_Handler
219 |
220 | .weak DebugMon_Handler
221 | .thumb_set DebugMon_Handler,Default_Handler
222 |
223 | .weak PendSV_Handler
224 | .thumb_set PendSV_Handler,Default_Handler
225 |
226 | .weak SysTick_Handler
227 | .thumb_set SysTick_Handler,Default_Handler
228 |
229 | .weak WWDG_IRQHandler
230 | .thumb_set WWDG_IRQHandler,Default_Handler
231 |
232 | .weak PVD_IRQHandler
233 | .thumb_set PVD_IRQHandler,Default_Handler
234 |
235 | .weak TAMPER_IRQHandler
236 | .thumb_set TAMPER_IRQHandler,Default_Handler
237 |
238 | .weak RTC_IRQHandler
239 | .thumb_set RTC_IRQHandler,Default_Handler
240 |
241 | .weak FLASH_IRQHandler
242 | .thumb_set FLASH_IRQHandler,Default_Handler
243 |
244 | .weak RCC_IRQHandler
245 | .thumb_set RCC_IRQHandler,Default_Handler
246 |
247 | .weak EXTI0_IRQHandler
248 | .thumb_set EXTI0_IRQHandler,Default_Handler
249 |
250 | .weak EXTI1_IRQHandler
251 | .thumb_set EXTI1_IRQHandler,Default_Handler
252 |
253 | .weak EXTI2_IRQHandler
254 | .thumb_set EXTI2_IRQHandler,Default_Handler
255 |
256 | .weak EXTI3_IRQHandler
257 | .thumb_set EXTI3_IRQHandler,Default_Handler
258 |
259 | .weak EXTI4_IRQHandler
260 | .thumb_set EXTI4_IRQHandler,Default_Handler
261 |
262 | .weak DMA1_Channel1_IRQHandler
263 | .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
264 |
265 | .weak DMA1_Channel2_IRQHandler
266 | .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
267 |
268 | .weak DMA1_Channel3_IRQHandler
269 | .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
270 |
271 | .weak DMA1_Channel4_IRQHandler
272 | .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
273 |
274 | .weak DMA1_Channel5_IRQHandler
275 | .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
276 |
277 | .weak DMA1_Channel6_IRQHandler
278 | .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
279 |
280 | .weak DMA1_Channel7_IRQHandler
281 | .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
282 |
283 | .weak ADC1_2_IRQHandler
284 | .thumb_set ADC1_2_IRQHandler,Default_Handler
285 |
286 | .weak USB_HP_CAN1_TX_IRQHandler
287 | .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
288 |
289 | .weak USB_LP_CAN1_RX0_IRQHandler
290 | .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
291 |
292 | .weak CAN1_RX1_IRQHandler
293 | .thumb_set CAN1_RX1_IRQHandler,Default_Handler
294 |
295 | .weak CAN1_SCE_IRQHandler
296 | .thumb_set CAN1_SCE_IRQHandler,Default_Handler
297 |
298 | .weak EXTI9_5_IRQHandler
299 | .thumb_set EXTI9_5_IRQHandler,Default_Handler
300 |
301 | .weak TIM1_BRK_IRQHandler
302 | .thumb_set TIM1_BRK_IRQHandler,Default_Handler
303 |
304 | .weak TIM1_UP_IRQHandler
305 | .thumb_set TIM1_UP_IRQHandler,Default_Handler
306 |
307 | .weak TIM1_TRG_COM_IRQHandler
308 | .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
309 |
310 | .weak TIM1_CC_IRQHandler
311 | .thumb_set TIM1_CC_IRQHandler,Default_Handler
312 |
313 | .weak TIM2_IRQHandler
314 | .thumb_set TIM2_IRQHandler,Default_Handler
315 |
316 | .weak TIM3_IRQHandler
317 | .thumb_set TIM3_IRQHandler,Default_Handler
318 |
319 | .weak TIM4_IRQHandler
320 | .thumb_set TIM4_IRQHandler,Default_Handler
321 |
322 | .weak I2C1_EV_IRQHandler
323 | .thumb_set I2C1_EV_IRQHandler,Default_Handler
324 |
325 | .weak I2C1_ER_IRQHandler
326 | .thumb_set I2C1_ER_IRQHandler,Default_Handler
327 |
328 | .weak I2C2_EV_IRQHandler
329 | .thumb_set I2C2_EV_IRQHandler,Default_Handler
330 |
331 | .weak I2C2_ER_IRQHandler
332 | .thumb_set I2C2_ER_IRQHandler,Default_Handler
333 |
334 | .weak SPI1_IRQHandler
335 | .thumb_set SPI1_IRQHandler,Default_Handler
336 |
337 | .weak SPI2_IRQHandler
338 | .thumb_set SPI2_IRQHandler,Default_Handler
339 |
340 | .weak USART1_IRQHandler
341 | .thumb_set USART1_IRQHandler,Default_Handler
342 |
343 | .weak USART2_IRQHandler
344 | .thumb_set USART2_IRQHandler,Default_Handler
345 |
346 | .weak USART3_IRQHandler
347 | .thumb_set USART3_IRQHandler,Default_Handler
348 |
349 | .weak EXTI15_10_IRQHandler
350 | .thumb_set EXTI15_10_IRQHandler,Default_Handler
351 |
352 | .weak RTCAlarm_IRQHandler
353 | .thumb_set RTCAlarm_IRQHandler,Default_Handler
354 |
355 | .weak USBWakeUp_IRQHandler
356 | .thumb_set USBWakeUp_IRQHandler,Default_Handler
357 |
358 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
359 |
--------------------------------------------------------------------------------
/sintable_q15_1024.inc:
--------------------------------------------------------------------------------
1 | 0,
2 | 0,
3 | -1,
4 | -3,
5 | -4,
6 | -2,
7 | 4,
8 | 12,
9 | 20,
10 | 21,
11 | 13,
12 | -6,
13 | -30,
14 | -51,
15 | -57,
16 | -41,
17 | -3,
18 | 46,
19 | 90,
20 | 110,
21 | 92,
22 | 34,
23 | -49,
24 | -130,
25 | -177,
26 | -167,
27 | -93,
28 | 28,
29 | 158,
30 | 249,
31 | 263,
32 | 184,
33 | 26,
34 | -161,
35 | -315,
36 | -374,
37 | -307,
38 | -122,
39 | 128,
40 | 360,
41 | 488,
42 | 457,
43 | 261,
44 | -47,
45 | -369,
46 | -590,
47 | -624,
48 | -442,
49 | -88,
50 | 327,
51 | 663,
52 | 794,
53 | 659,
54 | 282,
55 | -222,
56 | -687,
57 | -947,
58 | -897,
59 | -532,
60 | 44,
61 | 645,
62 | 1063,
63 | 1140,
64 | 828,
65 | 208,
66 | -523,
67 | -1119,
68 | -1365,
69 | -1154,
70 | -533,
71 | 309,
72 | 1093,
73 | 1545,
74 | 1490,
75 | 919,
76 | 0,
77 | -968,
78 | -1655,
79 | -1808,
80 | -1349,
81 | -402,
82 | 730,
83 | 1667,
84 | 2079,
85 | 1797,
86 | 886,
87 | -372,
88 | -1560,
89 | -2269,
90 | -2233,
91 | -1431,
92 | -104,
93 | 1317,
94 | 2349,
95 | 2622,
96 | 2011,
97 | 687,
98 | -926,
99 | -2289,
100 | -2925,
101 | -2588,
102 | -1355,
103 | 389,
104 | 2068,
105 | 3105,
106 | 3124,
107 | 2078,
108 | 285,
109 | -1671,
110 | -3128,
111 | -3573,
112 | -2816,
113 | -1075,
114 | 1093,
115 | 2964,
116 | 3891,
117 | 3525,
118 | 1948,
119 | -344,
120 | -2594,
121 | -4036,
122 | -4153,
123 | -2862,
124 | -558,
125 | 2009,
126 | 3973,
127 | 4648,
128 | 3766,
129 | 1578,
130 | -1211,
131 | -3672,
132 | -4960,
133 | -4602,
134 | -2673,
135 | 219,
136 | 3119,
137 | 5044,
138 | 5312,
139 | 3786,
140 | 935,
141 | -2311,
142 | -4862,
143 | -5834,
144 | -4855,
145 | -2205,
146 | 1262,
147 | 4391,
148 | 6115,
149 | 5811,
150 | 3532,
151 | 0,
152 | -3621,
153 | -6106,
154 | -6586,
155 | -4848,
156 | -1428,
157 | 2558,
158 | 5774,
159 | 7113,
160 | 6077,
161 | 2962,
162 | -1228,
163 | -5099,
164 | -7335,
165 | -7141,
166 | -4528,
167 | -326,
168 | 4079,
169 | 7203,
170 | 7961,
171 | 6045,
172 | 2044,
173 | -2732,
174 | -6687,
175 | -8467,
176 | -7423,
177 | -3851,
178 | 1097,
179 | 5775,
180 | 8599,
181 | 8576,
182 | 5657,
183 | 770,
184 | -4474,
185 | -8311,
186 | -9418,
187 | -7367,
188 | -2790,
189 | 2816,
190 | 7579,
191 | 9874,
192 | 8881,
193 | 4872,
194 | -854,
195 | -6398,
196 | -9885,
197 | -10101,
198 | -6914,
199 | -1338,
200 | 4789,
201 | 9409,
202 | 10937,
203 | 8805,
204 | 3667,
205 | -2796,
206 | -8427,
207 | -11313,
208 | -10434,
209 | -6023,
210 | 491,
211 | 6948,
212 | 11170,
213 | 11696,
214 | 8290,
215 | 2036,
216 | -5005,
217 | -10472,
218 | -12497,
219 | -10345,
220 | -4674,
221 | 2660,
222 | 9211,
223 | 12760,
224 | 12066,
225 | 7298,
226 | 0,
227 | -7407,
228 | -12430,
229 | -13342,
230 | -9775,
231 | -2865,
232 | 5110,
233 | 11479,
234 | 14076,
235 | 11971,
236 | 5807,
237 | -2398,
238 | -9911,
239 | -14193,
240 | -13757,
241 | -8686,
242 | -623,
243 | 7759,
244 | 13643,
245 | 15015,
246 | 11354,
247 | 3825,
248 | -5091,
249 | -12410,
250 | -15649,
251 | -13666,
252 | -7061,
253 | 2003,
254 | 10508,
255 | 15586,
256 | 15486,
257 | 10177,
258 | 1379,
259 | -7990,
260 | -14786,
261 | -16694,
262 | -13011,
263 | -4910,
264 | 4939,
265 | 13243,
266 | 17193,
267 | 15409,
268 | 8425,
269 | -1472,
270 | -10987,
271 | -16918,
272 | -17230,
273 | -11755,
274 | -2267,
275 | 8088,
276 | 15839,
277 | 18353,
278 | 14727,
279 | 6113,
280 | -4648,
281 | -13962,
282 | -18684,
283 | -17179,
284 | -9887,
285 | 803,
286 | 11335,
287 | 18167,
288 | 18966,
289 | 13403,
290 | 3282,
291 | -8044,
292 | -16781,
293 | -19969,
294 | -16481,
295 | -7425,
296 | 4214,
297 | 14550,
298 | 20099,
299 | 18953,
300 | 11431,
301 | 0,
302 | -11538,
303 | -19310,
304 | -20670,
305 | -15104,
306 | -4415,
307 | 7853,
308 | 17595,
309 | 21518,
310 | 18253,
311 | 8832,
312 | -3637,
313 | -14994,
314 | -21416,
315 | -20706,
316 | -13041,
317 | -933,
318 | 11590,
319 | 20329,
320 | 22318,
321 | 16835,
322 | 5657,
323 | -7511,
324 | -18265,
325 | -22977,
326 | -20018,
327 | -10318,
328 | 2920,
329 | 15282,
330 | 22614,
331 | 22416,
332 | 14696,
333 | 1987,
334 | -11485,
335 | -21206,
336 | -23886,
337 | -18574,
338 | -6993,
339 | 7019,
340 | 18778,
341 | 24325,
342 | 21753,
343 | 11867,
344 | -2069,
345 | -15408,
346 | -23674,
347 | -24058,
348 | -16377,
349 | -3152,
350 | 11220,
351 | 21926,
352 | 25352,
353 | 20300,
354 | 8409,
355 | -6379,
356 | -19125,
357 | -25540,
358 | -23434,
359 | -13459,
360 | 1091,
361 | 15367,
362 | 24579,
363 | 25609,
364 | 18061,
365 | 4413,
366 | -10796,
367 | -22477,
368 | -26693,
369 | -21988,
370 | -9886,
371 | 5599,
372 | 19297,
373 | 26605,
374 | 25038,
375 | 15072,
376 | 0,
377 | -15155,
378 | -25315,
379 | -27046,
380 | -19725,
381 | -5755,
382 | 10217,
383 | 22849,
384 | 27891,
385 | 23614,
386 | 11405,
387 | -4688,
388 | -19290,
389 | -27503,
390 | -26542,
391 | -16685,
392 | -1192,
393 | 14776,
394 | 25869,
395 | 28350,
396 | 21346,
397 | 7160,
398 | -9489,
399 | -23035,
400 | -28927,
401 | -25156,
402 | -12944,
403 | 3657,
404 | 19104,
405 | 28220,
406 | 27924,
407 | 18275,
408 | 2467,
409 | -14232,
410 | -26234,
411 | -29499,
412 | -22900,
413 | -8607,
414 | 8624,
415 | 23033,
416 | 29786,
417 | 26591,
418 | 14482,
419 | -2520,
420 | -18741,
421 | -28746,
422 | -29163,
423 | -19819,
424 | -3808,
425 | 13533,
426 | 26403,
427 | 30478,
428 | 24365,
429 | 10076,
430 | -7632,
431 | -22842,
432 | -30455,
433 | -27898,
434 | -15996,
435 | 1295,
436 | 18205,
437 | 29072,
438 | 30242,
439 | 21294,
440 | 5195,
441 | -12688,
442 | -26374,
443 | -31272,
444 | -25719,
445 | -11545,
446 | 6529,
447 | 22464,
448 | 30924,
449 | 29057,
450 | 17464,
451 | 0,
452 | -17505,
453 | -29195,
454 | -31143,
455 | -22678,
456 | -6606,
457 | 11710,
458 | 26148,
459 | 31869,
460 | 26941,
461 | 12991,
462 | -5332,
463 | -21907,
464 | -31186,
465 | -30051,
466 | -18862,
467 | -1345,
468 | 16653,
469 | 29111,
470 | 31855,
471 | 23949,
472 | 8021,
473 | -10615,
474 | -25728,
475 | -32260,
476 | -28013,
477 | -14392,
478 | 4060,
479 | 21179,
480 | 31238,
481 | 30864,
482 | 20170,
483 | 2719,
484 | -15661,
485 | -28824,
486 | -32364,
487 | -25087,
488 | -9415,
489 | 9419,
490 | 25122,
491 | 32439,
492 | 28918,
493 | 15726,
494 | -2733,
495 | -20291,
496 | -31079,
497 | -31484,
498 | -21365,
499 | -4099,
500 | 14546,
501 | 28339,
502 | 32665,
503 | 26075,
504 | 10768,
505 | -8144,
506 | -24339,
507 | -32405,
508 | -29641,
509 | -16972,
510 | 1372,
511 | 19259,
512 | 30712,
513 | 31901,
514 | 22430,
515 | 5464,
516 | -13326,
517 | -27662,
518 | -32752,
519 | -26897,
520 | -12057,
521 | 6809,
522 | 23393,
523 | 32156,
524 | 30172,
525 | 18108,
526 | 0,
527 | -18100,
528 | -30143,
529 | -32109,
530 | -23348,
531 | -6792,
532 | 12021,
533 | 26805,
534 | 32624,
535 | 27540,
536 | 13261,
537 | -5435,
538 | -22299,
539 | -31699,
540 | -30502,
541 | -19118,
542 | -1361,
543 | 16831,
544 | 29381,
545 | 32104,
546 | 24102,
547 | 8060,
548 | -10652,
549 | -25783,
550 | -32283,
551 | -27993,
552 | -14362,
553 | 4045,
554 | 21074,
555 | 31039,
556 | 30624,
557 | 19985,
558 | 2690,
559 | -15473,
560 | -28439,
561 | -31886,
562 | -24681,
563 | -9250,
564 | 9241,
565 | 24610,
566 | 31733,
567 | 28248,
568 | 15340,
569 | -2662,
570 | -19737,
571 | -30187,
572 | -30537,
573 | -20693,
574 | -3965,
575 | 14049,
576 | 27330,
577 | 31458,
578 | 25076,
579 | 10340,
580 | -7809,
581 | -23306,
582 | -30984,
583 | -28302,
584 | -16181,
585 | 1306,
586 | 18310,
587 | 29156,
588 | 30242,
589 | 21233,
590 | 5165,
591 | -12579,
592 | -26072,
593 | -30826,
594 | -25279,
595 | -11315,
596 | 6380,
597 | 21890,
598 | 30047,
599 | 28152,
600 | 16872,
601 | 0,
602 | -16814,
603 | -27962,
604 | -29742,
605 | -21595,
606 | -6273,
607 | 11087,
608 | 24685,
609 | 29999,
610 | 25287,
611 | 12159,
612 | -4976,
613 | -20385,
614 | -28935,
615 | -27801,
616 | -17400,
617 | -1237,
618 | 15273,
619 | 26622,
620 | 29046,
621 | 21774,
622 | 7271,
623 | -9595,
624 | -23188,
625 | -28991,
626 | -25101,
627 | -12859,
628 | 3616,
629 | 18811,
630 | 27665,
631 | 27254,
632 | 17759,
633 | 2387,
634 | -13708,
635 | -25157,
636 | -28163,
637 | -21766,
638 | -8145,
639 | 8125,
640 | 21605,
641 | 27815,
642 | 24722,
643 | 13405,
644 | -2322,
645 | -17194,
646 | -26256,
647 | -26520,
648 | -17943,
649 | -3432,
650 | 12144,
651 | 23587,
652 | 27107,
653 | 21574,
654 | 8882,
655 | -6698,
656 | -19957,
657 | -26490,
658 | -24158,
659 | -13790,
660 | 1111,
661 | 15555,
662 | 24729,
663 | 25609,
664 | 17951,
665 | 4360,
666 | -10600,
667 | -21936,
668 | -25894,
669 | -21200,
670 | -9474,
671 | 5333,
672 | 18268,
673 | 25034,
674 | 23417,
675 | 14011,
676 | 0,
677 | -13917,
678 | -23105,
679 | -24536,
680 | -17785,
681 | -5158,
682 | 9100,
683 | 20228,
684 | 24541,
685 | 20651,
686 | 9913,
687 | -4050,
688 | -16563,
689 | -23470,
690 | -22511,
691 | -14065,
692 | -998,
693 | 12303,
694 | 21408,
695 | 23317,
696 | 17448,
697 | 5816,
698 | -7662,
699 | -18484,
700 | -23069,
701 | -19938,
702 | -10196,
703 | 2862,
704 | 14863,
705 | 21819,
706 | 21456,
707 | 13955,
708 | 1872,
709 | -10733,
710 | -19661,
711 | -21971,
712 | -16949,
713 | -6331,
714 | 6303,
715 | 16730,
716 | 21500,
717 | 19073,
718 | 10323,
719 | -1785,
720 | -13190,
721 | -20105,
722 | -20268,
723 | -13687,
724 | -2613,
725 | 9228,
726 | 17889,
727 | 20519,
728 | 16298,
729 | 6697,
730 | -5040,
731 | -14989,
732 | -19856,
733 | -18072,
734 | -10296,
735 | 828,
736 | 11567,
737 | 18352,
738 | 18966,
739 | 13268,
740 | 3216,
741 | -7803,
742 | -16114,
743 | -18982,
744 | -15509,
745 | -6916,
746 | 3885,
747 | 13281,
748 | 18161,
749 | 16952,
750 | 10121,
751 | 0,
752 | -10011,
753 | -16584,
754 | -17572,
755 | -12710,
756 | -3678,
757 | 6475,
758 | 14361,
759 | 17384,
760 | 14597,
761 | 6991,
762 | -2850,
763 | -11628,
764 | -16440,
765 | -15733,
766 | -9807,
767 | -694,
768 | 8539,
769 | 14824,
770 | 16108,
771 | 12026,
772 | 3999,
773 | -5256,
774 | -12650,
775 | -15749,
776 | -13579,
777 | -6927,
778 | 1940,
779 | 10049,
780 | 14716,
781 | 14435,
782 | 9366,
783 | 1253,
784 | -7167,
785 | -13096,
786 | -14597,
787 | -11232,
788 | -4185,
789 | 4156,
790 | 11002,
791 | 14101,
792 | 12477,
793 | 6735,
794 | -1161,
795 | -8560,
796 | -13012,
797 | -13082,
798 | -8810,
799 | -1678,
800 | 5907,
801 | 11420,
802 | 13063,
803 | 10347,
804 | 4240,
805 | -3182,
806 | -9435,
807 | -12463,
808 | -11311,
809 | -6425,
810 | 515,
811 | 7176,
812 | 11351,
813 | 11696,
814 | 8158,
815 | 1971,
816 | -4769,
817 | -9818,
818 | -11529,
819 | -9390,
820 | -4174,
821 | 2338,
822 | 7966,
823 | 10858,
824 | 10103,
825 | 6012,
826 | 0,
827 | -5908,
828 | -9754,
829 | -10301,
830 | -7426,
831 | -2141,
832 | 3757,
833 | 8305,
834 | 10019,
835 | 8383,
836 | 4001,
837 | -1625,
838 | -6608,
839 | -9308,
840 | -8876,
841 | -5513,
842 | -389,
843 | 4765,
844 | 8240,
845 | 8921,
846 | 6635,
847 | 2198,
848 | -2877,
849 | -6898,
850 | -8555,
851 | -7347,
852 | -3733,
853 | 1041,
854 | 5372,
855 | 7834,
856 | 7653,
857 | 4945,
858 | 659,
859 | -3752,
860 | -6827,
861 | -7577,
862 | -5805,
863 | -2153,
864 | 2129,
865 | 5610,
866 | 7158,
867 | 6305,
868 | 3388,
869 | -582,
870 | -4266,
871 | -6454,
872 | -6458,
873 | -4328,
874 | -820,
875 | 2874,
876 | 5528,
877 | 6291,
878 | 4958,
879 | 2021,
880 | -1509,
881 | -4451,
882 | -5849,
883 | -5280,
884 | -2983,
885 | 238,
886 | 3295,
887 | 5184,
888 | 5312,
889 | 3684,
890 | 885,
891 | -2128,
892 | -4356,
893 | -5085,
894 | -4117,
895 | -1819,
896 | 1013,
897 | 3428,
898 | 4644,
899 | 4293,
900 | 2539,
901 | 0,
902 | -2462,
903 | -4038,
904 | -4235,
905 | -3032,
906 | -868,
907 | 1513,
908 | 3320,
909 | 3977,
910 | 3303,
911 | 1565,
912 | -631,
913 | -2546,
914 | -3559,
915 | -3367,
916 | -2075,
917 | -145,
918 | 1764,
919 | 3027,
920 | 3249,
921 | 2396,
922 | 787,
923 | -1021,
924 | -2427,
925 | -2983,
926 | -2538,
927 | -1278,
928 | 353,
929 | 1804,
930 | 2606,
931 | 2521,
932 | 1612,
933 | 213,
934 | -1199,
935 | -2158,
936 | -2370,
937 | -1796,
938 | -659,
939 | 644,
940 | 1678,
941 | 2117,
942 | 1843,
943 | 978,
944 | -166,
945 | -1202,
946 | -1795,
947 | -1773,
948 | -1173,
949 | -219,
950 | 758,
951 | 1438,
952 | 1613,
953 | 1253,
954 | 503,
955 | -370,
956 | -1075,
957 | -1390,
958 | -1235,
959 | -686,
960 | 54,
961 | 733,
962 | 1133,
963 | 1140,
964 | 776,
965 | 183,
966 | -432,
967 | -867,
968 | -992,
969 | -786,
970 | -340,
971 | 185,
972 | 614,
973 | 812,
974 | 733,
975 | 423,
976 | 0,
977 | -390,
978 | -624,
979 | -637,
980 | -443,
981 | -123,
982 | 209,
983 | 444,
984 | 516,
985 | 415,
986 | 190,
987 | -74,
988 | -288,
989 | -388,
990 | -353,
991 | -209,
992 | -14,
993 | 163,
994 | 267,
995 | 274,
996 | 192,
997 | 60,
998 | -74,
999 | -166,
1000 | -192,
1001 | -154,
1002 | -72,
1003 | 19,
1004 | 89,
1005 | 119,
1006 | 106,
1007 | 62,
1008 | 7,
1009 | -38,
1010 | -61,
1011 | -60,
1012 | -40,
1013 | -13,
1014 | 11,
1015 | 24,
1016 | 25,
1017 | 17,
1018 | 7,
1019 | -1,
1020 | -5,
1021 | -5,
1022 | -3,
1023 | -1,
1024 | 0,
1025 |
--------------------------------------------------------------------------------
/costable_q15_1024.inc:
--------------------------------------------------------------------------------
1 | 0,
2 | 0,
3 | 0,
4 | -1,
5 | -3,
6 | -8,
7 | -10,
8 | -9,
9 | 0,
10 | 13,
11 | 28,
12 | 37,
13 | 32,
14 | 12,
15 | -21,
16 | -56,
17 | -79,
18 | -76,
19 | -43,
20 | 16,
21 | 82,
22 | 132,
23 | 141,
24 | 98,
25 | 11,
26 | -96,
27 | -186,
28 | -223,
29 | -183,
30 | -70,
31 | 86,
32 | 232,
33 | 314,
34 | 293,
35 | 165,
36 | -39,
37 | -254,
38 | -402,
39 | -424,
40 | -298,
41 | -51,
42 | 239,
43 | 474,
44 | 565,
45 | 465,
46 | 192,
47 | -174,
48 | -512,
49 | -700,
50 | -658,
51 | -383,
52 | 50,
53 | 500,
54 | 811,
55 | 863,
56 | 618,
57 | 140,
58 | -422,
59 | -878,
60 | -1061,
61 | -888,
62 | -395,
63 | 267,
64 | 881,
65 | 1230,
66 | 1175,
67 | 710,
68 | -29,
69 | -802,
70 | -1345,
71 | -1456,
72 | -1071,
73 | -295,
74 | 626,
75 | 1383,
76 | 1704,
77 | 1457,
78 | 696,
79 | -345,
80 | -1321,
81 | -1892,
82 | -1843,
83 | -1159,
84 | -44,
85 | 1140,
86 | 1990,
87 | 2197,
88 | 1662,
89 | 532,
90 | -831,
91 | -1970,
92 | -2486,
93 | -2174,
94 | -1105,
95 | 387,
96 | 1810,
97 | 2674,
98 | 2661,
99 | 1738,
100 | 184,
101 | -1494,
102 | -2729,
103 | -3081,
104 | -2396,
105 | -867,
106 | 1015,
107 | 2621,
108 | 3394,
109 | 3039,
110 | 1635,
111 | -375,
112 | -2330,
113 | -3560,
114 | -3621,
115 | -2452,
116 | -409,
117 | 1843,
118 | 3543,
119 | 4096,
120 | 3273,
121 | 1312,
122 | -1160,
123 | -3316,
124 | -4414,
125 | -4047,
126 | -2294,
127 | 292,
128 | 2858,
129 | 4532,
130 | 4717,
131 | 3307,
132 | 732,
133 | -2166,
134 | -4413,
135 | -5228,
136 | -4293,
137 | -1876,
138 | 1246,
139 | 4032,
140 | 5528,
141 | 5191,
142 | 3086,
143 | -122,
144 | -3374,
145 | -5569,
146 | -5935,
147 | -4300,
148 | -1166,
149 | 2443,
150 | 5317,
151 | 6463,
152 | 5450,
153 | 2567,
154 | -1256,
155 | -4748,
156 | -6718,
157 | -6462,
158 | -4013,
159 | -149,
160 | 3857,
161 | 6652,
162 | 7262,
163 | 5430,
164 | 1720,
165 | -2656,
166 | -6232,
167 | -7782,
168 | -6736,
169 | -3390,
170 | 1176,
171 | 5443,
172 | 7963,
173 | 7846,
174 | 5076,
175 | 533,
176 | -4286,
177 | -7757,
178 | -8680,
179 | -6691,
180 | -2401,
181 | 2786,
182 | 7137,
183 | 9165,
184 | 8139,
185 | 4345,
186 | -990,
187 | -6094,
188 | -9240,
189 | -9328,
190 | -6270,
191 | -1038,
192 | 4643,
193 | 8863,
194 | 10171,
195 | 8072,
196 | 3212,
197 | -2820,
198 | -8010,
199 | -10591,
200 | -9646,
201 | -5432,
202 | 688,
203 | 6683,
204 | 10529,
205 | 10891,
206 | 7588,
207 | 1671,
208 | -4910,
209 | -9946,
210 | -11714,
211 | -9563,
212 | -4154,
213 | 2743,
214 | 8828,
215 | 12037,
216 | 11241,
217 | 6646,
218 | -262,
219 | -7190,
220 | -11804,
221 | -12514,
222 | -9020,
223 | -2434,
224 | 5072,
225 | 10984,
226 | 13286,
227 | 11148,
228 | 5225,
229 | -2545,
230 | -9573,
231 | -13480,
232 | -12905,
233 | -7978,
234 | -295,
235 | 7597,
236 | 13044,
237 | 14177,
238 | 10554,
239 | 3329,
240 | -5116,
241 | -11955,
242 | -14865,
243 | -12812,
244 | -6420,
245 | 2217,
246 | 10223,
247 | 14896,
248 | 14618,
249 | 9419,
250 | 985,
251 | -7890,
252 | -14225,
253 | -15855,
254 | -12174,
255 | -4352,
256 | 5032,
257 | 12840,
258 | 16426,
259 | 14533,
260 | 7730,
261 | -1755,
262 | -10764,
263 | -16262,
264 | -16358,
265 | -10956,
266 | -1807,
267 | 8056,
268 | 15325,
269 | 17527,
270 | 13863,
271 | 5497,
272 | -4811,
273 | -13618,
274 | -17947,
275 | -16292,
276 | -9145,
277 | 1155,
278 | 11178,
279 | 17554,
280 | 18101,
281 | 12571,
282 | 2759,
283 | -8084,
284 | -16325,
285 | -19168,
286 | -15601,
287 | -6756,
288 | 4449,
289 | 14273,
290 | 19403,
291 | 18067,
292 | 10650,
293 | -418,
294 | -11455,
295 | -18753,
296 | -19824,
297 | -14248,
298 | -3834,
299 | 7967,
300 | 17205,
301 | 20753,
302 | 17366,
303 | 8117,
304 | -3943,
305 | -14790,
306 | -20771,
307 | -19833,
308 | -12229,
309 | -451,
310 | 11584,
311 | 19836,
312 | 21503,
313 | 15967,
314 | 5023,
315 | -7701,
316 | -17949,
317 | -22260,
318 | -19138,
319 | -9566,
320 | 3296,
321 | 15158,
322 | 22031,
323 | 21568,
324 | 13864,
325 | 1446,
326 | -11557,
327 | -20786,
328 | -23114,
329 | -17705,
330 | -6314,
331 | 7283,
332 | 18542,
333 | 23666,
334 | 20891,
335 | 11086,
336 | -2511,
337 | -15366,
338 | -23162,
339 | -23247,
340 | -15535,
341 | -2557,
342 | 11372,
343 | 21586,
344 | 24633,
345 | 19441,
346 | 7692,
347 | -6717,
348 | -18973,
349 | -24950,
350 | -22602,
351 | -12659,
352 | 1595,
353 | 15409,
354 | 24147,
355 | 24846,
356 | 17220,
357 | 3771,
358 | -11027,
359 | -22223,
360 | -26039,
361 | -21150,
362 | -9141,
363 | 6007,
364 | 19233,
365 | 26093,
366 | 24248,
367 | 14264,
368 | -559,
369 | -15282,
370 | -24969,
371 | -26343,
372 | -18897,
373 | -5075,
374 | 10525,
375 | 22686,
376 | 27311,
377 | 22810,
378 | 10641,
379 | -5159,
380 | -19316,
381 | -27076,
382 | -25804,
383 | -15880,
384 | -584,
385 | 14986,
386 | 25615,
387 | 27716,
388 | 20542,
389 | 6451,
390 | -9871,
391 | -22966,
392 | -28430,
393 | -24397,
394 | -12173,
395 | 4186,
396 | 19220,
397 | 27885,
398 | 27250,
399 | 17485,
400 | 1820,
401 | -14524,
402 | -26076,
403 | -28945,
404 | -22132,
405 | -7879,
406 | 9073,
407 | 23058,
408 | 29379,
409 | 25889,
410 | 13715,
411 | -3100,
412 | -18944,
413 | -28507,
414 | -28563,
415 | -19055,
416 | -3131,
417 | 13902,
418 | 26343,
419 | 30011,
420 | 23645,
421 | 9340,
422 | -8143,
423 | -22961,
424 | -30145,
425 | -27262,
426 | -15244,
427 | 1918,
428 | 18494,
429 | 28934,
430 | 29724,
431 | 20567,
432 | 4497,
433 | -13128,
434 | -26413,
435 | -30899,
436 | -25057,
437 | -10812,
438 | 7093,
439 | 22676,
440 | 30715,
441 | 28497,
442 | 16737,
443 | -655,
444 | -17875,
445 | -29159,
446 | -30716,
447 | -21999,
448 | -5899,
449 | 12214,
450 | 26285,
451 | 31596,
452 | 26348,
453 | 12272,
454 | -5941,
455 | -22208,
456 | -31081,
457 | -29576,
458 | -18173,
459 | -668,
460 | 17097,
461 | 29179,
462 | 31524,
463 | 23328,
464 | 7315,
465 | -11176,
466 | -25962,
467 | -32091,
468 | -27497,
469 | -13699,
470 | 4704,
471 | 21563,
472 | 31238,
473 | 30481,
474 | 19529,
475 | 2030,
476 | -16173,
477 | -28993,
478 | -32135,
479 | -24536,
480 | -8722,
481 | 10028,
482 | 25448,
483 | 32376,
484 | 28487,
485 | 15069,
486 | -3402,
487 | -20754,
488 | -31184,
489 | -31199,
490 | -20783,
491 | -3410,
492 | 15118,
493 | 28606,
494 | 32541,
495 | 25601,
496 | 10098,
497 | -8790,
498 | -24752,
499 | -32449,
500 | -29303,
501 | -16361,
502 | 2055,
503 | 19792,
504 | 30921,
505 | 31718,
506 | 21915,
507 | 4785,
508 | -13948,
509 | -28023,
510 | -32735,
511 | -26508,
512 | -11422,
513 | 7482,
514 | 23886,
515 | 32307,
516 | 29932,
517 | 17555,
518 | -686,
519 | -18694,
520 | -30452,
521 | -32032,
522 | -22908,
523 | -6134,
524 | 12683,
525 | 27255,
526 | 32715,
527 | 27242,
528 | 12671,
529 | -6125,
530 | -22864,
531 | -31953,
532 | -30363,
533 | -18630,
534 | -683,
535 | 17478,
536 | 29785,
537 | 32133,
538 | 23746,
539 | 7435,
540 | -11343,
541 | -26314,
542 | -32480,
543 | -27791,
544 | -13826,
545 | 4741,
546 | 21701,
547 | 31393,
548 | 30589,
549 | 19570,
550 | 2031,
551 | -16162,
552 | -28932,
553 | -32022,
554 | -24414,
555 | -8666,
556 | 9950,
557 | 25214,
558 | 32034,
559 | 28146,
560 | 14867,
561 | -3351,
562 | -20418,
563 | -30636,
564 | -30607,
565 | -20359,
566 | -3335,
567 | 14768,
568 | 27904,
569 | 31698,
570 | 24902,
571 | 9808,
572 | -8526,
573 | -23973,
574 | -31383,
575 | -28301,
576 | -15779,
577 | 1979,
578 | 19033,
579 | 29693,
580 | 30415,
581 | 20985,
582 | 4575,
583 | -13318,
584 | -26719,
585 | -31167,
586 | -25201,
587 | -10843,
588 | 7093,
589 | 22611,
590 | 30538,
591 | 28252,
592 | 16546,
593 | -646,
594 | -17569,
595 | -28578,
596 | -30017,
597 | -21437,
598 | -5732,
599 | 11834,
600 | 25394,
601 | 30436,
602 | 25308,
603 | 11754,
604 | -5674,
605 | -21147,
606 | -29512,
607 | -28002,
608 | -17156,
609 | -628,
610 | 16048,
611 | 27309,
612 | 29418,
613 | 21708,
614 | 6787,
615 | -10339,
616 | -23949,
617 | -29517,
618 | -25218,
619 | -12527,
620 | 4289,
621 | 19605,
622 | 28319,
623 | 27552,
624 | 17601,
625 | 1824,
626 | -14492,
627 | -25904,
628 | -28627,
629 | -21793,
630 | -7724,
631 | 8855,
632 | 22406,
633 | 28423,
634 | 24935,
635 | 13152,
636 | -2960,
637 | -18007,
638 | -26977,
639 | -26910,
640 | -17873,
641 | -2923,
642 | 12925,
643 | 24384,
644 | 27656,
645 | 21693,
646 | 8531,
647 | -7404,
648 | -20787,
649 | -27170,
650 | -24463,
651 | -13618,
652 | 1705,
653 | 16375,
654 | 25506,
655 | 26086,
656 | 17969,
657 | 3912,
658 | -11368,
659 | -22771,
660 | -26519,
661 | -21409,
662 | -9197,
663 | 6007,
664 | 19116,
665 | 25777,
666 | 23809,
667 | 13921,
668 | -542,
669 | -14734,
670 | -23928,
671 | -25092,
672 | -17890,
673 | -4776,
674 | 9844,
675 | 21088,
676 | 25233,
677 | 20947,
678 | 9713,
679 | -4680,
680 | -17416,
681 | -24264,
682 | -22984,
683 | -14059,
684 | -514,
685 | 13106,
686 | 22264,
687 | 23943,
688 | 17637,
689 | 5505,
690 | -8372,
691 | -19359,
692 | -23818,
693 | -20315,
694 | -10074,
695 | 3443,
696 | 15711,
697 | 22654,
698 | 22001,
699 | 14030,
700 | 1451,
701 | -11511,
702 | -20539,
703 | -22658,
704 | -17219,
705 | -6092,
706 | 6971,
707 | 17607,
708 | 22295,
709 | 19524,
710 | 10279,
711 | -2309,
712 | -14022,
713 | -20968,
714 | -20877,
715 | -13841,
716 | -2260,
717 | 9971,
718 | 18777,
719 | 21257,
720 | 16642,
721 | 6532,
722 | -5659,
723 | -15856,
724 | -20686,
725 | -18589,
726 | -10328,
727 | 1291,
728 | 12371,
729 | 19232,
730 | 19630,
731 | 13496,
732 | 2932,
733 | -8504,
734 | -17000,
735 | -19759,
736 | -15920,
737 | -6825,
738 | 4449,
739 | 14129,
740 | 19013,
741 | 17526,
742 | 10226,
743 | -398,
744 | -10779,
745 | -17468,
746 | -18280,
747 | -13006,
748 | -3464,
749 | 7126,
750 | 15233,
751 | 18189,
752 | 15067,
753 | 6971,
754 | -3352,
755 | -12446,
756 | -17302,
757 | -16354,
758 | -9981,
759 | -364,
760 | 9263,
761 | 15701,
762 | 16848,
763 | 12383,
764 | 3856,
765 | -5851,
766 | -13499,
767 | -16570,
768 | -14100,
769 | -6976,
770 | 2379,
771 | 10828,
772 | 15577,
773 | 15092,
774 | 9602,
775 | 991,
776 | -7840,
777 | -13955,
778 | -15357,
779 | -11642,
780 | -4109,
781 | 4690,
782 | 11817,
783 | 14925,
784 | 13037,
785 | 6846,
786 | -1534,
787 | -9292,
788 | -13860,
789 | -13764,
790 | -9101,
791 | -1482,
792 | 6523,
793 | 12250,
794 | 13831,
795 | 10800,
796 | 4228,
797 | -3653,
798 | -10207,
799 | -13279,
800 | -11900,
801 | -6594,
802 | 822,
803 | 7854,
804 | 12175,
805 | 12392,
806 | 8495,
807 | 1840,
808 | -5322,
809 | -10609,
810 | -12294,
811 | -9876,
812 | -4221,
813 | 2743,
814 | 8687,
815 | 11655,
816 | 10710,
817 | 6230,
818 | -241,
819 | -6526,
820 | -10544,
821 | -10999,
822 | -7801,
823 | -2071,
824 | 4247,
825 | 9049,
826 | 10770,
827 | 8892,
828 | 4100,
829 | -1965,
830 | -7272,
831 | -10075,
832 | -9490,
833 | -5772,
834 | -210,
835 | 5320,
836 | 8986,
837 | 9608,
838 | 7036,
839 | 2183,
840 | -3301,
841 | -7587,
842 | -9280,
843 | -7867,
844 | -3878,
845 | 1317,
846 | 5974,
847 | 8561,
848 | 8263,
849 | 5236,
850 | 538,
851 | -4242,
852 | -7520,
853 | -8243,
854 | -6223,
855 | -2187,
856 | 2487,
857 | 6239,
858 | 7847,
859 | 6825,
860 | 3569,
861 | -796,
862 | -4802,
863 | -7131,
864 | -7051,
865 | -4641,
866 | -752,
867 | 3296,
868 | 6162,
869 | 6925,
870 | 5382,
871 | 2097,
872 | -1803,
873 | -5014,
874 | -6492,
875 | -5789,
876 | -3192,
877 | 396,
878 | 3764,
879 | 5804,
880 | 5877,
881 | 4008,
882 | 864,
883 | -2485,
884 | -4926,
885 | -5677,
886 | -4536,
887 | -1928,
888 | 1246,
889 | 3923,
890 | 5232,
891 | 4780,
892 | 2765,
893 | -107,
894 | -2861,
895 | -4595,
896 | -4763,
897 | -3357,
898 | -886,
899 | 1805,
900 | 3821,
901 | 4518,
902 | 3705,
903 | 1697,
904 | -808,
905 | -2969,
906 | -4086,
907 | -3821,
908 | -2308,
909 | -83,
910 | 2096,
911 | 3515,
912 | 3730,
913 | 2711,
914 | 835,
915 | -1252,
916 | -2856,
917 | -3465,
918 | -2913,
919 | -1424,
920 | 480,
921 | 2157,
922 | 3065,
923 | 2933,
924 | 1842,
925 | 188,
926 | -1465,
927 | -2574,
928 | -2795,
929 | -2090,
930 | -728,
931 | 819,
932 | 2034,
933 | 2533,
934 | 2181,
935 | 1128,
936 | -249,
937 | -1486,
938 | -2182,
939 | -2133,
940 | -1388,
941 | -222,
942 | 963,
943 | 1779,
944 | 1975,
945 | 1516,
946 | 583,
947 | -495,
948 | -1359,
949 | -1736,
950 | -1527,
951 | -830,
952 | 101,
953 | 951,
954 | 1445,
955 | 1441,
956 | 968,
957 | 205,
958 | -581,
959 | -1134,
960 | -1285,
961 | -1009,
962 | -421,
963 | 267,
964 | 827,
965 | 1082,
966 | 970,
967 | 550,
968 | -21,
969 | -547,
970 | -859,
971 | -872,
972 | -601,
973 | -155,
974 | 308,
975 | 637,
976 | 735,
977 | 588,
978 | 262,
979 | -121,
980 | -434,
981 | -581,
982 | -527,
983 | -309,
984 | -11,
985 | 263,
986 | 427,
987 | 437,
988 | 306,
989 | 91,
990 | -131,
991 | -287,
992 | -334,
993 | -269,
994 | -126,
995 | 40,
996 | 173,
997 | 234,
998 | 212,
999 | 126,
1000 | 12,
1001 | -89,
1002 | -146,
1003 | -148,
1004 | -103,
1005 | -33,
1006 | 34,
1007 | 78,
1008 | 89,
1009 | 69,
1010 | 32,
1011 | -6,
1012 | -33,
1013 | -42,
1014 | -36,
1015 | -20,
1016 | -3,
1017 | 9,
1018 | 13,
1019 | 11,
1020 | 6,
1021 | 2,
1022 | -1,
1023 | -1,
1024 | 0,
1025 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LTDZ-DSP
2 |
3 | ## Project Goals
4 |
5 | LTDZ-DSP project is an attempt to improve the performance of this inexpensive
6 | 35MHz-4400MHz spectrum analyzer and tracking generator using only minimal
7 | hardware modifications, and by replacing the original firmware with this new
8 | version of the firmware, while maintaining the compatibility with the existing
9 | PC GUI applications.
10 |
11 | Summary of the project goals are as follows:
12 |
13 | 1. Improve the dynamic range of the scalar network analyzer from 50dB to 80dB.
14 |
15 | 2. Implement digital receiver bandwidth filters with selectable bandwidth,
16 | which allows better spectrum resolution in the spectrum analyzer mode.
17 |
18 | 3. Improve the linearity of the RMS/LOG-detector, providing more accurate
19 | and wider dynamic range up to 80dB.
20 |
21 | 4. Provide firmware source code which can be used for experimenting with
22 | the LTDZ board.
23 |
24 | ## Disclaimer
25 |
26 | The firmware source code is provided "as-is", without any support, without
27 | any guarantee of its correctness, or that the the firmware will perform as
28 | expected. In short: Use this firmware at your own risk.
29 |
30 | Please note: It may not be possible to read and create a backup for the
31 | original firmware, as the boards may be shipped with copy-protection enabled.
32 | So, keep in mind that you will most probably lose the original firmware.
33 |
34 | Finally, if you do not know how to use ST-Link programming tools, you will most
35 | probably end up with a bricked LTDZ board.
36 |
37 | ## Introduction
38 |
39 | LTDZ is an inexpensive 35MHz-4400MHz spectrum analyzer and tracking generator,
40 | readily available from various on-line sellers in price range USD $40 - $50.
41 |
42 | LTDZ provides three main operating modes:
43 |
44 | 1. Signal generator 35MHz - 4400MHz.
45 | 2. Spectrum analyzer 35MHz - 4400MHz.
46 | 3. Scalar network analyzer 35MHz - 4400MHz.
47 |
48 | The original LTDZ hardware and firmware provide approximately 50dB of dynamic
49 | range in spectrum analyzer operating mode and network analyzer operating mode.
50 | After a few and simple hardware modifications and a firmware update, the
51 | available dynamic range in the network analyzer mode can increased up to 80dB.
52 |
53 | In the spectrum analyzer mode, the original receiver bandwidth filter
54 | (RBW-filter) is fixed to 120kHz, which makes it practically impossible to
55 | make RF measurements requiring good spectral resolution. The new firmware
56 | provides a set of digital filters with variable bandwidths from 3kHz to
57 | 120kHz, depending on the step size used during spectrum sweep, providing
58 | much better spectral resolution.
59 |
60 | In the scalar network analyzer mode, the original receiver bandwidth filter
61 | (RBW-filter) is fixed to 120kHz, which results wide noise bandwidth, limiting
62 | the maximum dynamic range to 50dB. The new firmware implements a very narrow
63 | bandwidth receiver filter, providing dynamic range up to 80dB.
64 |
65 | The new firmware will bypass the on-board AD8307 LOG/RMS-detector with
66 | STM32F103's 12-bit ADC (analog-to-digital converter). Applying some simple DSP
67 | (digital signal processing), it is possible to implement highly linear, high
68 | dynamic range digital LOG/RMS-detector up to 80dB of dynamic range.
69 | The on-board, fixed 120kHz RBW-filter will be sampled by the ADC, and the new
70 | firmware will provide a set of digital filter with adjustable bandwidths.
71 |
72 | The new firmware maintains 100% compatibility with the existing serial
73 | command protocol, which means that the updated LTDZ board can be used with
74 | the readily available PC GUI applications, such as WinNWT5, WinNWT4 and
75 | NWT4000lin.
76 |
77 | ## LTDZ Hardware
78 |
79 | LTDZ has two ADF4351 wide-band 35MHz-4400MHz Fractional-N synthesizers.
80 | The first ADF4351 is used as a signal generator, which is also used as a
81 | tracking generator in the scalar network analyzer mode. The second ADF4351 is
82 | used as an local oscillator (LO) for the receiver mixer in spectrum analyzer
83 | and scalar network analyzer modes.
84 |
85 | [LTDZ schematics](./hardware/ltdz-schematics.jpg)
86 |
87 | [LTDZ PCB and component layout](./hardware/ltdz-pcb.jpg)
88 |
89 | The mixer output is feeding the 120kHz 5th order LC low-pass filter
90 | (120kHz RBW-filter). The output of the RBW-filter is connected to the input
91 | of the AD8307 LOG/RMS-detector. The detected signal level from AD8307 is
92 | then sampled by the STM32F103's 12-bit ADC, and the signal level is sent
93 | to PC application over the on-board USB-to-serial interface.
94 |
95 | It was found out that without any modifications the dynamic range of the LTDZ
96 | 35MHz-4400MHz spectrum analyzer and tracking generator is around 45dB - 50dB.
97 | The linearity of the on-board AD8307 LOG/RMS-detector becomes less accurate as
98 | the signal levels become lower than -40dB (relative to the full scale).
99 |
100 | The receiver bandwidth is fixed to 120kHz by the 5th order receiver bandwidth
101 | LC-filter. As the receiver architecture is direct-conversion zero-IF,
102 | the actual receiver bandwidth is twice the 120kHz ie. 240kHz. This wide
103 | receiver bandwidth makes the device almost useless for making any practical
104 | measurements for RF filters, antenna tuning, spectrum analysis etc.for amateur
105 | radio purposes.
106 |
107 | The relatively high noise floor of the LTDZ hardware design, the wide 120kHz
108 | RBW-filter, and the spurious noise components limit the maximum available
109 | dynamic range of the AD8307 LOG/RMS-detector to 40-50dB. Using digital signal
110 | processing, some of theses limitations can be compensated for better dynamic
111 | range and performance.
112 |
113 | ## Hardware modifications
114 |
115 | Please find [LTDZ hardware modifications here](./hardware/ltdz-mods-v1.png).
116 |
117 | ### ST-Link V2 Programming Header
118 |
119 | Soldered ST-Link V2 programming header to the PCB.
120 |
121 | ### Decoupling Capacitors to Power Supply Lines
122 |
123 | Added following decoupling capacitors:
124 |
125 | 2 x 22uF ceramic capacitors to the outputs of the AMS1117 +3V3 regulators.
126 |
127 | 1 x 10uF ceramic capacitor to VDDA power supply.
128 |
129 | ### RBW-Filter Modifications
130 |
131 | The on-board 120kHz RBW-filter was redesigned to give better low-pass filter
132 | response between 0Hz - 120kHz.
133 |
134 | Fortunately the filter topology did not change, so modifying the component
135 | values is pretty easy to do.
136 |
137 | [Design specifications for the new 130kHz RBW-filter](./hardware/ltdz-130kHz-rbw-filter.pdf)
138 |
139 | [Component values for the new 130kHz RBW-filter](./hardware/ltdz-130kHz-rbw-filter.png)
140 |
141 | [LT-Spice simulation for the new and original 120kHz RBW-filter](./hardware/ltdz-new-and-original-120kHz-rbw-filters.png)
142 |
143 | ### Wiring RBW-Filter Output to ADC Input PA.2
144 |
145 | Added 2 x 12 Kohm biasing resistors to bias the ADC-input to 1.5V-1.6V.
146 |
147 | The other 12 Kohm resistor is connected between the output of the 120 kHz
148 | RBW-filter and the +3.3V linear regulator. The other 12 Kohm resistor is
149 | connected between the output of the 120 kHz RBF-filter and ground.
150 |
151 | Finally, wired the output of the RBW-filter to the ADC input PA.2.
152 |
153 | ### Component Datasheets
154 |
155 | [STM32F103 MCU datasheet and documentation](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html#documentation).
156 |
157 | [ADF4351 PLL/VCO product-page and documentation](https://www.analog.com/en/products/adf4351.html).
158 |
159 | [IAM81008 double-balanced 5GHz mixer datasheet](https://www.qsl.net/n9zia/omnitracs/IAM81008.pdf).
160 |
161 | [AD8307 LOG/RMS-detector product-page and documentation](https://www.analog.com/en/products/ad8307.html).
162 |
163 | [AMS1117 linear voltage regulator datasheet](http://www.advanced-monolithic.com/pdf/ds1117.pdf).
164 |
165 | [PS3120A switched capacitor dc-dc-converter datasheet](https://datasheetspdf.com/pdf-file/1307904/PULAN/PS3120A/1).
166 |
167 | ## Setting Up the Firmware Build Environment
168 |
169 | Project source code, tools and libraries:
170 |
171 | * LTDZ project source code from https://github.com/kalvin2021/ltdz-dsp
172 |
173 | * ARM GCC cross-compiler `gcc-arm-none-eabi`.
174 |
175 | * STM32CubeF1-1.8.3.
176 |
177 | * STM32F10x_StdPeriph_Lib_V3.5.0.
178 |
179 | * ST-Link V2 Programming Utility.
180 |
181 | The build environment is targeted for Linux platforms.
182 |
183 | However, since Windows 10 has now Linux subsystem available, setting up the build
184 | environment for Windows 10 should be quite easy as well.
185 |
186 | ### ARM GCC Cross-Compiler
187 |
188 | This project has been built & tested with the following ARM GCC compiler versions:
189 |
190 | - `gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2`
191 | - `gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2`
192 |
193 | It should be possible to build this project successfully with any other recent
194 | ARM GCC cross-compiler version.
195 |
196 | The ARM GCC cross-compiler package can be downloaded from here:
197 |
198 | https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
199 |
200 | User may install the downloaded ARM GCC cross-compiler tool-chain into any
201 | suitable directory.
202 |
203 | This documentation assumes that the ARM GCC cross-compiler tool-chain will be
204 | installed into the user's home directory under directory `opt`.
205 |
206 | ```
207 | $ mkdir -p ~/opt
208 | $ cd ~/opt
209 | $ tar xjf ~/Downloads/gcc-arm-none-eabi-_version_-linux.tar.bz2
210 | ```
211 |
212 | Checking the ARM GCC compiler version:
213 |
214 | ```
215 | $ ~/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version
216 |
217 | arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)
218 | Copyright (C) 2020 Free Software Foundation, Inc.
219 | This is free software; see the source for copying conditions. There is NO
220 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
221 | ```
222 |
223 | ### STM32CubeF1-1.8.3
224 |
225 | The STM32CubeF1-1.8.3 Github-repository can be found here:
226 |
227 | https://github.com/STMicroelectronics/STM32CubeF1/tree/v1.8.3
228 |
229 | Download the zip-package from this link:
230 |
231 | https://github.com/STMicroelectronics/STM32CubeF1/archive/refs/tags/v1.8.3.zip
232 |
233 | Note: This document and the project's `Makefile` uses the same default installation
234 | location for the zip-package that is used by the official STM32Cube ie.
235 | `~/STM32Cube/Repository/`.
236 | Should the user install the zip-package into some other location, it is required
237 | to update the `BSP_ROOT` in the project's `Makefile`.
238 |
239 | Install the downloaded zip-package into home directory under directory `STM32Cube/Repository/STM32CubeF1-1.8.3`:
240 |
241 | ```
242 | $ mkdir -p ~/STM32Cube/Repository
243 | $ cd ~/STM32Cube/Repository
244 | $ unzip ~/Downloads/STM32CubeF1-1.8.3.zip
245 | ```
246 |
247 | ### STM32F10x_StdPeriph_Lib_V3.5.0
248 |
249 | The STM32F10x_StdPeriph_Lib_V3.5.0 can be found here:
250 |
251 | https://www.st.com/en/embedded-software/stsw-stm32054.html
252 |
253 | Note: This document and the project's `Makefile` uses the same default installation
254 | location for the zip-package that is used by the official STM32Cube ie.
255 | `~/STM32Cube/Repository/`.
256 | Should the user install the zip-package into some other location, it is required
257 | to update the `BSP_ROOT` in the project's `Makefile`.
258 |
259 | Install the downloaded zip-package into home directory under directory `STM32Cube/Repository/STM32F10x_StdPeriph_Lib_V3.5.0`:
260 |
261 | ```
262 | $ mkdir -p ~/STM32Cube/Repository
263 | $ cd ~/STM32Cube/Repository
264 | $ unzip ~/Downloads/en.stsw-stm32054_v3.5.0.zip
265 | ```
266 |
267 | ### ST-Link V2 Programming Utility
268 |
269 | Updating the firmware will require use of ST-Link V2 USB-dongle and the utility.
270 |
271 | It is important to be aware that some cheap ST-Link V2 clones sold online
272 | may have wrong pin numbering on the USB-dongle's enclosure.
273 |
274 | It is possible to open the enclosure of the USB-dongle, and check the pin names
275 | from the PCB.
276 | Checking the actual pin numbering will reduce the amount of frustration experienced
277 | while trying to get the firmware update completed successfully.
278 |
279 | Use only the following ST-Link V2 signals: GND, SWDIO and SWDCLK.
280 |
281 | **WARNING: DO NOT CONNECT THE +3V3 OR +5V SIGNALS BETWEEN LTDZ AND THE ST-LINK V2 DONGLE!**
282 |
283 | Otherwise you will most probably damage your LTDZ or ST-Link V2 dongle.
284 |
285 | This project has been tested with ST-Link V2 version 1.7.0.
286 | Any other recent ST-Link V2 tool version should work ok.
287 |
288 | For the Windows build environment, a native Windows ST-Link V2 tool needs to be
289 | installed instead of this Linux version of the utility.
290 |
291 | The ST-Link V2 version 1.7.0 for Linux and Windows can be downloaded from the
292 | following link:
293 |
294 | https://github.com/stlink-org/stlink/releases/tag/v1.7.0
295 |
296 | It is also possible to build the tool from the source code.
297 |
298 | ## Building the Firmware
299 |
300 | Clone the LTDZ source code repository into user's home directory under `ltdz-dsp`:
301 |
302 | ```
303 | $ cd ~
304 | $ git clone --depth 1 https://github.com/kalvin2021/ltdz-dsp.git
305 | ```
306 |
307 | Update the firmware source and build the LTDZ firmware for STM32F103:
308 |
309 | ```
310 | $ cd ~/ltdz-dsp
311 | $ git pull
312 | $ export GCC_PATH=${HOME}/opt/gcc-arm-none-eabi-10-2020-q4-major/bin
313 | $ make
314 | ```
315 |
316 | Flash the firmware into the LTDZ board using ST-Link V2:
317 |
318 | ```
319 | $ make flash
320 | ```
321 |
322 | Use only the following ST-Link V2 signals: GND, SWDIO and SWDCLK.
323 |
324 | **WARNING: DO NOT CONNECT THE +3V3 OR +5V SIGNALS BETWEEN LTDZ AND THE ST-LINK V2 DONGLE!**
325 |
326 | Otherwise you will most probably damage your LTDZ or ST-Link V2 dongle.
327 |
328 | ## Using the `ltdz_adc_read.py` Utility
329 |
330 | The `ltdz_adc_read.py` utility can be used for capturing, plotting and saving
331 | the ADC sample buffer data.
332 |
333 | For example, the following will sweep the frequencies from 90MHz to 120MHz with
334 | a frequency step size of 1MHz (using 30 steps).
335 |
336 | ```
337 | $ python3 util/ltdz_adc_read.py -p /dev/ttyUSB0 --start 90m --end 120m --step 1m
338 | ```
339 |
340 | The utility will plot the ADC sample buffer data in time-domain, and compute
341 | the FFT of the samples for each sweep step (using Hanning window).
342 |
343 | The utility will also plot the overall signal spectrum over the frequency sweep range.
344 |
345 | Note: The ADC sample buffer is by default 4096 samples long.
346 | Transferring the complete ADC sample buffer after each frequency step over the USB
347 | serial line with 57600 bits/s will take some time.
348 |
349 | The utility will be used during firmware development for examining the ADC
350 | sample buffer during the frequency sweep.
351 |
352 | The captured ADC sample buffer data can be saved in Matlab/GNU Octave ASCII-format
353 | for later analysis.
354 |
355 | Here is a screen-capture from measuring a FM-band band-reject filter between
356 | frequency range 65MHz - 130MHz (65 steps):
357 |
358 | 
359 |
--------------------------------------------------------------------------------
/system_stm32f10x.c:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file system_stm32f10x.c
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 11-March-2011
7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
8 | *
9 | * 1. This file provides two functions and one global variable to be called from
10 | * user application:
11 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
12 | * factors, AHB/APBx prescalers and Flash settings).
13 | * This function is called at startup just after reset and
14 | * before branch to main program. This call is made inside
15 | * the "startup_stm32f10x_xx.s" file.
16 | *
17 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
18 | * by the user application to setup the SysTick
19 | * timer or configure other parameters.
20 | *
21 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
22 | * be called whenever the core clock is changed
23 | * during program execution.
24 | *
25 | * 2. After each device reset the HSI (8 MHz) is used as system clock source.
26 | * Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to
27 | * configure the system clock before to branch to main program.
28 | *
29 | * 3. If the system clock source selected by user fails to startup, the SystemInit()
30 | * function will do nothing and HSI still used as system clock source. User can
31 | * add some code to deal with this issue inside the SetSysClock() function.
32 | *
33 | * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on
34 | * the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file.
35 | * When HSE is used as system clock source, directly or through PLL, and you
36 | * are using different crystal you have to adapt the HSE value to your own
37 | * configuration.
38 | *
39 | ******************************************************************************
40 | * @attention
41 | *
42 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
43 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
44 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
45 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
46 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
47 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
48 | *
49 | * © COPYRIGHT 2011 STMicroelectronics
50 | ******************************************************************************
51 | */
52 |
53 | /** @addtogroup CMSIS
54 | * @{
55 | */
56 |
57 | /** @addtogroup stm32f10x_system
58 | * @{
59 | */
60 |
61 | /** @addtogroup STM32F10x_System_Private_Includes
62 | * @{
63 | */
64 |
65 | #include "stm32f10x.h"
66 |
67 | /**
68 | * @}
69 | */
70 |
71 | /** @addtogroup STM32F10x_System_Private_TypesDefinitions
72 | * @{
73 | */
74 |
75 | /**
76 | * @}
77 | */
78 |
79 | /** @addtogroup STM32F10x_System_Private_Defines
80 | * @{
81 | */
82 |
83 | /*!< Uncomment the line corresponding to the desired System clock (SYSCLK)
84 | frequency (after reset the HSI is used as SYSCLK source)
85 |
86 | IMPORTANT NOTE:
87 | ==============
88 | 1. After each device reset the HSI is used as System clock source.
89 |
90 | 2. Please make sure that the selected System clock doesn't exceed your device's
91 | maximum frequency.
92 |
93 | 3. If none of the define below is enabled, the HSI is used as System clock
94 | source.
95 |
96 | 4. The System clock configuration functions provided within this file assume that:
97 | - For Low, Medium and High density Value line devices an external 8MHz
98 | crystal is used to drive the System clock.
99 | - For Low, Medium and High density devices an external 8MHz crystal is
100 | used to drive the System clock.
101 | - For Connectivity line devices an external 25MHz crystal is used to drive
102 | the System clock.
103 | If you are using different crystal you have to adapt those functions accordingly.
104 | */
105 |
106 | #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
107 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */
108 | #define SYSCLK_FREQ_24MHz 24000000
109 | #else
110 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */
111 | /* #define SYSCLK_FREQ_24MHz 24000000 */
112 | /* #define SYSCLK_FREQ_36MHz 36000000 */
113 | /* #define SYSCLK_FREQ_48MHz 48000000 */
114 | /* #define SYSCLK_FREQ_56MHz 56000000 */
115 | #define SYSCLK_FREQ_72MHz 72000000
116 | #endif
117 |
118 | /*!< Uncomment the following line if you need to use external SRAM mounted
119 | on STM3210E-EVAL board (STM32 High density and XL-density devices) or on
120 | STM32100E-EVAL board (STM32 High-density value line devices) as data memory */
121 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
122 | /* #define DATA_IN_ExtSRAM */
123 | #endif
124 |
125 | /*!< Uncomment the following line if you need to relocate your vector Table in
126 | Internal SRAM. */
127 | /* #define VECT_TAB_SRAM */
128 | #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
129 | This value must be a multiple of 0x200. */
130 |
131 |
132 | /**
133 | * @}
134 | */
135 |
136 | /** @addtogroup STM32F10x_System_Private_Macros
137 | * @{
138 | */
139 |
140 | /**
141 | * @}
142 | */
143 |
144 | /** @addtogroup STM32F10x_System_Private_Variables
145 | * @{
146 | */
147 |
148 | /*******************************************************************************
149 | * Clock Definitions
150 | *******************************************************************************/
151 | #ifdef SYSCLK_FREQ_HSE
152 | uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */
153 | #elif defined SYSCLK_FREQ_24MHz
154 | uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */
155 | #elif defined SYSCLK_FREQ_36MHz
156 | uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */
157 | #elif defined SYSCLK_FREQ_48MHz
158 | uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */
159 | #elif defined SYSCLK_FREQ_56MHz
160 | uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */
161 | #elif defined SYSCLK_FREQ_72MHz
162 | uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
163 | #else /*!< HSI Selected as System Clock source */
164 | uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */
165 | #endif
166 |
167 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
168 | /**
169 | * @}
170 | */
171 |
172 | /** @addtogroup STM32F10x_System_Private_FunctionPrototypes
173 | * @{
174 | */
175 |
176 | static void SetSysClock(void);
177 |
178 | #ifdef SYSCLK_FREQ_HSE
179 | static void SetSysClockToHSE(void);
180 | #elif defined SYSCLK_FREQ_24MHz
181 | static void SetSysClockTo24(void);
182 | #elif defined SYSCLK_FREQ_36MHz
183 | static void SetSysClockTo36(void);
184 | #elif defined SYSCLK_FREQ_48MHz
185 | static void SetSysClockTo48(void);
186 | #elif defined SYSCLK_FREQ_56MHz
187 | static void SetSysClockTo56(void);
188 | #elif defined SYSCLK_FREQ_72MHz
189 | static void SetSysClockTo72(void);
190 | #endif
191 |
192 | #ifdef DATA_IN_ExtSRAM
193 | static void SystemInit_ExtMemCtl(void);
194 | #endif /* DATA_IN_ExtSRAM */
195 |
196 | /**
197 | * @}
198 | */
199 |
200 | /** @addtogroup STM32F10x_System_Private_Functions
201 | * @{
202 | */
203 |
204 | /**
205 | * @brief Setup the microcontroller system
206 | * Initialize the Embedded Flash Interface, the PLL and update the
207 | * SystemCoreClock variable.
208 | * @note This function should be used only after reset.
209 | * @param None
210 | * @retval None
211 | */
212 | void SystemInit (void)
213 | {
214 | /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
215 | /* Set HSION bit */
216 | RCC->CR |= (uint32_t)0x00000001;
217 |
218 | /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
219 | #ifndef STM32F10X_CL
220 | RCC->CFGR &= (uint32_t)0xF8FF0000;
221 | #else
222 | RCC->CFGR &= (uint32_t)0xF0FF0000;
223 | #endif /* STM32F10X_CL */
224 |
225 | /* Reset HSEON, CSSON and PLLON bits */
226 | RCC->CR &= (uint32_t)0xFEF6FFFF;
227 |
228 | /* Reset HSEBYP bit */
229 | RCC->CR &= (uint32_t)0xFFFBFFFF;
230 |
231 | /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
232 | RCC->CFGR &= (uint32_t)0xFF80FFFF;
233 |
234 | #ifdef STM32F10X_CL
235 | /* Reset PLL2ON and PLL3ON bits */
236 | RCC->CR &= (uint32_t)0xEBFFFFFF;
237 |
238 | /* Disable all interrupts and clear pending bits */
239 | RCC->CIR = 0x00FF0000;
240 |
241 | /* Reset CFGR2 register */
242 | RCC->CFGR2 = 0x00000000;
243 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
244 | /* Disable all interrupts and clear pending bits */
245 | RCC->CIR = 0x009F0000;
246 |
247 | /* Reset CFGR2 register */
248 | RCC->CFGR2 = 0x00000000;
249 | #else
250 | /* Disable all interrupts and clear pending bits */
251 | RCC->CIR = 0x009F0000;
252 | #endif /* STM32F10X_CL */
253 |
254 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
255 | #ifdef DATA_IN_ExtSRAM
256 | SystemInit_ExtMemCtl();
257 | #endif /* DATA_IN_ExtSRAM */
258 | #endif
259 |
260 | /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
261 | /* Configure the Flash Latency cycles and enable prefetch buffer */
262 | SetSysClock();
263 |
264 | #ifdef VECT_TAB_SRAM
265 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
266 | #else
267 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
268 | #endif
269 | }
270 |
271 | /**
272 | * @brief Update SystemCoreClock variable according to Clock Register Values.
273 | * The SystemCoreClock variable contains the core clock (HCLK), it can
274 | * be used by the user application to setup the SysTick timer or configure
275 | * other parameters.
276 | *
277 | * @note Each time the core clock (HCLK) changes, this function must be called
278 | * to update SystemCoreClock variable value. Otherwise, any configuration
279 | * based on this variable will be incorrect.
280 | *
281 | * @note - The system frequency computed by this function is not the real
282 | * frequency in the chip. It is calculated based on the predefined
283 | * constant and the selected clock source:
284 | *
285 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
286 | *
287 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
288 | *
289 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
290 | * or HSI_VALUE(*) multiplied by the PLL factors.
291 | *
292 | * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
293 | * 8 MHz) but the real value may vary depending on the variations
294 | * in voltage and temperature.
295 | *
296 | * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
297 | * 8 MHz or 25 MHz, depedning on the product used), user has to ensure
298 | * that HSE_VALUE is same as the real frequency of the crystal used.
299 | * Otherwise, this function may have wrong result.
300 | *
301 | * - The result of this function could be not correct when using fractional
302 | * value for HSE crystal.
303 | * @param None
304 | * @retval None
305 | */
306 | void SystemCoreClockUpdate (void)
307 | {
308 | uint32_t tmp = 0, pllmull = 0, pllsource = 0;
309 |
310 | #ifdef STM32F10X_CL
311 | uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
312 | #endif /* STM32F10X_CL */
313 |
314 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
315 | uint32_t prediv1factor = 0;
316 | #endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */
317 |
318 | /* Get SYSCLK source -------------------------------------------------------*/
319 | tmp = RCC->CFGR & RCC_CFGR_SWS;
320 |
321 | switch (tmp)
322 | {
323 | case 0x00: /* HSI used as system clock */
324 | SystemCoreClock = HSI_VALUE;
325 | break;
326 | case 0x04: /* HSE used as system clock */
327 | SystemCoreClock = HSE_VALUE;
328 | break;
329 | case 0x08: /* PLL used as system clock */
330 |
331 | /* Get PLL clock source and multiplication factor ----------------------*/
332 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
333 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
334 |
335 | #ifndef STM32F10X_CL
336 | pllmull = ( pllmull >> 18) + 2;
337 |
338 | if (pllsource == 0x00)
339 | {
340 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */
341 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
342 | }
343 | else
344 | {
345 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
346 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
347 | /* HSE oscillator clock selected as PREDIV1 clock entry */
348 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
349 | #else
350 | /* HSE selected as PLL clock entry */
351 | if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
352 | {/* HSE oscillator clock divided by 2 */
353 | SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
354 | }
355 | else
356 | {
357 | SystemCoreClock = HSE_VALUE * pllmull;
358 | }
359 | #endif
360 | }
361 | #else
362 | pllmull = pllmull >> 18;
363 |
364 | if (pllmull != 0x0D)
365 | {
366 | pllmull += 2;
367 | }
368 | else
369 | { /* PLL multiplication factor = PLL input clock * 6.5 */
370 | pllmull = 13 / 2;
371 | }
372 |
373 | if (pllsource == 0x00)
374 | {
375 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */
376 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
377 | }
378 | else
379 | {/* PREDIV1 selected as PLL clock entry */
380 |
381 | /* Get PREDIV1 clock source and division factor */
382 | prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
383 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
384 |
385 | if (prediv1source == 0)
386 | {
387 | /* HSE oscillator clock selected as PREDIV1 clock entry */
388 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
389 | }
390 | else
391 | {/* PLL2 clock selected as PREDIV1 clock entry */
392 |
393 | /* Get PREDIV2 division factor and PLL2 multiplication factor */
394 | prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
395 | pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;
396 | SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
397 | }
398 | }
399 | #endif /* STM32F10X_CL */
400 | break;
401 |
402 | default:
403 | SystemCoreClock = HSI_VALUE;
404 | break;
405 | }
406 |
407 | /* Compute HCLK clock frequency ----------------*/
408 | /* Get HCLK prescaler */
409 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
410 | /* HCLK clock frequency */
411 | SystemCoreClock >>= tmp;
412 | }
413 |
414 | /**
415 | * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
416 | * @param None
417 | * @retval None
418 | */
419 | static void SetSysClock(void)
420 | {
421 | #ifdef SYSCLK_FREQ_HSE
422 | SetSysClockToHSE();
423 | #elif defined SYSCLK_FREQ_24MHz
424 | SetSysClockTo24();
425 | #elif defined SYSCLK_FREQ_36MHz
426 | SetSysClockTo36();
427 | #elif defined SYSCLK_FREQ_48MHz
428 | SetSysClockTo48();
429 | #elif defined SYSCLK_FREQ_56MHz
430 | SetSysClockTo56();
431 | #elif defined SYSCLK_FREQ_72MHz
432 | SetSysClockTo72();
433 | #endif
434 |
435 | /* If none of the define above is enabled, the HSI is used as System clock
436 | source (default after reset) */
437 | }
438 |
439 | /**
440 | * @brief Setup the external memory controller. Called in startup_stm32f10x.s
441 | * before jump to __main
442 | * @param None
443 | * @retval None
444 | */
445 | #ifdef DATA_IN_ExtSRAM
446 | /**
447 | * @brief Setup the external memory controller.
448 | * Called in startup_stm32f10x_xx.s/.c before jump to main.
449 | * This function configures the external SRAM mounted on STM3210E-EVAL
450 | * board (STM32 High density devices). This SRAM will be used as program
451 | * data memory (including heap and stack).
452 | * @param None
453 | * @retval None
454 | */
455 | void SystemInit_ExtMemCtl(void)
456 | {
457 | /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
458 | required, then adjust the Register Addresses */
459 |
460 | /* Enable FSMC clock */
461 | RCC->AHBENR = 0x00000114;
462 |
463 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
464 | RCC->APB2ENR = 0x000001E0;
465 |
466 | /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
467 | /*---------------- SRAM Address lines configuration -------------------------*/
468 | /*---------------- NOE and NWE configuration --------------------------------*/
469 | /*---------------- NE3 configuration ----------------------------------------*/
470 | /*---------------- NBL0, NBL1 configuration ---------------------------------*/
471 |
472 | GPIOD->CRL = 0x44BB44BB;
473 | GPIOD->CRH = 0xBBBBBBBB;
474 |
475 | GPIOE->CRL = 0xB44444BB;
476 | GPIOE->CRH = 0xBBBBBBBB;
477 |
478 | GPIOF->CRL = 0x44BBBBBB;
479 | GPIOF->CRH = 0xBBBB4444;
480 |
481 | GPIOG->CRL = 0x44BBBBBB;
482 | GPIOG->CRH = 0x44444B44;
483 |
484 | /*---------------- FSMC Configuration ---------------------------------------*/
485 | /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
486 |
487 | FSMC_Bank1->BTCR[4] = 0x00001011;
488 | FSMC_Bank1->BTCR[5] = 0x00000200;
489 | }
490 | #endif /* DATA_IN_ExtSRAM */
491 |
492 | #ifdef SYSCLK_FREQ_HSE
493 | /**
494 | * @brief Selects HSE as System clock source and configure HCLK, PCLK2
495 | * and PCLK1 prescalers.
496 | * @note This function should be used only after reset.
497 | * @param None
498 | * @retval None
499 | */
500 | static void SetSysClockToHSE(void)
501 | {
502 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
503 |
504 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
505 | /* Enable HSE */
506 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
507 |
508 | /* Wait till HSE is ready and if Time out is reached exit */
509 | do
510 | {
511 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
512 | StartUpCounter++;
513 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
514 |
515 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
516 | {
517 | HSEStatus = (uint32_t)0x01;
518 | }
519 | else
520 | {
521 | HSEStatus = (uint32_t)0x00;
522 | }
523 |
524 | if (HSEStatus == (uint32_t)0x01)
525 | {
526 |
527 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
528 | /* Enable Prefetch Buffer */
529 | FLASH->ACR |= FLASH_ACR_PRFTBE;
530 |
531 | /* Flash 0 wait state */
532 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
533 |
534 | #ifndef STM32F10X_CL
535 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
536 | #else
537 | if (HSE_VALUE <= 24000000)
538 | {
539 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
540 | }
541 | else
542 | {
543 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
544 | }
545 | #endif /* STM32F10X_CL */
546 | #endif
547 |
548 | /* HCLK = SYSCLK */
549 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
550 |
551 | /* PCLK2 = HCLK */
552 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
553 |
554 | /* PCLK1 = HCLK */
555 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
556 |
557 | /* Select HSE as system clock source */
558 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
559 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;
560 |
561 | /* Wait till HSE is used as system clock source */
562 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
563 | {
564 | }
565 | }
566 | else
567 | { /* If HSE fails to start-up, the application will have wrong clock
568 | configuration. User can add here some code to deal with this error */
569 | }
570 | }
571 | #elif defined SYSCLK_FREQ_24MHz
572 | /**
573 | * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2
574 | * and PCLK1 prescalers.
575 | * @note This function should be used only after reset.
576 | * @param None
577 | * @retval None
578 | */
579 | static void SetSysClockTo24(void)
580 | {
581 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
582 |
583 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
584 | /* Enable HSE */
585 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
586 |
587 | /* Wait till HSE is ready and if Time out is reached exit */
588 | do
589 | {
590 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
591 | StartUpCounter++;
592 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
593 |
594 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
595 | {
596 | HSEStatus = (uint32_t)0x01;
597 | }
598 | else
599 | {
600 | HSEStatus = (uint32_t)0x00;
601 | }
602 |
603 | if (HSEStatus == (uint32_t)0x01)
604 | {
605 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
606 | /* Enable Prefetch Buffer */
607 | FLASH->ACR |= FLASH_ACR_PRFTBE;
608 |
609 | /* Flash 0 wait state */
610 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
611 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
612 | #endif
613 |
614 | /* HCLK = SYSCLK */
615 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
616 |
617 | /* PCLK2 = HCLK */
618 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
619 |
620 | /* PCLK1 = HCLK */
621 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
622 |
623 | #ifdef STM32F10X_CL
624 | /* Configure PLLs ------------------------------------------------------*/
625 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */
626 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
627 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
628 | RCC_CFGR_PLLMULL6);
629 |
630 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
631 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */
632 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
633 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
634 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
635 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
636 |
637 | /* Enable PLL2 */
638 | RCC->CR |= RCC_CR_PLL2ON;
639 | /* Wait till PLL2 is ready */
640 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
641 | {
642 | }
643 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
644 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */
645 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
646 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6);
647 | #else
648 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */
649 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
650 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6);
651 | #endif /* STM32F10X_CL */
652 |
653 | /* Enable PLL */
654 | RCC->CR |= RCC_CR_PLLON;
655 |
656 | /* Wait till PLL is ready */
657 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
658 | {
659 | }
660 |
661 | /* Select PLL as system clock source */
662 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
663 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
664 |
665 | /* Wait till PLL is used as system clock source */
666 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
667 | {
668 | }
669 | }
670 | else
671 | { /* If HSE fails to start-up, the application will have wrong clock
672 | configuration. User can add here some code to deal with this error */
673 | }
674 | }
675 | #elif defined SYSCLK_FREQ_36MHz
676 | /**
677 | * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2
678 | * and PCLK1 prescalers.
679 | * @note This function should be used only after reset.
680 | * @param None
681 | * @retval None
682 | */
683 | static void SetSysClockTo36(void)
684 | {
685 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
686 |
687 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
688 | /* Enable HSE */
689 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
690 |
691 | /* Wait till HSE is ready and if Time out is reached exit */
692 | do
693 | {
694 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
695 | StartUpCounter++;
696 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
697 |
698 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
699 | {
700 | HSEStatus = (uint32_t)0x01;
701 | }
702 | else
703 | {
704 | HSEStatus = (uint32_t)0x00;
705 | }
706 |
707 | if (HSEStatus == (uint32_t)0x01)
708 | {
709 | /* Enable Prefetch Buffer */
710 | FLASH->ACR |= FLASH_ACR_PRFTBE;
711 |
712 | /* Flash 1 wait state */
713 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
714 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
715 |
716 | /* HCLK = SYSCLK */
717 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
718 |
719 | /* PCLK2 = HCLK */
720 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
721 |
722 | /* PCLK1 = HCLK */
723 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
724 |
725 | #ifdef STM32F10X_CL
726 | /* Configure PLLs ------------------------------------------------------*/
727 |
728 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */
729 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
730 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
731 | RCC_CFGR_PLLMULL9);
732 |
733 | /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
734 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */
735 |
736 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
737 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
738 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
739 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
740 |
741 | /* Enable PLL2 */
742 | RCC->CR |= RCC_CR_PLL2ON;
743 | /* Wait till PLL2 is ready */
744 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
745 | {
746 | }
747 |
748 | #else
749 | /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */
750 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
751 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9);
752 | #endif /* STM32F10X_CL */
753 |
754 | /* Enable PLL */
755 | RCC->CR |= RCC_CR_PLLON;
756 |
757 | /* Wait till PLL is ready */
758 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
759 | {
760 | }
761 |
762 | /* Select PLL as system clock source */
763 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
764 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
765 |
766 | /* Wait till PLL is used as system clock source */
767 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
768 | {
769 | }
770 | }
771 | else
772 | { /* If HSE fails to start-up, the application will have wrong clock
773 | configuration. User can add here some code to deal with this error */
774 | }
775 | }
776 | #elif defined SYSCLK_FREQ_48MHz
777 | /**
778 | * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2
779 | * and PCLK1 prescalers.
780 | * @note This function should be used only after reset.
781 | * @param None
782 | * @retval None
783 | */
784 | static void SetSysClockTo48(void)
785 | {
786 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
787 |
788 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
789 | /* Enable HSE */
790 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
791 |
792 | /* Wait till HSE is ready and if Time out is reached exit */
793 | do
794 | {
795 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
796 | StartUpCounter++;
797 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
798 |
799 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
800 | {
801 | HSEStatus = (uint32_t)0x01;
802 | }
803 | else
804 | {
805 | HSEStatus = (uint32_t)0x00;
806 | }
807 |
808 | if (HSEStatus == (uint32_t)0x01)
809 | {
810 | /* Enable Prefetch Buffer */
811 | FLASH->ACR |= FLASH_ACR_PRFTBE;
812 |
813 | /* Flash 1 wait state */
814 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
815 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
816 |
817 | /* HCLK = SYSCLK */
818 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
819 |
820 | /* PCLK2 = HCLK */
821 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
822 |
823 | /* PCLK1 = HCLK */
824 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
825 |
826 | #ifdef STM32F10X_CL
827 | /* Configure PLLs ------------------------------------------------------*/
828 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
829 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
830 |
831 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
832 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
833 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
834 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
835 |
836 | /* Enable PLL2 */
837 | RCC->CR |= RCC_CR_PLL2ON;
838 | /* Wait till PLL2 is ready */
839 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
840 | {
841 | }
842 |
843 |
844 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */
845 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
846 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
847 | RCC_CFGR_PLLMULL6);
848 | #else
849 | /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
850 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
851 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);
852 | #endif /* STM32F10X_CL */
853 |
854 | /* Enable PLL */
855 | RCC->CR |= RCC_CR_PLLON;
856 |
857 | /* Wait till PLL is ready */
858 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
859 | {
860 | }
861 |
862 | /* Select PLL as system clock source */
863 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
864 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
865 |
866 | /* Wait till PLL is used as system clock source */
867 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
868 | {
869 | }
870 | }
871 | else
872 | { /* If HSE fails to start-up, the application will have wrong clock
873 | configuration. User can add here some code to deal with this error */
874 | }
875 | }
876 |
877 | #elif defined SYSCLK_FREQ_56MHz
878 | /**
879 | * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2
880 | * and PCLK1 prescalers.
881 | * @note This function should be used only after reset.
882 | * @param None
883 | * @retval None
884 | */
885 | static void SetSysClockTo56(void)
886 | {
887 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
888 |
889 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
890 | /* Enable HSE */
891 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
892 |
893 | /* Wait till HSE is ready and if Time out is reached exit */
894 | do
895 | {
896 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
897 | StartUpCounter++;
898 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
899 |
900 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
901 | {
902 | HSEStatus = (uint32_t)0x01;
903 | }
904 | else
905 | {
906 | HSEStatus = (uint32_t)0x00;
907 | }
908 |
909 | if (HSEStatus == (uint32_t)0x01)
910 | {
911 | /* Enable Prefetch Buffer */
912 | FLASH->ACR |= FLASH_ACR_PRFTBE;
913 |
914 | /* Flash 2 wait state */
915 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
916 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
917 |
918 | /* HCLK = SYSCLK */
919 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
920 |
921 | /* PCLK2 = HCLK */
922 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
923 |
924 | /* PCLK1 = HCLK */
925 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
926 |
927 | #ifdef STM32F10X_CL
928 | /* Configure PLLs ------------------------------------------------------*/
929 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
930 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
931 |
932 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
933 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
934 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
935 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
936 |
937 | /* Enable PLL2 */
938 | RCC->CR |= RCC_CR_PLL2ON;
939 | /* Wait till PLL2 is ready */
940 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
941 | {
942 | }
943 |
944 |
945 | /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */
946 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
947 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
948 | RCC_CFGR_PLLMULL7);
949 | #else
950 | /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
951 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
952 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7);
953 |
954 | #endif /* STM32F10X_CL */
955 |
956 | /* Enable PLL */
957 | RCC->CR |= RCC_CR_PLLON;
958 |
959 | /* Wait till PLL is ready */
960 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
961 | {
962 | }
963 |
964 | /* Select PLL as system clock source */
965 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
966 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
967 |
968 | /* Wait till PLL is used as system clock source */
969 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
970 | {
971 | }
972 | }
973 | else
974 | { /* If HSE fails to start-up, the application will have wrong clock
975 | configuration. User can add here some code to deal with this error */
976 | }
977 | }
978 |
979 | #elif defined SYSCLK_FREQ_72MHz
980 | /**
981 | * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2
982 | * and PCLK1 prescalers.
983 | * @note This function should be used only after reset.
984 | * @param None
985 | * @retval None
986 | */
987 | static void SetSysClockTo72(void)
988 | {
989 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
990 |
991 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
992 | /* Enable HSE */
993 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
994 |
995 | /* Wait till HSE is ready and if Time out is reached exit */
996 | do
997 | {
998 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
999 | StartUpCounter++;
1000 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
1001 |
1002 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
1003 | {
1004 | HSEStatus = (uint32_t)0x01;
1005 | }
1006 | else
1007 | {
1008 | HSEStatus = (uint32_t)0x00;
1009 | }
1010 |
1011 | if (HSEStatus == (uint32_t)0x01)
1012 | {
1013 | /* Enable Prefetch Buffer */
1014 | FLASH->ACR |= FLASH_ACR_PRFTBE;
1015 |
1016 | /* Flash 2 wait state */
1017 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
1018 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
1019 |
1020 |
1021 | /* HCLK = SYSCLK */
1022 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
1023 |
1024 | /* PCLK2 = HCLK */
1025 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
1026 |
1027 | /* PCLK1 = HCLK */
1028 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
1029 |
1030 | #ifdef STM32F10X_CL
1031 | /* Configure PLLs ------------------------------------------------------*/
1032 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
1033 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
1034 |
1035 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
1036 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
1037 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
1038 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
1039 |
1040 | /* Enable PLL2 */
1041 | RCC->CR |= RCC_CR_PLL2ON;
1042 | /* Wait till PLL2 is ready */
1043 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
1044 | {
1045 | }
1046 |
1047 |
1048 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
1049 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
1050 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
1051 | RCC_CFGR_PLLMULL9);
1052 | #else
1053 | /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
1054 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
1055 | RCC_CFGR_PLLMULL));
1056 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
1057 | #endif /* STM32F10X_CL */
1058 |
1059 | /* Enable PLL */
1060 | RCC->CR |= RCC_CR_PLLON;
1061 |
1062 | /* Wait till PLL is ready */
1063 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
1064 | {
1065 | }
1066 |
1067 | /* Select PLL as system clock source */
1068 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
1069 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
1070 |
1071 | /* Wait till PLL is used as system clock source */
1072 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
1073 | {
1074 | }
1075 | }
1076 | else
1077 | { /* If HSE fails to start-up, the application will have wrong clock
1078 | configuration. User can add here some code to deal with this error */
1079 | }
1080 | }
1081 | #endif
1082 |
1083 | /**
1084 | * @}
1085 | */
1086 |
1087 | /**
1088 | * @}
1089 | */
1090 |
1091 | /**
1092 | * @}
1093 | */
1094 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
1095 |
--------------------------------------------------------------------------------
/util/ltdz_adc_read.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | #
3 | # Author Kalvin
4 | #
5 | # A simple utility for reading and plotting the LTDZ ADC sample buffer.
6 | # The ADC sample data can be saved into a MATLAB ascii data file for later
7 | # analysis.
8 | #
9 | # Example:
10 | #
11 | # python3 ltdz_adc_read.py -p /dev/ttyUSB0 --start 90m --end 100m --count 10
12 | #
13 | # After a sweep, use the navigation buttons for navigating the sweep samples.
14 | #
15 | # File | New Start a new sweep
16 | # File | Save Save the current sweep sample in MATLAB ascii data format
17 | # File | Save All Save all sweep samples in MATLAB ascii data format
18 | # File | Exit Quit
19 | #
20 |
21 | APP_VERSION = "Ver 0.1"
22 | APP_TITLE = "LTDZ ADC Reader " + APP_VERSION
23 | APP_GEOMETRY = '1400x800'
24 |
25 | import tkinter as tk
26 | from tkinter import ttk
27 | from tkinter import messagebox
28 | from tkinter.filedialog import asksaveasfile
29 |
30 | import numpy as np
31 | import matplotlib.pyplot as plt
32 | from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
33 |
34 | from threading import Thread
35 | from queue import Queue
36 | import serial, struct
37 |
38 | from enum import Enum
39 |
40 | import argparse
41 |
42 | SERIAL_PORT = "/dev/ttyUSB0"
43 | SERIAL_BAUD = 57600
44 | SERIAL_TIMEOUT = 10
45 |
46 | serial_port = SERIAL_PORT
47 | serial_baud = SERIAL_BAUD
48 | serial_timeout = SERIAL_TIMEOUT
49 |
50 | MIN_Hz = 35e6
51 | MAX_Hz = 4400e6
52 | MIN_STEP_Hz = 1
53 | MAX_STEP_Hz = 1000e3
54 | MIN_STEP_COUNT = 3
55 | MAX_STEP_COUNT = 9999
56 | MIN_Fs_Hz = 100e3
57 | MAX_Fs_Hz = 2e6
58 |
59 | ADC_MIN_BUFFER = 256
60 | ADC_MAX_BUFFER = 8192
61 | ADC_REF_VALUE = 2048
62 |
63 | FFT_MIN_dB = -100
64 | FFT_MAX_dB = 0
65 | SPECTRUM_MIN_dB = -90
66 | SPECTRUM_MAX_dB = 10
67 |
68 | TG_STATE_DISABLED = 0x00
69 | TG_STATE_ENABLED = 0x01
70 | TG_STATE_LOCAL = 0x00
71 | TG_STATE_REMOTE = 0x02
72 |
73 | # Set Matplotlib style
74 | plt.style.use('ggplot')
75 |
76 | #------------------------------------------------------------------------------
77 | # LTDZ sweep process
78 | #------------------------------------------------------------------------------
79 |
80 | # LTDZ sweep configuration
81 | class LtdzSweepConfig:
82 | def __init__(self):
83 | # Serial port
84 | self.serial_port = None
85 |
86 | # Serial port baud rate
87 | self.serial_baud = None
88 |
89 | # Serial port read/write timeout in seconds
90 | self.serial_timeout = None
91 |
92 | # Tracking generator remote control
93 | self.tg_state = None
94 |
95 | # Sweep start frequency
96 | self.start_Hz = None
97 |
98 | # Sweep step frequency
99 | self.step_Hz = None
100 |
101 | # Sweep step count
102 | self.step_count = None
103 |
104 | # LTDZ sweep data
105 | class LtdzSweepData:
106 | def __init__(self):
107 | # Device hardware ID
108 | self.hardware = None;
109 |
110 | # Device firmware version major
111 | self.firmware_major = None;
112 |
113 | # Device firmware version minor
114 | self.firmware_major = None;
115 |
116 | # Device tracking generator state
117 | self.tg_state = None;
118 |
119 | # Current sweep number
120 | self.n = None
121 |
122 | # Current frequency
123 | self.f_Hz = None
124 |
125 | # RX offset (0=Tracking generator disabled)
126 | self.rx_offset_Hz = None
127 |
128 | # Frequency step size
129 | self.step_Hz = None
130 |
131 | # ADC Sample rate
132 | self.sample_rate_Hz = None
133 |
134 | # ADC buffer size
135 | self.buffer_size = None
136 |
137 | # ADC samples
138 | self.samples = None
139 |
140 | # LTDZ status
141 | class LtdzStatus(Enum):
142 | # Success
143 | SUCCESS = 0
144 | # Serial port timeout
145 | TIMEOUT = 1
146 | # Serial port communication error
147 | ERROR = 2
148 | # Serial port other error
149 | FAIL = 3
150 |
151 | # LTDZ process exit sentinel
152 | class LtdzSweepExitStatus:
153 | def __init__(self, status: LtdzStatus, message: str=None):
154 | # Exit code
155 | self.status = status
156 | # Optional error message
157 | self.message = message
158 |
159 | # LTDZ sweep processing thread
160 | def ltdz_sweep_run(q: Queue, config: LtdzSweepConfig) -> None:
161 | print("LTDZ thread started.")
162 |
163 | try:
164 | with serial.Serial(config.serial_port,
165 | config.serial_baud, timeout=config.serial_timeout) as ser:
166 |
167 | if config.tg_state is not None:
168 | tg_state = TG_STATE_REMOTE | config.tg_state
169 | else:
170 | tg_state = TG_STATE_LOCAL
171 |
172 | # Create LTDZ tracking generator control command
173 | command = b'\x8f'
174 | command += b't'
175 | command += "{:1}".format(tg_state).encode()
176 |
177 | # Write LTDZ command to serial port
178 | num_bytes = ser.write(command)
179 | if num_bytes < len(command):
180 | q.put(LtdzSweepExitStatus(LtdzStatus.FAIL,
181 | "Fatal serial port '{}' error while writing command").format(config.serial_port))
182 | ser.close()
183 | return
184 |
185 | # Create LTDZ sweep command
186 | command = b'\x8f'
187 | command += b'b'
188 | command += "{:09}00{:06}{:04}".format(config.start_Hz//10, config.step_Hz//10, config.step_count).encode()
189 |
190 | # Write LTDZ command to serial port
191 | num_bytes = ser.write(command)
192 | if num_bytes < len(command):
193 | q.put(LtdzSweepExitStatus(LtdzStatus.FAIL,
194 | "Fatal serial port '{}' error while writing command").format(config.serial_port))
195 | ser.close()
196 | return
197 |
198 | # Read sweep data from LTDZ
199 | for n in range(0, config.step_count):
200 | sd = LtdzSweepData()
201 |
202 | sd.n = n
203 |
204 | # Read device hardware ID
205 | buf = ser.read(1)
206 | if len(buf) < 1:
207 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
208 | break
209 |
210 | sd.hardware = struct.unpack_from("B"*1, buf)[0]
211 |
212 | # Read device firmware version major
213 | buf = ser.read(1)
214 | if len(buf) < 1:
215 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
216 | break
217 |
218 | sd.firmware_major = struct.unpack_from("B"*1, buf)[0]
219 |
220 | # Read device firmware version minor
221 | buf = ser.read(1)
222 | if len(buf) < 1:
223 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
224 | break
225 |
226 | sd.firmware_minor = struct.unpack_from("B"*1, buf)[0]
227 |
228 | # Read device tracking generator state
229 | buf = ser.read(1)
230 | if len(buf) < 1:
231 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
232 | break
233 |
234 | sd.tg_state = struct.unpack_from("B"*1, buf)[0]
235 |
236 | # Read center frequency
237 | buf = ser.read(4)
238 | if len(buf) < 4:
239 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
240 | break
241 |
242 | sd.f_Hz = struct.unpack_from("<" + "I"*1, buf)[0]*10
243 |
244 | if sd.f_Hz < MIN_Hz or MAX_Hz < sd.f_Hz:
245 | q.put(LtdzSweepExitStatus(LtdzStatus.ERROR,
246 | "Frequency '{}' outside valid range".format(sd.f_Hz)))
247 | break
248 |
249 | # Read RX offset frequency (0 if tracking generator disabled)
250 | buf = ser.read(4)
251 | if len(buf) < 4:
252 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
253 | break
254 |
255 | sd.rx_offset_Hz = struct.unpack_from("<" + "I"*1, buf)[0]*10
256 |
257 | # Read frequency step size
258 | buf = ser.read(4)
259 | if len(buf) < 4:
260 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
261 | break
262 |
263 | sd.step_Hz = struct.unpack_from("<" + "i"*1, buf)[0]*10
264 |
265 | if sd.step_Hz < MIN_STEP_Hz or MAX_STEP_Hz < sd.step_Hz:
266 | q.put(LtdzSweepExitStatus(LtdzStatus.ERROR,
267 | "Frequency step '{}' outside valid range.".format(sd.step_Hz)))
268 | break
269 |
270 | # Read ADC sample clock M
271 | buf = ser.read(4)
272 | if len(buf) < 4:
273 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
274 | break
275 |
276 | adc_clock_m = struct.unpack_from("<" + "I"*1, buf)[0]
277 |
278 | # Read ADC sample clock N
279 | buf = ser.read(4)
280 | if len(buf) < 4:
281 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
282 | break
283 |
284 | adc_clock_n = struct.unpack_from("<" + "I"*1, buf)[0]
285 |
286 | if adc_clock_n == 0:
287 | q.put(LtdzSweepExitStatus(LtdzStatus.ERROR,
288 | "ADC sample clock value N is zero"))
289 | break
290 |
291 | sd.sample_rate_Hz = adc_clock_m/adc_clock_n;
292 |
293 | if sd.sample_rate_Hz < MIN_Fs_Hz or MAX_Fs_Hz < sd.sample_rate_Hz:
294 | q.put(LtdzSweepExitStatus(LtdzStatus.ERROR,
295 | "Sample rate '{}' is outsize valid range.".format(sd.sample_rate_Hz)))
296 | break
297 |
298 | if sd.sample_rate_Hz/2 < sd.rx_offset_Hz:
299 | q.put(LtdzSweepExitStatus(LtdzStatus.ERROR,
300 | "RX offset '{}' is outsize valid range.".format(sd.rx_offset_Hz)))
301 | break
302 |
303 | # Read ADC sample buffer size
304 | buf = ser.read(2)
305 | if len(buf) < 2:
306 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
307 | break
308 |
309 | sd.buffer_size = struct.unpack_from("<" + "H"*1, buf)[0]
310 |
311 | if sd.buffer_size < ADC_MIN_BUFFER or ADC_MAX_BUFFER < sd.buffer_size:
312 | q.put(LtdzSweepExitStatus(LtdzStatus.ERROR,
313 | "ADC buffser size '{}' is outsize valid range.".format(sd.buffer_size)))
314 | break
315 |
316 | # Read ADC sample buffer samples
317 | byte_count = 2*sd.buffer_size
318 | buf = ser.read(byte_count)
319 | if len(buf) < byte_count:
320 | q.put(LtdzSweepExitStatus(LtdzStatus.TIMEOUT))
321 | break
322 |
323 | sd.samples = struct.unpack_from("<" + "h"*sd.buffer_size, buf)
324 |
325 | # Push data to the main thread
326 | q.put(sd)
327 |
328 | # Successful sweep
329 | q.put(LtdzSweepExitStatus(LtdzStatus.SUCCESS))
330 | ser.close()
331 |
332 | except serial.SerialException:
333 | # Fatal error with serial port
334 | q.put(LtdzSweepExitStatus(LtdzStatus.FAIL,
335 | "Fatal serial port '{}' error.".format(config.serial_port)))
336 |
337 | print("LTDZ thread ended.")
338 |
339 | # -----------------------------------------------------------------------------
340 | # Application GUI
341 | # -----------------------------------------------------------------------------
342 |
343 | MENU_FILE = "File"
344 | MENU_FILE_NEW = "New"
345 | MENU_FILE_NEW_KB = ""
346 | MENU_FILE_SAVE = "Save"
347 | MENU_FILE_SAVE_KB = ""
348 | MENU_FILE_SAVE_ALL = "Save all"
349 | MENU_FILE_SAVE_ALL_KB = ""
350 | MENU_FILE_EXIT = "Exit"
351 | MENU_FILE_EXIT_KB1 = ""
352 | MENU_FILE_EXIT_KB2 = ""
353 |
354 | class Application(tk.Frame):
355 | def __init__(self, win, sweep_settings):
356 | super().__init__(win)
357 | # Sample frequencies
358 | self.f_Hz = []
359 | # Sample data items
360 | self.samples = []
361 | # Sample levels in dB
362 | self.level_dB = []
363 | self.win = win
364 | self.win.geometry(APP_GEOMETRY)
365 | self.win.resizable(False, False)
366 | self.sweep_settings = sweep_settings
367 | self.create_widgets()
368 | self.update_sweep_settings()
369 | self.sweep_run()
370 |
371 | def create_widgets(self):
372 | self.win.title(APP_TITLE)
373 |
374 | #
375 | # Create menus
376 | #
377 |
378 | self.menu_bar = tk.Menu(self.win)
379 | self.win.config(menu=self.menu_bar)
380 | self.file_menu = tk.Menu(self.menu_bar, tearoff=0)
381 | self.file_menu.add_command(label=MENU_FILE_NEW,
382 | command=self._file_new, accelerator="Ctrl+N")
383 | self.file_menu.add_command(label=MENU_FILE_SAVE,
384 | command=self._file_save, accelerator="Ctrl+S")
385 | self.file_menu.add_command(label=MENU_FILE_SAVE_ALL,
386 | command=self._file_save_all, accelerator="Ctrl+A")
387 | self.file_menu.add_separator();
388 | self.file_menu.add_command(label=MENU_FILE_EXIT,
389 | command=self._quit, accelerator="Ctrl-X")
390 | self.file_menu.bind_all(MENU_FILE_EXIT_KB1, self._quit_shortcut)
391 | self.file_menu.bind_all(MENU_FILE_EXIT_KB2, self._quit_shortcut)
392 | self.menu_bar.add_cascade(menu=self.file_menu, label=MENU_FILE)
393 |
394 | #
395 | # Default settings
396 | #
397 |
398 | PLOT_PADX = 5
399 | PLOT_PADY = 2
400 |
401 | PADX = 5
402 | PADY = 2
403 |
404 | LABEL_WIDTH = 10
405 | VALUE_WIDTH = 15
406 |
407 | #
408 | # Sweep parameters label frame items
409 | #
410 |
411 | COL = 0
412 | ROW = 0
413 | frm = ttk.LabelFrame(self.win, text=" Sweep Parameters ")
414 | frm.grid(column=COL, row=ROW, padx=5, pady=5, sticky=tk.EW)
415 |
416 | COL = 0
417 | ROW = 0
418 | self.sweep_start = tk.StringVar()
419 | ttk.Label(frm, text="Start:", width=LABEL_WIDTH, anchor=tk.W).grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
420 | ttk.Label(frm, textvariable=self.sweep_start, width=VALUE_WIDTH, anchor=tk.E).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
421 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
422 |
423 | ROW += 1
424 | self.sweep_center = tk.StringVar()
425 | ttk.Label(frm, text="Center:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
426 | ttk.Label(frm, textvariable=self.sweep_center).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
427 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
428 |
429 | ROW += 1
430 | self.sweep_end = tk.StringVar()
431 | ttk.Label(frm, text="End:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
432 | ttk.Label(frm, textvariable=self.sweep_end).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
433 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
434 |
435 | ROW += 1
436 | self.sweep_span = tk.StringVar()
437 | ttk.Label(frm, text="Span:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
438 | ttk.Label(frm, textvariable=self.sweep_span).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
439 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
440 |
441 | ROW += 1
442 | self.sweep_step = tk.StringVar()
443 | ttk.Label(frm, text="Step:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
444 | ttk.Label(frm, textvariable=self.sweep_step).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
445 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
446 |
447 | ROW += 1
448 | self.sweep_count = tk.StringVar()
449 | ttk.Label(frm, text="Count:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
450 | ttk.Label(frm, textvariable=self.sweep_count).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
451 |
452 | #
453 | # Sampling configuration label frame items
454 | #
455 |
456 | COL = 0
457 | ROW = 1
458 | frm = ttk.LabelFrame(self.win, text=" Sampling Configuration ")
459 | frm.grid(column=COL, row=ROW, padx=5, pady=5, sticky=tk.EW)
460 |
461 | COL = 0
462 | ROW = 0
463 | self.sampling_rx_offset = tk.StringVar()
464 | ttk.Label(frm, text="RX Offset:", width=LABEL_WIDTH, anchor=tk.W).grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
465 | ttk.Label(frm, textvariable=self.sampling_rx_offset, width=VALUE_WIDTH, anchor=tk.E).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
466 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
467 |
468 | ROW += 1
469 | self.sampling_step = tk.StringVar()
470 | ttk.Label(frm, text="Step size:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
471 | ttk.Label(frm, textvariable=self.sampling_step).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
472 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
473 |
474 | ROW += 1
475 | self.sampling_rate = tk.StringVar()
476 | ttk.Label(frm, text="Sample rate:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
477 | ttk.Label(frm, textvariable=self.sampling_rate).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
478 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
479 |
480 | ROW += 1
481 | self.sampling_buffer_length = tk.StringVar()
482 | ttk.Label(frm, text="Buffer length:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
483 | ttk.Label(frm, textvariable=self.sampling_buffer_length).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
484 | self.sampling_buffer_length.set("")
485 |
486 | #
487 | # Sample label frame items
488 | #
489 |
490 | COL = 0
491 | ROW = 5
492 | frm = ttk.LabelFrame(self.win, text=" Sample # ")
493 | frm.grid(column=COL, row=ROW, padx=5, pady=5, sticky=tk.EW)
494 |
495 | COL = 0
496 | ROW = 0
497 | self.sample_n = tk.StringVar()
498 | ttk.Label(frm, text="N:", width=LABEL_WIDTH, anchor=tk.W).grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
499 | ttk.Label(frm, textvariable=self.sample_n, width=VALUE_WIDTH, anchor=tk.E).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
500 |
501 | ROW += 1
502 | self.sample_tg_state = tk.StringVar()
503 | if self.sweep_settings.tg_state is None:
504 | tg_control = "TG (Local):"
505 | else:
506 | tg_control = "TG (Remote):"
507 |
508 | ttk.Label(frm, text=tg_control).grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
509 | ttk.Label(frm, textvariable=self.sample_tg_state).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
510 |
511 | ROW += 1
512 | self.sample_tx = tk.StringVar()
513 | ttk.Label(frm, text="TX:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
514 | ttk.Label(frm, textvariable=self.sample_tx).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
515 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
516 |
517 | ROW += 1
518 | self.sample_rx = tk.StringVar()
519 | ttk.Label(frm, text="RX:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
520 | ttk.Label(frm, textvariable=self.sample_rx).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
521 | ttk.Label(frm, text="Hz").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
522 |
523 | ROW += 1
524 | self.sample_level = tk.StringVar()
525 | ttk.Label(frm, text="Level:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
526 | ttk.Label(frm, textvariable=self.sample_level).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
527 | ttk.Label(frm, text="dB").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
528 |
529 | ROW += 1
530 | self.sample_rms = tk.StringVar()
531 | ttk.Label(frm, text="RMS:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
532 | ttk.Label(frm, textvariable=self.sample_rms).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
533 |
534 | ROW += 1
535 | self.sample_max = tk.StringVar()
536 | ttk.Label(frm, text="Max:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
537 | ttk.Label(frm, textvariable=self.sample_max).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
538 |
539 | ROW += 1
540 | self.sample_max_dB = tk.StringVar()
541 | ttk.Label(frm, text="Max:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
542 | ttk.Label(frm, textvariable=self.sample_max_dB).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
543 | ttk.Label(frm, text="dB").grid(column=COL+2, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
544 |
545 | ROW += 1
546 | self.sample_mean = tk.StringVar()
547 | ttk.Label(frm, text="Mean:").grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
548 | ttk.Label(frm, textvariable=self.sample_mean).grid(column=COL+1, row=ROW, padx=PADX, pady=PADY, sticky=tk.E)
549 |
550 | #
551 | # Navigation buttons
552 | #
553 |
554 | COL = 0
555 | ROW += 1
556 | frm = ttk.LabelFrame(frm, relief=tk.FLAT)
557 | frm.grid(column=COL, row=ROW, columnspan=3, padx=5, sticky=tk.EW)
558 |
559 | COL = 0
560 | ROW = 0
561 | self.sample_index = tk.IntVar()
562 | self.sample_scale = ttk.Scale(frm, variable=self.sample_index, orient='horizontal',
563 | to=self.sweep_settings.step_count-1, command=self._sample_index_set)
564 | self.sample_scale.grid(column=COL, row=ROW, columnspan=4, padx=PADX, sticky=tk.EW)
565 |
566 | ROW += 1
567 | self.sample_button_first = ttk.Button(frm, text="|<<", width=5, command=self._sweep_button_first)
568 | self.sample_button_first.grid(column=COL, row=ROW, padx=PADX, pady=5, sticky=tk.EW)
569 |
570 | self.sample_button_prev = ttk.Button(frm, text="<", width=5, command=self._sweep_button_prev)
571 | self.sample_button_prev.grid(column=COL+1, row=ROW, padx=PADX, pady=5, sticky=tk.EW)
572 |
573 | self.sample_button_next = ttk.Button(frm, text=">", width=5, command=self._sweep_button_next)
574 | self.sample_button_next.grid(column=COL+2, row=ROW, padx=PADX, pady=5, sticky=tk.EW)
575 |
576 | self.sample_button_last = ttk.Button(frm, text=">>|", width=5, command=self._sweep_button_last)
577 | self.sample_button_last.grid(column=COL+3, row=ROW, padx=PADX, pady=5, sticky=tk.EW)
578 |
579 | #
580 | # Download progressbar
581 | #
582 |
583 | COL = 0
584 | ROW = 14
585 | self.progressbar = ttk.Progressbar(self.win, orient='horizontal', mode='determinate')
586 | self.progressbar.grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.EW)
587 | self.progressbar['maximum'] = 100
588 | self.progressbar['value'] = 0
589 |
590 | #
591 | # Serial port parameters
592 | #
593 |
594 | COL = 0
595 | ROW = 16
596 | ttk.Label(self.win, text="Serial port: {}, Timeout: {}".format(serial_port, serial_timeout)).grid(column=COL, row=ROW, padx=PADX, pady=PADY, sticky=tk.W)
597 |
598 | #
599 | # Matplotlib time-domain graph
600 | #
601 |
602 | COL = 1
603 | ROW = 0
604 | fig = plt.Figure(figsize=(14,3))
605 | canvas = FigureCanvasTkAgg(fig, self.win)
606 | canvas.get_tk_widget().grid(column=COL, row=ROW, rowspan=5, columnspan=15, padx=PLOT_PADX, pady=PLOT_PADY, sticky=tk.EW)
607 | plot = fig.add_subplot(111)
608 | plot.set_ylim(-ADC_REF_VALUE, ADC_REF_VALUE)
609 | plot.set_title('Time Domain')
610 | self.time_domain_graph = fig
611 | self.time_domain_plot = plot
612 | self.time_domain_canvas = canvas;
613 |
614 | #
615 | # Matplotlib FFT graph
616 | #
617 |
618 | ROW += 5
619 | fig = plt.Figure(figsize=(14,3))
620 | canvas = FigureCanvasTkAgg(fig, self.win)
621 | canvas.get_tk_widget().grid(column=COL, row=ROW, rowspan=5, columnspan=15, padx=PLOT_PADX, pady=PLOT_PADY, sticky=tk.EW)
622 | plot = fig.add_subplot(111)
623 | plot.set_ylim(FFT_MIN_dB, FFT_MAX_dB)
624 | plot.set_title('FFT')
625 | self.fft_graph = fig
626 | self.fft_plot = plot
627 | self.fft_canvas = canvas;
628 |
629 | #
630 | # Matplotlib spectrum graph
631 | #
632 |
633 | ROW += 5
634 | fig = plt.Figure(figsize=(14,3))
635 | canvas = FigureCanvasTkAgg(fig, self.win)
636 | canvas.get_tk_widget().grid(column=COL, row=ROW, rowspan=5, columnspan=15, padx=PLOT_PADX, pady=PLOT_PADY, sticky=tk.EW)
637 | plot = fig.add_subplot(111)
638 | plot.set_ylim(SPECTRUM_MIN_dB, SPECTRUM_MAX_dB)
639 | plot.set_xlim(self.sweep_settings.start_Hz/1e6, self.sweep_settings.end_Hz/1e6)
640 | plot.set_title('Spectrum')
641 | self.spectrum_graph = fig
642 | self.spectrum_plot = plot
643 | self.spectrum_canvas = canvas;
644 |
645 | def _quit(self):
646 | self.sweep_stop()
647 | self.win.quit()
648 | self.win.destroy()
649 | print("Bye.")
650 | exit()
651 |
652 | def _file_new(self):
653 | self.sweep_run()
654 |
655 | @staticmethod
656 | def file_write_samples(f, sd):
657 | f.write("# Index: {}\n".format(round(sd.n)))
658 | f.write("# Frequency: {}\n".format(round(sd.f_Hz)))
659 | f.write("# Rx offset: {}\n".format(round(sd.rx_offset_Hz)))
660 | f.write("# Sampling rate: {}\n".format(round(sd.sample_rate_Hz, 1)))
661 | f.write("# Samples: {}\n".format(len(sd.samples)))
662 | for s in sd.samples:
663 | f.write("{}\n".format(s))
664 |
665 | def _file_save(self):
666 | if len(self.samples) > 0:
667 | n = self.sample_index.get()
668 | f = asksaveasfile(filetypes=[("MATLAB ascii data file", "*.dat")], mode="w")
669 | if f is not None:
670 | f.write("# LTDZ ADC SAMPLE BUFFER FILE\n")
671 | f.write("# Records: {}\n".format(1))
672 | sd = self.samples[n]
673 | self.file_write_samples(f, sd)
674 | f.close()
675 |
676 | def _file_save_all(self):
677 | if len(self.samples) > 0:
678 | f = asksaveasfile(filetypes=[("MATLAB ascii data file", "*.dat")], mode="w")
679 | if f is not None:
680 | f.write("# LTDZ ADC SAMPLE BUFFER FILE\n")
681 | f.write("# Records: {}\n".format(len(self.samples)))
682 | for sd in self.samples:
683 | self.file_write_samples(f, sd)
684 | f.close()
685 |
686 | def _quit_shortcut(self, event):
687 | self._quit()
688 |
689 | def _file_new_shortcut(self, event):
690 | self._file_new()
691 |
692 | def _file_save_shortcut(self, event):
693 | self._file_save()
694 |
695 | def _file_save_all_shortcut(self, event):
696 | self._file_save_all()
697 |
698 | def _sweep_button_first(self):
699 | if len(self.samples) > 0:
700 | n = 0
701 | self.sample_index.set(n)
702 | sd = self.samples[n]
703 | self.update_sample_view(sd)
704 |
705 | def _sweep_button_prev(self):
706 | if len(self.samples) > 0:
707 | n = self.sample_index.get()
708 | if n > 0:
709 | n = n - 1
710 | self.sample_index.set(n)
711 | sd = self.samples[n]
712 | self.update_sample_view(sd)
713 |
714 | def _sweep_button_next(self):
715 | if len(self.samples) > 0:
716 | n = self.sample_index.get()
717 | if n < len(self.samples)-1:
718 | n = n + 1
719 | self.sample_index.set(n)
720 | sd = self.samples[n]
721 | self.update_sample_view(sd)
722 |
723 | def _sweep_button_last(self):
724 | if len(self.samples) > 0:
725 | n = len(self.samples)-1
726 | self.sample_index.set(n)
727 | sd = self.samples[n]
728 | self.update_sample_view(sd)
729 |
730 | def _sample_index_set(self, n):
731 | if len(self.samples) > 0:
732 | n = round(float(n))
733 | self.sample_index.set(n)
734 | sd = self.samples[n]
735 | self.update_sample_view(sd)
736 |
737 | def update_sweep_settings(self):
738 | FORMAT_FREQ = "{: >15,}"
739 | FORMAT_NUM = "{: >15}"
740 | self.sweep_start.set(FORMAT_FREQ.format(self.sweep_settings.start_Hz))
741 | self.sweep_center.set(FORMAT_FREQ.format(self.sweep_settings.center_Hz))
742 | self.sweep_end.set(FORMAT_FREQ.format(self.sweep_settings.end_Hz))
743 | self.sweep_span.set(FORMAT_FREQ.format(self.sweep_settings.span_Hz))
744 | self.sweep_step.set(FORMAT_FREQ.format(self.sweep_settings.step_Hz))
745 | self.sweep_count.set(FORMAT_NUM.format(self.sweep_settings.step_count))
746 | self.spectrum_plot.set_xlim(self.sweep_settings.start_Hz/1e6,
747 | (self.sweep_settings.end_Hz-self.sweep_settings.step_Hz)/1e6)
748 | self.spectrum_canvas.draw()
749 |
750 | def gui_disable(self):
751 | NULL_FREQ = "{: >15}".format("-")
752 | NULL_NUM = "{: >15}".format("-")
753 | self.file_menu.entryconfigure(MENU_FILE_NEW, state=tk.DISABLED)
754 | self.file_menu.unbind_all(MENU_FILE_NEW_KB)
755 | self.file_menu.entryconfigure(MENU_FILE_SAVE, state=tk.DISABLED)
756 | self.file_menu.unbind_all(MENU_FILE_SAVE_KB)
757 | self.file_menu.entryconfigure(MENU_FILE_SAVE_ALL, state=tk.DISABLED)
758 | self.file_menu.unbind_all(MENU_FILE_SAVE_ALL_KB)
759 | self.sampling_rx_offset.set(NULL_FREQ)
760 | self.sampling_step.set(NULL_FREQ)
761 | self.sampling_rate.set(NULL_FREQ)
762 | self.sampling_buffer_length.set(NULL_NUM)
763 | self.sample_n.set(NULL_NUM)
764 | self.sample_tg_state.set(NULL_NUM)
765 | self.sample_tx.set(NULL_FREQ)
766 | self.sample_rx.set(NULL_FREQ)
767 | self.sample_level.set(NULL_NUM)
768 | self.sample_mean.set(NULL_NUM)
769 | #self.sample_scale.state([tk.DISABLED])
770 | self.sample_button_first['state'] = tk.DISABLED
771 | self.sample_button_prev['state'] = tk.DISABLED
772 | self.sample_button_next['state'] = tk.DISABLED
773 | self.sample_button_last['state'] = tk.DISABLED
774 |
775 | def gui_enable(self):
776 | self.file_menu.entryconfigure(MENU_FILE_NEW, state=tk.NORMAL)
777 | self.file_menu.bind_all(MENU_FILE_NEW_KB, self._file_new_shortcut)
778 | self.file_menu.entryconfigure(MENU_FILE_SAVE, state=tk.NORMAL)
779 | self.file_menu.bind_all(MENU_FILE_SAVE_KB, self._file_save_shortcut)
780 | self.file_menu.entryconfigure(MENU_FILE_SAVE_ALL, state=tk.NORMAL)
781 | self.file_menu.bind_all(MENU_FILE_SAVE_ALL_KB, self._file_save_all_shortcut)
782 | #self.sample_scale.state([tk.ACTIVE])
783 | self.sample_button_first['state'] = tk.NORMAL
784 | self.sample_button_prev['state'] = tk.NORMAL
785 | self.sample_button_next['state'] = tk.NORMAL
786 | self.sample_button_last['state'] = tk.NORMAL
787 |
788 | def sweep_init(self):
789 | self.f_Hz = []
790 | self.samples = []
791 | self.level_dB = []
792 | self.sample_index.set(0)
793 | self.gui_disable()
794 | self.progressbar['value'] = 0
795 | self.progressbar['maximum'] = self.sweep_settings.step_count
796 |
797 | def sweep_poll(self):
798 | sd = self.q.get()
799 | if isinstance(sd, LtdzSweepExitStatus):
800 | self.sweep_stop()
801 | if sd.status == LtdzStatus.SUCCESS:
802 | pass
803 | elif sd.status == LtdzStatus.TIMEOUT:
804 | messagebox.showerror("LTDZ Timeout",
805 | "Fatal serial port '{}' communication timeout.".format(serial_port))
806 | elif sd.status == LtdzStatus.ERROR:
807 | messagebox.showerror("LTDZ Protocol Error",
808 | sd.message)
809 | elif sd.status == LtdzStatus.FAIL:
810 | messagebox.showerror("LTDZ Serial Port Error",
811 | sd.message)
812 | else:
813 | messagebox.showerror("LTDZ Unknown Error",
814 | "Error code: {}".format(sd.status))
815 | else:
816 | sd.rms = np.sqrt(np.mean(np.array(sd.samples)**2))
817 | sd.level_dB = 20.0*np.log10(sd.rms/ADC_REF_VALUE)
818 | sd.max = np.max(np.abs(sd.samples))
819 | sd.max_dB = 20.0*np.log10(sd.max/ADC_REF_VALUE)
820 | sd.mean = np.mean(sd.samples)
821 | self.f_Hz.append(sd.f_Hz/1e6)
822 | self.samples.append(sd)
823 | self.level_dB.append(sd.level_dB)
824 | self.progressbar['value'] = sd.n+1
825 | self.update_sample_view(sd)
826 | self.win.after(10, self.sweep_poll)
827 |
828 | def sweep_run(self):
829 | self.sweep_init()
830 | self.q = Queue()
831 | config = LtdzSweepConfig()
832 | config.serial_port = serial_port
833 | config.serial_baud = serial_baud
834 | config.serial_timeout = serial_timeout
835 | config.tg_state = self.sweep_settings.tg_state
836 | config.start_Hz = self.sweep_settings.start_Hz
837 | config.step_Hz = self.sweep_settings.step_Hz
838 | config.step_count = self.sweep_settings.step_count
839 | self.ltdz_thread = Thread(target=ltdz_sweep_run, args=(self.q, config,))
840 | self.ltdz_thread.start()
841 | self.win.after(10, self.sweep_poll)
842 |
843 | def sweep_stop(self):
844 | self.q = None
845 | self.gui_enable()
846 | self._sweep_button_first()
847 |
848 | def update_sample_view(self, sd):
849 | FORMAT_FREQ = "{: >15,}"
850 | FORMAT_NUM = "{: >15}"
851 | FORMAT_LEVEL = "{: >15.2f}"
852 |
853 | self.sample_index.set(sd.n)
854 |
855 | # Sampling configuration
856 | self.sampling_rx_offset.set(FORMAT_FREQ.format(sd.rx_offset_Hz))
857 | self.sampling_step.set(FORMAT_FREQ.format(sd.step_Hz))
858 | self.sampling_rate.set(FORMAT_NUM.format(round(sd.sample_rate_Hz, 1)))
859 | self.sampling_buffer_length.set(FORMAT_NUM.format(sd.buffer_size))
860 |
861 | # Sample info
862 | self.sample_n.set(FORMAT_NUM.format(sd.n))
863 | self.sample_tg_state.set(FORMAT_NUM.format(sd.tg_state & TG_STATE_ENABLED))
864 | self.sample_tx.set(FORMAT_FREQ.format(sd.f_Hz))
865 | self.sample_rx.set(FORMAT_FREQ.format(sd.rx_offset_Hz))
866 | self.sample_rms.set(FORMAT_LEVEL.format(sd.rms))
867 | self.sample_level.set(FORMAT_LEVEL.format(sd.level_dB))
868 | self.sample_max.set(FORMAT_LEVEL.format(sd.max))
869 | self.sample_max_dB.set(FORMAT_LEVEL.format(sd.max_dB))
870 | self.sample_mean.set(FORMAT_LEVEL.format(sd.mean))
871 |
872 | # Update time-domain samples
873 | self.time_domain_plot.clear()
874 | self.time_domain_plot.plot(sd.samples)
875 | #self.time_domain_plot.set_ylim(-ADC_REF_VALUE, ADC_REF_VALUE)
876 | self.time_domain_plot.set_title('Time Domain')
877 | self.time_domain_canvas.draw()
878 |
879 | # Update FFT
880 | f_Hz = np.fft.fftshift(np.fft.fftfreq(sd.buffer_size, 1.0/sd.sample_rate_Hz))
881 | fft = np.abs(np.fft.fftshift(np.fft.fft(sd.samples * np.hanning(sd.buffer_size)))) / len(sd.samples)
882 | fft_dB = 20.0*np.log10(fft/ADC_REF_VALUE)
883 | self.fft_plot.clear()
884 | self.fft_plot.plot(f_Hz, fft_dB)
885 | self.fft_plot.set_ylim(FFT_MIN_dB, FFT_MAX_dB)
886 | self.fft_plot.set_title('FFT')
887 | self.fft_canvas.draw()
888 |
889 | # Update spectrum
890 | self.spectrum_plot.clear()
891 | self.spectrum_plot.plot(self.f_Hz, self.level_dB)
892 | self.spectrum_plot.set_xlim(self.sweep_settings.start_Hz/1e6,
893 | (self.sweep_settings.end_Hz-self.sweep_settings.step_Hz)/1e6)
894 | self.spectrum_plot.set_ylim(SPECTRUM_MIN_dB, SPECTRUM_MAX_dB)
895 | self.spectrum_plot.set_title('Spectrum')
896 | self.spectrum_plot.axvline(x=sd.f_Hz/1e6, color='red')
897 | self.spectrum_canvas.draw()
898 |
899 | #
900 | # Sweep settings
901 | #
902 |
903 | class SweepSettings:
904 | def __init__(self, args):
905 | self.tg_state = args.tg_state
906 | self.start_Hz = self.kmg_to_num(args.start_Hz)
907 | self.center_Hz = self.kmg_to_num(args.center_Hz)
908 | self.end_Hz = self.kmg_to_num(args.end_Hz)
909 | self.span_Hz = self.kmg_to_num(args.span_Hz)
910 | self.step_Hz = self.kmg_to_num(args.step_Hz)
911 | self.step_count = self.kmg_to_num(args.step_count)
912 |
913 | @staticmethod
914 | def kmg_to_num(v):
915 | if v is None:
916 | return None
917 | v = v.lower()
918 | scale = 1
919 | if "k" in v:
920 | scale = 1e3
921 | v = v.replace("k", ".")
922 | if "m" in v:
923 | scale = 1e6
924 | v = v.replace("m", ".")
925 | if "g" in v:
926 | scale = 1e9
927 | v = v.replace("g", ".")
928 | if "." in v:
929 | v=round(float(v)*scale)
930 | else:
931 | v=int(v)
932 | return v
933 |
934 | def parse(self):
935 | if self.start_Hz is not None:
936 | # Start frequency was given
937 | if self.end_Hz is not None:
938 | if self.end_Hz <= self.start_Hz:
939 | print("End frequency must be larger than start frequency.")
940 | exit(1)
941 | if self.span_Hz is not None:
942 | print("Span not allowed when the start and the end frequency specified.")
943 | exit(1)
944 | if self.center_Hz is not None:
945 | print("Center frequency not allowed when the start and the end frequency specified.")
946 | exit(1)
947 | if self.step_Hz is not None and self.step_count is not None:
948 | print("Only step size or step count allowed when the start and the end frequency specified.")
949 | exit(1)
950 | self.span_Hz = self.end_Hz - self.start_Hz
951 | elif self.span_Hz is not None:
952 | if self.center_Hz is not None:
953 | print("Center frequency not allowed when the start frequency and span specified.")
954 | exit(1)
955 | if self.step_Hz is not None and self.step_count is not None:
956 | print("Only step size or step count allowed when the start frequency and span specified.")
957 | exit(1)
958 | elif self.center_Hz is not None:
959 | if self.center_Hz <= self.start_Hz:
960 | print("Center frequency must be larger than start frequency.")
961 | exit(1)
962 | if self.step_Hz is not None and self.step_count is not None:
963 | print("Only step size or step count allowed when the start frequency and center frequency specified.")
964 | exit(1)
965 | self.span_Hz = 2*(self.center_Hz - self.start_Hz)
966 | elif self.step_Hz is not None and self.step_count is not None:
967 | self.span_Hz = self.step_Hz * self.step_count
968 | else:
969 | print("Could not solve the start frequency and the frequency span.")
970 | exit(1)
971 | elif self.end_Hz is not None:
972 | # End frequency was given
973 | if self.span_Hz is not None:
974 | if self.center_Hz is not None:
975 | print("Center frequency not allowed when the end frequency and span specified.")
976 | exit(1)
977 | if self.step_Hz is not None and self.step_count is not None:
978 | print("Only step size or step count allowed when the end frequency and span specified.")
979 | exit(1)
980 | elif self.center_Hz is not None:
981 | if self.end_Hz <= self.center_Hz:
982 | print("Center frequency must be smaller than end frequency.")
983 | exit(1)
984 | if self.step_Hz is not None and self.step_count is not None:
985 | print("Only step size or step count allowed when the end frequency and center frequency specified.")
986 | exit(1)
987 | self.span_Hz = 2*(self.end_Hz - self.center_Hz)
988 | elif self.step_Hz is not None and self.step_count is not None:
989 | self.span_Hz = self.step_Hz * self.step_count
990 | else:
991 | print("Could not solve the the start frequency and frequency span.")
992 | exit(1)
993 | self.start_Hz = self.end_Hz - self.span_Hz
994 | elif self.center_Hz is not None:
995 | # Center frequency was given
996 | if self.span_Hz is not None:
997 | if self.step_Hz is not None and self.step_count is not None:
998 | print("Only step size or step count allowed when center frequency and span specified.")
999 | exit(1)
1000 | elif self.step_Hz is not None and self.step_count is not None:
1001 | self.span_Hz = self.step_Hz * self.step_count
1002 | else:
1003 | print("Could not solve for start frequency and frequency span.")
1004 | exit(1)
1005 | self.start_Hz = round(self.center_Hz - self.span_Hz/2)
1006 | else:
1007 | print("Missing start, end or center frequency.")
1008 | exit(1)
1009 |
1010 | assert(self.start_Hz is not None)
1011 | assert(self.span_Hz is not None)
1012 |
1013 | self.end_Hz = self.start_Hz + self.span_Hz
1014 |
1015 | if self.start_Hz < MIN_Hz:
1016 | print("Minimum start frequency is", MIN_Hz)
1017 | exit(1)
1018 |
1019 | if self.end_Hz >= MAX_Hz:
1020 | print("Maximum end frequency is", MAX_Hz)
1021 | exit(1)
1022 |
1023 | if self.step_Hz is None and self.step_count is None:
1024 | # Step size or step count is required
1025 | print("Step size or step count need to be specified.")
1026 | exit(1)
1027 |
1028 | if self.step_Hz is not None:
1029 | self.step_count = round(self.span_Hz / self.step_Hz)
1030 |
1031 | if self.step_count is not None:
1032 | self.step_Hz = round(self.span_Hz / self.step_count)
1033 |
1034 | if self.step_Hz < MIN_STEP_Hz:
1035 | print("Warning: Minimum allowed step size is", MIN_STEP_Hz)
1036 | self.step_Hz = round(MIN_STEP_Hz)
1037 | self.step_count = round(self.span_Hz / self.step_Hz)
1038 |
1039 | if self.step_Hz > MAX_STEP_Hz:
1040 | print("Warning: Maximum allowed step size is", MAX_STEP_Hz)
1041 | self.step_Hz = round(MAX_STEP_Hz)
1042 | self.step_count = round(self.span_Hz / self.step_Hz)
1043 |
1044 | if self.step_count < MIN_STEP_COUNT:
1045 | print("Warning: Minimum allowed step count is", MIN_STEP_COUNT)
1046 | self.step_count = MIN_STEP_COUNT
1047 | self.span_Hz = self.step_Hz * self.step_count
1048 |
1049 | if self.step_count > MAX_STEP_COUNT:
1050 | print("Warning: Maximum allowed step count is", MAX_STEP_COUNT)
1051 | self.step_count = MAX_STEP_COUNT
1052 | self.span_Hz = self.step_Hz * self.step_count
1053 |
1054 | self.end_Hz = self.start_Hz + self.span_Hz
1055 | self.center_Hz = round((self.start_Hz + self.end_Hz) / 2)
1056 |
1057 | return self
1058 |
1059 | #
1060 | # main starts here
1061 | #
1062 |
1063 | parser = argparse.ArgumentParser(description='LTDZ ADC sample buffer reader.')
1064 | parser.add_argument('-p', "--port",
1065 | dest='port',
1066 | default=SERIAL_PORT,
1067 | help="Serial port")
1068 | parser.add_argument('-b', "--baud",
1069 | dest='baud',
1070 | type=int,
1071 | default=SERIAL_BAUD,
1072 | help="Serial port baud rate")
1073 | parser.add_argument('-t', "--timeout",
1074 | dest='timeout',
1075 | type=int,
1076 | default=SERIAL_TIMEOUT,
1077 | help="Serial port timeout value in seconds")
1078 | parser.add_argument('--tg',
1079 | dest='tg_state',
1080 | type=int,
1081 | default=None,
1082 | help="Optional tracking generator state: 0=disable, 1=enable")
1083 | parser.add_argument('--start',
1084 | dest='start_Hz',
1085 | default=None,
1086 | type=str,
1087 | help="Start frequency [Hz]")
1088 | parser.add_argument('--end',
1089 | dest='end_Hz',
1090 | default=None,
1091 | type=str,
1092 | help="End frequency [Hz]")
1093 | parser.add_argument('--center',
1094 | dest='center_Hz',
1095 | default=None,
1096 | type=str,
1097 | help="Center frequency [Hz]")
1098 | parser.add_argument('--span',
1099 | dest='span_Hz',
1100 | default=None,
1101 | type=str,
1102 | help="Frequency span [Hz]")
1103 | parser.add_argument('--step',
1104 | dest='step_Hz',
1105 | default=None,
1106 | type=str,
1107 | help="Step size [Hz]")
1108 | parser.add_argument('--count',
1109 | dest='step_count',
1110 | default=None,
1111 | type=str,
1112 | help="Step count")
1113 |
1114 | args = parser.parse_args()
1115 |
1116 | serial_port = args.port
1117 | serial_baud = args.baud
1118 | serial_timeout = args.timeout
1119 |
1120 | sweep = SweepSettings(args).parse()
1121 |
1122 | win = tk.Tk()
1123 | app = Application(win=win, sweep_settings=sweep)
1124 | app.mainloop()
1125 |
--------------------------------------------------------------------------------
/sintable_q15_4096.inc:
--------------------------------------------------------------------------------
1 | 0,
2 | 0,
3 | 0,
4 | 0,
5 | 0,
6 | 0,
7 | 0,
8 | 1,
9 | 1,
10 | 1,
11 | 1,
12 | 0,
13 | -2,
14 | -3,
15 | -4,
16 | -3,
17 | 0,
18 | 3,
19 | 6,
20 | 7,
21 | 6,
22 | 2,
23 | -3,
24 | -8,
25 | -11,
26 | -10,
27 | -6,
28 | 2,
29 | 10,
30 | 16,
31 | 16,
32 | 12,
33 | 2,
34 | -10,
35 | -20,
36 | -23,
37 | -19,
38 | -8,
39 | 8,
40 | 23,
41 | 31,
42 | 29,
43 | 16,
44 | -3,
45 | -23,
46 | -37,
47 | -39,
48 | -28,
49 | -6,
50 | 21,
51 | 42,
52 | 50,
53 | 41,
54 | 18,
55 | -14,
56 | -43,
57 | -60,
58 | -57,
59 | -34,
60 | 3,
61 | 41,
62 | 67,
63 | 72,
64 | 52,
65 | 13,
66 | -33,
67 | -71,
68 | -86,
69 | -73,
70 | -34,
71 | 20,
72 | 69,
73 | 98,
74 | 95,
75 | 58,
76 | 0,
77 | -62,
78 | -105,
79 | -115,
80 | -86,
81 | -26,
82 | 46,
83 | 106,
84 | 133,
85 | 115,
86 | 57,
87 | -24,
88 | -100,
89 | -145,
90 | -143,
91 | -92,
92 | -7,
93 | 84,
94 | 151,
95 | 168,
96 | 129,
97 | 44,
98 | -60,
99 | -147,
100 | -188,
101 | -167,
102 | -87,
103 | 25,
104 | 133,
105 | 200,
106 | 202,
107 | 134,
108 | 18,
109 | -108,
110 | -202,
111 | -231,
112 | -183,
113 | -70,
114 | 71,
115 | 193,
116 | 253,
117 | 229,
118 | 127,
119 | -22,
120 | -169,
121 | -263,
122 | -271,
123 | -187,
124 | -36,
125 | 131,
126 | 260,
127 | 304,
128 | 247,
129 | 104,
130 | -80,
131 | -241,
132 | -326,
133 | -303,
134 | -176,
135 | 14,
136 | 206,
137 | 333,
138 | 351,
139 | 250,
140 | 62,
141 | -153,
142 | -322,
143 | -387,
144 | -322,
145 | -147,
146 | 84,
147 | 292,
148 | 407,
149 | 388,
150 | 236,
151 | 0,
152 | -242,
153 | -409,
154 | -441,
155 | -325,
156 | -96,
157 | 172,
158 | 388,
159 | 479,
160 | 409,
161 | 200,
162 | -83,
163 | -345,
164 | -496,
165 | -483,
166 | -307,
167 | -22,
168 | 277,
169 | 490,
170 | 542,
171 | 412,
172 | 139,
173 | -186,
174 | -457,
175 | -579,
176 | -508,
177 | -264,
178 | 75,
179 | 397,
180 | 591,
181 | 590,
182 | 390,
183 | 53,
184 | -309,
185 | -575,
186 | -652,
187 | -510,
188 | -193,
189 | 196,
190 | 527,
191 | 687,
192 | 619,
193 | 340,
194 | -60,
195 | -447,
196 | -692,
197 | -708,
198 | -485,
199 | -94,
200 | 337,
201 | 663,
202 | 771,
203 | 622,
204 | 259,
205 | -198,
206 | -597,
207 | -803,
208 | -741,
209 | -428,
210 | 35,
211 | 495,
212 | 797,
213 | 836,
214 | 593,
215 | 146,
216 | -359,
217 | -752,
218 | -899,
219 | -745,
220 | -337,
221 | 192,
222 | 666,
223 | 924,
224 | 875,
225 | 530,
226 | 0,
227 | -539,
228 | -906,
229 | -974,
230 | -715,
231 | -210,
232 | 375,
233 | 843,
234 | 1035,
235 | 882,
236 | 428,
237 | -177,
238 | -733,
239 | -1051,
240 | -1020,
241 | -645,
242 | -46,
243 | 578,
244 | 1018,
245 | 1122,
246 | 850,
247 | 287,
248 | -382,
249 | -933,
250 | -1178,
251 | -1031,
252 | -533,
253 | 152,
254 | 796,
255 | 1183,
256 | 1177,
257 | 775,
258 | 105,
259 | -610,
260 | -1131,
261 | -1279,
262 | -998,
263 | -377,
264 | 380,
265 | 1021,
266 | 1328,
267 | 1192,
268 | 653,
269 | -114,
270 | -854,
271 | -1317,
272 | -1344,
273 | -918,
274 | -177,
275 | 634,
276 | 1244,
277 | 1444,
278 | 1160,
279 | 483,
280 | -367,
281 | -1106,
282 | -1483,
283 | -1366,
284 | -787,
285 | 64,
286 | 906,
287 | 1454,
288 | 1521,
289 | 1077,
290 | 264,
291 | -649,
292 | -1355,
293 | -1616,
294 | -1336,
295 | -603,
296 | 343,
297 | 1186,
298 | 1642,
299 | 1551,
300 | 937,
301 | 0,
302 | -949,
303 | -1592,
304 | -1707,
305 | -1250,
306 | -366,
307 | 652,
308 | 1464,
309 | 1794,
310 | 1525,
311 | 739,
312 | -305,
313 | -1260,
314 | -1804,
315 | -1747,
316 | -1103,
317 | -79,
318 | 984,
319 | 1729,
320 | 1902,
321 | 1438,
322 | 484,
323 | -644,
324 | -1569,
325 | -1978,
326 | -1727,
327 | -892,
328 | 253,
329 | 1327,
330 | 1967,
331 | 1954,
332 | 1284,
333 | 174,
334 | -1008,
335 | -1864,
336 | -2104,
337 | -1640,
338 | -619,
339 | 622,
340 | 1669,
341 | 2166,
342 | 1941,
343 | 1061,
344 | -185,
345 | -1384,
346 | -2132,
347 | -2171,
348 | -1481,
349 | -286,
350 | 1019,
351 | 1996,
352 | 2313,
353 | 1857,
354 | 771,
355 | -586,
356 | -1761,
357 | -2357,
358 | -2168,
359 | -1248,
360 | 101,
361 | 1431,
362 | 2295,
363 | 2397,
364 | 1694,
365 | 415,
366 | -1018,
367 | -2123,
368 | -2528,
369 | -2087,
370 | -941,
371 | 534,
372 | 1845,
373 | 2550,
374 | 2406,
375 | 1452,
376 | 0,
377 | -1467,
378 | -2456,
379 | -2630,
380 | -1923,
381 | -563,
382 | 1001,
383 | 2244,
384 | 2747,
385 | 2331,
386 | 1129,
387 | -465,
388 | -1919,
389 | -2743,
390 | -2654,
391 | -1673,
392 | -120,
393 | 1489,
394 | 2613,
395 | 2871,
396 | 2167,
397 | 729,
398 | -969,
399 | -2358,
400 | -2968,
401 | -2588,
402 | -1335,
403 | 378,
404 | 1981,
405 | 2935,
406 | 2912,
407 | 1911,
408 | 259,
409 | -1496,
410 | -2765,
411 | -3118,
412 | -2427,
413 | -915,
414 | 919,
415 | 2461,
416 | 3192,
417 | 2857,
418 | 1560,
419 | -272,
420 | -2031,
421 | -3124,
422 | -3178,
423 | -2166,
424 | -417,
425 | 1487,
426 | 2910,
427 | 3369,
428 | 2701,
429 | 1120,
430 | -851,
431 | -2554,
432 | -3415,
433 | -3138,
434 | -1804,
435 | 147,
436 | 2066,
437 | 3308,
438 | 3452,
439 | 2438,
440 | 596,
441 | -1461,
442 | -3046,
443 | -3623,
444 | -2989,
445 | -1346,
446 | 763,
447 | 2634,
448 | 3637,
449 | 3428,
450 | 2067,
451 | 0,
452 | -2085,
453 | -3487,
454 | -3732,
455 | -2726,
456 | -797,
457 | 1416,
458 | 3173,
459 | 3879,
460 | 3290,
461 | 1591,
462 | -655,
463 | -2701,
464 | -3857,
465 | -3728,
466 | -2348,
467 | -168,
468 | 2086,
469 | 3659,
470 | 4017,
471 | 3030,
472 | 1018,
473 | -1352,
474 | -3287,
475 | -4135,
476 | -3603,
477 | -1857,
478 | 526,
479 | 2751,
480 | 4072,
481 | 4036,
482 | 2647,
483 | 358,
484 | -2069,
485 | -3821,
486 | -4305,
487 | -3349,
488 | -1261,
489 | 1266,
490 | 3388,
491 | 4390,
492 | 3927,
493 | 2143,
494 | -374,
495 | -2785,
496 | -4280,
497 | -4351,
498 | -2963,
499 | -571,
500 | 2032,
501 | 3973,
502 | 4596,
503 | 3682,
504 | 1526,
505 | -1158,
506 | -3474,
507 | -4642,
508 | -4262,
509 | -2449,
510 | 199,
511 | 2800,
512 | 4481,
513 | 4672,
514 | 3297,
515 | 806,
516 | -1974,
517 | -4112,
518 | -4887,
519 | -4028,
520 | -1813,
521 | 1027,
522 | 3544,
523 | 4890,
524 | 4605,
525 | 2775,
526 | 0,
527 | -2795,
528 | -4672,
529 | -4996,
530 | -3647,
531 | -1065,
532 | 1893,
533 | 4237,
534 | 5177,
535 | 4387,
536 | 2121,
537 | -873,
538 | -3595,
539 | -5131,
540 | -4957,
541 | -3119,
542 | -223,
543 | 2768,
544 | 4852,
545 | 5323,
546 | 4013,
547 | 1347,
548 | -1788,
549 | -4346,
550 | -5464,
551 | -4757,
552 | -2451,
553 | 693,
554 | 3626,
555 | 5363,
556 | 5314,
557 | 3482,
558 | 471,
559 | -2719,
560 | -5019,
561 | -5651,
562 | -4393,
563 | -1653,
564 | 1659,
565 | 4437,
566 | 5746,
567 | 5137,
568 | 2802,
569 | -488,
570 | -3637,
571 | -5586,
572 | -5676,
573 | -3863,
574 | -743,
575 | 2646,
576 | 5171,
577 | 5978,
578 | 4787,
579 | 1983,
580 | -1504,
581 | -4509,
582 | -6022,
583 | -5526,
584 | -3174,
585 | 257,
586 | 3624,
587 | 5797,
588 | 6041,
589 | 4261,
590 | 1041,
591 | -2548,
592 | -5306,
593 | -6302,
594 | -5193,
595 | -2335,
596 | 1323,
597 | 4561,
598 | 6290,
599 | 5921,
600 | 3566,
601 | 0,
602 | -3588,
603 | -5995,
604 | -6408,
605 | -4675,
606 | -1365,
607 | 2424,
608 | 5423,
609 | 6622,
610 | 5610,
611 | 2711,
612 | -1115,
613 | -4590,
614 | -6547,
615 | -6322,
616 | -3977,
617 | -284,
618 | 3526,
619 | 6177,
620 | 6774,
621 | 5104,
622 | 1713,
623 | -2272,
624 | -5519,
625 | -6936,
626 | -6036,
627 | -3108,
628 | 879,
629 | 4595,
630 | 6793,
631 | 6727,
632 | 4406,
633 | 595,
634 | -3438,
635 | -6342,
636 | -7138,
637 | -5546,
638 | -2086,
639 | 2092,
640 | 5594,
641 | 7241,
642 | 6471,
643 | 3528,
644 | -615,
645 | -4575,
646 | -7025,
647 | -7134,
648 | -4854,
649 | -934,
650 | 3322,
651 | 6488,
652 | 7498,
653 | 6001,
654 | 2485,
655 | -1884,
656 | -5646,
657 | -7537,
658 | -6913,
659 | -3969,
660 | 322,
661 | 4528,
662 | 7240,
663 | 7541,
664 | 5317,
665 | 1299,
666 | -3177,
667 | -6613,
668 | -7851,
669 | -6466,
670 | -2907,
671 | 1646,
672 | 5672,
673 | 7820,
674 | 7359,
675 | 4429,
676 | 0,
677 | -4453,
678 | -7438,
679 | -7947,
680 | -5796,
681 | -1691,
682 | 3002,
683 | 6715,
684 | 8197,
685 | 6941,
686 | 3353,
687 | -1378,
688 | -5672,
689 | -8089,
690 | -7808,
691 | -4909,
692 | -351,
693 | 4349,
694 | 7617,
695 | 8349,
696 | 6288,
697 | 2110,
698 | -2797,
699 | -6793,
700 | -8533,
701 | -7423,
702 | -3821,
703 | 1080,
704 | 5644,
705 | 8341,
706 | 8258,
707 | 5407,
708 | 730,
709 | -4215,
710 | -7773,
711 | -8746,
712 | -6793,
713 | -2555,
714 | 2561,
715 | 6844,
716 | 8856,
717 | 7912,
718 | 4312,
719 | -751,
720 | -5587,
721 | -8576,
722 | -8707,
723 | -5921,
724 | -1139,
725 | 4049,
726 | 7907,
727 | 9134,
728 | 7308,
729 | 3025,
730 | -2293,
731 | -6869,
732 | -9166,
733 | -8404,
734 | -4823,
735 | 391,
736 | 5499,
737 | 8790,
738 | 9153,
739 | 6451,
740 | 1575,
741 | -3852,
742 | -8015,
743 | -9513,
744 | -7832,
745 | -3520,
746 | 1993,
747 | 6864,
748 | 9459,
749 | 8898,
750 | 5354,
751 | 0,
752 | -5380,
753 | -8983,
754 | -9594,
755 | -6995,
756 | -2040,
757 | 3621,
758 | 8096,
759 | 9880,
760 | 8363,
761 | 4038,
762 | -1660,
763 | -6828,
764 | -9734,
765 | -9393,
766 | -5904,
767 | -422,
768 | 5227,
769 | 9151,
770 | 10028,
771 | 7551,
772 | 2533,
773 | -3357,
774 | -8149,
775 | -10233,
776 | -8900,
777 | -4580,
778 | 1294,
779 | 6761,
780 | 9988,
781 | 9885,
782 | 6470,
783 | 874,
784 | -5041,
785 | -9294,
786 | -10453,
787 | -8117,
788 | -3051,
789 | 3058,
790 | 8171,
791 | 10570,
792 | 9440,
793 | 5143,
794 | -895,
795 | -6660,
796 | -10220,
797 | -10373,
798 | -7052,
799 | -1356,
800 | 4820,
801 | 9409,
802 | 10866,
803 | 8691,
804 | 3596,
805 | -2725,
806 | -8162,
807 | -10888,
808 | -9980,
809 | -5726,
810 | 464,
811 | 6525,
812 | 10427,
813 | 10854,
814 | 7648,
815 | 1867,
816 | -4564,
817 | -9494,
818 | -11266,
819 | -9272,
820 | -4166,
821 | 2358,
822 | 8119,
823 | 11186,
824 | 10520,
825 | 6328,
826 | 0,
827 | -6355,
828 | -10608,
829 | -11327,
830 | -8256,
831 | -2408,
832 | 4272,
833 | 9548,
834 | 11649,
835 | 9858,
836 | 4759,
837 | -1955,
838 | -8042,
839 | -11461,
840 | -11056,
841 | -6948,
842 | -496,
843 | 6148,
844 | 10761,
845 | 11789,
846 | 8874,
847 | 2976,
848 | -3943,
849 | -9569,
850 | -12014,
851 | -10446,
852 | -5374,
853 | 1518,
854 | 7929,
855 | 11711,
856 | 11587,
857 | 7583,
858 | 1024,
859 | -5905,
860 | -10883,
861 | -12238,
862 | -9500,
863 | -3571,
864 | 3578,
865 | 9556,
866 | 12359,
867 | 11034,
868 | 6010,
869 | -1046,
870 | -7780,
871 | -11935,
872 | -12110,
873 | -8232,
874 | -1582,
875 | 5623,
876 | 10974,
877 | 12671,
878 | 10132,
879 | 4191,
880 | -3176,
881 | -9508,
882 | -12681,
883 | -11621,
884 | -6666,
885 | 540,
886 | 7592,
887 | 12129,
888 | 12623,
889 | 8892,
890 | 2170,
891 | -5304,
892 | -11030,
893 | -13086,
894 | -10768,
895 | -4836,
896 | 2737,
897 | 9422,
898 | 12978,
899 | 12202,
900 | 7339,
901 | 0,
902 | -7366,
903 | -12293,
904 | -13123,
905 | -9563,
906 | -2788,
907 | 4945,
908 | 11052,
909 | 13481,
910 | 11405,
911 | 5504,
912 | -2261,
913 | -9298,
914 | -13248,
915 | -12777,
916 | -8027,
917 | -573,
918 | 7100,
919 | 12424,
920 | 13608,
921 | 10241,
922 | 3433,
923 | -4548,
924 | -11036,
925 | -13853,
926 | -12042,
927 | -6194,
928 | 1749,
929 | 9135,
930 | 13489,
931 | 13343,
932 | 8730,
933 | 1178,
934 | -6795,
935 | -12521,
936 | -14076,
937 | -10925,
938 | -4105,
939 | 4112,
940 | 10982,
941 | 14200,
942 | 12676,
943 | 6903,
944 | -1201,
945 | -8931,
946 | -13698,
947 | -13896,
948 | -9444,
949 | -1815,
950 | 6448,
951 | 12581,
952 | 14524,
953 | 11612,
954 | 4802,
955 | -3638,
956 | -10889,
957 | -14520,
958 | -13303,
959 | -7629,
960 | 618,
961 | 8686,
962 | 13874,
963 | 14436,
964 | 10167,
965 | 2481,
966 | -6061,
967 | -12604,
968 | -14950,
969 | -12299,
970 | -5523,
971 | 3124,
972 | 10755,
973 | 14811,
974 | 13923,
975 | 8372,
976 | 0,
977 | -8400,
978 | -14015,
979 | -14959,
980 | -10898,
981 | -3177,
982 | 5634,
983 | 12587,
984 | 15350,
985 | 12985,
986 | 6265,
987 | -2573,
988 | -10579,
989 | -15070,
990 | -14532,
991 | -9128,
992 | -651,
993 | 8071,
994 | 14120,
995 | 15462,
996 | 11634,
997 | 3899,
998 | -5165,
999 | -12530,
1000 | -15724,
1001 | -13666,
1002 | -7028,
1003 | 1984,
1004 | 10361,
1005 | 15296,
1006 | 15128,
1007 | 9896,
1008 | 1335,
1009 | -7699,
1010 | -14185,
1011 | -15944,
1012 | -12372,
1013 | -4648,
1014 | 4655,
1015 | 12430,
1016 | 16069,
1017 | 14341,
1018 | 7808,
1019 | -1358,
1020 | -10099,
1021 | -15486,
1022 | -15707,
1023 | -10672,
1024 | -2050,
1025 | 7285,
1026 | 14210,
1027 | 16401,
1028 | 13110,
1029 | 5421,
1030 | -4106,
1031 | -12287,
1032 | -16382,
1033 | -15006,
1034 | -8604,
1035 | 697,
1036 | 9792,
1037 | 15639,
1038 | 16269,
1039 | 11456,
1040 | 2795,
1041 | -6827,
1042 | -14194,
1043 | -16832,
1044 | -13845,
1045 | -6216,
1046 | 3516,
1047 | 12101,
1048 | 16661,
1049 | 15659,
1050 | 9414,
1051 | 0,
1052 | -9442,
1053 | -15752,
1054 | -16809,
1055 | -12244,
1056 | -3568,
1057 | 6327,
1058 | 14134,
1059 | 17234,
1060 | 14575,
1061 | 7032,
1062 | -2887,
1063 | -11869,
1064 | -16904,
1065 | -16298,
1066 | -10235,
1067 | -730,
1068 | 9047,
1069 | 15824,
1070 | 17326,
1071 | 13034,
1072 | 4368,
1073 | -5784,
1074 | -14030,
1075 | -17604,
1076 | -15297,
1077 | -7865,
1078 | 2220,
1079 | 11591,
1080 | 17110,
1081 | 16918,
1082 | 11065,
1083 | 1493,
1084 | -8606,
1085 | -15854,
1086 | -17816,
1087 | -13822,
1088 | -5192,
1089 | 5199,
1090 | 13880,
1091 | 17941,
1092 | 16009,
1093 | 8715,
1094 | -1516,
1095 | -11267,
1096 | -17275,
1097 | -17519,
1098 | -11902,
1099 | -2286,
1100 | 8121,
1101 | 15839,
1102 | 18278,
1103 | 14608,
1104 | 6039,
1105 | -4573,
1106 | -13684,
1107 | -18241,
1108 | -16707,
1109 | -9578,
1110 | 775,
1111 | 10897,
1112 | 17399,
1113 | 18097,
1114 | 12742,
1115 | 3108,
1116 | -7591,
1117 | -15779,
1118 | -18709,
1119 | -15386,
1120 | -6907,
1121 | 3906,
1122 | 13441,
1123 | 18504,
1124 | 17388,
1125 | 10452,
1126 | 0,
1127 | -10479,
1128 | -17480,
1129 | -18650,
1130 | -13583,
1131 | -3958,
1132 | 7017,
1133 | 15672,
1134 | 19106,
1135 | 16156,
1136 | 7793,
1137 | -3199,
1138 | -13150,
1139 | -18726,
1140 | -18051,
1141 | -11335,
1142 | -809,
1143 | 10015,
1144 | 17515,
1145 | 19174,
1146 | 14422,
1147 | 4832,
1148 | -6399,
1149 | -15517,
1150 | -19467,
1151 | -16914,
1152 | -8695,
1153 | 2454,
1154 | 12810,
1155 | 18906,
1156 | 18692,
1157 | 12223,
1158 | 1649,
1159 | -9504,
1160 | -17504,
1161 | -19668,
1162 | -15257,
1163 | -5730,
1164 | 5737,
1165 | 15314,
1166 | 19791,
1167 | 17657,
1168 | 9610,
1169 | -1671,
1170 | -12422,
1171 | -19042,
1172 | -19308,
1173 | -13115,
1174 | -2519,
1175 | 8946,
1176 | 17446,
1177 | 20129,
1178 | 16085,
1179 | 6649,
1180 | -5034,
1181 | -15061,
1182 | -20074,
1183 | -18382,
1184 | -10537,
1185 | 853,
1186 | 11984,
1187 | 19133,
1188 | 19897,
1189 | 14007,
1190 | 3416,
1191 | -8342,
1192 | -17338,
1193 | -20555,
1194 | -16902,
1195 | -7586,
1196 | 4290,
1197 | 14758,
1198 | 20314,
1199 | 19087,
1200 | 11471,
1201 | 0,
1202 | -11498,
1203 | -19176,
1204 | -20457,
1205 | -14897,
1206 | -4340,
1207 | 7693,
1208 | 17180,
1209 | 20942,
1210 | 17706,
1211 | 8539,
1212 | -3505,
1213 | -14405,
1214 | -20511,
1215 | -19768,
1216 | -12411,
1217 | -885,
1218 | 10963,
1219 | 19171,
1220 | 20984,
1221 | 15781,
1222 | 5287,
1223 | -6999,
1224 | -16972,
1225 | -21289,
1226 | -18494,
1227 | -9506,
1228 | 2683,
1229 | 14001,
1230 | 20661,
1231 | 20424,
1232 | 13354,
1233 | 1801,
1234 | -10380,
1235 | -19116,
1236 | -21476,
1237 | -16657,
1238 | -6255,
1239 | 6262,
1240 | 16712,
1241 | 21594,
1242 | 19263,
1243 | 10483,
1244 | -1823,
1245 | -13546,
1246 | -20763,
1247 | -21050,
1248 | -14296,
1249 | -2745,
1250 | 9749,
1251 | 19009,
1252 | 21931,
1253 | 17522,
1254 | 7242,
1255 | -5482,
1256 | -16400,
1257 | -21855,
1258 | -20011,
1259 | -11469,
1260 | 928,
1261 | 13041,
1262 | 20817,
1263 | 21645,
1264 | 15236,
1265 | 3716,
1266 | -9072,
1267 | -18851,
1268 | -22345,
1269 | -18372,
1270 | -8245,
1271 | 4661,
1272 | 16035,
1273 | 22069,
1274 | 20733,
1275 | 12459,
1276 | 0,
1277 | -12485,
1278 | -20819,
1279 | -22206,
1280 | -16168,
1281 | -4710,
1282 | 8348,
1283 | 18640,
1284 | 22718,
1285 | 19205,
1286 | 9261,
1287 | -3801,
1288 | -15618,
1289 | -22235,
1290 | -21428,
1291 | -13451,
1292 | -959,
1293 | 11879,
1294 | 20769,
1295 | 22730,
1296 | 17092,
1297 | 5726,
1298 | -7579,
1299 | -18375,
1300 | -23046,
1301 | -20018,
1302 | -10288,
1303 | 2903,
1304 | 15148,
1305 | 22351,
1306 | 22092,
1307 | 14443,
1308 | 1948,
1309 | -11224,
1310 | -20666,
1311 | -23215,
1312 | -18004,
1313 | -6760,
1314 | 6767,
1315 | 18056,
1316 | 23328,
1317 | 20807,
1318 | 11322,
1319 | -1968,
1320 | -14626,
1321 | -22416,
1322 | -22723,
1323 | -15430,
1324 | -2963,
1325 | 10520,
1326 | 20509,
1327 | 23658,
1328 | 18899,
1329 | 7810,
1330 | -5912,
1331 | -17683,
1332 | -23561,
1333 | -21570,
1334 | -12361,
1335 | 1000,
1336 | 14052,
1337 | 22428,
1338 | 23318,
1339 | 16411,
1340 | 4002,
1341 | -9769,
1342 | -20298,
1343 | -24057,
1344 | -19777,
1345 | -8874,
1346 | 5017,
1347 | 17255,
1348 | 23745,
1349 | 22305,
1350 | 13402,
1351 | 0,
1352 | -13426,
1353 | -22386,
1354 | -23875,
1355 | -17381,
1356 | -5063,
1357 | 8972,
1358 | 20030,
1359 | 24410,
1360 | 20633,
1361 | 9948,
1362 | -4083,
1363 | -16773,
1364 | -23876,
1365 | -23007,
1366 | -14441,
1367 | -1030,
1368 | 12749,
1369 | 22289,
1370 | 24390,
1371 | 18338,
1372 | 6142,
1373 | -8130,
1374 | -19707,
1375 | -24714,
1376 | -21464,
1377 | -11030,
1378 | 3112,
1379 | 16237,
1380 | 23955,
1381 | 23674,
1382 | 15475,
1383 | 2087,
1384 | -12023,
1385 | -22136,
1386 | -24863,
1387 | -19279,
1388 | -7238,
1389 | 7244,
1390 | 19328,
1391 | 24969,
1392 | 22268,
1393 | 12115,
1394 | -2106,
1395 | -15647,
1396 | -23978,
1397 | -24304,
1398 | -16502,
1399 | -3168,
1400 | 11248,
1401 | 21926,
1402 | 25289,
1403 | 20200,
1404 | 8347,
1405 | -6317,
1406 | -18893,
1407 | -25171,
1408 | -23041,
1409 | -13202,
1410 | 1068,
1411 | 15005,
1412 | 23946,
1413 | 24894,
1414 | 17517,
1415 | 4271,
1416 | -10425,
1417 | -21659,
1418 | -25667,
1419 | -21098,
1420 | -9466,
1421 | 5351,
1422 | 18402,
1423 | 25320,
1424 | 23781,
1425 | 14287,
1426 | 0,
1427 | -14310,
1428 | -23857,
1429 | -25441,
1430 | -18519,
1431 | -5393,
1432 | 9557,
1433 | 21334,
1434 | 25996,
1435 | 21971,
1436 | 10592,
1437 | -4346,
1438 | -17855,
1439 | -25413,
1440 | -24485,
1441 | -15367,
1442 | -1096,
1443 | 13564,
1444 | 23710,
1445 | 25942,
1446 | 19503,
1447 | 6532,
1448 | -8644,
1449 | -20952,
1450 | -26272,
1451 | -22814,
1452 | -11722,
1453 | 3307,
1454 | 17253,
1455 | 25450,
1456 | 25149,
1457 | 16438,
1458 | 2216,
1459 | -12768,
1460 | -23504,
1461 | -26397,
1462 | -20466,
1463 | -7683,
1464 | 7689,
1465 | 20512,
1466 | 26495,
1467 | 23626,
1468 | 12853,
1469 | -2234,
1470 | -16596,
1471 | -25430,
1472 | -25772,
1473 | -17497,
1474 | -3358,
1475 | 11923,
1476 | 23240,
1477 | 26802,
1478 | 21406,
1479 | 8844,
1480 | -6693,
1481 | -20014,
1482 | -26662,
1483 | -24403,
1484 | -13981,
1485 | 1131,
1486 | 15886,
1487 | 25350,
1488 | 26351,
1489 | 18541,
1490 | 4520,
1491 | -11032,
1492 | -22917,
1493 | -27155,
1494 | -22319,
1495 | -10012,
1496 | 5659,
1497 | 19460,
1498 | 26772,
1499 | 25143,
1500 | 15103,
1501 | 0,
1502 | -15124,
1503 | -25212,
1504 | -26883,
1505 | -19567,
1506 | -5698,
1507 | 10095,
1508 | 22534,
1509 | 27454,
1510 | 23201,
1511 | 11184,
1512 | -4589,
1513 | -18848,
1514 | -26825,
1515 | -25842,
1516 | -16217,
1517 | -1156,
1518 | 14311,
1519 | 25013,
1520 | 27366,
1521 | 20571,
1522 | 6888,
1523 | -9115,
1524 | -22092,
1525 | -27698,
1526 | -24051,
1527 | -12356,
1528 | 3485,
1529 | 18182,
1530 | 26818,
1531 | 26498,
1532 | 17317,
1533 | 2334,
1534 | -13448,
1535 | -24754,
1536 | -27797,
1537 | -21550,
1538 | -8089,
1539 | 8094,
1540 | 21591,
1541 | 27886,
1542 | 24864,
1543 | 13525,
1544 | -2351,
1545 | -17460,
1546 | -26751,
1547 | -27108,
1548 | -18402,
1549 | -3532,
1550 | 12537,
1551 | 24434,
1552 | 28176,
1553 | 22501,
1554 | 9296,
1555 | -7034,
1556 | -21032,
1557 | -28015,
1558 | -25639,
1559 | -14687,
1560 | 1188,
1561 | 16685,
1562 | 26623,
1563 | 27670,
1564 | 19467,
1565 | 4745,
1566 | -11581,
1567 | -24054,
1568 | -28500,
1569 | -23422,
1570 | -10506,
1571 | 5937,
1572 | 20415,
1573 | 28084,
1574 | 26372,
1575 | 15840,
1576 | 0,
1577 | -15859,
1578 | -26433,
1579 | -28182,
1580 | -20510,
1581 | -5972,
1582 | 10580,
1583 | 23613,
1584 | 28766,
1585 | 24308,
1586 | 11716,
1587 | -4807,
1588 | -19741,
1589 | -28092,
1590 | -27060,
1591 | -16979,
1592 | -1210,
1593 | 14981,
1594 | 26182,
1595 | 28641,
1596 | 21527,
1597 | 7208,
1598 | -9537,
1599 | -23112,
1600 | -28975,
1601 | -25156,
1602 | -12923,
1603 | 3645,
1604 | 19012,
1605 | 28039,
1606 | 27702,
1607 | 18102,
1608 | 2440,
1609 | -14055,
1610 | -25869,
1611 | -29046,
1612 | -22516,
1613 | -8451,
1614 | 8455,
1615 | 22552,
1616 | 29123,
1617 | 25965,
1618 | 14123,
1619 | -2454,
1620 | -18228,
1621 | -27924,
1622 | -28294,
1623 | -19205,
1624 | -3686,
1625 | 13082,
1626 | 25493,
1627 | 29394,
1628 | 23472,
1629 | 9696,
1630 | -7336,
1631 | -21932,
1632 | -29211,
1633 | -26731,
1634 | -15312,
1635 | 1238,
1636 | 17391,
1637 | 27746,
1638 | 28835,
1639 | 20285,
1640 | 4944,
1641 | -12064,
1642 | -25057,
1643 | -29684,
1644 | -24393,
1645 | -10941,
1646 | 6182,
1647 | 21255,
1648 | 29237,
1649 | 27452,
1650 | 16487,
1651 | 0,
1652 | -16503,
1653 | -27505,
1654 | -29322,
1655 | -21337,
1656 | -6212,
1657 | 11004,
1658 | 24558,
1659 | 29915,
1660 | 25276,
1661 | 12182,
1662 | -4997,
1663 | -20521,
1664 | -29199,
1665 | -28124,
1666 | -17645,
1667 | -1258,
1668 | 15565,
1669 | 27200,
1670 | 29753,
1671 | 22361,
1672 | 7486,
1673 | -9904,
1674 | -24000,
1675 | -30084,
1676 | -26117,
1677 | -13415,
1678 | 3783,
1679 | 19732,
1680 | 29099,
1681 | 28746,
1682 | 18783,
1683 | 2531,
1684 | -14580,
1685 | -26833,
1686 | -30126,
1687 | -23351,
1688 | -8763,
1689 | 8767,
1690 | 23381,
1691 | 30192,
1692 | 26915,
1693 | 14638,
1694 | -2544,
1695 | -18889,
1696 | -28934,
1697 | -29315,
1698 | -19896,
1699 | -3818,
1700 | 13550,
1701 | 26403,
1702 | 30440,
1703 | 24305,
1704 | 10039,
1705 | -7595,
1706 | -22704,
1707 | -30236,
1708 | -27666,
1709 | -15846,
1710 | 1281,
1711 | 17994,
1712 | 28705,
1713 | 29829,
1714 | 20982,
1715 | 5114,
1716 | -12477,
1717 | -25911,
1718 | -30693,
1719 | -25219,
1720 | -11310,
1721 | 6390,
1722 | 21969,
1723 | 30216,
1724 | 28368,
1725 | 17036,
1726 | 0,
1727 | -17049,
1728 | -28412,
1729 | -30286,
1730 | -22037,
1731 | -6415,
1732 | 11363,
1733 | 25357,
1734 | 30884,
1735 | 26092,
1736 | 12574,
1737 | -5158,
1738 | -21178,
1739 | -30132,
1740 | -29019,
1741 | -18205,
1742 | -1297,
1743 | 16056,
1744 | 28055,
1745 | 30685,
1746 | 23059,
1747 | 7719,
1748 | -10212,
1749 | -24742,
1750 | -31012,
1751 | -26920,
1752 | -13826,
1753 | 3899,
1754 | 20333,
1755 | 29982,
1756 | 29616,
1757 | 19349,
1758 | 2608,
1759 | -15017,
1760 | -27635,
1761 | -31023,
1762 | -24044,
1763 | -9022,
1764 | 9025,
1765 | 24068,
1766 | 31076,
1767 | 27701,
1768 | 15064,
1769 | -2617,
1770 | -19435,
1771 | -29768,
1772 | -30157,
1773 | -20465,
1774 | -3927,
1775 | 13935,
1776 | 27151,
1777 | 31300,
1778 | 24988,
1779 | 10320,
1780 | -7807,
1781 | -23336,
1782 | -31075,
1783 | -28431,
1784 | -16283,
1785 | 1317,
1786 | 18487,
1787 | 29488,
1788 | 30640,
1789 | 21550,
1790 | 5252,
1791 | -12812,
1792 | -26605,
1793 | -31513,
1794 | -25890,
1795 | -11610,
1796 | 6559,
1797 | 22547,
1798 | 31008,
1799 | 29110,
1800 | 17480,
1801 | 0,
1802 | -17490,
1803 | -29144,
1804 | -31063,
1805 | -22601,
1806 | -6579,
1807 | 11652,
1808 | 25998,
1809 | 31662,
1810 | 26747,
1811 | 12888,
1812 | -5286,
1813 | -21704,
1814 | -30876,
1815 | -29733,
1816 | -18651,
1817 | -1329,
1818 | 16447,
1819 | 28735,
1820 | 31426,
1821 | 23614,
1822 | 7904,
1823 | -10455,
1824 | -25330,
1825 | -31747,
1826 | -27555,
1827 | -14151,
1828 | 3990,
1829 | 20807,
1830 | 30678,
1831 | 30300,
1832 | 19795,
1833 | 2667,
1834 | -15360,
1835 | -28263,
1836 | -31725,
1837 | -24586,
1838 | -9225,
1839 | 9227,
1840 | 24604,
1841 | 31765,
1842 | 28312,
1843 | 15395,
1844 | -2675,
1845 | -19859,
1846 | -30414,
1847 | -30808,
1848 | -20906,
1849 | -4011,
1850 | 14233,
1851 | 27728,
1852 | 31961,
1853 | 25514,
1854 | 10537,
1855 | -7970,
1856 | -23821,
1857 | -31718,
1858 | -29017,
1859 | -16616,
1860 | 1344,
1861 | 18862,
1862 | 30084,
1863 | 31256,
1864 | 21982,
1865 | 5356,
1866 | -13067,
1867 | -27130,
1868 | -32132,
1869 | -26397,
1870 | -11836,
1871 | 6686,
1872 | 22982,
1873 | 31604,
1874 | 29666,
1875 | 17812,
1876 | 0,
1877 | -17819,
1878 | -29690,
1879 | -31642,
1880 | -23020,
1881 | -6700,
1882 | 11866,
1883 | 26473,
1884 | 32238,
1885 | 27231,
1886 | 13120,
1887 | -5381,
1888 | -22090,
1889 | -31423,
1890 | -30257,
1891 | -18978,
1892 | -1352,
1893 | 16732,
1894 | 29231,
1895 | 31965,
1896 | 24017,
1897 | 8039,
1898 | -10632,
1899 | -25756,
1900 | -32277,
1901 | -28013,
1902 | -14385,
1903 | 4056,
1904 | 21147,
1905 | 31177,
1906 | 30790,
1907 | 20113,
1908 | 2710,
1909 | -15604,
1910 | -28709,
1911 | -32224,
1912 | -24970,
1913 | -9368,
1914 | 9370,
1915 | 24982,
1916 | 32250,
1917 | 28742,
1918 | 15627,
1919 | -2715,
1920 | -20155,
1921 | -30864,
1922 | -31261,
1923 | -21211,
1924 | -4069,
1925 | 14438,
1926 | 28125,
1927 | 32417,
1928 | 25876,
1929 | 10685,
1930 | -8081,
1931 | -24152,
1932 | -32155,
1933 | -29414,
1934 | -16842,
1935 | 1362,
1936 | 19116,
1937 | 30486,
1938 | 31671,
1939 | 22271,
1940 | 5426,
1941 | -13236,
1942 | -27480,
1943 | -32544,
1944 | -26732,
1945 | -11986,
1946 | 6770,
1947 | 23268,
1948 | 31994,
1949 | 30029,
1950 | 18029,
1951 | 0,
1952 | -18033,
1953 | -30043,
1954 | -32016,
1955 | -23290,
1956 | -6778,
1957 | 12002,
1958 | 26776,
1959 | 32604,
1960 | 27537,
1961 | 13267,
1962 | -5440,
1963 | -22333,
1964 | -31766,
1965 | -30585,
1966 | -19182,
1967 | -1367,
1968 | 16909,
1969 | 29537,
1970 | 32297,
1971 | 24264,
1972 | 8120,
1973 | -10739,
1974 | -26014,
1975 | -32597,
1976 | -28288,
1977 | -14525,
1978 | 4095,
1979 | 21349,
1980 | 31472,
1981 | 31079,
1982 | 20299,
1983 | 2735,
1984 | -15746,
1985 | -28968,
1986 | -32511,
1987 | -25190,
1988 | -9450,
1989 | 9451,
1990 | 25196,
1991 | 32523,
1992 | 28983,
1993 | 15757,
1994 | -2737,
1995 | -20318,
1996 | -31112,
1997 | -31510,
1998 | -21378,
1999 | -4101,
2000 | 14549,
2001 | 28339,
2002 | 32660,
2003 | 26067,
2004 | 10763,
2005 | -8140,
2006 | -24324,
2007 | -32382,
2008 | -29619,
2009 | -16958,
2010 | 1371,
2011 | 19244,
2012 | 30687,
2013 | 31877,
2014 | 22414,
2015 | 5461,
2016 | -13319,
2017 | -27649,
2018 | -32741,
2019 | -26892,
2020 | -12056,
2021 | 6810,
2022 | 23401,
2023 | 32174,
2024 | 30196,
2025 | 18127,
2026 | 0,
2027 | -18128,
2028 | -30199,
2029 | -32179,
2030 | -23406,
2031 | -6811,
2032 | 12060,
2033 | 26903,
2034 | 32755,
2035 | 27663,
2036 | 13326,
2037 | -5464,
2038 | -22429,
2039 | -31899,
2040 | -30710,
2041 | -19259,
2042 | -1372,
2043 | 16974,
2044 | 29648,
2045 | 32415,
2046 | 24350,
2047 | 8149,
2048 | -10776,
2049 | -26100,
2050 | -32702,
2051 | -28377,
2052 | -14569,
2053 | 4107,
2054 | 21410,
2055 | 31559,
2056 | 31162,
2057 | 20352,
2058 | 2742,
2059 | -15785,
2060 | -29036,
2061 | -32585,
2062 | -25245,
2063 | -9470,
2064 | 9469,
2065 | 25244,
2066 | 32582,
2067 | 29033,
2068 | 15782,
2069 | -2741,
2070 | -20348,
2071 | -31154,
2072 | -31550,
2073 | -21403,
2074 | -4105,
2075 | 14564,
2076 | 28365,
2077 | 32687,
2078 | 26087,
2079 | 10770,
2080 | -8144,
2081 | -24336,
2082 | -32395,
2083 | -29628,
2084 | -16962,
2085 | 1371,
2086 | 19244,
2087 | 30686,
2088 | 31873,
2089 | 22409,
2090 | 5459,
2091 | -13314,
2092 | -27636,
2093 | -32723,
2094 | -26875,
2095 | -12047,
2096 | 6804,
2097 | 23379,
2098 | 32141,
2099 | 30162,
2100 | 18105,
2101 | 0,
2102 | -18103,
2103 | -30155,
2104 | -32129,
2105 | -23368,
2106 | -6800,
2107 | 12038,
2108 | 26852,
2109 | 32690,
2110 | 27606,
2111 | 13297,
2112 | -5452,
2113 | -22377,
2114 | -31822,
2115 | -30633,
2116 | -19209,
2117 | -1368,
2118 | 16927,
2119 | 29563,
2120 | 32319,
2121 | 24276,
2122 | 8123,
2123 | -10741,
2124 | -26014,
2125 | -32591,
2126 | -28278,
2127 | -14517,
2128 | 4092,
2129 | 21330,
2130 | 31438,
2131 | 31040,
2132 | 20271,
2133 | 2731,
2134 | -15719,
2135 | -28912,
2136 | -32443,
2137 | -25133,
2138 | -9427,
2139 | 9426,
2140 | 25125,
2141 | 32426,
2142 | 28891,
2143 | 15704,
2144 | -2727,
2145 | -20243,
2146 | -30991,
2147 | -31382,
2148 | -21287,
2149 | -4083,
2150 | 14482,
2151 | 28204,
2152 | 32499,
2153 | 25934,
2154 | 10706,
2155 | -8095,
2156 | -24187,
2157 | -32194,
2158 | -29442,
2159 | -16854,
2160 | 1362,
2161 | 19118,
2162 | 30482,
2163 | 31658,
2164 | 22256,
2165 | 5421,
2166 | -13221,
2167 | -27440,
2168 | -32488,
2169 | -26679,
2170 | -11959,
2171 | 6753,
2172 | 23203,
2173 | 31896,
2174 | 29930,
2175 | 17964,
2176 | 0,
2177 | -17959,
2178 | -29912,
2179 | -31868,
2180 | -23176,
2181 | -6743,
2182 | 11937,
2183 | 26623,
2184 | 32410,
2185 | 27366,
2186 | 13181,
2187 | -5404,
2188 | -22177,
2189 | -31535,
2190 | -30354,
2191 | -19032,
2192 | -1356,
2193 | 16768,
2194 | 29283,
2195 | 32011,
2196 | 24042,
2197 | 8044,
2198 | -10636,
2199 | -25756,
2200 | -32266,
2201 | -27993,
2202 | -14370,
2203 | 4050,
2204 | 21109,
2205 | 31110,
2206 | 30714,
2207 | 20056,
2208 | 2701,
2209 | -15549,
2210 | -28598,
2211 | -32087,
2212 | -24855,
2213 | -9322,
2214 | 9320,
2215 | 24840,
2216 | 32056,
2217 | 28559,
2218 | 15522,
2219 | -2696,
2220 | -20005,
2221 | -30624,
2222 | -31008,
2223 | -21032,
2224 | -4033,
2225 | 14305,
2226 | 27857,
2227 | 32097,
2228 | 25611,
2229 | 10572,
2230 | -7993,
2231 | -23879,
2232 | -31781,
2233 | -29062,
2234 | -16635,
2235 | 1344,
2236 | 18866,
2237 | 30078,
2238 | 31236,
2239 | 21958,
2240 | 5348,
2241 | -13041,
2242 | -27064,
2243 | -32040,
2244 | -26309,
2245 | -11792,
2246 | 6658,
2247 | 22875,
2248 | 31443,
2249 | 29501,
2250 | 17705,
2251 | 0,
2252 | -17697,
2253 | -29473,
2254 | -31397,
2255 | -22832,
2256 | -6642,
2257 | 11758,
2258 | 26221,
2259 | 31917,
2260 | 26948,
2261 | 12978,
2262 | -5320,
2263 | -21832,
2264 | -31042,
2265 | -29877,
2266 | -18731,
2267 | -1334,
2268 | 16500,
2269 | 28812,
2270 | 31493,
2271 | 23651,
2272 | 7913,
2273 | -10461,
2274 | -25330,
2275 | -31730,
2276 | -27526,
2277 | -14128,
2278 | 3981,
2279 | 20751,
2280 | 30580,
2281 | 30187,
2282 | 19710,
2283 | 2654,
2284 | -15278,
2285 | -28097,
2286 | -31523,
2287 | -24415,
2288 | -9156,
2289 | 9153,
2290 | 24395,
2291 | 31478,
2292 | 28041,
2293 | 15239,
2294 | -2646,
2295 | -19637,
2296 | -30058,
2297 | -30432,
2298 | -20639,
2299 | -3958,
2300 | 14036,
2301 | 27330,
2302 | 31486,
2303 | 25122,
2304 | 10369,
2305 | -7839,
2306 | -23417,
2307 | -31163,
2308 | -28494,
2309 | -16308,
2310 | 1318,
2311 | 18493,
2312 | 29479,
2313 | 30611,
2314 | 21517,
2315 | 5240,
2316 | -12776,
2317 | -26514,
2318 | -31385,
2319 | -25769,
2320 | -11549,
2321 | 6520,
2322 | 22400,
2323 | 30786,
2324 | 28883,
2325 | 17332,
2326 | 0,
2327 | -17321,
2328 | -28844,
2329 | -30725,
2330 | -22340,
2331 | -6499,
2332 | 11503,
2333 | 25650,
2334 | 31219,
2335 | 26356,
2336 | 12692,
2337 | -5202,
2338 | -21346,
2339 | -30349,
2340 | -29207,
2341 | -18310,
2342 | -1304,
2343 | 16126,
2344 | 28156,
2345 | 30773,
2346 | 23109,
2347 | 7730,
2348 | -10219,
2349 | -24742,
2350 | -30990,
2351 | -26882,
2352 | -13797,
2353 | 3888,
2354 | 20260,
2355 | 29853,
2356 | 29467,
2357 | 19238,
2358 | 2591,
2359 | -14910,
2360 | -27417,
2361 | -30757,
2362 | -23820,
2363 | -8932,
2364 | 8929,
2365 | 23793,
2366 | 30699,
2367 | 27345,
2368 | 14859,
2369 | -2580,
2370 | -19144,
2371 | -29301,
2372 | -29662,
2373 | -20115,
2374 | -3857,
2375 | 13677,
2376 | 26629,
2377 | 30676,
2378 | 24473,
2379 | 10100,
2380 | -7635,
2381 | -22806,
2382 | -30347,
2383 | -27745,
2384 | -15878,
2385 | 1283,
2386 | 18002,
2387 | 28694,
2388 | 29793,
2389 | 20939,
2390 | 5099,
2391 | -12431,
2392 | -25795,
2393 | -30532,
2394 | -25066,
2395 | -11233,
2396 | 6341,
2397 | 21782,
2398 | 29935,
2399 | 28082,
2400 | 16850,
2401 | 0,
2402 | -16836,
2403 | -28034,
2404 | -29859,
2405 | -21709,
2406 | -6315,
2407 | 11176,
2408 | 24918,
2409 | 30325,
2410 | 25599,
2411 | 12326,
2412 | -5052,
2413 | -20727,
2414 | -29466,
2415 | -28355,
2416 | -17774,
2417 | -1266,
2418 | 15650,
2419 | 27324,
2420 | 29861,
2421 | 22422,
2422 | 7500,
2423 | -9913,
2424 | -24000,
2425 | -30057,
2426 | -26070,
2427 | -13379,
2428 | 3769,
2429 | 19643,
2430 | 28941,
2431 | 28564,
2432 | 18647,
2433 | 2511,
2434 | -14449,
2435 | -26567,
2436 | -29800,
2437 | -23077,
2438 | -8652,
2439 | 8648,
2440 | 23044,
2441 | 29729,
2442 | 26479,
2443 | 14387,
2444 | -2498,
2445 | -18533,
2446 | -28362,
2447 | -28709,
2448 | -19467,
2449 | -3732,
2450 | 13234,
2451 | 25764,
2452 | 29676,
2453 | 23673,
2454 | 9769,
2455 | -7384,
2456 | -22054,
2457 | -29343,
2458 | -26825,
2459 | -15350,
2460 | 1240,
2461 | 17400,
2462 | 27732,
2463 | 28791,
2464 | 20234,
2465 | 4927,
2466 | -12010,
2467 | -24919,
2468 | -29491,
2469 | -24210,
2470 | -10848,
2471 | 6124,
2472 | 21032,
2473 | 28901,
2474 | 27109,
2475 | 16265,
2476 | 0,
2477 | -16248,
2478 | -27053,
2479 | -28811,
2480 | -20945,
2481 | -6092,
2482 | 10780,
2483 | 24034,
2484 | 29246,
2485 | 24686,
2486 | 11886,
2487 | -4871,
2488 | -19982,
2489 | -28404,
2490 | -27330,
2491 | -17130,
2492 | -1220,
2493 | 15081,
2494 | 26327,
2495 | 28768,
2496 | 21599,
2497 | 7224,
2498 | -9548,
2499 | -23112,
2500 | -28943,
2501 | -25101,
2502 | -12880,
2503 | 3629,
2504 | 18907,
2505 | 27854,
2506 | 27489,
2507 | 17943,
2508 | 2416,
2509 | -13901,
2510 | -25557,
2511 | -28664,
2512 | -22195,
2513 | -8321,
2514 | 8316,
2515 | 22157,
2516 | 28582,
2517 | 25455,
2518 | 13830,
2519 | -2401,
2520 | -17811,
2521 | -27254,
2522 | -27585,
2523 | -18703,
2524 | -3585,
2525 | 12712,
2526 | 24745,
2527 | 28500,
2528 | 22733,
2529 | 9380,
2530 | -7089,
2531 | -21171,
2532 | -28167,
2533 | -25747,
2534 | -14732,
2535 | 1190,
2536 | 16695,
2537 | 26607,
2538 | 27620,
2539 | 19409,
2540 | 4725,
2541 | -11518,
2542 | -23895,
2543 | -28278,
2544 | -23211,
2545 | -10399,
2546 | 5870,
2547 | 20158,
2548 | 27698,
2549 | 25978,
2550 | 15585,
2551 | 0,
2552 | -15565,
2553 | -25913,
2554 | -27595,
2555 | -20058,
2556 | -5833,
2557 | 10322,
2558 | 23010,
2559 | 27998,
2560 | 23629,
2561 | 11376,
2562 | -4661,
2563 | -19121,
2564 | -27177,
2565 | -26147,
2566 | -16387,
2567 | -1167,
2568 | 14424,
2569 | 25177,
2570 | 27509,
2571 | 20651,
2572 | 6906,
2573 | -9127,
2574 | -22092,
2575 | -27662,
2576 | -23988,
2577 | -12308,
2578 | 3467,
2579 | 18063,
2580 | 26608,
2581 | 26256,
2582 | 17137,
2583 | 2307,
2584 | -13274,
2585 | -24401,
2586 | -27365,
2587 | -21187,
2588 | -7942,
2589 | 7937,
2590 | 21144,
2591 | 27273,
2592 | 24286,
2593 | 13193,
2594 | -2290,
2595 | -16988,
2596 | -25992,
2597 | -26305,
2598 | -17834,
2599 | -3418,
2600 | 12119,
2601 | 23587,
2602 | 27164,
2603 | 21664,
2604 | 8938,
2605 | -6755,
2606 | -20170,
2607 | -26832,
2608 | -24524,
2609 | -14031,
2610 | 1133,
2611 | 15898,
2612 | 25332,
2613 | 26295,
2614 | 18475,
2615 | 4498,
2616 | -10962,
2617 | -22739,
2618 | -26907,
2619 | -22083,
2620 | -9893,
2621 | 5583,
2622 | 19173,
2623 | 26341,
2624 | 24703,
2625 | 14818,
2626 | 0,
2627 | -14797,
2628 | -24631,
2629 | -26226,
2630 | -19062,
2631 | -5543,
2632 | 9807,
2633 | 21860,
2634 | 26595,
2635 | 22444,
2636 | 10804,
2637 | -4426,
2638 | -18156,
2639 | -25802,
2640 | -24822,
2641 | -15555,
2642 | -1107,
2643 | 13688,
2644 | 23891,
2645 | 26101,
2646 | 19592,
2647 | 6551,
2648 | -8657,
2649 | -20952,
2650 | -26232,
2651 | -22745,
2652 | -11669,
2653 | 3287,
2654 | 17122,
2655 | 25219,
2656 | 24883,
2657 | 16239,
2658 | 2186,
2659 | -12575,
2660 | -23114,
2661 | -25919,
2662 | -20066,
2663 | -7521,
2664 | 7515,
2665 | 20019,
2666 | 25818,
2667 | 22988,
2668 | 12487,
2669 | -2167,
2670 | -16075,
2671 | -24593,
2672 | -24886,
2673 | -16870,
2674 | -3233,
2675 | 11461,
2676 | 22305,
2677 | 25684,
2678 | 20482,
2679 | 8450,
2680 | -6385,
2681 | -19063,
2682 | -25356,
2683 | -23173,
2684 | -13256,
2685 | 1071,
2686 | 15017,
2687 | 23926,
2688 | 24833,
2689 | 17446,
2690 | 4247,
2691 | -10349,
2692 | -21465,
2693 | -25396,
2694 | -20842,
2695 | -9336,
2696 | 5268,
2697 | 18089,
2698 | 24849,
2699 | 23301,
2700 | 13976,
2701 | 0,
2702 | -13952,
2703 | -23223,
2704 | -24724,
2705 | -17968,
2706 | -5224,
2707 | 9242,
2708 | 20598,
2709 | 25058,
2710 | 21144,
2711 | 10177,
2712 | -4169,
2713 | -17099,
2714 | -24297,
2715 | -23371,
2716 | -14644,
2717 | -1042,
2718 | 12884,
2719 | 22484,
2720 | 24562,
2721 | 18435,
2722 | 6164,
2723 | -8144,
2724 | -19707,
2725 | -24671,
2726 | -21389,
2727 | -10972,
2728 | 3090,
2729 | 16096,
2730 | 23705,
2731 | 23386,
2732 | 15260,
2733 | 2054,
2734 | -11815,
2735 | -21714,
2736 | -24347,
2737 | -18846,
2738 | -7063,
2739 | 7057,
2740 | 18795,
2741 | 24238,
2742 | 21578,
2743 | 11720,
2744 | -2034,
2745 | -15084,
2746 | -23074,
2747 | -23346,
2748 | -15824,
2749 | -3032,
2750 | 10748,
2751 | 20915,
2752 | 24081,
2753 | 19202,
2754 | 7921,
2755 | -5984,
2756 | -17865,
2757 | -23760,
2758 | -21712,
2759 | -12419,
2760 | 1003,
2761 | 14065,
2762 | 22407,
2763 | 23253,
2764 | 16334,
2765 | 3976,
2766 | -9687,
2767 | -20090,
2768 | -23767,
2769 | -19502,
2770 | -8735,
2771 | 4928,
2772 | 16920,
2773 | 23241,
2774 | 21790,
2775 | 13068,
2776 | 0,
2777 | -13043,
2778 | -21707,
2779 | -23108,
2780 | -16791,
2781 | -4882,
2782 | 8635,
2783 | 19243,
2784 | 23406,
2785 | 19747,
2786 | 9504,
2787 | -3893,
2788 | -15964,
2789 | -22682,
2790 | -21815,
2791 | -13667,
2792 | -973,
2793 | 12021,
2794 | 20977,
2795 | 22912,
2796 | 17194,
2797 | 5748,
2798 | -7594,
2799 | -18375,
2800 | -23000,
2801 | -19938,
2802 | -10227,
2803 | 2880,
2804 | 14998,
2805 | 22086,
2806 | 21787,
2807 | 14215,
2808 | 1913,
2809 | -11003,
2810 | -20219,
2811 | -22667,
2812 | -17544,
2813 | -6574,
2814 | 6568,
2815 | 17490,
2816 | 22552,
2817 | 20075,
2818 | 10902,
2819 | -1892,
2820 | -14028,
2821 | -21456,
2822 | -21707,
2823 | -14711,
2824 | -2819,
2825 | 9990,
2826 | 19437,
2827 | 22376,
2828 | 17840,
2829 | 7358,
2830 | -5558,
2831 | -16592,
2832 | -22064,
2833 | -20159,
2834 | -11529,
2835 | 931,
2836 | 13054,
2837 | 20794,
2838 | 21577,
2839 | 15155,
2840 | 3688,
2841 | -8986,
2842 | -18633,
2843 | -22040,
2844 | -18083,
2845 | -8098,
2846 | 4569,
2847 | 15683,
2848 | 21538,
2849 | 20192,
2850 | 12108,
2851 | 0,
2852 | -12082,
2853 | -20104,
2854 | -21399,
2855 | -15547,
2856 | -4519,
2857 | 7993,
2858 | 17810,
2859 | 21661,
2860 | 18273,
2861 | 8793,
2862 | -3601,
2863 | -14766,
2864 | -20977,
2865 | -20173,
2866 | -12637,
2867 | -899,
2868 | 11112,
2869 | 19388,
2870 | 21174,
2871 | 15888,
2872 | 5311,
2873 | -7015,
2874 | -16972,
2875 | -21241,
2876 | -18411,
2877 | -9442,
2878 | 2659,
2879 | 13844,
2880 | 20384,
2881 | 20105,
2882 | 13116,
2883 | 1765,
2884 | -10149,
2885 | -18648,
2886 | -20904,
2887 | -16177,
2888 | -6061,
2889 | 6054,
2890 | 16121,
2891 | 20784,
2892 | 18499,
2893 | 10045,
2894 | -1743,
2895 | -12921,
2896 | -19760,
2897 | -19989,
2898 | -13545,
2899 | -2595,
2900 | 9195,
2901 | 17889,
2902 | 20591,
2903 | 16415,
2904 | 6769,
2905 | -5113,
2906 | -15260,
2907 | -20290,
2908 | -18536,
2909 | -10600,
2910 | 856,
2911 | 11999,
2912 | 19110,
2913 | 19826,
2914 | 13924,
2915 | 3388,
2916 | -8253,
2917 | -17112,
2918 | -20238,
2919 | -16602,
2920 | -7434,
2921 | 4193,
2922 | 14393,
2923 | 19764,
2924 | 18525,
2925 | 11107,
2926 | 0,
2927 | -11080,
2928 | -18435,
2929 | -19619,
2930 | -14253,
2931 | -4142,
2932 | 7326,
2933 | 16320,
2934 | 19846,
2935 | 16740,
2936 | 8054,
2937 | -3298,
2938 | -13521,
2939 | -19206,
2940 | -18467,
2941 | -11567,
2942 | -823,
2943 | 10168,
2944 | 17739,
2945 | 19370,
2946 | 14532,
2947 | 4857,
2948 | -6415,
2949 | -15517,
2950 | -19418,
2951 | -16828,
2952 | -8629,
2953 | 2429,
2954 | 12649,
2955 | 18621,
2956 | 18363,
2957 | 11978,
2958 | 1612,
2959 | -9266,
2960 | -17023,
2961 | -19079,
2962 | -14763,
2963 | -5531,
2964 | 5523,
2965 | 14706,
2966 | 18956,
2967 | 16870,
2968 | 9159,
2969 | -1589,
2970 | -11778,
2971 | -18010,
2972 | -18215,
2973 | -12341,
2974 | -2364,
2975 | 8376,
2976 | 16292,
2977 | 18750,
2978 | 14945,
2979 | 6162,
2980 | -4654,
2981 | -13888,
2982 | -18463,
2983 | -16864,
2984 | -9642,
2985 | 778,
2986 | 10911,
2987 | 17376,
2988 | 18025,
2989 | 12656,
2990 | 3079,
2991 | -7500,
2992 | -15547,
2993 | -18385,
2994 | -15080,
2995 | -6751,
2996 | 3808,
2997 | 13067,
2998 | 17941,
2999 | 16814,
3000 | 10080,
3001 | 0,
3002 | -10052,
3003 | -16722,
3004 | -17794,
3005 | -12924,
3006 | -3756,
3007 | 6641,
3008 | 14792,
3009 | 17985,
3010 | 15168,
3011 | 7297,
3012 | -2988,
3013 | -12246,
3014 | -17392,
3015 | -16720,
3016 | -10471,
3017 | -745,
3018 | 9202,
3019 | 16051,
3020 | 17524,
3021 | 13145,
3022 | 4393,
3023 | -5801,
3024 | -14030,
3025 | -17554,
3026 | -15211,
3027 | -7798,
3028 | 2195,
3029 | 11427,
3030 | 16820,
3031 | 16585,
3032 | 10816,
3033 | 1455,
3034 | -8365,
3035 | -15365,
3036 | -17218,
3037 | -13320,
3038 | -4989,
3039 | 4982,
3040 | 13262,
3041 | 17093,
3042 | 15209,
3043 | 8256,
3044 | -1432,
3045 | -10614,
3046 | -16227,
3047 | -16409,
3048 | -11116,
3049 | -2129,
3050 | 7542,
3051 | 14667,
3052 | 16878,
3053 | 13450,
3054 | 5545,
3055 | -4187,
3056 | -12493,
3057 | -16606,
3058 | -15165,
3059 | -8669,
3060 | 700,
3061 | 9807,
3062 | 15615,
3063 | 16195,
3064 | 11370,
3065 | 2766,
3066 | -6735,
3067 | -13960,
3068 | -16506,
3069 | -13536,
3070 | -6059,
3071 | 3417,
3072 | 11724,
3073 | 16093,
3074 | 15080,
3075 | 9039,
3076 | 0,
3077 | -9011,
3078 | -14988,
3079 | -15945,
3080 | -11580,
3081 | -3365,
3082 | 5948,
3083 | 13247,
3084 | 16104,
3085 | 13578,
3086 | 6531,
3087 | -2674,
3088 | -10957,
3089 | -15559,
3090 | -14956,
3091 | -9364,
3092 | -666,
3093 | 8227,
3094 | 14347,
3095 | 15661,
3096 | 11746,
3097 | 3924,
3098 | -5181,
3099 | -12530,
3100 | -15674,
3101 | -13579,
3102 | -6961,
3103 | 1959,
3104 | 10196,
3105 | 15006,
3106 | 14793,
3107 | 9646,
3108 | 1297,
3109 | -7457,
3110 | -13695,
3111 | -15345,
3112 | -11869,
3113 | -4445,
3114 | 4438,
3115 | 11811,
3116 | 15220,
3117 | 13540,
3118 | 7348,
3119 | -1274,
3120 | -9444,
3121 | -14435,
3122 | -14595,
3123 | -9885,
3124 | -1893,
3125 | 6704,
3126 | 13036,
3127 | 14998,
3128 | 11950,
3129 | 4926,
3130 | -3719,
3131 | -11093,
3132 | -14743,
3133 | -13462,
3134 | -7694,
3135 | 621,
3136 | 8701,
3137 | 13851,
3138 | 14363,
3139 | 10082,
3140 | 2452,
3141 | -5970,
3142 | -12372,
3143 | -14624,
3144 | -11991,
3145 | -5366,
3146 | 3026,
3147 | 10380,
3148 | 14246,
3149 | 13347,
3150 | 7998,
3151 | 0,
3152 | -7970,
3153 | -13255,
3154 | -14099,
3155 | -10237,
3156 | -2974,
3157 | 5256,
3158 | 11704,
3159 | 14225,
3160 | 11992,
3161 | 5767,
3162 | -2360,
3163 | -9672,
3164 | -13731,
3165 | -13196,
3166 | -8261,
3167 | -587,
3168 | 7255,
3169 | 12649,
3170 | 13805,
3171 | 10352,
3172 | 3458,
3173 | -4565,
3174 | -11036,
3175 | -13803,
3176 | -11956,
3177 | -6127,
3178 | 1724,
3179 | 8972,
3180 | 13202,
3181 | 13012,
3182 | 8483,
3183 | 1141,
3184 | -6555,
3185 | -12037,
3186 | -13484,
3187 | -10427,
3188 | -3904,
3189 | 3897,
3190 | 10370,
3191 | 13361,
3192 | 11883,
3193 | 6448,
3194 | -1118,
3195 | -8283,
3196 | -12659,
3197 | -12796,
3198 | -8665,
3199 | -1659,
3200 | 5874,
3201 | 11420,
3202 | 13137,
3203 | 10465,
3204 | 4313,
3205 | -3255,
3206 | -9709,
3207 | -12900,
3208 | -11776,
3209 | -6729,
3210 | 543,
3211 | 7607,
3212 | 12106,
3213 | 12551,
3214 | 8808,
3215 | 2142,
3216 | -5214,
3217 | -10802,
3218 | -12767,
3219 | -10465,
3220 | -4683,
3221 | 2640,
3222 | 9053,
3223 | 12423,
3224 | 11636,
3225 | 6972,
3226 | 0,
3227 | -6945,
3228 | -11546,
3229 | -12279,
3230 | -8914,
3231 | -2589,
3232 | 4575,
3233 | 10184,
3234 | 12376,
3235 | 10431,
3236 | 5015,
3237 | -2052,
3238 | -8407,
3239 | -11933,
3240 | -11465,
3241 | -7176,
3242 | -510,
3243 | 6299,
3244 | 10980,
3245 | 11981,
3246 | 8982,
3247 | 3000,
3248 | -3959,
3249 | -9569,
3250 | -11966,
3251 | -10362,
3252 | -5309,
3253 | 1494,
3254 | 7771,
3255 | 11431,
3256 | 11265,
3257 | 7342,
3258 | 987,
3259 | -5671,
3260 | -10411,
3261 | -11660,
3262 | -9015,
3263 | -3375,
3264 | 3368,
3265 | 8959,
3266 | 11540,
3267 | 10262,
3268 | 5567,
3269 | -965,
3270 | -7148,
3271 | -10921,
3272 | -11037,
3273 | -7472,
3274 | -1430,
3275 | 5063,
3276 | 9841,
3277 | 11317,
3278 | 9013,
3279 | 3714,
3280 | -2802,
3281 | -8356,
3282 | -11100,
3283 | -10131,
3284 | -5788,
3285 | 467,
3286 | 6539,
3287 | 10405,
3288 | 10785,
3289 | 7567,
3290 | 1839,
3291 | -4477,
3292 | -9273,
3293 | -10956,
3294 | -8979,
3295 | -4017,
3296 | 2264,
3297 | 7762,
3298 | 10648,
3299 | 9972,
3300 | 5973,
3301 | 0,
3302 | -5947,
3303 | -9885,
3304 | -10509,
3305 | -7627,
3306 | -2215,
3307 | 3912,
3308 | 8708,
3309 | 10579,
3310 | 8914,
3311 | 4285,
3312 | -1753,
3313 | -7179,
3314 | -10187,
3315 | -9785,
3316 | -6123,
3317 | -435,
3318 | 5372,
3319 | 9362,
3320 | 10213,
3321 | 7654,
3322 | 2556,
3323 | -3372,
3324 | -8149,
3325 | -10187,
3326 | -8819,
3327 | -4518,
3328 | 1271,
3329 | 6609,
3330 | 9719,
3331 | 9575,
3332 | 6239,
3333 | 839,
3334 | -4817,
3335 | -8840,
3336 | -9897,
3337 | -7650,
3338 | -2863,
3339 | 2856,
3340 | 7597,
3341 | 9782,
3342 | 8697,
3343 | 4716,
3344 | -817,
3345 | -6053,
3346 | -9245,
3347 | -9341,
3348 | -6322,
3349 | -1210,
3350 | 4282,
3351 | 8320,
3352 | 9565,
3353 | 7616,
3354 | 3137,
3355 | -2366,
3356 | -7054,
3357 | -9368,
3358 | -8548,
3359 | -4882,
3360 | 394,
3361 | 5513,
3362 | 8769,
3363 | 9087,
3364 | 6374,
3365 | 1549,
3366 | -3769,
3367 | -7804,
3368 | -9218,
3369 | -7552,
3370 | -3377,
3371 | 1903,
3372 | 6523,
3373 | 8946,
3374 | 8375,
3375 | 5015,
3376 | 0,
3377 | -4990,
3378 | -8292,
3379 | -8814,
3380 | -6395,
3381 | -1856,
3382 | 3278,
3383 | 7294,
3384 | 8859,
3385 | 7462,
3386 | 3586,
3387 | -1467,
3388 | -6004,
3389 | -8518,
3390 | -8180,
3391 | -5117,
3392 | -364,
3393 | 4486,
3394 | 7816,
3395 | 8524,
3396 | 6387,
3397 | 2132,
3398 | -2812,
3399 | -6793,
3400 | -8489,
3401 | -7347,
3402 | -3762,
3403 | 1058,
3404 | 5500,
3405 | 8086,
3406 | 7964,
3407 | 5188,
3408 | 697,
3409 | -4002,
3410 | -7343,
3411 | -8219,
3412 | -6351,
3413 | -2376,
3414 | 2370,
3415 | 6301,
3416 | 8111,
3417 | 7208,
3418 | 3908,
3419 | -677,
3420 | -5012,
3421 | -7653,
3422 | -7730,
3423 | -5230,
3424 | -1000,
3425 | 3540,
3426 | 6876,
3427 | 7902,
3428 | 6289,
3429 | 2590,
3430 | -1953,
3431 | -5820,
3432 | -7727,
3433 | -7048,
3434 | -4024,
3435 | 324,
3436 | 4541,
3437 | 7220,
3438 | 7479,
3439 | 5244,
3440 | 1274,
3441 | -3099,
3442 | -6414,
3443 | -7574,
3444 | -6204,
3445 | -2773,
3446 | 1562,
3447 | 5352,
3448 | 7338,
3449 | 6867,
3450 | 4111,
3451 | 0,
3452 | -4087,
3453 | -6790,
3454 | -7214,
3455 | -5232,
3456 | -1518,
3457 | 2680,
3458 | 5962,
3459 | 7238,
3460 | 6095,
3461 | 2928,
3462 | -1197,
3463 | -4899,
3464 | -6947,
3465 | -6669,
3466 | -4170,
3467 | -296,
3468 | 3654,
3469 | 6363,
3470 | 6936,
3471 | 5195,
3472 | 1733,
3473 | -2286,
3474 | -5519,
3475 | -6895,
3476 | -5965,
3477 | -3054,
3478 | 858,
3479 | 4461,
3480 | 6556,
3481 | 6454,
3482 | 4203,
3483 | 564,
3484 | -3240,
3485 | -5942,
3486 | -6648,
3487 | -5135,
3488 | -1920,
3489 | 1915,
3490 | 5088,
3491 | 6547,
3492 | 5817,
3493 | 3152,
3494 | -546,
3495 | -4039,
3496 | -6166,
3497 | -6225,
3498 | -4210,
3499 | -805,
3500 | 2847,
3501 | 5528,
3502 | 6351,
3503 | 5053,
3504 | 2080,
3505 | -1568,
3506 | -4670,
3507 | -6197,
3508 | -5650,
3509 | -3225,
3510 | 260,
3511 | 3636,
3512 | 5779,
3513 | 5984,
3514 | 4194,
3515 | 1018,
3516 | -2476,
3517 | -5123,
3518 | -6047,
3519 | -4951,
3520 | -2212,
3521 | 1245,
3522 | 4266,
3523 | 5846,
3524 | 5468,
3525 | 3272,
3526 | 0,
3527 | -3251,
3528 | -5397,
3529 | -5732,
3530 | -4155,
3531 | -1205,
3532 | 2127,
3533 | 4729,
3534 | 5738,
3535 | 4830,
3536 | 2319,
3537 | -948,
3538 | -3877,
3539 | -5495,
3540 | -5272,
3541 | -3295,
3542 | -234,
3543 | 2885,
3544 | 5021,
3545 | 5471,
3546 | 4096,
3547 | 1366,
3548 | -1800,
3549 | -4346,
3550 | -5426,
3551 | -4692,
3552 | -2401,
3553 | 674,
3554 | 3504,
3555 | 5147,
3556 | 5065,
3557 | 3296,
3558 | 443,
3559 | -2539,
3560 | -4654,
3561 | -5204,
3562 | -4018,
3563 | -1502,
3564 | 1497,
3565 | 3975,
3566 | 5113,
3567 | 4540,
3568 | 2459,
3569 | -426,
3570 | -3148,
3571 | -4803,
3572 | -4847,
3573 | -3276,
3574 | -626,
3575 | 2213,
3576 | 4295,
3577 | 4932,
3578 | 3922,
3579 | 1613,
3580 | -1216,
3581 | -3619,
3582 | -4800,
3583 | -4374,
3584 | -2495,
3585 | 201,
3586 | 2810,
3587 | 4464,
3588 | 4620,
3589 | 3236,
3590 | 785,
3591 | -1909,
3592 | -3947,
3593 | -4656,
3594 | -3810,
3595 | -1702,
3596 | 957,
3597 | 3278,
3598 | 4489,
3599 | 4197,
3600 | 2510,
3601 | 0,
3602 | -2491,
3603 | -4133,
3604 | -4387,
3605 | -3178,
3606 | -921,
3607 | 1625,
3608 | 3611,
3609 | 4379,
3610 | 3684,
3611 | 1768,
3612 | -722,
3613 | -2952,
3614 | -4181,
3615 | -4010,
3616 | -2505,
3617 | -178,
3618 | 2190,
3619 | 3810,
3620 | 4149,
3621 | 3104,
3622 | 1035,
3623 | -1363,
3624 | -3287,
3625 | -4102,
3626 | -3545,
3627 | -1813,
3628 | 509,
3629 | 2642,
3630 | 3879,
3631 | 3814,
3632 | 2481,
3633 | 333,
3634 | -1908,
3635 | -3496,
3636 | -3907,
3637 | -3015,
3638 | -1126,
3639 | 1121,
3640 | 2977,
3641 | 3826,
3642 | 3395,
3643 | 1838,
3644 | -318,
3645 | -2350,
3646 | -3582,
3647 | -3613,
3648 | -2440,
3649 | -466,
3650 | 1646,
3651 | 3193,
3652 | 3664,
3653 | 2912,
3654 | 1197,
3655 | -901,
3656 | -2681,
3657 | -3554,
3658 | -3236,
3659 | -1845,
3660 | 148,
3661 | 2075,
3662 | 3294,
3663 | 3406,
3664 | 2384,
3665 | 578,
3666 | -1404,
3667 | -2902,
3668 | -3421,
3669 | -2797,
3670 | -1248,
3671 | 702,
3672 | 2401,
3673 | 3286,
3674 | 3070,
3675 | 1834,
3676 | 0,
3677 | -1817,
3678 | -3014,
3679 | -3197,
3680 | -2314,
3681 | -670,
3682 | 1181,
3683 | 2623,
3684 | 3179,
3685 | 2672,
3686 | 1281,
3687 | -523,
3688 | -2136,
3689 | -3023,
3690 | -2897,
3691 | -1808,
3692 | -128,
3693 | 1578,
3694 | 2744,
3695 | 2985,
3696 | 2232,
3697 | 743,
3698 | -978,
3699 | -2358,
3700 | -2940,
3701 | -2538,
3702 | -1297,
3703 | 364,
3704 | 1887,
3705 | 2768,
3706 | 2720,
3707 | 1767,
3708 | 237,
3709 | -1357,
3710 | -2484,
3711 | -2774,
3712 | -2138,
3713 | -798,
3714 | 794,
3715 | 2106,
3716 | 2704,
3717 | 2398,
3718 | 1297,
3719 | -224,
3720 | -1655,
3721 | -2521,
3722 | -2540,
3723 | -1714,
3724 | -327,
3725 | 1154,
3726 | 2236,
3727 | 2564,
3728 | 2035,
3729 | 836,
3730 | -629,
3731 | -1869,
3732 | -2475,
3733 | -2251,
3734 | -1282,
3735 | 103,
3736 | 1439,
3737 | 2283,
3738 | 2358,
3739 | 1649,
3740 | 400,
3741 | -969,
3742 | -2001,
3743 | -2356,
3744 | -1925,
3745 | -858,
3746 | 482,
3747 | 1647,
3748 | 2252,
3749 | 2101,
3750 | 1254,
3751 | 0,
3752 | -1240,
3753 | -2054,
3754 | -2177,
3755 | -1574,
3756 | -455,
3757 | 802,
3758 | 1778,
3759 | 2153,
3760 | 1808,
3761 | 866,
3762 | -353,
3763 | -1440,
3764 | -2036,
3765 | -1949,
3766 | -1215,
3767 | -86,
3768 | 1058,
3769 | 1837,
3770 | 1997,
3771 | 1491,
3772 | 496,
3773 | -652,
3774 | -1569,
3775 | -1954,
3776 | -1686,
3777 | -860,
3778 | 241,
3779 | 1249,
3780 | 1829,
3781 | 1795,
3782 | 1165,
3783 | 156,
3784 | -892,
3785 | -1631,
3786 | -1819,
3787 | -1401,
3788 | -522,
3789 | 519,
3790 | 1374,
3791 | 1762,
3792 | 1560,
3793 | 843,
3794 | -145,
3795 | -1073,
3796 | -1632,
3797 | -1642,
3798 | -1106,
3799 | -211,
3800 | 743,
3801 | 1438,
3802 | 1646,
3803 | 1305,
3804 | 535,
3805 | -402,
3806 | -1193,
3807 | -1577,
3808 | -1433,
3809 | -815,
3810 | 65,
3811 | 912,
3812 | 1444,
3813 | 1490,
3814 | 1040,
3815 | 252,
3816 | -610,
3817 | -1256,
3818 | -1477,
3819 | -1205,
3820 | -536,
3821 | 301,
3822 | 1026,
3823 | 1401,
3824 | 1305,
3825 | 778,
3826 | 0,
3827 | -767,
3828 | -1268,
3829 | -1341,
3830 | -968,
3831 | -280,
3832 | 491,
3833 | 1088,
3834 | 1315,
3835 | 1102,
3836 | 527,
3837 | -214,
3838 | -874,
3839 | -1233,
3840 | -1178,
3841 | -733,
3842 | -52,
3843 | 636,
3844 | 1102,
3845 | 1196,
3846 | 891,
3847 | 296,
3848 | -388,
3849 | -933,
3850 | -1160,
3851 | -998,
3852 | -508,
3853 | 142,
3854 | 735,
3855 | 1075,
3856 | 1053,
3857 | 682,
3858 | 91,
3859 | -520,
3860 | -949,
3861 | -1056,
3862 | -811,
3863 | -302,
3864 | 299,
3865 | 791,
3866 | 1012,
3867 | 894,
3868 | 482,
3869 | -83,
3870 | -611,
3871 | -927,
3872 | -931,
3873 | -626,
3874 | -119,
3875 | 418,
3876 | 808,
3877 | 922,
3878 | 729,
3879 | 298,
3880 | -224,
3881 | -662,
3882 | -874,
3883 | -792,
3884 | -449,
3885 | 36,
3886 | 500,
3887 | 790,
3888 | 813,
3889 | 566,
3890 | 137,
3891 | -330,
3892 | -678,
3893 | -795,
3894 | -647,
3895 | -287,
3896 | 161,
3897 | 547,
3898 | 744,
3899 | 691,
3900 | 411,
3901 | 0,
3902 | -403,
3903 | -664,
3904 | -700,
3905 | -504,
3906 | -145,
3907 | 254,
3908 | 561,
3909 | 676,
3910 | 565,
3911 | 269,
3912 | -109,
3913 | -444,
3914 | -624,
3915 | -595,
3916 | -369,
3917 | -26,
3918 | 318,
3919 | 549,
3920 | 594,
3921 | 441,
3922 | 146,
3923 | -191,
3924 | -457,
3925 | -566,
3926 | -485,
3927 | -246,
3928 | 69,
3929 | 354,
3930 | 515,
3931 | 502,
3932 | 324,
3933 | 43,
3934 | -245,
3935 | -446,
3936 | -494,
3937 | -378,
3938 | -140,
3939 | 138,
3940 | 364,
3941 | 464,
3942 | 408,
3943 | 219,
3944 | -38,
3945 | -275,
3946 | -416,
3947 | -416,
3948 | -278,
3949 | -53,
3950 | 184,
3951 | 354,
3952 | 403,
3953 | 317,
3954 | 129,
3955 | -96,
3956 | -284,
3957 | -372,
3958 | -336,
3959 | -189,
3960 | 15,
3961 | 209,
3962 | 328,
3963 | 336,
3964 | 233,
3965 | 56,
3966 | -134,
3967 | -274,
3968 | -320,
3969 | -259,
3970 | -114,
3971 | 63,
3972 | 215,
3973 | 290,
3974 | 268,
3975 | 158,
3976 | 0,
3977 | -153,
3978 | -251,
3979 | -263,
3980 | -188,
3981 | -54,
3982 | 94,
3983 | 205,
3984 | 245,
3985 | 204,
3986 | 96,
3987 | -39,
3988 | -156,
3989 | -218,
3990 | -206,
3991 | -127,
3992 | -9,
3993 | 108,
3994 | 185,
3995 | 198,
3996 | 146,
3997 | 48,
3998 | -62,
3999 | -147,
4000 | -181,
4001 | -154,
4002 | -77,
4003 | 21,
4004 | 109,
4005 | 157,
4006 | 152,
4007 | 97,
4008 | 13,
4009 | -72,
4010 | -129,
4011 | -142,
4012 | -107,
4013 | -39,
4014 | 38,
4015 | 100,
4016 | 126,
4017 | 109,
4018 | 58,
4019 | -10,
4020 | -71,
4021 | -106,
4022 | -104,
4023 | -69,
4024 | -13,
4025 | 44,
4026 | 84,
4027 | 94,
4028 | 73,
4029 | 29,
4030 | -22,
4031 | -62,
4032 | -81,
4033 | -71,
4034 | -40,
4035 | 3,
4036 | 42,
4037 | 65,
4038 | 65,
4039 | 44,
4040 | 10,
4041 | -25,
4042 | -49,
4043 | -56,
4044 | -44,
4045 | -19,
4046 | 10,
4047 | 34,
4048 | 45,
4049 | 41,
4050 | 24,
4051 | 0,
4052 | -22,
4053 | -34,
4054 | -35,
4055 | -24,
4056 | -7,
4057 | 11,
4058 | 24,
4059 | 28,
4060 | 22,
4061 | 10,
4062 | -4,
4063 | -15,
4064 | -20,
4065 | -18,
4066 | -11,
4067 | -1,
4068 | 8,
4069 | 14,
4070 | 14,
4071 | 10,
4072 | 3,
4073 | -4,
4074 | -8,
4075 | -9,
4076 | -7,
4077 | -3,
4078 | 1,
4079 | 4,
4080 | 5,
4081 | 5,
4082 | 3,
4083 | 0,
4084 | -2,
4085 | -2,
4086 | -2,
4087 | -1,
4088 | 0,
4089 | 0,
4090 | 1,
4091 | 1,
4092 | 0,
4093 | 0,
4094 | 0,
4095 | 0,
4096 | 0,
4097 |
--------------------------------------------------------------------------------