├── .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 |
32 |
33 |
34 |
35 |
36 |
37 |
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 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
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 |
--------------------------------------------------------------------------------