├── .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 | ![FM band-reject filter response](images/ltdz_adc_reader_v0.0.png) 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 | --------------------------------------------------------------------------------