mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/sta-core.git
synced 2025-06-12 01:25:59 +00:00
90 lines
2.2 KiB
C++
90 lines
2.2 KiB
C++
#include <sta/devices/stm32/delay.hpp>
|
|
|
|
#ifdef STA_PLATFORM_STM32
|
|
|
|
#include <sta/devices/stm32/hal.hpp>
|
|
#include <sta/devices/stm32/clocks.hpp>
|
|
|
|
#include <sta/debug/assert.hpp>
|
|
#include <sta/lang.hpp>
|
|
|
|
|
|
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 <tim.h>
|
|
|
|
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
|