PageRenderTime 116ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/external/mbed-os/targets/TARGET_STM/hal_tick_16b.c

https://github.com/adamgreen/gcc4mbed
C | 182 lines | 122 code | 25 blank | 35 comment | 17 complexity | 109dbf311c8398d47c174452de7b0d0e MD5 | raw file
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2006-2016 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "hal_tick.h"
  17. // A 16-bit timer is used
  18. #if TIM_MST_16BIT
  19. #define DEBUG_TICK 0 // Set to 1 to toggle a pin (see below which pin) at each tick
  20. extern TIM_HandleTypeDef TimMasterHandle;
  21. extern volatile uint32_t SlaveCounter;
  22. extern volatile uint32_t oc_int_part;
  23. extern volatile uint16_t oc_rem_part;
  24. extern volatile uint8_t tim_it_update;
  25. extern volatile uint32_t tim_it_counter;
  26. volatile uint32_t PreviousVal = 0;
  27. void us_ticker_irq_handler(void);
  28. void set_compare(uint16_t count);
  29. #if defined(TARGET_STM32F0)
  30. void timer_update_irq_handler(void) {
  31. #else
  32. void timer_irq_handler(void)
  33. {
  34. #endif
  35. uint16_t cnt_val = TIM_MST->CNT;
  36. TimMasterHandle.Instance = TIM_MST;
  37. // Clear Update interrupt flag
  38. if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
  39. if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_UPDATE) == SET) {
  40. __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_UPDATE);
  41. SlaveCounter++;
  42. tim_it_counter = cnt_val + (uint32_t)(SlaveCounter << 16);
  43. tim_it_update = 1;
  44. }
  45. }
  46. #if defined(TARGET_STM32F0)
  47. } // end timer_update_irq_handler function
  48. // Used for mbed timeout (channel 1) and HAL tick (channel 2)
  49. void timer_oc_irq_handler(void)
  50. {
  51. uint16_t cnt_val = TIM_MST->CNT;
  52. TimMasterHandle.Instance = TIM_MST;
  53. #endif
  54. // Channel 1 for mbed timeout
  55. if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
  56. if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) {
  57. __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
  58. if (oc_rem_part > 0) {
  59. set_compare(oc_rem_part); // Finish the remaining time left
  60. oc_rem_part = 0;
  61. } else {
  62. if (oc_int_part > 0) {
  63. set_compare(0xFFFF);
  64. oc_rem_part = cnt_val; // To finish the counter loop the next time
  65. oc_int_part--;
  66. } else {
  67. us_ticker_irq_handler();
  68. }
  69. }
  70. }
  71. }
  72. // Channel 2 for HAL tick
  73. if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC2) == SET) {
  74. if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC2) == SET) {
  75. __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC2);
  76. uint32_t val = __HAL_TIM_GetCounter(&TimMasterHandle);
  77. if ((val - PreviousVal) >= HAL_TICK_DELAY) {
  78. // Increment HAL variable
  79. HAL_IncTick();
  80. // Prepare next interrupt
  81. __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY);
  82. PreviousVal = val;
  83. #if DEBUG_TICK > 0
  84. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
  85. #endif
  86. }
  87. }
  88. }
  89. }
  90. // Reconfigure the HAL tick using a standard timer instead of systick.
  91. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
  92. {
  93. // Enable timer clock
  94. TIM_MST_RCC;
  95. // Reset timer
  96. TIM_MST_RESET_ON;
  97. TIM_MST_RESET_OFF;
  98. // Update the SystemCoreClock variable
  99. SystemCoreClockUpdate();
  100. // Configure time base
  101. TimMasterHandle.Instance = TIM_MST;
  102. TimMasterHandle.Init.Period = 0xFFFF;
  103. TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 us tick
  104. TimMasterHandle.Init.ClockDivision = 0;
  105. TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
  106. #ifdef TARGET_STM32F0
  107. TimMasterHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  108. #endif
  109. HAL_TIM_Base_Init(&TimMasterHandle);
  110. // Configure output compare channel 1 for mbed timeout (enabled later when used)
  111. HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
  112. // Configure output compare channel 2 for HAL tick
  113. HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2);
  114. PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle);
  115. __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY);
  116. // Configure interrupts
  117. // Update interrupt used for 32-bit counter
  118. // Output compare channel 1 interrupt for mbed timeout
  119. // Output compare channel 2 interrupt for HAL tick
  120. #if defined(TARGET_STM32F0)
  121. NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)timer_update_irq_handler);
  122. NVIC_EnableIRQ(TIM_MST_UP_IRQ);
  123. NVIC_SetPriority(TIM_MST_UP_IRQ, 0);
  124. NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)timer_oc_irq_handler);
  125. NVIC_EnableIRQ(TIM_MST_OC_IRQ);
  126. NVIC_SetPriority(TIM_MST_OC_IRQ, 1);
  127. #else
  128. NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
  129. NVIC_EnableIRQ(TIM_MST_IRQ);
  130. #endif
  131. // Enable interrupts
  132. __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE); // For 32-bit counter
  133. __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); // For HAL tick
  134. // Enable timer
  135. HAL_TIM_Base_Start(&TimMasterHandle);
  136. #if DEBUG_TICK > 0
  137. __GPIOB_CLK_ENABLE();
  138. GPIO_InitTypeDef GPIO_InitStruct;
  139. GPIO_InitStruct.Pin = GPIO_PIN_6;
  140. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  141. GPIO_InitStruct.Pull = GPIO_PULLUP;
  142. GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  143. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  144. #endif
  145. return HAL_OK;
  146. }
  147. void HAL_SuspendTick(void)
  148. {
  149. TimMasterHandle.Instance = TIM_MST;
  150. __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC2);
  151. }
  152. void HAL_ResumeTick(void)
  153. {
  154. TimMasterHandle.Instance = TIM_MST;
  155. __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2);
  156. }
  157. #endif // TIM_MST_16BIT