#include #ifdef STA_PLATFORM_STM32 #include #include #include #include namespace sta { void delayMs(uint32_t ms) { HAL_Delay(ms); } } // namespace sta #ifdef STA_STM32_DELAY_US_TIM #ifndef HAL_TIM_MODULE_ENABLED # error "STM32 HAL TIM module not enabled!" #endif // HAL_TIM_MODULE_ENABLED #include namespace sta { uint32_t gDelayUsMul = 1; bool isValidDelayUsTIM() { // Get PCLK multiplier for TIM clock uint32_t pclkMul = 1; switch (STA_STM32_DELAY_US_TIM.Init.ClockDivision) { case TIM_CLOCKDIVISION_DIV1: pclkMul = 1; break; case TIM_CLOCKDIVISION_DIV2: pclkMul = 2; break; case TIM_CLOCKDIVISION_DIV4: pclkMul = 4; break; default: STA_ASSERT(false); STA_UNREACHABLE(); } // Calculate TIM clock frequency 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; uint32_t updateFreq = clkFreq / prescaler; gDelayUsMul = updateFreq / 1000000; // TIM must have at least microsecond precision (>= 1 MHz frequency) return (updateFreq >= 1000000); } void delayUs(uint32_t us) { // Check if the specified timer is usable for microsecond delays. STA_ASSERT(isValidDelayUsTIM()); // Save the current value of the counter. uint32_t current = __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM); // Set the timer counter to zero to avoid overflows during delay- __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); // Wait for the desired microseconds. while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul); // 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