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.

115 lines
3.1 KiB

1 year ago
  1. #include "zusdelay.hpp"
  2. extern "C" {
  3. static TIM_HandleTypeDef* m_usdleaytim;
  4. static HAL_StatusTypeDef _HAL_TIM_Base_Start(TIM_HandleTypeDef* htim) __attribute__((optimize("O2")));
  5. static HAL_StatusTypeDef _HAL_TIM_Base_Stop(TIM_HandleTypeDef* htim) __attribute__((optimize("O2")));
  6. static HAL_StatusTypeDef _HAL_TIM_Base_Start(TIM_HandleTypeDef* htim) {
  7. uint32_t tmpsmcr;
  8. /* Check the TIM state */
  9. if (htim->State != HAL_TIM_STATE_READY) {
  10. return HAL_ERROR;
  11. }
  12. htim->State = HAL_TIM_STATE_BUSY;
  13. if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) {
  14. tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
  15. if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) {
  16. __HAL_TIM_ENABLE(htim);
  17. }
  18. } else {
  19. __HAL_TIM_ENABLE(htim);
  20. }
  21. return HAL_OK;
  22. }
  23. static HAL_StatusTypeDef _HAL_TIM_Base_Stop(TIM_HandleTypeDef* htim) {
  24. /* Disable the Peripheral */
  25. __HAL_TIM_DISABLE(htim);
  26. /* Set the TIM state */
  27. htim->State = HAL_TIM_STATE_READY;
  28. /* Return function status */
  29. return HAL_OK;
  30. }
  31. static uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim) {
  32. uint32_t timClkFreq = 0;
  33. #if 0
  34. uint32_t pclk1Freq = HAL_RCC_GetPCLK1Freq();
  35. uint32_t pclk2Freq = HAL_RCC_GetPCLK2Freq();
  36. uint32_t sysClkFreq = HAL_RCC_GetSysClockFreq();
  37. #endif
  38. uint32_t pFLatency;
  39. RCC_ClkInitTypeDef clkconfig;
  40. HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
  41. bool isAPB2 = false;
  42. #ifdef TIM1
  43. if (tim->Instance == TIM1) isAPB2 = true;
  44. #endif
  45. #ifdef TIM8
  46. if (tim->Instance == TIM8) isAPB2 = true;
  47. #endif
  48. #ifdef TIM9
  49. if (tim->Instance == TIM9) isAPB2 = true;
  50. #endif
  51. #ifdef TIM10
  52. if (tim->Instance == TIM10) isAPB2 = true;
  53. #endif
  54. #ifdef TIM11
  55. if (tim->Instance == TIM11) isAPB2 = true;
  56. #endif
  57. if (isAPB2) {
  58. if (clkconfig.APB2CLKDivider == RCC_HCLK_DIV1) {
  59. timClkFreq = HAL_RCC_GetPCLK2Freq();
  60. } else {
  61. timClkFreq = 2 * HAL_RCC_GetPCLK2Freq();
  62. }
  63. } else {
  64. if (clkconfig.APB1CLKDivider == RCC_HCLK_DIV1) {
  65. timClkFreq = HAL_RCC_GetPCLK1Freq();
  66. } else {
  67. timClkFreq = 2 * HAL_RCC_GetPCLK1Freq();
  68. }
  69. }
  70. return timClkFreq;
  71. }
  72. uint32_t zusdelay_init(TIM_HandleTypeDef* tim) {
  73. m_usdleaytim = tim;
  74. uint32_t freq = chip_get_timer_clock_sorce_freq(tim);
  75. uint32_t prescaler = freq / 1000000 - 1; // 1us
  76. uint32_t autoreload = 65535;
  77. HAL_TIM_Base_DeInit(tim);
  78. tim->Init.Prescaler = prescaler;
  79. tim->Init.CounterMode = TIM_COUNTERMODE_UP;
  80. tim->Init.Period = autoreload;
  81. tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  82. HAL_TIM_Base_Init(tim);
  83. return 0;
  84. }
  85. static inline void __zchip_clock_early_delayus(uint32_t n) {
  86. volatile uint32_t counter = 0;
  87. __HAL_TIM_SET_COUNTER(m_usdleaytim, 0);
  88. _HAL_TIM_Base_Start(m_usdleaytim);
  89. while (counter < n) {
  90. counter = __HAL_TIM_GET_COUNTER(m_usdleaytim);
  91. }
  92. _HAL_TIM_Base_Stop(m_usdleaytim);
  93. }
  94. void zusdelay_early_delayus(uint32_t _us) {
  95. uint32_t us = _us % 1000;
  96. uint32_t ms = _us / 1000;
  97. if (us > 0) {
  98. __zchip_clock_early_delayus(us);
  99. }
  100. for (uint32_t i = 0; i < ms; i++) {
  101. __zchip_clock_early_delayus(1000);
  102. }
  103. }
  104. }