You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.1 KiB
116 lines
3.1 KiB
#include "zusdelay.hpp"
|
|
extern "C" {
|
|
|
|
static TIM_HandleTypeDef* m_usdleaytim;
|
|
|
|
static HAL_StatusTypeDef _HAL_TIM_Base_Start(TIM_HandleTypeDef* htim) __attribute__((optimize("O2")));
|
|
static HAL_StatusTypeDef _HAL_TIM_Base_Stop(TIM_HandleTypeDef* htim) __attribute__((optimize("O2")));
|
|
|
|
static HAL_StatusTypeDef _HAL_TIM_Base_Start(TIM_HandleTypeDef* htim) {
|
|
uint32_t tmpsmcr;
|
|
/* Check the TIM state */
|
|
if (htim->State != HAL_TIM_STATE_READY) {
|
|
return HAL_ERROR;
|
|
}
|
|
htim->State = HAL_TIM_STATE_BUSY;
|
|
if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) {
|
|
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
|
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) {
|
|
__HAL_TIM_ENABLE(htim);
|
|
}
|
|
} else {
|
|
__HAL_TIM_ENABLE(htim);
|
|
}
|
|
return HAL_OK;
|
|
}
|
|
|
|
static HAL_StatusTypeDef _HAL_TIM_Base_Stop(TIM_HandleTypeDef* htim) {
|
|
/* Disable the Peripheral */
|
|
__HAL_TIM_DISABLE(htim);
|
|
/* Set the TIM state */
|
|
htim->State = HAL_TIM_STATE_READY;
|
|
/* Return function status */
|
|
return HAL_OK;
|
|
}
|
|
|
|
static uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim) {
|
|
uint32_t timClkFreq = 0;
|
|
#if 0
|
|
uint32_t pclk1Freq = HAL_RCC_GetPCLK1Freq();
|
|
uint32_t pclk2Freq = HAL_RCC_GetPCLK2Freq();
|
|
uint32_t sysClkFreq = HAL_RCC_GetSysClockFreq();
|
|
#endif
|
|
|
|
uint32_t pFLatency;
|
|
RCC_ClkInitTypeDef clkconfig;
|
|
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
|
bool isAPB2 = false;
|
|
|
|
#ifdef TIM1
|
|
if (tim->Instance == TIM1) isAPB2 = true;
|
|
#endif
|
|
#ifdef TIM8
|
|
if (tim->Instance == TIM8) isAPB2 = true;
|
|
#endif
|
|
#ifdef TIM9
|
|
if (tim->Instance == TIM9) isAPB2 = true;
|
|
#endif
|
|
#ifdef TIM10
|
|
if (tim->Instance == TIM10) isAPB2 = true;
|
|
#endif
|
|
#ifdef TIM11
|
|
if (tim->Instance == TIM11) isAPB2 = true;
|
|
#endif
|
|
if (isAPB2) {
|
|
if (clkconfig.APB2CLKDivider == RCC_HCLK_DIV1) {
|
|
timClkFreq = HAL_RCC_GetPCLK2Freq();
|
|
} else {
|
|
timClkFreq = 2 * HAL_RCC_GetPCLK2Freq();
|
|
}
|
|
} else {
|
|
if (clkconfig.APB1CLKDivider == RCC_HCLK_DIV1) {
|
|
timClkFreq = HAL_RCC_GetPCLK1Freq();
|
|
} else {
|
|
timClkFreq = 2 * HAL_RCC_GetPCLK1Freq();
|
|
}
|
|
}
|
|
return timClkFreq;
|
|
}
|
|
|
|
uint32_t zusdelay_init(TIM_HandleTypeDef* tim) {
|
|
m_usdleaytim = tim;
|
|
|
|
uint32_t freq = chip_get_timer_clock_sorce_freq(tim);
|
|
uint32_t prescaler = freq / 1000000 - 1; // 1us
|
|
uint32_t autoreload = 65535;
|
|
|
|
HAL_TIM_Base_DeInit(tim);
|
|
|
|
tim->Init.Prescaler = prescaler;
|
|
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
|
|
tim->Init.Period = autoreload;
|
|
tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
|
HAL_TIM_Base_Init(tim);
|
|
|
|
return 0;
|
|
}
|
|
static inline void __zchip_clock_early_delayus(uint32_t n) {
|
|
volatile uint32_t counter = 0;
|
|
__HAL_TIM_SET_COUNTER(m_usdleaytim, 0);
|
|
_HAL_TIM_Base_Start(m_usdleaytim);
|
|
while (counter < n) {
|
|
counter = __HAL_TIM_GET_COUNTER(m_usdleaytim);
|
|
}
|
|
_HAL_TIM_Base_Stop(m_usdleaytim);
|
|
}
|
|
void zusdelay_early_delayus(uint32_t _us) {
|
|
uint32_t us = _us % 1000;
|
|
uint32_t ms = _us / 1000;
|
|
if (us > 0) {
|
|
__zchip_clock_early_delayus(us);
|
|
}
|
|
for (uint32_t i = 0; i < ms; i++) {
|
|
__zchip_clock_early_delayus(1000);
|
|
}
|
|
}
|
|
}
|