From 267cd61c1914bc1d71f47f020d391c2d3ac1c224 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 11 Feb 2012 08:57:22 +0000 Subject: Fixed bug 3485500. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3950 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 | 2 + 8 files changed, 112 insertions(+), 68 deletions(-) diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 3e96376a2..ff0c489a7 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -73,6 +73,7 @@ /* Driver macros. */ /*===========================================================================*/ +#if HAL_IMPLEMENTS_COUNTERS || defined(__DOXYGEN__) /** * @name Time conversion utilities for the realtime counter * @{ @@ -123,11 +124,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() @@ -135,75 +137,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. */ @@ -213,6 +155,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 bc2b8b0f2..53bafb1b5 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.c +++ b/os/hal/platforms/STM32F1xx/hal_lld.c @@ -105,7 +105,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 1caa61d89..75d217c69 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.c +++ b/os/hal/platforms/STM32F2xx/hal_lld.c @@ -107,7 +107,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 e7c09cc06..44de90602 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.c +++ b/os/hal/platforms/STM32F4xx/hal_lld.c @@ -107,7 +107,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 df666815b..1d28df62b 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.c +++ b/os/hal/platforms/STM32L1xx/hal_lld.c @@ -104,7 +104,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 3cf15226a..dad579ad0 100644 --- a/os/hal/src/hal.c +++ b/os/hal/src/hal.c @@ -120,4 +120,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 ec86d5ad1..e4b6757a0 100644 --- a/os/ports/common/ARMCMx/nvic.h +++ b/os/ports/common/ARMCMx/nvic.h @@ -228,6 +228,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 ed5374e95..ccaa7d81f 100644 --- a/readme.txt +++ b/readme.txt @@ -79,6 +79,8 @@ ***************************************************************************** *** 2.5.0 *** +- FIX: Fixed Realtime counter initialization in STM32 HALs (bug 3485500) + (backported to 2.4.1). - FIX: Fixed PPC port broken when CH_DBG_SYSTEM_STATE_CHECK is activated (bug 3485667)(backported to 2.4.1). - FIX: Fixed missing PLL3 check in STM32F107 HAL (bug 3485278)(backported -- cgit v1.2.3