diff --git a/include/sta/debug/assert.hpp b/include/sta/debug/assert.hpp index f6e82a9..bd02810 100644 --- a/include/sta/debug/assert.hpp +++ b/include/sta/debug/assert.hpp @@ -3,9 +3,8 @@ * @brief Assertion handling. * * Configuration: - * * STA_ASSERT_FORCE: Ignore debug defines and always enable assertions - * * DEBUG: Enables assertions when defined - * * NDEBUG: Disables assertions when defined (overrides DEBUG) + * * STA_ASSERT_ENABLED: Enable assertions + * * STA_ASSERT_FORCE: Enable assertions. Still there for backwards compatibility. */ #ifndef STA_CORE_ASSERT_HPP #define STA_CORE_ASSERT_HPP @@ -24,18 +23,10 @@ #include -// Determine if module should be enabled -// Condition: -// STA_ASSERT_FORCE is defined -// or -// DEBUG is defined but not NDEBUG +// Keep STA_ASSERT_FORCE for backwards comapatibility. #ifdef STA_ASSERT_FORCE -# define STA_ASSERT_ENABLED -#else // !STA_ASSERT_FORCE -# if defined(DEBUG) && !defined(NDEBUG) -# define STA_ASSERT_ENABLED -# endif // DEBUG && !NDEBUG -#endif // !STA_ASSERT_FORCE +# define STA_ASSERT_ENABLED +#endif // STA_ASSERT_FORCE #if defined(STA_ASSERT_ENABLED) || defined(DOXYGEN) diff --git a/include/sta/debug/profile.hpp b/include/sta/debug/profile.hpp index 051f7ef..f256ac5 100644 --- a/include/sta/debug/profile.hpp +++ b/include/sta/debug/profile.hpp @@ -9,7 +9,16 @@ #define STA_DEBUGGING_PROFILING_HPP #include -#ifdef STA_DEBUGGING_ENABLED + +#ifdef STA_PROFILING_ENABLED + +#ifndef STA_DEBUGGING_ENABLED +# error "Debugging has to be enabled in order to use profiling." +#endif // STA_DEBUGGING_ENABLED + +#ifndef STA_STM32_DELAY_US_TIM +# error "A microsecond timer has to be defined in order to use profiling." +#endif // STA_STM32_DELAY_US_TIM namespace sta { @@ -29,8 +38,10 @@ namespace sta */ #define STA_TIME_IT(name) sta::Profiler profiler(name); -#endif // STA_DEBUGGING_ENABLED +#else #define STA_TIME_IT(name) ((void)0) +#endif // // STA_PROFILING_ENABLED + #endif // STA_DEBUGGING_PROFILING_HPP diff --git a/include/sta/devices/stm32/clocks.hpp b/include/sta/devices/stm32/clocks.hpp index cd2ac38..bb1be59 100644 --- a/include/sta/devices/stm32/clocks.hpp +++ b/include/sta/devices/stm32/clocks.hpp @@ -39,7 +39,7 @@ namespace sta * * @param n Index of peripheral clock */ -#define STA_STM32_GET_PCLK_FREQ_FN(n) HAL_RCC_GetPCLK ## n ## Freq +#define STA_STM32_GET_PCLK_FREQ_FN(n) HAL_RCC_GetPCLK ## n ## Freq /** * @brief Internal helper for macro expansion. @@ -47,7 +47,31 @@ namespace sta * @param n PCLK index * @return Function returning PCLK frequency */ -#define _STA_STM32_GET_PCLK_FREQ_FN(n) STA_STM32_GET_PCLK_FREQ_FN(n) +#define _STA_STM32_GET_PCLK_FREQ_FN(n) STA_STM32_GET_PCLK_FREQ_FN(n) + +/** + * @brief Get the PCLK frequency. + * + * @param n PCLK index + * @return The PCLK frequency + */ +#define _STA_STM32_GET_PCLK_FREQ(n) STA_STM32_GET_PCLK_FREQ_FN(n)() + +/** + * @brief Gets the prescaler from APBx to APBx timer clocks. + * + * @param n PCLK index + * @return The prescaler from PCLK to TIM + */ +#define STA_STM32_GET_PCLK_TIM_PRESCALER(n) STA_STM32_TIM_PCLK_ ## n ## ## _PRESCALER + +/** + * @brief Internal helper for macro expansion. + * + * @param n PCLK index + * @return Function returning PCLK frequency + */ +#define _STA_STM32_GET_PCLK_TIM_PRESCALER(n) STA_STM32_GET_PCLK_TIM_PRESCALER(n) /** * @brief Map instance name to PCLK index. @@ -56,7 +80,7 @@ namespace sta * @param idx Instance index * @return PCLK index */ -#define _STA_STM32_PCLK_IDX_MAP(type, idx) STA_STM32_ ## type ## _ ## idx ## _PCLK_IDX +#define _STA_STM32_PCLK_IDX_MAP(type, idx) STA_STM32_ ## type ## _ ## idx ## _PCLK_IDX // Get HAL handle to PCLK index map macro /** @@ -65,44 +89,58 @@ namespace sta * @param handle HAL handle * @return PCLK index */ -#define _STA_STM32_HANDLE_PCLK_IDX_MAP(handle) STA_STM32_ ## handle ## _PCLK_IDX - +#define _STA_STM32_HANDLE_PCLK_IDX_MAP(handle) STA_STM32_ ## handle ## _PCLK_IDX /** - * @brief Get function returning frequency of PCLK used by TIM. + * @brief Get a function returning the frequency of PCLK used by TIM. * * @param n TIM index */ -#define STA_STM32_GET_TIM_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(TIM, n)) +#define STA_STM32_GET_TIM_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(TIM, n)) /** - * @brief Get function returning frequency of PCLK used by SPI interface. + * @brief Internal helper for macro expansion. + * + * @param n TIM index + */ +#define _STA_STM32_GET_TIM_PCLK_FREQ_FN(n) STA_STM32_GET_TIM_PCLK_FREQ_FN(n) + +/** + * @brief Get a function returning the frequency of PCLK used by SPI interface. * * @param n SPI interface index */ -#define STA_STM32_GET_SPI_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(SPI, n)) +#define STA_STM32_GET_SPI_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(SPI, n)) /** - * @brief Get function returning frequency of PCLK used by I2C interface. + * @brief Get a function returning the frequency of PCLK used by I2C interface. * * @param n I2C interface index */ -#define STA_STM32_GET_I2C_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(I2C, n)) +#define STA_STM32_GET_I2C_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(I2C, n)) /** - * @brief Get function returning frequency of PCLK used by USART interface. + * @brief Get a function returning the frequency of PCLK used by USART interface. * * @param n USART interface index */ -#define STA_STM32_GET_USART_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(USART, n)) +#define STA_STM32_GET_USART_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(USART, n)) /** - * @brief Get function returning frequency of PCLK used by HAL instance. + * @brief Get a function returning the frequency of PCLK used by HAL instance. * * @param handle Instance handle */ -#define STA_STM32_GET_HANDLE_PCLK_FREQ_FN(handle) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_HANDLE_PCLK_IDX_MAP(handle)) +#define STA_STM32_GET_HANDLE_PCLK_FREQ_FN(handle) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_HANDLE_PCLK_IDX_MAP(handle)) + +/** + * @brief Get the PCLK to timer prescaler for TIM given by the handle. + * + * @param handle TIM handle + * @return PCLK-TIM prescaler + */ +#define STA_STM32_GET_HANDLE_PCLK_TIM_PRESCALER(handle) _STA_STM32_GET_PCLK_TIM_PRESCALER(_STA_STM32_HANDLE_PCLK_IDX_MAP(handle)) /** @} */ diff --git a/include/sta/devices/stm32/mcu/STM32F411xE.hpp b/include/sta/devices/stm32/mcu/STM32F411xE.hpp index ee91c61..56608f5 100644 --- a/include/sta/devices/stm32/mcu/STM32F411xE.hpp +++ b/include/sta/devices/stm32/mcu/STM32F411xE.hpp @@ -63,8 +63,13 @@ #define STA_STM32_USART_2_PCLK_IDX 1 /**< USART2 to PCLK index 1 */ #define STA_STM32_USART_6_PCLK_IDX 2 /**< USART6 to PCLK index 2 */ +// prescaler from APBx to APBx timer clocks +#define STA_STM32_TIM_PCLK_1_PRESCALER 2 /**< PCLK1 has prescaler of 2 */ +#define STA_STM32_TIM_PCLK_2_PRESCALER 1 /**< PCLK2 has prescaler of 1 */ + // HAL handle mappings +// // TIM to PCLK #define STA_STM32_htim1_PCLK_IDX STA_STM32_TIM_1_PCLK_IDX /**< HAL TIM1 to PCLK index */ diff --git a/src/devices/stm32/delay.cpp b/src/devices/stm32/delay.cpp index 6475b51..3e754d5 100644 --- a/src/devices/stm32/delay.cpp +++ b/src/devices/stm32/delay.cpp @@ -51,7 +51,7 @@ namespace sta } // Calculate TIM clock frequency - uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)(); + uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)() * STA_STM32_GET_HANDLE_PCLK_TIM_PRESCALER(STA_STM32_DELAY_US_TIM); // Calculate update frequency based on prescaler value uint32_t prescaler = (STA_STM32_DELAY_US_TIM.Init.Prescaler) ? STA_STM32_DELAY_US_TIM.Init.Prescaler : 1; @@ -68,33 +68,22 @@ namespace sta // Check if the specified timer is usable for microsecond delays. STA_ASSERT(isValidDelayUsTIM()); - // Use millisecond delays for us > 1000 and use microseconds delay for the remainder. - delayMs(us / 1000); - us = us % 1000; + // Save the current value of the counter. + uint32_t current = __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM); - // __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); + // Set the timer counter to zero to avoid overflows during delay- + __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); - uint32_t startTime = __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM); + // Wait for the desired microseconds. + while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul); - // Check if an overflow is expected during the delay time. - if (startTime < __HAL_TIM_GET_AUTORELOAD(&STA_STM32_DELAY_US_TIM) - us * gDelayUsMul) - { - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < startTime + us * gDelayUsMul); - } - else - { - uint32_t overflowTime = __HAL_TIM_GET_AUTORELOAD(&STA_STM32_DELAY_US_TIM) - startTime; - // Wait until the overflow happens - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) > startTime); - - // Wait the remaining time after the overflow. - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul - overflowTime); - } + // Set the timer counter to the previous value and add the waited duration to it. + // This avoids collisions with code relying on timeUs measurements. + __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, current + us * gDelayUsMul); } } // namespace sta #endif // STA_STM32_DELAY_US_TIM - #endif // STA_PLATFORM_STM32 diff --git a/src/devices/stm32/time.cpp b/src/devices/stm32/time.cpp index 3cc7df5..97d5a1c 100644 --- a/src/devices/stm32/time.cpp +++ b/src/devices/stm32/time.cpp @@ -11,6 +11,7 @@ #ifdef STA_PLATFORM_STM32 #include +#include namespace sta { diff --git a/src/time.cpp b/src/time.cpp index eeeba78..6e00ccf 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -14,12 +14,16 @@ namespace sta uint32_t timeMs() { STA_NOT_IMPLEMENTED(); + + return 0; } STA_WEAK uint32_t timeUs() { STA_NOT_IMPLEMENTED(); + + return 0; } } // namespace sta