├── .project ├── README.md ├── stlink-trace.h ├── Examples └── Keil-simple │ ├── main.c │ ├── startup_stm32f10x_cl.s │ └── system_stm32f10x.c ├── .cproject └── stlink-trace.c /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | stlink-trace 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 25 | 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | stlink-trace 2 | ============ 3 | 4 | ST-Link V2 ITM trace utility 5 | 6 | This utility can be used with an ST-Link V2 JTAG device connected to an STM32Fxxx series microcontroller to capture the ITM data sent via the printf port (ITM stimulus port 0). 7 | 8 | For the STMF1xx microcontroller, running at 72MHz, the default clock divisor is fine. For the 120MHz models (E.g. STM32F207Z), uncomment the define for the appropriate frequency in stlink-trace.c 9 | 10 | Build 11 | ----- 12 | Eclipse project files can be used. Alternatively use the following: 13 | 14 | gcc stlink-trace.c -lusb-1.0 -L/usr/local/lib -o stlink-trace 15 | 16 | TODO 17 | ---- 18 | * Fix the problem where a packet with 0xF8xx length is received containing junk data - for now it is read, but indicates some error condition that needs to be investigated further. Possibly overrun? 19 | * Merge into stlink or openOCD projects 20 | * Add a user interface to handle the different trace output 21 | * Support multiple trace stimulus ports i.e. remove hard-coding :) 22 | * Clean-up the code 23 | * Anything else that comes to mind... time permitting 24 | 25 | ---- 26 | Chris 27 | -------------------------------------------------------------------------------- /stlink-trace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stlink-trace.h 3 | * 4 | * Created on: 21/02/2013 5 | * Author: Chris Storah 6 | * 7 | * Parts of the ST-Link code comes from the stlink project: 8 | * https://github.com/texane/stlink 9 | * 10 | */ 11 | 12 | #ifndef STLINK_TRACE_H_ 13 | #define STLINK_TRACE_H_ 14 | 15 | // Bus 002 Device 052: ID 0483:3748 SGS Thomson Microelectronics ST-LINK/V2 16 | 17 | #define STLINKV2_VENDOR_ID 0x0483 18 | #define STLINKV2_PRODUCT_ID 0x3748 19 | 20 | #define DEBUG_LEVEL 3 21 | 22 | #define DEBUG_COMMAND 0xF2 23 | 24 | #define READ32 0x07 25 | #define WRITE32 0x08 26 | 27 | #define WRITE_DATA 0x35 28 | #define READ_DATA 0x36 29 | 30 | /* 31 | * USB modes: 32 | * DFU = Device Firmware Update 33 | * MSD = Mass Storage Device 34 | * DBG = Debug 35 | */ 36 | #define MODE_DFU 0x0000 37 | #define MODE_MSD 0x0001 38 | #define MODE_DBG 0x0002 39 | 40 | #define STLINK_DEBUG_COMMAND 0xF2 41 | #define STLINK_DFU_COMMAND 0xF3 42 | #define STLINK_DFU_EXIT 0x07 43 | //?? #define STLINK_DFU_ENTER 0x08 44 | 45 | #define STLINK_DEBUG_FORCEDEBUG 0x02 46 | #define STLINK_DEBUG_RESETSYS 0x03 47 | 48 | #endif /* STLINK_TRACE_H_ */ 49 | -------------------------------------------------------------------------------- /Examples/Keil-simple/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stm32f10x.h" 3 | #include "stm32f10x_gpio.h" 4 | #include "stm32f10x_rcc.h" 5 | 6 | volatile uint32_t msTicks; /* counts 1ms timeTicks */ 7 | volatile uint32_t msDelayCount; 8 | 9 | /*---------------------------------------------------------------------------- 10 | 11 | SysTick_Handler 12 | 13 | *----------------------------------------------------------------------------*/ 14 | 15 | void SysTick_Handler(void) { 16 | 17 | msTicks++; 18 | if (msDelayCount > 0) msDelayCount--; 19 | } 20 | 21 | #define ITM_PORT *(volatile unsigned *)0xE0000000 22 | 23 | static void msDelay(uint32_t ms) { 24 | msDelayCount = ms; 25 | while (msDelayCount > 0); 26 | } 27 | 28 | void GPIO_Configuration() 29 | { 30 | GPIO_InitTypeDef GPIO_InitStructure; 31 | 32 | RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); 33 | 34 | // LED1 -> PB0 , LED2 -> PB1 , LED3 -> PB14 , LED4 -> PB15 35 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_14 | GPIO_Pin_15; 36 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 37 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 38 | GPIO_Init(GPIOB, &GPIO_InitStructure); 39 | } 40 | 41 | void SendMsgViaITM(char* msg) 42 | { 43 | int pos = 0; 44 | char ch; 45 | 46 | while (msg[pos] != '\0') { 47 | ch = msg[pos++]; 48 | while (ITM_PORT == 0); // Wait while Fifo full 49 | ITM->PORT[0].u8 = ch; 50 | } 51 | } 52 | 53 | int main(void) 54 | { 55 | long i = 0; 56 | char buffer[100]; 57 | 58 | // configure and enable the SystTick interrupt 59 | SysTick->LOAD = 0x000000C8*((8000000UL/8)/1000)-1; // set reload register 60 | SysTick->CTRL = 0x00000006; // set clock source and Interrupt 61 | SysTick->VAL = 0; // clear the counter 62 | SysTick->CTRL |= ((unsigned long)0x00000001); // enable the counter 63 | 64 | GPIO_Configuration(); // configure the IO pins for the LEDs 65 | 66 | while (1) { 67 | GPIO_SetBits(GPIOB , GPIO_Pin_0); 68 | sprintf(&buffer[0], "Switched the LED on. Counter: %d\n", i); 69 | SendMsgViaITM(buffer); 70 | // msDelay(1); 71 | 72 | GPIO_ResetBits(GPIOB , GPIO_Pin_0); 73 | sprintf(&buffer[0], "Switched the LED off. Counter: %d\n", i); 74 | SendMsgViaITM(buffer); 75 | // msDelay(1); 76 | i++; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 40 | 41 | 42 | 43 | 49 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 93 | 94 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Examples/Keil-simple/startup_stm32f10x_cl.s: -------------------------------------------------------------------------------- 1 | ;******************** (C) COPYRIGHT 2010 STMicroelectronics ******************** 2 | ;* File Name : startup_stm32f10x_cl.s 3 | ;* Author : MCD Application Team 4 | ;* Version : V3.4.0 5 | ;* Date : 10/15/2010 6 | ;* Description : STM32F10x Connectivity line devices vector table for MDK-ARM 7 | ;* 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 CortexM3 processor is in Thread mode, 16 | ;* priority is Privileged, and the Stack is set to Main. 17 | ;* <<< Use Configuration Wizard in Context Menu >>> 18 | ;******************************************************************************* 19 | ; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 20 | ; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 21 | ; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 22 | ; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 23 | ; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 24 | ; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 25 | ;******************************************************************************* 26 | 27 | ; Amount of memory (in bytes) allocated for Stack 28 | ; Tailor this value to your application needs 29 | ; Stack Configuration 30 | ; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> 31 | ; 32 | 33 | Stack_Size EQU 0x00000400 34 | 35 | AREA STACK, NOINIT, READWRITE, ALIGN=3 36 | Stack_Mem SPACE Stack_Size 37 | __initial_sp 38 | 39 | 40 | ; Heap Configuration 41 | ; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> 42 | ; 43 | 44 | Heap_Size EQU 0x00000200 45 | 46 | AREA HEAP, NOINIT, READWRITE, ALIGN=3 47 | __heap_base 48 | Heap_Mem SPACE Heap_Size 49 | __heap_limit 50 | 51 | PRESERVE8 52 | THUMB 53 | 54 | 55 | ; Vector Table Mapped to Address 0 at Reset 56 | AREA RESET, DATA, READONLY 57 | EXPORT __Vectors 58 | EXPORT __Vectors_End 59 | EXPORT __Vectors_Size 60 | 61 | __Vectors DCD __initial_sp ; Top of Stack 62 | DCD Reset_Handler ; Reset Handler 63 | DCD NMI_Handler ; NMI Handler 64 | DCD HardFault_Handler ; Hard Fault Handler 65 | DCD MemManage_Handler ; MPU Fault Handler 66 | DCD BusFault_Handler ; Bus Fault Handler 67 | DCD UsageFault_Handler ; Usage Fault Handler 68 | DCD 0 ; Reserved 69 | DCD 0 ; Reserved 70 | DCD 0 ; Reserved 71 | DCD 0 ; Reserved 72 | DCD SVC_Handler ; SVCall Handler 73 | DCD DebugMon_Handler ; Debug Monitor Handler 74 | DCD 0 ; Reserved 75 | DCD PendSV_Handler ; PendSV Handler 76 | DCD SysTick_Handler ; SysTick Handler 77 | 78 | ; External Interrupts 79 | DCD WWDG_IRQHandler ; Window Watchdog 80 | DCD PVD_IRQHandler ; PVD through EXTI Line detect 81 | DCD TAMPER_IRQHandler ; Tamper 82 | DCD RTC_IRQHandler ; RTC 83 | DCD FLASH_IRQHandler ; Flash 84 | DCD RCC_IRQHandler ; RCC 85 | DCD EXTI0_IRQHandler ; EXTI Line 0 86 | DCD EXTI1_IRQHandler ; EXTI Line 1 87 | DCD EXTI2_IRQHandler ; EXTI Line 2 88 | DCD EXTI3_IRQHandler ; EXTI Line 3 89 | DCD EXTI4_IRQHandler ; EXTI Line 4 90 | DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 91 | DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 92 | DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 93 | DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 94 | DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 95 | DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 96 | DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 97 | DCD ADC1_2_IRQHandler ; ADC1 and ADC2 98 | DCD CAN1_TX_IRQHandler ; CAN1 TX 99 | DCD CAN1_RX0_IRQHandler ; CAN1 RX0 100 | DCD CAN1_RX1_IRQHandler ; CAN1 RX1 101 | DCD CAN1_SCE_IRQHandler ; CAN1 SCE 102 | DCD EXTI9_5_IRQHandler ; EXTI Line 9..5 103 | DCD TIM1_BRK_IRQHandler ; TIM1 Break 104 | DCD TIM1_UP_IRQHandler ; TIM1 Update 105 | DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation 106 | DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare 107 | DCD TIM2_IRQHandler ; TIM2 108 | DCD TIM3_IRQHandler ; TIM3 109 | DCD TIM4_IRQHandler ; TIM4 110 | DCD I2C1_EV_IRQHandler ; I2C1 Event 111 | DCD I2C1_ER_IRQHandler ; I2C1 Error 112 | DCD I2C2_EV_IRQHandler ; I2C2 Event 113 | DCD I2C2_ER_IRQHandler ; I2C1 Error 114 | DCD SPI1_IRQHandler ; SPI1 115 | DCD SPI2_IRQHandler ; SPI2 116 | DCD USART1_IRQHandler ; USART1 117 | DCD USART2_IRQHandler ; USART2 118 | DCD USART3_IRQHandler ; USART3 119 | DCD EXTI15_10_IRQHandler ; EXTI Line 15..10 120 | DCD RTCAlarm_IRQHandler ; RTC alarm through EXTI line 121 | DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line 122 | DCD 0 ; Reserved 123 | DCD 0 ; Reserved 124 | DCD 0 ; Reserved 125 | DCD 0 ; Reserved 126 | DCD 0 ; Reserved 127 | DCD 0 ; Reserved 128 | DCD 0 ; Reserved 129 | DCD TIM5_IRQHandler ; TIM5 130 | DCD SPI3_IRQHandler ; SPI3 131 | DCD UART4_IRQHandler ; UART4 132 | DCD UART5_IRQHandler ; UART5 133 | DCD TIM6_IRQHandler ; TIM6 134 | DCD TIM7_IRQHandler ; TIM7 135 | DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1 136 | DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2 137 | DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3 138 | DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4 139 | DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5 140 | DCD ETH_IRQHandler ; Ethernet 141 | DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line 142 | DCD CAN2_TX_IRQHandler ; CAN2 TX 143 | DCD CAN2_RX0_IRQHandler ; CAN2 RX0 144 | DCD CAN2_RX1_IRQHandler ; CAN2 RX1 145 | DCD CAN2_SCE_IRQHandler ; CAN2 SCE 146 | DCD OTG_FS_IRQHandler ; USB OTG FS 147 | __Vectors_End 148 | 149 | __Vectors_Size EQU __Vectors_End - __Vectors 150 | 151 | AREA |.text|, CODE, READONLY 152 | 153 | ; Reset handler 154 | Reset_Handler PROC 155 | EXPORT Reset_Handler [WEAK] 156 | IMPORT SystemInit 157 | IMPORT __main 158 | LDR R0, =SystemInit 159 | BLX R0 160 | LDR R0, =__main 161 | BX R0 162 | ENDP 163 | 164 | ; Dummy Exception Handlers (infinite loops which can be modified) 165 | 166 | NMI_Handler PROC 167 | EXPORT NMI_Handler [WEAK] 168 | B . 169 | ENDP 170 | HardFault_Handler\ 171 | PROC 172 | EXPORT HardFault_Handler [WEAK] 173 | B . 174 | ENDP 175 | MemManage_Handler\ 176 | PROC 177 | EXPORT MemManage_Handler [WEAK] 178 | B . 179 | ENDP 180 | BusFault_Handler\ 181 | PROC 182 | EXPORT BusFault_Handler [WEAK] 183 | B . 184 | ENDP 185 | UsageFault_Handler\ 186 | PROC 187 | EXPORT UsageFault_Handler [WEAK] 188 | B . 189 | ENDP 190 | SVC_Handler PROC 191 | EXPORT SVC_Handler [WEAK] 192 | B . 193 | ENDP 194 | DebugMon_Handler\ 195 | PROC 196 | EXPORT DebugMon_Handler [WEAK] 197 | B . 198 | ENDP 199 | PendSV_Handler PROC 200 | EXPORT PendSV_Handler [WEAK] 201 | B . 202 | ENDP 203 | SysTick_Handler PROC 204 | EXPORT SysTick_Handler [WEAK] 205 | B . 206 | ENDP 207 | 208 | Default_Handler PROC 209 | 210 | EXPORT WWDG_IRQHandler [WEAK] 211 | EXPORT PVD_IRQHandler [WEAK] 212 | EXPORT TAMPER_IRQHandler [WEAK] 213 | EXPORT RTC_IRQHandler [WEAK] 214 | EXPORT FLASH_IRQHandler [WEAK] 215 | EXPORT RCC_IRQHandler [WEAK] 216 | EXPORT EXTI0_IRQHandler [WEAK] 217 | EXPORT EXTI1_IRQHandler [WEAK] 218 | EXPORT EXTI2_IRQHandler [WEAK] 219 | EXPORT EXTI3_IRQHandler [WEAK] 220 | EXPORT EXTI4_IRQHandler [WEAK] 221 | EXPORT DMA1_Channel1_IRQHandler [WEAK] 222 | EXPORT DMA1_Channel2_IRQHandler [WEAK] 223 | EXPORT DMA1_Channel3_IRQHandler [WEAK] 224 | EXPORT DMA1_Channel4_IRQHandler [WEAK] 225 | EXPORT DMA1_Channel5_IRQHandler [WEAK] 226 | EXPORT DMA1_Channel6_IRQHandler [WEAK] 227 | EXPORT DMA1_Channel7_IRQHandler [WEAK] 228 | EXPORT ADC1_2_IRQHandler [WEAK] 229 | EXPORT CAN1_TX_IRQHandler [WEAK] 230 | EXPORT CAN1_RX0_IRQHandler [WEAK] 231 | EXPORT CAN1_RX1_IRQHandler [WEAK] 232 | EXPORT CAN1_SCE_IRQHandler [WEAK] 233 | EXPORT EXTI9_5_IRQHandler [WEAK] 234 | EXPORT TIM1_BRK_IRQHandler [WEAK] 235 | EXPORT TIM1_UP_IRQHandler [WEAK] 236 | EXPORT TIM1_TRG_COM_IRQHandler [WEAK] 237 | EXPORT TIM1_CC_IRQHandler [WEAK] 238 | EXPORT TIM2_IRQHandler [WEAK] 239 | EXPORT TIM3_IRQHandler [WEAK] 240 | EXPORT TIM4_IRQHandler [WEAK] 241 | EXPORT I2C1_EV_IRQHandler [WEAK] 242 | EXPORT I2C1_ER_IRQHandler [WEAK] 243 | EXPORT I2C2_EV_IRQHandler [WEAK] 244 | EXPORT I2C2_ER_IRQHandler [WEAK] 245 | EXPORT SPI1_IRQHandler [WEAK] 246 | EXPORT SPI2_IRQHandler [WEAK] 247 | EXPORT USART1_IRQHandler [WEAK] 248 | EXPORT USART2_IRQHandler [WEAK] 249 | EXPORT USART3_IRQHandler [WEAK] 250 | EXPORT EXTI15_10_IRQHandler [WEAK] 251 | EXPORT RTCAlarm_IRQHandler [WEAK] 252 | EXPORT OTG_FS_WKUP_IRQHandler [WEAK] 253 | EXPORT TIM5_IRQHandler [WEAK] 254 | EXPORT SPI3_IRQHandler [WEAK] 255 | EXPORT UART4_IRQHandler [WEAK] 256 | EXPORT UART5_IRQHandler [WEAK] 257 | EXPORT TIM6_IRQHandler [WEAK] 258 | EXPORT TIM7_IRQHandler [WEAK] 259 | EXPORT DMA2_Channel1_IRQHandler [WEAK] 260 | EXPORT DMA2_Channel2_IRQHandler [WEAK] 261 | EXPORT DMA2_Channel3_IRQHandler [WEAK] 262 | EXPORT DMA2_Channel4_IRQHandler [WEAK] 263 | EXPORT DMA2_Channel5_IRQHandler [WEAK] 264 | EXPORT ETH_IRQHandler [WEAK] 265 | EXPORT ETH_WKUP_IRQHandler [WEAK] 266 | EXPORT CAN2_TX_IRQHandler [WEAK] 267 | EXPORT CAN2_RX0_IRQHandler [WEAK] 268 | EXPORT CAN2_RX1_IRQHandler [WEAK] 269 | EXPORT CAN2_SCE_IRQHandler [WEAK] 270 | EXPORT OTG_FS_IRQHandler [WEAK] 271 | 272 | WWDG_IRQHandler 273 | PVD_IRQHandler 274 | TAMPER_IRQHandler 275 | RTC_IRQHandler 276 | FLASH_IRQHandler 277 | RCC_IRQHandler 278 | EXTI0_IRQHandler 279 | EXTI1_IRQHandler 280 | EXTI2_IRQHandler 281 | EXTI3_IRQHandler 282 | EXTI4_IRQHandler 283 | DMA1_Channel1_IRQHandler 284 | DMA1_Channel2_IRQHandler 285 | DMA1_Channel3_IRQHandler 286 | DMA1_Channel4_IRQHandler 287 | DMA1_Channel5_IRQHandler 288 | DMA1_Channel6_IRQHandler 289 | DMA1_Channel7_IRQHandler 290 | ADC1_2_IRQHandler 291 | CAN1_TX_IRQHandler 292 | CAN1_RX0_IRQHandler 293 | CAN1_RX1_IRQHandler 294 | CAN1_SCE_IRQHandler 295 | EXTI9_5_IRQHandler 296 | TIM1_BRK_IRQHandler 297 | TIM1_UP_IRQHandler 298 | TIM1_TRG_COM_IRQHandler 299 | TIM1_CC_IRQHandler 300 | TIM2_IRQHandler 301 | TIM3_IRQHandler 302 | TIM4_IRQHandler 303 | I2C1_EV_IRQHandler 304 | I2C1_ER_IRQHandler 305 | I2C2_EV_IRQHandler 306 | I2C2_ER_IRQHandler 307 | SPI1_IRQHandler 308 | SPI2_IRQHandler 309 | USART1_IRQHandler 310 | USART2_IRQHandler 311 | USART3_IRQHandler 312 | EXTI15_10_IRQHandler 313 | RTCAlarm_IRQHandler 314 | OTG_FS_WKUP_IRQHandler 315 | TIM5_IRQHandler 316 | SPI3_IRQHandler 317 | UART4_IRQHandler 318 | UART5_IRQHandler 319 | TIM6_IRQHandler 320 | TIM7_IRQHandler 321 | DMA2_Channel1_IRQHandler 322 | DMA2_Channel2_IRQHandler 323 | DMA2_Channel3_IRQHandler 324 | DMA2_Channel4_IRQHandler 325 | DMA2_Channel5_IRQHandler 326 | ETH_IRQHandler 327 | ETH_WKUP_IRQHandler 328 | CAN2_TX_IRQHandler 329 | CAN2_RX0_IRQHandler 330 | CAN2_RX1_IRQHandler 331 | CAN2_SCE_IRQHandler 332 | OTG_FS_IRQHandler 333 | 334 | B . 335 | 336 | ENDP 337 | 338 | ALIGN 339 | 340 | ;******************************************************************************* 341 | ; User Stack and Heap initialization 342 | ;******************************************************************************* 343 | IF :DEF:__MICROLIB 344 | 345 | EXPORT __initial_sp 346 | EXPORT __heap_base 347 | EXPORT __heap_limit 348 | 349 | ELSE 350 | 351 | IMPORT __use_two_region_memory 352 | EXPORT __user_initial_stackheap 353 | 354 | __user_initial_stackheap 355 | 356 | LDR R0, = Heap_Mem 357 | LDR R1, =(Stack_Mem + Stack_Size) 358 | LDR R2, = (Heap_Mem + Heap_Size) 359 | LDR R3, = Stack_Mem 360 | BX LR 361 | 362 | ALIGN 363 | 364 | ENDIF 365 | 366 | END 367 | 368 | ;******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE***** 369 | -------------------------------------------------------------------------------- /stlink-trace.c: -------------------------------------------------------------------------------- 1 | /* 2 | * stlink-trace.c 3 | * 4 | * Created on: 21/02/2013 5 | * Author: Chris Storah 6 | * Parts of the ST-Link code comes from the stlink project: 7 | * https://github.com/texane/stlink 8 | * 9 | * Requires an updated ST-Link V2 firmware: 10 | * Use the STM32 ST-LINK Utility to update to the latest version: 11 | * (V2.J17.S4 JTAG+SWIM Debugger) 12 | * See: http://www.st.com/web/en/catalog/tools/PF258168 13 | */ 14 | 15 | #define HEXDUMP 0 16 | #define ASYNC 0 17 | 18 | // for the STM32F107Z, system clock is 72MHz 19 | // (CLK/SWO_CLK) - 1 = (72MHz/2MHz) - 1 = 35 = 0x23 20 | #define CLOCK_DIVISOR 0x00000023 21 | // for the STM32F207Z, system clock is 120MHz 22 | // (CLK/SWO_CLK) - 1 = (120MHz/2MHz) - 1 = 59 = 0x3B 23 | //#define CLOCK_DIVISOR 0x0000003B 24 | 25 | #include 26 | #include 27 | #include 28 | #include "ncurses.h" 29 | #include "stlink-trace.h" 30 | #include "stdio.h" 31 | #include "libusb-1.0/libusb.h" 32 | #include 33 | 34 | libusb_context* ctx = 0; 35 | libusb_device_handle* stlinkhandle = 0; 36 | libusb_device* stlinkdev = 0; 37 | libusb_device** deviceList = 0; 38 | ssize_t listSize = 0; 39 | struct libusb_transfer* responseTransfer = 0; 40 | struct libusb_transfer* requestTransfer = 0; 41 | 42 | void Cleanup(); 43 | int IsStlink(libusb_device* dev); 44 | void GetCoreId(); 45 | void EnterSWD(); 46 | int submit_wait(struct libusb_transfer* trans); 47 | ssize_t TransferData(int terminate, 48 | unsigned char* transmitBuffer, size_t transmitLength, 49 | unsigned char* receiveBuffer, size_t receiveLength); 50 | int FetchTraceByteCount(); 51 | void EnterDebugState(); 52 | int ReadTraceData(int toscreen, int byteCount); 53 | void RunCore(); 54 | void StepCore(); 55 | void GetVersion(); 56 | int GetCurrentMode(); 57 | void GetTargetVoltage(); 58 | int SendAndReceive(unsigned char* txBuffer, size_t txSize, unsigned char* rxBuffer, size_t rxSize); 59 | void Write32Bit(uint32_t address, uint32_t value); 60 | uint32_t Read32Bit(uint32_t address); 61 | void ExitDFUMode(); 62 | void HaltRunningSystem(); 63 | void ForceDebug(); 64 | void ResetCore(); 65 | void LocalReset(); 66 | void EnableTrace(); 67 | void UnknownCommand(); 68 | uint32_t ReadDHCSRValue(); 69 | 70 | FILE* resultsFile = NULL; 71 | FILE* fullResultsFile = NULL; 72 | int debugEnabled = 0; 73 | 74 | int main(int argc, char** argv) 75 | { 76 | int ret, pos, opt = 0; 77 | char* filename = "trace.txt"; 78 | char* fullTraceFilename = "trace-full.txt"; 79 | 80 | while ((opt = getopt(argc, argv, "f:t:d")) != -1) { 81 | switch (opt) { 82 | case 'd': 83 | debugEnabled = 1; 84 | break; 85 | case 't': 86 | filename = optarg; 87 | break; 88 | case 'f': 89 | fullTraceFilename = optarg; 90 | break; 91 | } 92 | } 93 | 94 | resultsFile = fopen(filename, "w+"); // create or overwrite 95 | fullResultsFile = fopen(fullTraceFilename, "w+"); // create or overwrite 96 | 97 | // initialise the USB session context 98 | ret = libusb_init(&ctx); 99 | if (ret != 0) { 100 | printf("Error initialising libusb: 0x%x\n", ret); 101 | Cleanup(); 102 | exit(ret); 103 | } 104 | 105 | // turn debug messages on - full logging 106 | libusb_set_debug(ctx, DEBUG_LEVEL); 107 | 108 | // enumerate the USB devices 109 | listSize = libusb_get_device_list(ctx, &deviceList); 110 | for (pos=0; pos 1)\n", config); 143 | if (libusb_set_configuration(stlinkhandle, 1)) { 144 | printf("Unable to set configuration\n"); 145 | } 146 | } 147 | 148 | ret = libusb_claim_interface(stlinkhandle, 0); 149 | if (ret != 0) { 150 | printf("Unable to claim interface.\n"); 151 | Cleanup(); 152 | exit(ret); 153 | } 154 | 155 | requestTransfer = libusb_alloc_transfer(0); 156 | if (requestTransfer == NULL) { 157 | printf("Allocation of request transfer failed.\n"); 158 | Cleanup(); 159 | exit(ret); 160 | } 161 | 162 | responseTransfer = libusb_alloc_transfer(0); 163 | if (responseTransfer == NULL) { 164 | printf("Allocation of response transfer failed.\n"); 165 | Cleanup(); 166 | exit(ret); 167 | } 168 | 169 | responseTransfer->flags &= ~LIBUSB_TRANSFER_SHORT_NOT_OK; 170 | 171 | //============================ 172 | // identify the microcontroller, set up the debugging and step through instructions to get the trace data 173 | //============================ 174 | 175 | GetCurrentMode(); 176 | GetVersion(); 177 | 178 | //libusb_clear_halt(stlinkhandle, 0x81); 179 | 180 | ExitDFUMode(); 181 | 182 | if (GetCurrentMode() != MODE_DBG) { 183 | EnterSWD(); 184 | } 185 | 186 | GetTargetVoltage(); 187 | EnterDebugState(); 188 | GetCoreId(); 189 | 190 | ResetCore(); 191 | ForceDebug(); 192 | 193 | EnableTrace(); 194 | RunCore(); 195 | 196 | unsigned char checkCount = 0; 197 | while (1) { 198 | usleep(100); 199 | 200 | unsigned int byteCount = FetchTraceByteCount(); 201 | 202 | if (byteCount == 0) continue; 203 | 204 | if (byteCount > 2048) { 205 | int toread = 0; 206 | printf("**** more than 2048 bytes in trace data!! : 0x%4x ****\n", byteCount); 207 | 208 | if ((byteCount & 0xF800) == 0xF800) { 209 | //byteCount -= 0xF800; 210 | printf("Detected overrun packet?/n"); 211 | //ReadTraceData(1, byteCount); 212 | //ForceDebug(); 213 | //RunCore(); // run it - stalled? 214 | //continue; 215 | } 216 | if (resultsFile != NULL) fprintf(resultsFile, "\n>>> BAD PACKET START: byteCount = 0x%04x <<<\n", byteCount); 217 | 218 | while (byteCount > 0) { 219 | toread = byteCount > 2048 ? 2048 : byteCount; 220 | ReadTraceData(0, toread); 221 | byteCount -= toread; 222 | 223 | // check the register values 224 | //unsigned int value = 225 | ReadDHCSRValue(); 226 | //printf("DHCSR = 0x%04x\n", value); 227 | } 228 | 229 | ForceDebug(); 230 | RunCore(); // run it - stalled? 231 | 232 | if (resultsFile != NULL) fprintf(resultsFile, "\n>>> BAD PACKET END <<<\n"); 233 | 234 | continue; 235 | } 236 | 237 | ReadTraceData(1, byteCount); 238 | 239 | // check the stall status regularly 240 | if (checkCount++ > 4) { 241 | checkCount = 0; 242 | unsigned int value = ReadDHCSRValue(); 243 | printf("DHCSR = 0x%04x\n", value); 244 | } 245 | } 246 | 247 | //============================ will not get here, but if the code is ever changed to exit the loop, it should clean up below. 248 | 249 | ret = libusb_release_interface(stlinkhandle, 0); 250 | if (ret != 0) { 251 | printf("Unable to release interface.\n"); 252 | Cleanup(); 253 | exit(ret); 254 | } 255 | 256 | // finished - clean everything 257 | Cleanup(); 258 | 259 | return 0; 260 | } 261 | 262 | void Cleanup() 263 | { 264 | if (stlinkhandle != 0) libusb_close(stlinkhandle); 265 | if (ctx != 0) libusb_exit(ctx); 266 | if (deviceList != 0) libusb_free_device_list(deviceList, 1); 267 | } 268 | 269 | int IsStlink(libusb_device* dev) 270 | { 271 | struct libusb_device_descriptor desc; 272 | 273 | int ret = libusb_get_device_descriptor(dev, &desc); 274 | if (ret < 0) { 275 | printf("Unable to get device descriptor/n"); 276 | return 0; 277 | } 278 | 279 | if ((desc.idVendor != STLINKV2_VENDOR_ID) || (desc.idProduct != STLINKV2_PRODUCT_ID)) 280 | return 0; 281 | 282 | printf("Found an ST-Link V2\n"); 283 | printf("NumConfigurations: %d\n", desc.bNumConfigurations); 284 | printf("DeviceClass: 0x%02x\n", desc.bDeviceClass); 285 | printf("VendorID: 0x%04x\n", desc.idVendor); 286 | printf("ProductID: 0x%04x\n", desc.idProduct); 287 | 288 | struct libusb_config_descriptor *config; 289 | const struct libusb_interface *inter; 290 | const struct libusb_interface_descriptor *interdesc; 291 | const struct libusb_endpoint_descriptor *epdesc; 292 | 293 | libusb_get_config_descriptor(dev, 0, &config); 294 | printf("Interfaces: %d\n", config->bNumInterfaces); 295 | int i,j,k=0; 296 | for (i=0; i<(int)config->bNumInterfaces; i++) { 297 | inter = &config->interface[i]; 298 | printf("Number of alternate settings: %d\n", 299 | inter->num_altsetting); 300 | for (j=0; jnum_altsetting; j++) { 301 | interdesc = &inter->altsetting[j]; 302 | printf("Interface Number: %d\n", interdesc->bInterfaceNumber); 303 | printf("Number of endpoints: %d\n", interdesc->bNumEndpoints); 304 | for (k=0; kbNumEndpoints; k++) { 305 | epdesc = &interdesc->endpoint[k]; 306 | printf("Descriptor Type: 0x%02x\n", 307 | epdesc->bDescriptorType); 308 | printf("EP Address: 0x%02x\n", epdesc->bEndpointAddress); 309 | } 310 | } 311 | } 312 | libusb_free_config_descriptor(config); 313 | return 1; 314 | } 315 | 316 | void Write32Bit(uint32_t address, uint32_t value) 317 | { 318 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, WRITE32, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 319 | 320 | // Note: this series of commands do not return data - so send only on the first two packets 321 | 322 | // address to write 323 | txBuffer[2] = (address & 0xFF); 324 | txBuffer[3] = ((address >> 8) & 0xFF); 325 | txBuffer[4] = ((address >> 16) & 0xFF); 326 | txBuffer[5] = ((address >> 24) & 0xFF); 327 | SendAndReceive(&txBuffer[0], 16, NULL, 0); 328 | 329 | // data to write 330 | unsigned char txValueBuffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 331 | txValueBuffer[0] = (value & 0xFF); 332 | txValueBuffer[1] = ((value >> 8) & 0xFF); 333 | txValueBuffer[2] = ((value >> 16) & 0xFF); 334 | txValueBuffer[3] = ((value >> 24) & 0xFF); 335 | SendAndReceive(&txValueBuffer[0], 16, NULL, 0); 336 | 337 | UnknownCommand(); 338 | } 339 | 340 | uint32_t Read32Bit(uint32_t address) 341 | { 342 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, READ32, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 343 | unsigned char rxBuffer[100]; 344 | uint32_t value = 0; 345 | 346 | // address to read 347 | txBuffer[2] = (address & 0xFF); 348 | txBuffer[3] = ((address >> 8) & 0xFF); 349 | txBuffer[4] = ((address >> 16) & 0xFF); 350 | txBuffer[5] = ((address >> 24) & 0xFF); 351 | SendAndReceive(&txBuffer[0], 16, rxBuffer, 64); 352 | 353 | value = (rxBuffer[3] << 24) | (rxBuffer[2] << 16) | (rxBuffer[1] << 8) | (rxBuffer[0] << 0); 354 | 355 | UnknownCommand(); 356 | 357 | return value; 358 | } 359 | 360 | void UnknownCommand() 361 | { 362 | unsigned char rxBuffer[100]; 363 | 364 | // end of data packet? 365 | unsigned char txEndBuffer[] = {STLINK_DEBUG_COMMAND, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 366 | SendAndReceive(&txEndBuffer[0], 16, &rxBuffer[0], 64); 367 | } 368 | 369 | uint32_t ReadDHCSRValue() 370 | { 371 | return Read32Bit(0xE000EDF0); 372 | } 373 | 374 | /* 375 | * Enable the ITM trace functionality 376 | */ 377 | void EnableTrace() 378 | { 379 | // set up the ITM 380 | EnterDebugState(); 381 | HaltRunningSystem(); 382 | LocalReset(); 383 | 384 | // Set DHCSR to C_HALT and C_DEBUGEN 385 | Write32Bit(0xE000EDF0, 0xA05F0003); 386 | 387 | // Set TRCENA flag to enable global DWT and ITM 388 | Write32Bit(0xE000EDFC, 0x01000000); 389 | 390 | // Set FP_CTRL to enable write 391 | Write32Bit(0xE0002000, 0x00000002); 392 | 393 | // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling 394 | Write32Bit(0xE0001028, 0x00000000); 395 | Write32Bit(0xE0001038, 0x00000000); 396 | Write32Bit(0xE0001048, 0x00000000); 397 | Write32Bit(0xE0001058, 0x00000000); 398 | 399 | // Clear DWT_CTRL and other registers 400 | Write32Bit(0xE0001000, 0x00000000); 401 | Write32Bit(0xE0001004, 0x00000000); 402 | Write32Bit(0xE0001008, 0x00000000); 403 | Write32Bit(0xE000100C, 0x00000000); 404 | Write32Bit(0xE0001010, 0x00000000); 405 | Write32Bit(0xE0001014, 0x00000000); 406 | Write32Bit(0xE0001018, 0x00000000); 407 | 408 | unsigned char txBuffer1[] = {STLINK_DEBUG_COMMAND, 0x33, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 409 | unsigned char rxBuffer1[100]; 410 | SendAndReceive(&txBuffer1[0], 16, &rxBuffer1[0], 64); 411 | 412 | unsigned char txBuffer2[] = {STLINK_DEBUG_COMMAND, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 413 | unsigned char rxBuffer2[100]; 414 | SendAndReceive(&txBuffer2[0], 16, &rxBuffer2[0], 64); 415 | 416 | // Set DBGMCU_CR to enable asynchronous transmission 417 | Write32Bit(0xE0042004, 0x00000027); 418 | 419 | unsigned char txBuffer3[] = {STLINK_DEBUG_COMMAND, 0x40, 0x00, 0x10, 0x80, 0x84, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 420 | unsigned char rxBuffer3[100]; 421 | SendAndReceive(&txBuffer3[0], 16, &rxBuffer3[0], 64); 422 | 423 | // Set TPIU_CSPSR to enable trace port width of 2 424 | Write32Bit(0xE0040004, 0x00000001); 425 | 426 | // Set TPIU_ACPR clock divisor 427 | Write32Bit(0xE0040010, CLOCK_DIVISOR); 428 | 429 | // Set TPIU_SPPR to Asynchronous SWO (NRZ) 430 | Write32Bit(0xE00400F0, 0x00000002); 431 | 432 | // Set TPIU_FFCR continuous formatting) 433 | Write32Bit(0xE0040304, 0x00000100); 434 | 435 | // Unlock the ITM registers for write 436 | Write32Bit(0xE0000FB0, 0xC5ACCE55); 437 | 438 | // Set ITM_TCR flags : ITMENA,SYNCENA,DWTENA, ATB=0 439 | Write32Bit(0xE0000E80, 0x0001000D); 440 | 441 | // Enable all trace ports in ITM_TER 442 | Write32Bit(0xE0000E00, 0xFFFFFFFF); 443 | 444 | // Enable trace ports 31:24 in ITM_TPR 445 | //Write32Bit(0xE0000E40, 0x00000008); 446 | Write32Bit(0xE0000E40, 0x0000000F); // 8 was wrong? 447 | 448 | // Set DWT_CTRL flags) 449 | Write32Bit(0xE0000E40, 0x400003FE); // Keil one 450 | 451 | // Enable tracing (DEMCR - TRCENA bit) 452 | Write32Bit(0xE000EDFC, 0x01000000); 453 | } 454 | 455 | /* 456 | * Resets the target board by setting a bit in the AIRCR 457 | */ 458 | void LocalReset() 459 | { 460 | //F2 35 0C ED 00 E0 04 00 FA 05 461 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, WRITE_DATA, 0x0C, 0xED, 0x00, 0xE0, 0x04, 0x00, 0xFA, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 462 | unsigned char rxBuffer[100]; 463 | SendAndReceive(&txBuffer[0], 16, &rxBuffer[0], 2); 464 | 465 | unsigned char txBufferWait[] = {STLINK_DEBUG_COMMAND, READ_DATA, 0x0C, 0xED, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 466 | 467 | printf("Waiting for local reset\n"); 468 | while (1) { 469 | int byteCount = SendAndReceive(&txBufferWait[0], 16, &rxBuffer[0], 64); 470 | if (byteCount > 0) { 471 | // reset successful? 472 | if ((rxBuffer[0] == 0x80) && (rxBuffer[4] == 0x00) && (rxBuffer[5] == 0x00) 473 | && (rxBuffer[6] == 0x05) && (rxBuffer[7] == 0xFA)) break; 474 | } 475 | } 476 | 477 | printf("Local reset complete\n"); 478 | } 479 | 480 | void ExitDFUMode() 481 | { 482 | size_t txSize = 16; 483 | unsigned char txBuffer[] = {STLINK_DFU_COMMAND, STLINK_DFU_EXIT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 484 | 485 | // do not read anything for DFU exit command 486 | TransferData(0, (unsigned char*) &txBuffer, txSize, NULL, 0); 487 | printf("Exited DFU mode\n"); 488 | } 489 | 490 | int GetCurrentMode() 491 | { 492 | unsigned char rxBuffer[100]; 493 | size_t rxSize = 2; 494 | int bytesRead = 0; 495 | unsigned char txBuffer[] = {0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 496 | size_t txSize = 16; 497 | 498 | bytesRead = TransferData(0, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 499 | if (bytesRead > 0) { 500 | printf("Mode: 0x%02x 0x%02x\n", 501 | rxBuffer[0], rxBuffer[1]); 502 | return (rxBuffer[1]<<8) | rxBuffer[0]; 503 | } 504 | else { 505 | printf("Unable to read mode\n"); 506 | } 507 | 508 | return 0; 509 | } 510 | 511 | int SendAndReceive(unsigned char* txBuffer, size_t txSize, unsigned char* rxBuffer, size_t rxSize) 512 | { 513 | return TransferData(0, txBuffer, txSize, rxBuffer, rxSize); 514 | } 515 | 516 | void EnterDebugState() 517 | { 518 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, 0x35, 0xF0, 0xED, 0x00, 0xE0, 0x03, 0x00, 0x5F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 519 | unsigned char rxBuffer[100]; 520 | SendAndReceive(&txBuffer[0], 16, &rxBuffer[0], 64); 521 | } 522 | 523 | void ResetCore() 524 | { 525 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_RESETSYS, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 526 | unsigned char rxBuffer[100]; 527 | SendAndReceive(&txBuffer[0], 16, &rxBuffer[0], 2); 528 | } 529 | 530 | void ForceDebug() 531 | { 532 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_FORCEDEBUG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 533 | unsigned char rxBuffer[100]; 534 | SendAndReceive(&txBuffer[0], 16, &rxBuffer[0], 2); 535 | } 536 | 537 | void HaltRunningSystem() 538 | { 539 | unsigned char txBuffer[] = {STLINK_DEBUG_COMMAND, 0x35, 0xFC, 0xED, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 540 | unsigned char rxBuffer[100]; 541 | SendAndReceive(&txBuffer[0], 16, &rxBuffer[0], 64); 542 | } 543 | 544 | void GetTargetVoltage() 545 | { 546 | unsigned char txBuffer[] = {0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 547 | unsigned char rxBuffer[100]; 548 | int bytesRead = SendAndReceive(&txBuffer[0], 16, &rxBuffer[0],64); 549 | if (bytesRead > 0) { 550 | printf("Target Voltage: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 551 | rxBuffer[0], rxBuffer[1], rxBuffer[2], rxBuffer[3], rxBuffer[4], rxBuffer[5], rxBuffer[6], rxBuffer[7]); 552 | } 553 | else { 554 | printf("Unable to read target voltage\n"); 555 | } 556 | } 557 | 558 | void GetVersion() 559 | { 560 | size_t txSize = 16; 561 | unsigned char rxBuffer[100]; 562 | size_t rxSize = 6; 563 | int bytesRead = 0; 564 | unsigned char txBuffer[] = {0xF1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 565 | 566 | bytesRead = TransferData(1, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 567 | if (bytesRead > 0) { 568 | printf("Version: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 569 | rxBuffer[0], rxBuffer[1], rxBuffer[2], rxBuffer[3], rxBuffer[4], rxBuffer[5]); 570 | } 571 | else { 572 | printf("Unable to read version\n"); 573 | } 574 | } 575 | 576 | void GetCoreId() 577 | { 578 | size_t txSize = 16; 579 | unsigned char rxBuffer[100]; 580 | size_t rxSize = 64; 581 | int bytesRead = 0; 582 | unsigned char txBuffer[] = {DEBUG_COMMAND, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 583 | 584 | bytesRead = TransferData(1, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 585 | if (bytesRead > 0) { 586 | uint32_t coreid = (rxBuffer[3] << 24) | (rxBuffer[2] << 16) | (rxBuffer[1] << 8) | (rxBuffer[0] << 0); 587 | printf("Core ID: 0x%08x\n", coreid); 588 | if (coreid == 0x1ba01477) printf("Cortex-M3 detected\n"); 589 | } 590 | else { 591 | printf("Unable to read core ID\n"); 592 | } 593 | } 594 | 595 | void EnterSWD() 596 | { 597 | size_t txSize = 16; 598 | unsigned char rxBuffer[100]; 599 | size_t rxSize = 64; 600 | int bytesRead = 0; 601 | unsigned char txBuffer[] = {DEBUG_COMMAND, 0x30, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 602 | 603 | bytesRead = TransferData(1, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 604 | if (bytesRead > 0) { 605 | printf("Switched to SWD\n"); 606 | } 607 | else { 608 | printf("Error switching to SWD\n"); 609 | } 610 | } 611 | 612 | void StepCore() 613 | { 614 | size_t txSize = 16; 615 | unsigned char rxBuffer[100]; 616 | size_t rxSize = 64; 617 | unsigned char txBuffer[] = {DEBUG_COMMAND, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 618 | 619 | TransferData(1, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 620 | } 621 | 622 | void RunCore() 623 | { 624 | size_t txSize = 16; 625 | unsigned char rxBuffer[100]; 626 | size_t rxSize = 64; 627 | unsigned char txBuffer[] = {DEBUG_COMMAND, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 628 | 629 | int bytesRead = TransferData(1, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 630 | if (bytesRead > 0) { 631 | printf("Running\n"); 632 | } 633 | else { 634 | printf("Error running\n"); 635 | } 636 | } 637 | 638 | int FetchTraceByteCount() 639 | { 640 | size_t txSize = 16; 641 | unsigned char rxBuffer[100]; 642 | size_t rxSize = 100; 643 | int bytesRead = 0; 644 | unsigned char txBuffer[] = {DEBUG_COMMAND, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 645 | int traceByteCount = 0; 646 | 647 | bytesRead = TransferData(1, (unsigned char*) &txBuffer, txSize, (unsigned char*) &rxBuffer, rxSize); 648 | if (bytesRead > 0) { 649 | traceByteCount = rxBuffer[0]+(rxBuffer[1] << 8); // original one - did not handle large packets 650 | } 651 | else { 652 | printf("Unable to step instruction\n"); 653 | } 654 | 655 | if (debugEnabled) printf("trace bytes available: %d\n", traceByteCount); 656 | return traceByteCount; 657 | } 658 | 659 | // for trace 660 | uint8_t trace_offset = 1; 661 | 662 | int ReadTraceData(int toscreen, int rxSize) 663 | { 664 | if (debugEnabled) printf("Reading %d bytes\n", (int)rxSize); 665 | 666 | unsigned char rxBuffer[2050]; 667 | int bytesRead = 0; 668 | 669 | #if ASYNC 670 | libusb_fill_bulk_transfer( 671 | responseTransfer, 672 | stlinkhandle, 673 | 3 | LIBUSB_ENDPOINT_IN, 674 | (unsigned char*) &rxBuffer, 675 | rxSize, 676 | NULL, 677 | NULL, 678 | 0); 679 | 680 | // no data? 681 | if (submit_wait(responseTransfer)) return; 682 | 683 | // have trace data - display it 684 | bytesRead = responseTransfer->actual_length; 685 | printf("Read response of %d bytes\n", bytesRead); 686 | #else 687 | int ret = 0; 688 | int totalBytes = rxSize; 689 | 690 | while (totalBytes > 0) { 691 | 692 | ret = libusb_bulk_transfer( 693 | stlinkhandle, 694 | 3 | LIBUSB_ENDPOINT_IN, 695 | rxBuffer, 696 | totalBytes, 697 | &bytesRead, 698 | 0); 699 | printf("Read response %d of %d bytes. ret = %d\n", bytesRead, rxSize, ret); 700 | if (bytesRead != rxSize) { 701 | printf("\n\n>>>>>>>>>>>>>>>>> Not read all trace data. <<<<<<<<<<<<<<<<<<<<\n\n"); 702 | } 703 | totalBytes -= bytesRead; 704 | 705 | #endif 706 | if (bytesRead > 0) { 707 | //TODO: re-factor my following junk code :) 708 | int pos = 0; 709 | unsigned char ch = ' '; 710 | 711 | #if HEXDUMP 712 | printf("Trace bytes read: %d\n", bytesRead); 713 | int width=16; //8; 714 | unsigned char line[9] = "\0"; 715 | for (pos=0; pos < bytesRead; pos++) { 716 | ch = rxBuffer[pos]; 717 | line[pos%width] = ((ch > 31) && (ch < 128)) ? ch : '.'; 718 | line[(pos%width)+1] = '\0'; 719 | if (toscreen) printf("%02x ", ch); 720 | if (pos%width > (width-2)) { 721 | if (toscreen) printf(" %s\n", line); 722 | } 723 | } 724 | if (pos%width != 0) { 725 | int p; 726 | for (p=0; p 127)) ? '.' : ch); 750 | } 751 | if (resultsFile != NULL) fprintf(resultsFile, "%c",ch); 752 | pos += 2; 753 | } 754 | 755 | //trace_offset = ((bytesRead+trace_offset) & 0x01); 756 | if (resultsFile != NULL) fflush(resultsFile); 757 | if (fullResultsFile != NULL) fflush(fullResultsFile); 758 | } 759 | else { 760 | printf("Unable to read trace data\n"); 761 | } 762 | } 763 | 764 | return bytesRead; 765 | } 766 | 767 | ssize_t TransferData(int terminate, 768 | unsigned char* transmitBuffer, size_t transmitLength, 769 | unsigned char* receiveBuffer, size_t receiveLength) 770 | { 771 | int res = 0; 772 | 773 | #if ASYNC 774 | libusb_fill_bulk_transfer( 775 | requestTransfer, 776 | stlinkhandle, 777 | 2 | LIBUSB_ENDPOINT_OUT, 778 | transmitBuffer, 779 | transmitLength, 780 | NULL, 781 | NULL, 782 | 0); 783 | 784 | if (debugEnabled) printf("TransferData - request\n"); 785 | 786 | if (submit_wait(requestTransfer)) return -1; 787 | 788 | // response required? 789 | if (receiveBuffer != NULL) { 790 | libusb_fill_bulk_transfer( 791 | responseTransfer, 792 | stlinkhandle, 793 | 1 | LIBUSB_ENDPOINT_IN, 794 | receiveBuffer, 795 | receiveLength, 796 | NULL, 797 | NULL, 798 | 0); 799 | 800 | if (debugEnabled) printf("TransferData - response\n"); 801 | 802 | if (submit_wait(responseTransfer)) return -1; 803 | res = responseTransfer->actual_length; 804 | } 805 | #else 806 | int bytesTransferred = 0; 807 | int ret = 0; 808 | 809 | ret = libusb_bulk_transfer( 810 | stlinkhandle, 811 | 2 | LIBUSB_ENDPOINT_OUT, 812 | transmitBuffer, 813 | transmitLength, 814 | &bytesTransferred, 815 | 0); 816 | 817 | if (debugEnabled) printf("TransferData - request, %d of %d bytes written, ret = %d\n", bytesTransferred, (int)transmitLength, ret); 818 | if (bytesTransferred != transmitLength) { 819 | printf("\n\n>>>>>>>>>>>>>>>>> Not written all data. <<<<<<<<<<<<<<<<<<<<\n\n"); 820 | } 821 | 822 | // response required? 823 | if (receiveBuffer != NULL) { 824 | ret = libusb_bulk_transfer( 825 | stlinkhandle, 826 | 1 | LIBUSB_ENDPOINT_IN, 827 | receiveBuffer, 828 | receiveLength, 829 | &bytesTransferred, 830 | 0); 831 | 832 | if (debugEnabled) printf("TransferData - response, ret = %d\n", ret); 833 | // if (bytesTransferred != receiveLength) { 834 | // printf("\n\n>>>>>>>>>>>>>>>>> Not read all data. <<<<<<<<<<<<<<<<<<<<\n\n"); 835 | // } 836 | 837 | res = bytesTransferred; 838 | } 839 | #endif 840 | 841 | return res; 842 | } 843 | 844 | #if ASYNC 845 | struct trans_ctx { 846 | #define TRANS_FLAGS_IS_DONE (1 << 0) 847 | #define TRANS_FLAGS_HAS_ERROR (1 << 1) 848 | volatile unsigned long flags; 849 | }; 850 | 851 | static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) { 852 | struct trans_ctx * const ctx = trans->user_data; 853 | 854 | if (trans->status != LIBUSB_TRANSFER_COMPLETED) { 855 | if (trans->status != LIBUSB_TRANSFER_STALL) { 856 | ctx->flags |= TRANS_FLAGS_HAS_ERROR; 857 | } 858 | } 859 | 860 | ctx->flags |= TRANS_FLAGS_IS_DONE; 861 | } 862 | 863 | int submit_wait(struct libusb_transfer* trans) 864 | { 865 | struct timeval start; 866 | struct timeval now; 867 | struct timeval diff; 868 | struct trans_ctx trans_ctx; 869 | enum libusb_error error; 870 | 871 | trans_ctx.flags = 0; 872 | 873 | /* brief intrusion inside the libusb interface */ 874 | trans->callback = on_trans_done; 875 | trans->user_data = &trans_ctx; 876 | 877 | if ((error = libusb_submit_transfer(trans))) { 878 | printf("libusb_submit_transfer(%d)\n", error); 879 | return -1; 880 | } 881 | 882 | gettimeofday(&start, NULL); 883 | 884 | while (trans_ctx.flags == 0) { 885 | struct timeval timeout; 886 | timeout.tv_sec = 10; 887 | timeout.tv_usec = 0; 888 | if (libusb_handle_events_timeout(ctx, &timeout)) { 889 | printf("libusb_handle_events_timeout()\n"); 890 | return -1; 891 | } 892 | 893 | gettimeofday(&now, NULL); 894 | timersub(&now, &start, &diff); 895 | if (diff.tv_sec >= 10) { 896 | printf("libusb_handle_events_timeout() timeout\n"); 897 | return -1; 898 | } 899 | } 900 | 901 | if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) { 902 | printf("libusb_handle_events_timeout() | has_error\n"); 903 | return -1; 904 | } 905 | 906 | return 0; 907 | } 908 | #endif 909 | -------------------------------------------------------------------------------- /Examples/Keil-simple/system_stm32f10x.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.c 4 | * @author MCD Application Team 5 | * @version V3.4.0 6 | * @date 10/15/2010 7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. 8 | ****************************************************************************** 9 | * 10 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 11 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 12 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 13 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 14 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 15 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 16 | * 17 | *

