Fixed bug 3485500.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3950 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2012-02-11 08:57:22 +00:00
parent 0921f80daa
commit 267cd61c19
8 changed files with 112 additions and 68 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 */
/** @} */

View File

@ -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.
*/

View File

@ -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