1 /* 2 * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>. 3 * 4 * See file `LICENSE` for full details 5 */ 6 7 #ifndef DWT_INC_DWT_H_ 8 #define DWT_INC_DWT_H_ 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 /* init cycle counter */ 15 /* DWT (Data Watchpoint and Trace) registers, only exists on ARM Cortex with a DWT unit */ 16 /*!< DEMCR: Debug Exception and Monitor Control Register */ 17 /*!< TRCENA: Enable trace and debug block DEMCR (Debug Exception and Monitor Control Register) */ 18 /*!< DWT Cycle Counter register */ 19 /*!< CYCCNTENA bit in DWT_CONTROL register */ 20 static inline void cycle_counter_init(void) __attribute__((always_inline)); 21 static inline void cycle_counter_init(void) 22 { 23 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; /* enable DWT hardware */ 24 DWT->CYCCNT = 0; /* reset cycle counter */ 25 DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; /* start counting */ 26 } 27 28 /* reset cycle counter */ 29 /*!< DWT Cycle Counter register */ 30 static inline void cycle_counter_reset(void) __attribute__((always_inline)); 31 static inline void cycle_counter_reset(void) 32 { 33 DWT->CYCCNT = 0; 34 } 35 36 /* enable counting */ 37 /*!< CYCCNTENA bit in DWT_CONTROL register */ 38 static inline void cycle_counter_enable(void) __attribute__((always_inline)); 39 static inline void cycle_counter_enable(void) 40 { 41 DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 42 } 43 44 /* disable counting */ 45 /*!< CYCCNTENA bit in DWT_CONTROL register */ 46 static inline void cycle_counter_disable(void) __attribute__((always_inline)); 47 static inline void cycle_counter_disable(void) 48 { 49 DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; 50 } 51 52 /* read cycle counter */ 53 /*!< DWT Cycle Counter register */ 54 static inline uint32_t cycle_counter_get(void) __attribute__((always_inline)); 55 static inline uint32_t cycle_counter_get(void) 56 { 57 return (DWT->CYCCNT); 58 } 59 60 static inline uint32_t cycle_counter_get_time_us(void) __attribute__((always_inline)); 61 static inline uint32_t cycle_counter_get_time_us(void) 62 { 63 return (DWT->CYCCNT / (SystemCoreClock / 1000000)); 64 } 65 66 /* uint32_t cycle_counter = 0; 67 * uint32_t cycle_counter_time_us = 0; 68 * // PC8 (GPIO) 69 * HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET); // => ______ 70 * cycle_counter_init(); 71 * 72 * ... 73 * ... // => ______ 74 * // ___ 75 * HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET); // => __/ 76 * // or => HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8); 77 * cycle_counter_reset(); 78 * // ______ 79 * ... // => 80 * 81 * cycle_counter = cycle_counter_get(); 82 * cycle_counter_time_us = cycle_counter_get_time_us(); // __ 83 * HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET); // => \___ 84 * // or => HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8); 85 * 86 * // => ______ 87 * 88 * LOGGER_LOG("Cycles: %lu - Time %lu uS\r\n", cycle_counter, cycle_counter_time_us); 89 */ 90 91 #ifdef __cplusplus 92 } 93 #endif 94 95 #endif /* DWT_INC_DWT_H_ */
