Mercurial > ~darius > hgwebdir.cgi > stm32temp
changeset 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 | 969bb070b181 |
children | 2db4bb90cfca |
files | delay.c hw.c main.c |
diffstat | 3 files changed, 36 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- a/delay.c Mon Apr 01 19:45:38 2013 +1030 +++ b/delay.c Mon Apr 01 20:06:03 2013 +1030 @@ -1,83 +1,36 @@ +#include <assert.h> #include <stdint.h> #include "stm32f10x.h" #include "delay.h" /* Sleep for nCount usec - * TDS1012 on 2.5usec/div shows... - * 30usec = 29.60usec - * 60usec = 59.20usec - * - * XXX: not sure disable IRQ stuff is working as I see occasional (small) extra delays */ void delay(uint32_t nCount) { - __disable_irq(); - for(; nCount != 0; nCount--) { -#ifdef SYSCLK_FREQ_72MHz - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); + uint32_t dly, cnt, clk_per_usec, max_dly; + volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xe0001004; - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); + __disable_irq(); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); - __asm__("nop"); +#ifdef SYSCLK_FREQ_72MHz + clk_per_usec = 72; + max_dly = (1<<31) / clk_per_usec; /* Really half the maximum (still ~30 seconds at 72MHz) */ #else -#error Unknown clock frequency +#error "Unknown clock frequency" #endif - } + assert(nCount < max_dly); + + cnt = *DWT_CYCCNT; /* Get current cycle count */ + dly = nCount * clk_per_usec; + dly += cnt; /* Compute cycle count to stop at */ + if (dly < cnt) + /* Stop count wrapped, wait until the counter wraps around */ + while (*DWT_CYCCNT > cnt) + ; + /* Wait until we get to the stop count */ + while (*DWT_CYCCNT < dly) + ; + __enable_irq(); }
--- a/hw.c Mon Apr 01 19:45:38 2013 +1030 +++ b/hw.c Mon Apr 01 20:06:03 2013 +1030 @@ -363,4 +363,12 @@ } #endif + + // From http://forums.arm.com/index.php?/topic/13949-cycle-count-in-cortex-m3/ + // via http://stackoverflow.com/questions/11530593/cycle-counter-on-arm-cortex-m4-or-m3/11530829#11530829 + volatile uint32_t *DWT_CONTROL = (uint32_t *)0xe0001000; + volatile uint32_t *SCB_DEMCR = (uint32_t *)0xe000edfc; + + *SCB_DEMCR = *SCB_DEMCR | 0x01000000; + *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter }
--- a/main.c Mon Apr 01 19:45:38 2013 +1030 +++ b/main.c Mon Apr 01 20:06:03 2013 +1030 @@ -350,25 +350,14 @@ } else if (!strcmp("assert", argv[0])) { assert(0 == 1); } else if (!strcmp("cyc", argv[0])) { - // From http://forums.arm.com/index.php?/topic/13949-cycle-count-in-cortex-m3/ - // via http://stackoverflow.com/questions/11530593/cycle-counter-on-arm-cortex-m4-or-m3/11530829#11530829 - uint32_t c1, c2, c; - volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xe0001004; - volatile uint32_t *DWT_CONTROL = (uint32_t *)0xe0001000; - volatile uint32_t *SCB_DEMCR = (uint32_t *)0xe000edfc; + if (argc != 2) { + fputs("Incorrect number of arguments\r\n", stdout); + goto out; + } + + delay(atoi(argv[1])); - *SCB_DEMCR = *SCB_DEMCR | 0x01000000; - *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter - c1 = *DWT_CYCCNT; - for (volatile int i = 0; i < 1000; i++) - ; - c2 = *DWT_CYCCNT; - if (c2 > c1) - c = c2 - c1; - else { - c = (0xffffffff - c1) + c2; - } - printf("Took %ld cycles\r\n", c); + fputs("Done\r\n", stdout); } else if (!strcmp("zz", argv[0])) { NVIC_SystemReset(); } else {