From 9385daa8cba6db644afc8661636ad9f4914fd894 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 11 Feb 2012 08:56:57 +0000 Subject: [PATCH] Fixed bug 3485500. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_2.4.x@3949 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal.h | 74 ++++------------------------ os/hal/platforms/STM32F1xx/hal_lld.c | 3 +- os/hal/platforms/STM32F2xx/hal_lld.c | 3 +- os/hal/platforms/STM32F4xx/hal_lld.c | 3 +- os/hal/platforms/STM32L1xx/hal_lld.c | 3 +- os/hal/src/hal.c | 71 ++++++++++++++++++++++++++ os/ports/common/ARMCMx/nvic.h | 21 ++++++++ readme.txt | 1 + 8 files changed, 111 insertions(+), 68 deletions(-) diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index a99cbaf66..734dca5ff 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -80,6 +80,7 @@ /* Driver macros. */ /*===========================================================================*/ +#if HAL_IMPLEMENTS_COUNTERS || defined(__DOXYGEN__) /** * @name Time conversion utilities for the realtime counter * @{ @@ -130,11 +131,12 @@ * @brief Returns the current value of the system free running counter. * @note This is an optional service that could not be implemented in * all HAL implementations. + * @note This function can be called from any context. * * @return The value of the system free running counter of * type halrtcnt_t. * - * @api + * @special */ #define halGetCounterValue() hal_lld_get_counter_value() @@ -142,75 +144,15 @@ * @brief Realtime counter frequency. * @note This is an optional service that could not be implemented in * all HAL implementations. + * @note This function can be called from any context. * * @return The realtime counter frequency of type halclock_t. * - * @api + * @special */ #define halGetCounterFrequency() hal_lld_get_counter_frequency() - -/** - * @brief Realtime window test. - * @details This function verifies if the current realtime counter value - * lies within the specified range or not. The test takes care - * of the realtime counter wrapping to zero on overflow. - * @note When start==end then the function returns always true because the - * whole time range is specified. - * - * @par Example 1 - * Example of a guarded loop using the realtime counter. The loop implements - * a timeout after one second. - * @code - * halrtcnt_t start = halGetCounterValue(); - * halrtcnt_t timeout = start + S2RTT(1); - * while (my_condition) { - * if (!halIsCounterWithin(start, timeout) - * return TIMEOUT; - * // Do something. - * } - * // Continue. - * @endcode - * - * @par Example 2 - * Example of a loop that lasts exactly 50 microseconds. - * @code - * halrtcnt_t start = halGetCounterValue(); - * halrtcnt_t timeout = start + US2RTT(50); - * while (halIsCounterWithin(start, timeout)) { - * // Do something. - * } - * // Continue. - * @endcode - * - * @param[in] start the start of the time window (inclusive) - * @param[in] end the end of the time window (non inclusive) - * @retval TRUE current time within the specified time window. - * @retval FALSE current time not within the specified time window. - * - * @api - */ -#define halIsCounterWithin(start, end) \ - (end > start ? (halGetCounterValue() >= start) && \ - (halGetCounterValue() < end) : \ - (halGetCounterValue() >= start) || \ - (halGetCounterValue() < end)) /** @} */ - -/** - * @brief Polled delay. - * @note The real delays is always few cycles in excess of the specified - * value. - * - * @param[in] ticks number of ticks - * - * @api - */ -#define halPolledDelay(ticks) { \ - halrtcnt_t start = halGetCounterValue(); \ - halrtcnt_t timeout = start + (ticks); \ - while (halIsCounterWithin(start, timeout)) \ - ; \ -} +#endif /* HAL_IMPLEMENTS_COUNTERS */ /*===========================================================================*/ /* External declarations. */ @@ -220,6 +162,10 @@ extern "C" { #endif void halInit(void); +#if HAL_IMPLEMENTS_COUNTERS + bool_t halIsCounterWithin(halrtcnt_t start, halrtcnt_t end); + void halPolledDelay(halrtcnt_t ticks); +#endif /* HAL_IMPLEMENTS_COUNTERS */ #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32F1xx/hal_lld.c b/os/hal/platforms/STM32F1xx/hal_lld.c index 3e8f2c10c..f14f2b98f 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.c +++ b/os/hal/platforms/STM32F1xx/hal_lld.c @@ -112,7 +112,8 @@ void hal_lld_init(void) { SysTick_CTRL_TICKINT_Msk; /* DWT cycle counter enable.*/ - DWT_CTRL |= DWT_CTRL_CYCCNTENA; + SCS_DEMCR |= SCS_DEMCR_TRCENA; + DWT_CTRL |= DWT_CTRL_CYCCNTENA; /* PWR and BD clocks enabled.*/ rccEnablePWRInterface(FALSE); diff --git a/os/hal/platforms/STM32F2xx/hal_lld.c b/os/hal/platforms/STM32F2xx/hal_lld.c index 286b5752b..966d81136 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.c +++ b/os/hal/platforms/STM32F2xx/hal_lld.c @@ -114,7 +114,8 @@ void hal_lld_init(void) { SysTick_CTRL_TICKINT_Msk; /* DWT cycle counter enable.*/ - DWT_CTRL |= DWT_CTRL_CYCCNTENA; + SCS_DEMCR |= SCS_DEMCR_TRCENA; + DWT_CTRL |= DWT_CTRL_CYCCNTENA; /* PWR clock enabled.*/ rccEnablePWRInterface(FALSE); diff --git a/os/hal/platforms/STM32F4xx/hal_lld.c b/os/hal/platforms/STM32F4xx/hal_lld.c index 123dd3295..3452ce9ff 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -114,7 +114,8 @@ void hal_lld_init(void) { SysTick_CTRL_TICKINT_Msk; /* DWT cycle counter enable.*/ - DWT_CTRL |= DWT_CTRL_CYCCNTENA; + SCS_DEMCR |= SCS_DEMCR_TRCENA; + DWT_CTRL |= DWT_CTRL_CYCCNTENA; /* PWR clock enabled.*/ rccEnablePWRInterface(FALSE); diff --git a/os/hal/platforms/STM32L1xx/hal_lld.c b/os/hal/platforms/STM32L1xx/hal_lld.c index 5bcfecd37..3686e1c6e 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.c +++ b/os/hal/platforms/STM32L1xx/hal_lld.c @@ -111,7 +111,8 @@ void hal_lld_init(void) { SysTick_CTRL_TICKINT_Msk; /* DWT cycle counter enable.*/ - DWT_CTRL |= DWT_CTRL_CYCCNTENA; + SCS_DEMCR |= SCS_DEMCR_TRCENA; + DWT_CTRL |= DWT_CTRL_CYCCNTENA; /* PWR clock enabled.*/ rccEnablePWRInterface(FALSE); diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c index 5d80be972..a46bdbb0d 100644 --- a/os/hal/src/hal.c +++ b/os/hal/src/hal.c @@ -127,4 +127,75 @@ void halInit(void) { boardInit(); } +#if HAL_IMPLEMENTS_COUNTERS || defined(__DOXYGEN__) +/** + * @brief Realtime window test. + * @details This function verifies if the current realtime counter value + * lies within the specified range or not. The test takes care + * of the realtime counter wrapping to zero on overflow. + * @note When start==end then the function returns always true because the + * whole time range is specified. + * @note This is an optional service that could not be implemented in + * all HAL implementations. + * @note This function can be called from any context. + * + * @par Example 1 + * Example of a guarded loop using the realtime counter. The loop implements + * a timeout after one second. + * @code + * halrtcnt_t start = halGetCounterValue(); + * halrtcnt_t timeout = start + S2RTT(1); + * while (my_condition) { + * if (!halIsCounterWithin(start, timeout) + * return TIMEOUT; + * // Do something. + * } + * // Continue. + * @endcode + * + * @par Example 2 + * Example of a loop that lasts exactly 50 microseconds. + * @code + * halrtcnt_t start = halGetCounterValue(); + * halrtcnt_t timeout = start + US2RTT(50); + * while (halIsCounterWithin(start, timeout)) { + * // Do something. + * } + * // Continue. + * @endcode + * + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval TRUE current time within the specified time window. + * @retval FALSE current time not within the specified time window. + * + * @special + */ +bool_t halIsCounterWithin(halrtcnt_t start, halrtcnt_t end) { + halrtcnt_t now = halGetCounterValue(); + + return end > start ? (now >= start) && (now < end) : + (now >= start) || (now < end); +} + +/** + * @brief Polled delay. + * @note The real delays is always few cycles in excess of the specified + * value. + * @note This is an optional service that could not be implemented in + * all HAL implementations. + * @note This function can be called from any context. + * + * @param[in] ticks number of ticks + * + * @special + */ +void halPolledDelay(halrtcnt_t ticks) { + halrtcnt_t start = halGetCounterValue(); + halrtcnt_t timeout = start + (ticks); + while (halIsCounterWithin(start, timeout)) + ; +} +#endif /* HAL_IMPLEMENTS_COUNTERS */ + /** @} */ diff --git a/os/ports/common/ARMCMx/nvic.h b/os/ports/common/ARMCMx/nvic.h index 779eac966..729f326a0 100644 --- a/os/ports/common/ARMCMx/nvic.h +++ b/os/ports/common/ARMCMx/nvic.h @@ -235,6 +235,27 @@ typedef struct { #define FPDSCR_FZ (0x1U << 24) #define FPDSCR_RMODE(n) ((n##U) << 22) +/** + * @brief Structure representing the SCS I/O space. + */ +typedef struct { + IOREG32 DHCSR; + IOREG32 DCRSR; + IOREG32 DCRDR; + IOREG32 DEMCR; +} CMx_SCS; + +/** + * @brief SCS peripheral base address. + */ +#define SCSBase ((CMx_SCS *)0xE000EDF0U) +#define SCS_DHCSR (SCSBase->DHCSR) +#define SCS_DCRSR (SCSBase->DCRSR) +#define SCS_DCRDR (SCSBase->DCRDR) +#define SCS_DEMCR (SCSBase->DEMCR) + +#define SCS_DEMCR_TRCENA (0x1U << 24) + /** * @brief Structure representing the DWT I/O space. */ diff --git a/readme.txt b/readme.txt index 052505788..596160227 100644 --- a/readme.txt +++ b/readme.txt @@ -79,6 +79,7 @@ ***************************************************************************** *** 2.4.1 *** +- FIX: Fixed Realtime counter initialization in STM32 HALs (bug 3485500). - FIX: Fixed PPC port broken when CH_DBG_SYSTEM_STATE_CHECK is activated (bug 3485667). - FIX: Fixed missing PLL3 check in STM32F107 HAL (bug 3485278).