© COPYRIGHT 2010 STMicroelectronics

18 | ****************************************************************************** 19 | */ 20 | 21 | /** @addtogroup CMSIS 22 | * @{ 23 | */ 24 | 25 | /** @addtogroup stm32f10x_system 26 | * @{ 27 | */ 28 | 29 | /** @addtogroup STM32F10x_System_Private_Includes 30 | * @{ 31 | */ 32 | 33 | #include "stm32f10x.h" 34 | 35 | /** 36 | * @} 37 | */ 38 | 39 | /** @addtogroup STM32F10x_System_Private_TypesDefinitions 40 | * @{ 41 | */ 42 | 43 | /** 44 | * @} 45 | */ 46 | 47 | /** @addtogroup STM32F10x_System_Private_Defines 48 | * @{ 49 | */ 50 | 51 | /*!< Uncomment the line corresponding to the desired System clock (SYSCLK) 52 | frequency (after reset the HSI is used as SYSCLK source) 53 | 54 | IMPORTANT NOTE: 55 | ============== 56 | 1. After each device reset the HSI is used as System clock source. 57 | 58 | 2. Please make sure that the selected System clock doesn't exceed your device's 59 | maximum frequency. 60 | 61 | 3. If none of the define below is enabled, the HSI is used as System clock 62 | source. 63 | 64 | 4. The System clock configuration functions provided within this file assume that: 65 | - For Low, Medium and High density Value line devices an external 8MHz 66 | crystal is used to drive the System clock. 67 | - For Low, Medium and High density devices an external 8MHz crystal is 68 | used to drive the System clock. 69 | - For Connectivity line devices an external 25MHz crystal is used to drive 70 | the System clock. 71 | If you are using different crystal you have to adapt those functions accordingly. 72 | */ 73 | 74 | #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 75 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */ 76 | #define SYSCLK_FREQ_24MHz 24000000 77 | #else 78 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */ 79 | /* #define SYSCLK_FREQ_24MHz 24000000 */ 80 | /* #define SYSCLK_FREQ_36MHz 36000000 */ 81 | /* #define SYSCLK_FREQ_48MHz 48000000 */ 82 | /* #define SYSCLK_FREQ_56MHz 56000000 */ 83 | #define SYSCLK_FREQ_72MHz 72000000 84 | #endif 85 | 86 | /*!< Uncomment the following line if you need to use external SRAM mounted 87 | on STM3210E-EVAL board (STM32 High density and XL-density devices) or on 88 | STM32100E-EVAL board (STM32 High-density value line devices) as data memory */ 89 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 90 | /* #define DATA_IN_ExtSRAM */ 91 | #endif 92 | 93 | /*!< Uncomment the following line if you need to relocate your vector Table in 94 | Internal SRAM. */ 95 | /* #define VECT_TAB_SRAM */ 96 | #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. 97 | This value must be a multiple of 0x100. */ 98 | 99 | 100 | /** 101 | * @} 102 | */ 103 | 104 | /** @addtogroup STM32F10x_System_Private_Macros 105 | * @{ 106 | */ 107 | 108 | /** 109 | * @} 110 | */ 111 | 112 | /** @addtogroup STM32F10x_System_Private_Variables 113 | * @{ 114 | */ 115 | 116 | /******************************************************************************* 117 | * Clock Definitions 118 | *******************************************************************************/ 119 | #ifdef SYSCLK_FREQ_HSE 120 | uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ 121 | #elif defined SYSCLK_FREQ_24MHz 122 | uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */ 123 | #elif defined SYSCLK_FREQ_36MHz 124 | uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */ 125 | #elif defined SYSCLK_FREQ_48MHz 126 | uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */ 127 | #elif defined SYSCLK_FREQ_56MHz 128 | uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */ 129 | #elif defined SYSCLK_FREQ_72MHz 130 | uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ 131 | #else /*!< HSI Selected as System Clock source */ 132 | uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */ 133 | #endif 134 | 135 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 136 | /** 137 | * @} 138 | */ 139 | 140 | /** @addtogroup STM32F10x_System_Private_FunctionPrototypes 141 | * @{ 142 | */ 143 | 144 | static void SetSysClock(void); 145 | 146 | #ifdef SYSCLK_FREQ_HSE 147 | static void SetSysClockToHSE(void); 148 | #elif defined SYSCLK_FREQ_24MHz 149 | static void SetSysClockTo24(void); 150 | #elif defined SYSCLK_FREQ_36MHz 151 | static void SetSysClockTo36(void); 152 | #elif defined SYSCLK_FREQ_48MHz 153 | static void SetSysClockTo48(void); 154 | #elif defined SYSCLK_FREQ_56MHz 155 | static void SetSysClockTo56(void); 156 | #elif defined SYSCLK_FREQ_72MHz 157 | static void SetSysClockTo72(void); 158 | #endif 159 | 160 | #ifdef DATA_IN_ExtSRAM 161 | static void SystemInit_ExtMemCtl(void); 162 | #endif /* DATA_IN_ExtSRAM */ 163 | 164 | /** 165 | * @} 166 | */ 167 | 168 | /** @addtogroup STM32F10x_System_Private_Functions 169 | * @{ 170 | */ 171 | 172 | /** 173 | * @brief Setup the microcontroller system 174 | * Initialize the Embedded Flash Interface, the PLL and update the 175 | * SystemCoreClock variable. 176 | * @note This function should be used only after reset. 177 | * @param None 178 | * @retval None 179 | */ 180 | void SystemInit (void) 181 | { 182 | /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ 183 | /* Set HSION bit */ 184 | RCC->CR |= (uint32_t)0x00000001; 185 | 186 | /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ 187 | #ifndef STM32F10X_CL 188 | RCC->CFGR &= (uint32_t)0xF8FF0000; 189 | #else 190 | RCC->CFGR &= (uint32_t)0xF0FF0000; 191 | #endif /* STM32F10X_CL */ 192 | 193 | /* Reset HSEON, CSSON and PLLON bits */ 194 | RCC->CR &= (uint32_t)0xFEF6FFFF; 195 | 196 | /* Reset HSEBYP bit */ 197 | RCC->CR &= (uint32_t)0xFFFBFFFF; 198 | 199 | /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ 200 | RCC->CFGR &= (uint32_t)0xFF80FFFF; 201 | 202 | #ifdef STM32F10X_CL 203 | /* Reset PLL2ON and PLL3ON bits */ 204 | RCC->CR &= (uint32_t)0xEBFFFFFF; 205 | 206 | /* Disable all interrupts and clear pending bits */ 207 | RCC->CIR = 0x00FF0000; 208 | 209 | /* Reset CFGR2 register */ 210 | RCC->CFGR2 = 0x00000000; 211 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 212 | /* Disable all interrupts and clear pending bits */ 213 | RCC->CIR = 0x009F0000; 214 | 215 | /* Reset CFGR2 register */ 216 | RCC->CFGR2 = 0x00000000; 217 | #else 218 | /* Disable all interrupts and clear pending bits */ 219 | RCC->CIR = 0x009F0000; 220 | #endif /* STM32F10X_CL */ 221 | 222 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 223 | #ifdef DATA_IN_ExtSRAM 224 | SystemInit_ExtMemCtl(); 225 | #endif /* DATA_IN_ExtSRAM */ 226 | #endif 227 | 228 | /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ 229 | /* Configure the Flash Latency cycles and enable prefetch buffer */ 230 | SetSysClock(); 231 | 232 | #ifdef VECT_TAB_SRAM 233 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ 234 | #else 235 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ 236 | #endif 237 | } 238 | 239 | /** 240 | * @brief Update SystemCoreClock according to Clock Register Values 241 | * @note None 242 | * @param None 243 | * @retval None 244 | */ 245 | void SystemCoreClockUpdate (void) 246 | { 247 | uint32_t tmp = 0, pllmull = 0, pllsource = 0; 248 | 249 | #ifdef STM32F10X_CL 250 | uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; 251 | #endif /* STM32F10X_CL */ 252 | 253 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 254 | uint32_t prediv1factor = 0; 255 | #endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */ 256 | 257 | /* Get SYSCLK source -------------------------------------------------------*/ 258 | tmp = RCC->CFGR & RCC_CFGR_SWS; 259 | 260 | switch (tmp) 261 | { 262 | case 0x00: /* HSI used as system clock */ 263 | SystemCoreClock = HSI_VALUE; 264 | break; 265 | case 0x04: /* HSE used as system clock */ 266 | SystemCoreClock = HSE_VALUE; 267 | break; 268 | case 0x08: /* PLL used as system clock */ 269 | 270 | /* Get PLL clock source and multiplication factor ----------------------*/ 271 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 272 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 273 | 274 | #ifndef STM32F10X_CL 275 | pllmull = ( pllmull >> 18) + 2; 276 | 277 | if (pllsource == 0x00) 278 | { 279 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 280 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 281 | } 282 | else 283 | { 284 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 285 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 286 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 287 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 288 | #else 289 | /* HSE selected as PLL clock entry */ 290 | if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) 291 | {/* HSE oscillator clock divided by 2 */ 292 | SystemCoreClock = (HSE_VALUE >> 1) * pllmull; 293 | } 294 | else 295 | { 296 | SystemCoreClock = HSE_VALUE * pllmull; 297 | } 298 | #endif 299 | } 300 | #else 301 | pllmull = pllmull >> 18; 302 | 303 | if (pllmull != 0x0D) 304 | { 305 | pllmull += 2; 306 | } 307 | else 308 | { /* PLL multiplication factor = PLL input clock * 6.5 */ 309 | pllmull = 13 / 2; 310 | } 311 | 312 | if (pllsource == 0x00) 313 | { 314 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 315 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 316 | } 317 | else 318 | {/* PREDIV1 selected as PLL clock entry */ 319 | 320 | /* Get PREDIV1 clock source and division factor */ 321 | prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; 322 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 323 | 324 | if (prediv1source == 0) 325 | { 326 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 327 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 328 | } 329 | else 330 | {/* PLL2 clock selected as PREDIV1 clock entry */ 331 | 332 | /* Get PREDIV2 division factor and PLL2 multiplication factor */ 333 | prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1; 334 | pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; 335 | SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; 336 | } 337 | } 338 | #endif /* STM32F10X_CL */ 339 | break; 340 | 341 | default: 342 | SystemCoreClock = HSI_VALUE; 343 | break; 344 | } 345 | 346 | /* Compute HCLK clock frequency ----------------*/ 347 | /* Get HCLK prescaler */ 348 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 349 | /* HCLK clock frequency */ 350 | SystemCoreClock >>= tmp; 351 | } 352 | 353 | /** 354 | * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. 355 | * @param None 356 | * @retval None 357 | */ 358 | static void SetSysClock(void) 359 | { 360 | #ifdef SYSCLK_FREQ_HSE 361 | SetSysClockToHSE(); 362 | #elif defined SYSCLK_FREQ_24MHz 363 | SetSysClockTo24(); 364 | #elif defined SYSCLK_FREQ_36MHz 365 | SetSysClockTo36(); 366 | #elif defined SYSCLK_FREQ_48MHz 367 | SetSysClockTo48(); 368 | #elif defined SYSCLK_FREQ_56MHz 369 | SetSysClockTo56(); 370 | #elif defined SYSCLK_FREQ_72MHz 371 | SetSysClockTo72(); 372 | #endif 373 | 374 | /* If none of the define above is enabled, the HSI is used as System clock 375 | source (default after reset) */ 376 | } 377 | 378 | /** 379 | * @brief Setup the external memory controller. Called in startup_stm32f10x.s 380 | * before jump to __main 381 | * @param None 382 | * @retval None 383 | */ 384 | #ifdef DATA_IN_ExtSRAM 385 | /** 386 | * @brief Setup the external memory controller. 387 | * Called in startup_stm32f10x_xx.s/.c before jump to main. 388 | * This function configures the external SRAM mounted on STM3210E-EVAL 389 | * board (STM32 High density devices). This SRAM will be used as program 390 | * data memory (including heap and stack). 391 | * @param None 392 | * @retval None 393 | */ 394 | void SystemInit_ExtMemCtl(void) 395 | { 396 | /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 397 | required, then adjust the Register Addresses */ 398 | 399 | /* Enable FSMC clock */ 400 | RCC->AHBENR = 0x00000114; 401 | 402 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ 403 | RCC->APB2ENR = 0x000001E0; 404 | 405 | /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ 406 | /*---------------- SRAM Address lines configuration -------------------------*/ 407 | /*---------------- NOE and NWE configuration --------------------------------*/ 408 | /*---------------- NE3 configuration ----------------------------------------*/ 409 | /*---------------- NBL0, NBL1 configuration ---------------------------------*/ 410 | 411 | GPIOD->CRL = 0x44BB44BB; 412 | GPIOD->CRH = 0xBBBBBBBB; 413 | 414 | GPIOE->CRL = 0xB44444BB; 415 | GPIOE->CRH = 0xBBBBBBBB; 416 | 417 | GPIOF->CRL = 0x44BBBBBB; 418 | GPIOF->CRH = 0xBBBB4444; 419 | 420 | GPIOG->CRL = 0x44BBBBBB; 421 | GPIOG->CRH = 0x44444B44; 422 | 423 | /*---------------- FSMC Configuration ---------------------------------------*/ 424 | /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ 425 | 426 | FSMC_Bank1->BTCR[4] = 0x00001011; 427 | FSMC_Bank1->BTCR[5] = 0x00000200; 428 | } 429 | #endif /* DATA_IN_ExtSRAM */ 430 | 431 | #ifdef SYSCLK_FREQ_HSE 432 | /** 433 | * @brief Selects HSE as System clock source and configure HCLK, PCLK2 434 | * and PCLK1 prescalers. 435 | * @note This function should be used only after reset. 436 | * @param None 437 | * @retval None 438 | */ 439 | static void SetSysClockToHSE(void) 440 | { 441 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 442 | 443 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 444 | /* Enable HSE */ 445 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 446 | 447 | /* Wait till HSE is ready and if Time out is reached exit */ 448 | do 449 | { 450 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 451 | StartUpCounter++; 452 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 453 | 454 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 455 | { 456 | HSEStatus = (uint32_t)0x01; 457 | } 458 | else 459 | { 460 | HSEStatus = (uint32_t)0x00; 461 | } 462 | 463 | if (HSEStatus == (uint32_t)0x01) 464 | { 465 | 466 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 467 | /* Enable Prefetch Buffer */ 468 | FLASH->ACR |= FLASH_ACR_PRFTBE; 469 | 470 | /* Flash 0 wait state */ 471 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 472 | 473 | #ifndef STM32F10X_CL 474 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 475 | #else 476 | if (HSE_VALUE <= 24000000) 477 | { 478 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 479 | } 480 | else 481 | { 482 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 483 | } 484 | #endif /* STM32F10X_CL */ 485 | #endif 486 | 487 | /* HCLK = SYSCLK */ 488 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 489 | 490 | /* PCLK2 = HCLK */ 491 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 492 | 493 | /* PCLK1 = HCLK */ 494 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 495 | 496 | /* Select HSE as system clock source */ 497 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 498 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE; 499 | 500 | /* Wait till HSE is used as system clock source */ 501 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04) 502 | { 503 | } 504 | } 505 | else 506 | { /* If HSE fails to start-up, the application will have wrong clock 507 | configuration. User can add here some code to deal with this error */ 508 | } 509 | } 510 | #elif defined SYSCLK_FREQ_24MHz 511 | /** 512 | * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 513 | * and PCLK1 prescalers. 514 | * @note This function should be used only after reset. 515 | * @param None 516 | * @retval None 517 | */ 518 | static void SetSysClockTo24(void) 519 | { 520 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 521 | 522 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 523 | /* Enable HSE */ 524 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 525 | 526 | /* Wait till HSE is ready and if Time out is reached exit */ 527 | do 528 | { 529 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 530 | StartUpCounter++; 531 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 532 | 533 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 534 | { 535 | HSEStatus = (uint32_t)0x01; 536 | } 537 | else 538 | { 539 | HSEStatus = (uint32_t)0x00; 540 | } 541 | 542 | if (HSEStatus == (uint32_t)0x01) 543 | { 544 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 545 | /* Enable Prefetch Buffer */ 546 | FLASH->ACR |= FLASH_ACR_PRFTBE; 547 | 548 | /* Flash 0 wait state */ 549 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 550 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 551 | #endif 552 | 553 | /* HCLK = SYSCLK */ 554 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 555 | 556 | /* PCLK2 = HCLK */ 557 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 558 | 559 | /* PCLK1 = HCLK */ 560 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 561 | 562 | #ifdef STM32F10X_CL 563 | /* Configure PLLs ------------------------------------------------------*/ 564 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ 565 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 566 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 567 | RCC_CFGR_PLLMULL6); 568 | 569 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 570 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ 571 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 572 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 573 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 574 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); 575 | 576 | /* Enable PLL2 */ 577 | RCC->CR |= RCC_CR_PLL2ON; 578 | /* Wait till PLL2 is ready */ 579 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 580 | { 581 | } 582 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) 583 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ 584 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 585 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6); 586 | #else 587 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ 588 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 589 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6); 590 | #endif /* STM32F10X_CL */ 591 | 592 | /* Enable PLL */ 593 | RCC->CR |= RCC_CR_PLLON; 594 | 595 | /* Wait till PLL is ready */ 596 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 597 | { 598 | } 599 | 600 | /* Select PLL as system clock source */ 601 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 602 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 603 | 604 | /* Wait till PLL is used as system clock source */ 605 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 606 | { 607 | } 608 | } 609 | else 610 | { /* If HSE fails to start-up, the application will have wrong clock 611 | configuration. User can add here some code to deal with this error */ 612 | } 613 | } 614 | #elif defined SYSCLK_FREQ_36MHz 615 | /** 616 | * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 617 | * and PCLK1 prescalers. 618 | * @note This function should be used only after reset. 619 | * @param None 620 | * @retval None 621 | */ 622 | static void SetSysClockTo36(void) 623 | { 624 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 625 | 626 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 627 | /* Enable HSE */ 628 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 629 | 630 | /* Wait till HSE is ready and if Time out is reached exit */ 631 | do 632 | { 633 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 634 | StartUpCounter++; 635 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 636 | 637 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 638 | { 639 | HSEStatus = (uint32_t)0x01; 640 | } 641 | else 642 | { 643 | HSEStatus = (uint32_t)0x00; 644 | } 645 | 646 | if (HSEStatus == (uint32_t)0x01) 647 | { 648 | /* Enable Prefetch Buffer */ 649 | FLASH->ACR |= FLASH_ACR_PRFTBE; 650 | 651 | /* Flash 1 wait state */ 652 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 653 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 654 | 655 | /* HCLK = SYSCLK */ 656 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 657 | 658 | /* PCLK2 = HCLK */ 659 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 660 | 661 | /* PCLK1 = HCLK */ 662 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 663 | 664 | #ifdef STM32F10X_CL 665 | /* Configure PLLs ------------------------------------------------------*/ 666 | 667 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ 668 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 669 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 670 | RCC_CFGR_PLLMULL9); 671 | 672 | /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 673 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ 674 | 675 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 676 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 677 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 678 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); 679 | 680 | /* Enable PLL2 */ 681 | RCC->CR |= RCC_CR_PLL2ON; 682 | /* Wait till PLL2 is ready */ 683 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 684 | { 685 | } 686 | 687 | #else 688 | /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */ 689 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 690 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9); 691 | #endif /* STM32F10X_CL */ 692 | 693 | /* Enable PLL */ 694 | RCC->CR |= RCC_CR_PLLON; 695 | 696 | /* Wait till PLL is ready */ 697 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 698 | { 699 | } 700 | 701 | /* Select PLL as system clock source */ 702 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 703 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 704 | 705 | /* Wait till PLL is used as system clock source */ 706 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 707 | { 708 | } 709 | } 710 | else 711 | { /* If HSE fails to start-up, the application will have wrong clock 712 | configuration. User can add here some code to deal with this error */ 713 | } 714 | } 715 | #elif defined SYSCLK_FREQ_48MHz 716 | /** 717 | * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 718 | * and PCLK1 prescalers. 719 | * @note This function should be used only after reset. 720 | * @param None 721 | * @retval None 722 | */ 723 | static void SetSysClockTo48(void) 724 | { 725 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 726 | 727 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 728 | /* Enable HSE */ 729 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 730 | 731 | /* Wait till HSE is ready and if Time out is reached exit */ 732 | do 733 | { 734 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 735 | StartUpCounter++; 736 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 737 | 738 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 739 | { 740 | HSEStatus = (uint32_t)0x01; 741 | } 742 | else 743 | { 744 | HSEStatus = (uint32_t)0x00; 745 | } 746 | 747 | if (HSEStatus == (uint32_t)0x01) 748 | { 749 | /* Enable Prefetch Buffer */ 750 | FLASH->ACR |= FLASH_ACR_PRFTBE; 751 | 752 | /* Flash 1 wait state */ 753 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 754 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 755 | 756 | /* HCLK = SYSCLK */ 757 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 758 | 759 | /* PCLK2 = HCLK */ 760 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 761 | 762 | /* PCLK1 = HCLK */ 763 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 764 | 765 | #ifdef STM32F10X_CL 766 | /* Configure PLLs ------------------------------------------------------*/ 767 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 768 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 769 | 770 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 771 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 772 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 773 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 774 | 775 | /* Enable PLL2 */ 776 | RCC->CR |= RCC_CR_PLL2ON; 777 | /* Wait till PLL2 is ready */ 778 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 779 | { 780 | } 781 | 782 | 783 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ 784 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 785 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 786 | RCC_CFGR_PLLMULL6); 787 | #else 788 | /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ 789 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 790 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); 791 | #endif /* STM32F10X_CL */ 792 | 793 | /* Enable PLL */ 794 | RCC->CR |= RCC_CR_PLLON; 795 | 796 | /* Wait till PLL is ready */ 797 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 798 | { 799 | } 800 | 801 | /* Select PLL as system clock source */ 802 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 803 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 804 | 805 | /* Wait till PLL is used as system clock source */ 806 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 807 | { 808 | } 809 | } 810 | else 811 | { /* If HSE fails to start-up, the application will have wrong clock 812 | configuration. User can add here some code to deal with this error */ 813 | } 814 | } 815 | 816 | #elif defined SYSCLK_FREQ_56MHz 817 | /** 818 | * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 819 | * and PCLK1 prescalers. 820 | * @note This function should be used only after reset. 821 | * @param None 822 | * @retval None 823 | */ 824 | static void SetSysClockTo56(void) 825 | { 826 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 827 | 828 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 829 | /* Enable HSE */ 830 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 831 | 832 | /* Wait till HSE is ready and if Time out is reached exit */ 833 | do 834 | { 835 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 836 | StartUpCounter++; 837 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 838 | 839 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 840 | { 841 | HSEStatus = (uint32_t)0x01; 842 | } 843 | else 844 | { 845 | HSEStatus = (uint32_t)0x00; 846 | } 847 | 848 | if (HSEStatus == (uint32_t)0x01) 849 | { 850 | /* Enable Prefetch Buffer */ 851 | FLASH->ACR |= FLASH_ACR_PRFTBE; 852 | 853 | /* Flash 2 wait state */ 854 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 855 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 856 | 857 | /* HCLK = SYSCLK */ 858 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 859 | 860 | /* PCLK2 = HCLK */ 861 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 862 | 863 | /* PCLK1 = HCLK */ 864 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 865 | 866 | #ifdef STM32F10X_CL 867 | /* Configure PLLs ------------------------------------------------------*/ 868 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 869 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 870 | 871 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 872 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 873 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 874 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 875 | 876 | /* Enable PLL2 */ 877 | RCC->CR |= RCC_CR_PLL2ON; 878 | /* Wait till PLL2 is ready */ 879 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 880 | { 881 | } 882 | 883 | 884 | /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ 885 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 886 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 887 | RCC_CFGR_PLLMULL7); 888 | #else 889 | /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ 890 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 891 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7); 892 | 893 | #endif /* STM32F10X_CL */ 894 | 895 | /* Enable PLL */ 896 | RCC->CR |= RCC_CR_PLLON; 897 | 898 | /* Wait till PLL is ready */ 899 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 900 | { 901 | } 902 | 903 | /* Select PLL as system clock source */ 904 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 905 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 906 | 907 | /* Wait till PLL is used as system clock source */ 908 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 909 | { 910 | } 911 | } 912 | else 913 | { /* If HSE fails to start-up, the application will have wrong clock 914 | configuration. User can add here some code to deal with this error */ 915 | } 916 | } 917 | 918 | #elif defined SYSCLK_FREQ_72MHz 919 | /** 920 | * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 921 | * and PCLK1 prescalers. 922 | * @note This function should be used only after reset. 923 | * @param None 924 | * @retval None 925 | */ 926 | static void SetSysClockTo72(void) 927 | { 928 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 929 | 930 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 931 | /* Enable HSE */ 932 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 933 | 934 | /* Wait till HSE is ready and if Time out is reached exit */ 935 | do 936 | { 937 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 938 | StartUpCounter++; 939 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 940 | 941 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 942 | { 943 | HSEStatus = (uint32_t)0x01; 944 | } 945 | else 946 | { 947 | HSEStatus = (uint32_t)0x00; 948 | } 949 | 950 | if (HSEStatus == (uint32_t)0x01) 951 | { 952 | /* Enable Prefetch Buffer */ 953 | FLASH->ACR |= FLASH_ACR_PRFTBE; 954 | 955 | /* Flash 2 wait state */ 956 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 957 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 958 | 959 | 960 | /* HCLK = SYSCLK */ 961 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 962 | 963 | /* PCLK2 = HCLK */ 964 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 965 | 966 | /* PCLK1 = HCLK */ 967 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 968 | 969 | #ifdef STM32F10X_CL 970 | /* Configure PLLs ------------------------------------------------------*/ 971 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 972 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 973 | 974 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 975 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 976 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 977 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 978 | 979 | /* Enable PLL2 */ 980 | RCC->CR |= RCC_CR_PLL2ON; 981 | /* Wait till PLL2 is ready */ 982 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 983 | { 984 | } 985 | 986 | 987 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 988 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 989 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 990 | RCC_CFGR_PLLMULL9); 991 | #else 992 | /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ 993 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 994 | RCC_CFGR_PLLMULL)); 995 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 996 | #endif /* STM32F10X_CL */ 997 | 998 | /* Enable PLL */ 999 | RCC->CR |= RCC_CR_PLLON; 1000 | 1001 | /* Wait till PLL is ready */ 1002 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 1003 | { 1004 | } 1005 | 1006 | /* Select PLL as system clock source */ 1007 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 1008 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 1009 | 1010 | /* Wait till PLL is used as system clock source */ 1011 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 1012 | { 1013 | } 1014 | } 1015 | else 1016 | { /* If HSE fails to start-up, the application will have wrong clock 1017 | configuration. User can add here some code to deal with this error */ 1018 | } 1019 | } 1020 | #endif 1021 | 1022 | /** 1023 | * @} 1024 | */ 1025 | 1026 | /** 1027 | * @} 1028 | */ 1029 | 1030 | /** 1031 | * @} 1032 | */ 1033 | /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ 1034 | --------------------------------------------------------------------------------