Mercurial > ~darius > hgwebdir.cgi > stm32temp
comparison delay.c @ 40:a38003b97de6
Use debug cycle counter to handle delays.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Mon, 01 Apr 2013 20:06:03 +1030 |
parents | 891841f5f785 |
children | cecb0506f4b8 |
comparison
equal
deleted
inserted
replaced
39:969bb070b181 | 40:a38003b97de6 |
---|---|
1 #include <assert.h> | |
1 #include <stdint.h> | 2 #include <stdint.h> |
2 #include "stm32f10x.h" | 3 #include "stm32f10x.h" |
3 #include "delay.h" | 4 #include "delay.h" |
4 | 5 |
5 /* Sleep for nCount usec | 6 /* Sleep for nCount usec |
6 * TDS1012 on 2.5usec/div shows... | |
7 * 30usec = 29.60usec | |
8 * 60usec = 59.20usec | |
9 * | |
10 * XXX: not sure disable IRQ stuff is working as I see occasional (small) extra delays | |
11 */ | 7 */ |
12 void | 8 void |
13 delay(uint32_t nCount) { | 9 delay(uint32_t nCount) { |
10 uint32_t dly, cnt, clk_per_usec, max_dly; | |
11 volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xe0001004; | |
12 | |
14 __disable_irq(); | 13 __disable_irq(); |
15 for(; nCount != 0; nCount--) { | 14 |
16 #ifdef SYSCLK_FREQ_72MHz | 15 #ifdef SYSCLK_FREQ_72MHz |
17 __asm__("nop"); | 16 clk_per_usec = 72; |
18 __asm__("nop"); | 17 max_dly = (1<<31) / clk_per_usec; /* Really half the maximum (still ~30 seconds at 72MHz) */ |
19 __asm__("nop"); | |
20 __asm__("nop"); | |
21 __asm__("nop"); | |
22 __asm__("nop"); | |
23 __asm__("nop"); | |
24 __asm__("nop"); | |
25 | |
26 __asm__("nop"); | |
27 __asm__("nop"); | |
28 __asm__("nop"); | |
29 __asm__("nop"); | |
30 __asm__("nop"); | |
31 __asm__("nop"); | |
32 __asm__("nop"); | |
33 __asm__("nop"); | |
34 | |
35 __asm__("nop"); | |
36 __asm__("nop"); | |
37 __asm__("nop"); | |
38 __asm__("nop"); | |
39 __asm__("nop"); | |
40 __asm__("nop"); | |
41 __asm__("nop"); | |
42 __asm__("nop"); | |
43 | |
44 __asm__("nop"); | |
45 __asm__("nop"); | |
46 __asm__("nop"); | |
47 __asm__("nop"); | |
48 __asm__("nop"); | |
49 __asm__("nop"); | |
50 __asm__("nop"); | |
51 | |
52 __asm__("nop"); | |
53 __asm__("nop"); | |
54 __asm__("nop"); | |
55 __asm__("nop"); | |
56 __asm__("nop"); | |
57 __asm__("nop"); | |
58 __asm__("nop"); | |
59 __asm__("nop"); | |
60 | |
61 __asm__("nop"); | |
62 __asm__("nop"); | |
63 __asm__("nop"); | |
64 __asm__("nop"); | |
65 __asm__("nop"); | |
66 __asm__("nop"); | |
67 __asm__("nop"); | |
68 | |
69 __asm__("nop"); | |
70 __asm__("nop"); | |
71 __asm__("nop"); | |
72 __asm__("nop"); | |
73 __asm__("nop"); | |
74 __asm__("nop"); | |
75 __asm__("nop"); | |
76 __asm__("nop"); | |
77 #else | 18 #else |
78 #error Unknown clock frequency | 19 #error "Unknown clock frequency" |
79 #endif | 20 #endif |
80 } | 21 assert(nCount < max_dly); |
22 | |
23 cnt = *DWT_CYCCNT; /* Get current cycle count */ | |
24 dly = nCount * clk_per_usec; | |
25 dly += cnt; /* Compute cycle count to stop at */ | |
26 if (dly < cnt) | |
27 /* Stop count wrapped, wait until the counter wraps around */ | |
28 while (*DWT_CYCCNT > cnt) | |
29 ; | |
30 /* Wait until we get to the stop count */ | |
31 while (*DWT_CYCCNT < dly) | |
32 ; | |
33 | |
81 __enable_irq(); | 34 __enable_irq(); |
82 } | 35 } |
83 | 36 |