#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); } } }