/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_dualtimer.c

https://gitlab.com/YaoQ/mbed-for-linknode · C · 393 lines · 217 code · 28 blank · 148 comment · 50 complexity · 5708be372eb6a04e7056213bb25728a3 MD5 · raw file

  1. /* mbed Microcontroller Library
  2. * Copyright (c) 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 "cmsis.h"
  17. #include "apb_dualtimer.h"
  18. /* DualTimer Private Data */
  19. typedef struct {
  20. /* DualTimer 1 Definition */
  21. CMSDK_DUALTIMER_SINGLE_TypeDef *dualtimer1;
  22. /* DualTimer 2 Definition */
  23. CMSDK_DUALTIMER_SINGLE_TypeDef *dualtimer2;
  24. /* Dual Timer IRQn */
  25. uint32_t dualtimerIRQn;
  26. /* DualTimer 1 Reload Value */
  27. uint32_t dualtimer1Reload;
  28. /* DualTimer 2 Reload Value */
  29. uint32_t dualtimer2Reload;
  30. /* Timer state */
  31. uint32_t state;
  32. } apb_dualtimer_t;
  33. /* Timer state definitions */
  34. #define DUALTIMER_INITIALIZED (1)
  35. #define DUALTIMER_ENABLED (1 << 1)
  36. /*
  37. * This Timer is written for MBED OS and keeps count
  38. * of the ticks. All the elaboration logic is demanded
  39. * to the upper layers.
  40. */
  41. #define DUALTIMER_MAX_VALUE 0xFFFFFFFF
  42. #define DUALTIMER_TICKS_US (SystemCoreClock/1000000)
  43. /* Dual Timers Array */
  44. static apb_dualtimer_t DualTimers[NUM_DUALTIMERS];
  45. /*
  46. * DualTimer_Initialize(): Initializes a hardware timer
  47. * timer: timer to be Initialized
  48. * time_us: timer reload value in us - 0 to reload to timer max value
  49. * time_us = ticks_value / TIMER_TICK_US
  50. */
  51. void DualTimer_Initialize(uint32_t timer, uint32_t time_us)
  52. {
  53. uint32_t reload = 0;
  54. if (timer < NUM_DUALTIMERS)
  55. {
  56. if (time_us == 0)
  57. reload = DUALTIMER_MAX_VALUE;
  58. else
  59. reload = (time_us) * DUALTIMER_TICKS_US;
  60. switch(timer) {
  61. case 0: DualTimers[timer].dualtimer1 = CMSDK_DUALTIMER1;
  62. DualTimers[timer].dualtimer2 = CMSDK_DUALTIMER2;
  63. DualTimers[timer].dualtimerIRQn = DUALTIMER_IRQn;
  64. DualTimers[timer].dualtimer1Reload = reload;
  65. DualTimers[timer].dualtimer2Reload = reload;
  66. DualTimers[timer].state = DUALTIMER_INITIALIZED;
  67. default: break;
  68. }
  69. }
  70. }
  71. /*
  72. * DualTimer_ReturnMode(): returns the correct mode for Dual Timer Control
  73. * mode: mode set by user
  74. * @return: mode for TimeControl register
  75. */
  76. uint32_t DualTimer_ReturnMode(timerenable_t mode)
  77. {
  78. uint32_t return_mode = 0;
  79. /* Check Interrupt Enable */
  80. if (((mode & DUALTIMER_INT) >> DUALTIMER_INT_MASK) == 1)
  81. return_mode |= CMSDK_DUALTIMER_CTRL_INTEN_Msk;
  82. /* Check 32 bit Counter */
  83. if (((mode & DUALTIMER_COUNT_32) >> DUALTIMER_COUNT_32_MASK) == 1)
  84. return_mode |= CMSDK_DUALTIMER_CTRL_SIZE_Msk;
  85. /* Check Periodic Mode */
  86. if (((mode & DUALTIMER_PERIODIC) >> DUALTIMER_PERIODIC_MASK) == 1)
  87. return_mode |= CMSDK_DUALTIMER_CTRL_MODE_Msk;
  88. /* Check OneShot Mode */
  89. if (((mode & DUALTIMER_ONESHOT) >> DUALTIMER_ONESHOT_MASK) == 1)
  90. return_mode |= CMSDK_DUALTIMER_CTRL_ONESHOOT_Msk;
  91. return return_mode;
  92. }
  93. /*
  94. * DualTimer_Enable(): Enables a hardware timer
  95. * timer: timer to be enabled
  96. * mode: enable mode
  97. */
  98. void DualTimer_Enable(uint32_t timer, timerenable_t mode)
  99. {
  100. uint32_t dualtimerControl = 0;
  101. /* The timer has to be contained in a valid range */
  102. if (timer < NUM_DUALTIMERS) {
  103. /* Timer has to be already initialized */
  104. if (DualTimers[timer].state == DUALTIMER_INITIALIZED) {
  105. /* Disable Timer */
  106. (DualTimers[timer].dualtimer1)->TimerControl = 0x0;
  107. (DualTimers[timer].dualtimer2)->TimerControl = 0x0;
  108. /* Reload Value */
  109. (DualTimers[timer].dualtimer1)->TimerLoad =
  110. DualTimers[timer].dualtimer1Reload;
  111. (DualTimers[timer].dualtimer2)->TimerLoad =
  112. DualTimers[timer].dualtimer2Reload;
  113. /* Set up Dual Timer Control */
  114. dualtimerControl = DualTimer_ReturnMode(mode);
  115. (DualTimers[timer].dualtimer1)->TimerControl = dualtimerControl;
  116. (DualTimers[timer].dualtimer2)->TimerControl = dualtimerControl;
  117. /* Enable Counter */
  118. (DualTimers[timer].dualtimer1)->TimerControl |=
  119. CMSDK_DUALTIMER_CTRL_EN_Msk;
  120. (DualTimers[timer].dualtimer2)->TimerControl |=
  121. CMSDK_DUALTIMER_CTRL_EN_Msk;
  122. /* Change timer state */
  123. DualTimers[timer].state |= DUALTIMER_ENABLED;
  124. }
  125. }
  126. }
  127. /*
  128. * DualTimer_Disable(): Disables a hardware timer
  129. * timer: timer to be disabled
  130. * dis_timer: 0 both - 1 dual timer 1 - 2 dual timer 2
  131. */
  132. void DualTimer_Disable(uint32_t timer, uint32_t dis_timer)
  133. {
  134. /* The timer has to be contained in a valid range */
  135. if (timer < NUM_DUALTIMERS) {
  136. /* Timer has to be already initialized and enabled */
  137. if (DualTimers[timer].state == (DUALTIMER_INITIALIZED | DUALTIMER_ENABLED)) {
  138. /* Disable Timer */
  139. switch (dis_timer)
  140. {
  141. case 0: (DualTimers[timer].dualtimer1)->TimerControl = 0x0;
  142. (DualTimers[timer].dualtimer2)->TimerControl = 0x0;
  143. break;
  144. case 1: (DualTimers[timer].dualtimer1)->TimerControl = 0x0;
  145. break;
  146. case 2: (DualTimers[timer].dualtimer2)->TimerControl = 0x0;
  147. break;
  148. default: break;
  149. }
  150. /* Change timer state */
  151. DualTimers[timer].state = DUALTIMER_INITIALIZED;
  152. }
  153. }
  154. }
  155. /*
  156. * DualTimer_isEnabled(): verifies if a timer is enabled
  157. * timer: timer to be verified
  158. * @return: 0 disabled - 1 enabled
  159. */
  160. uint32_t DualTimer_isEnabled(uint32_t timer)
  161. {
  162. /* The timer has to be contained in a valid range */
  163. if (timer < NUM_DUALTIMERS) {
  164. /* Timer has to be already initialized and enabled */
  165. if (DualTimers[timer].state == (DUALTIMER_INITIALIZED | DUALTIMER_ENABLED))
  166. return 1;
  167. } else {
  168. return 0;
  169. }
  170. return 0;
  171. }
  172. /*
  173. * DualTimer_Read_1(): provides single timer 1 VALUE
  174. * timer: timer to be read
  175. * @return: timer VALUE
  176. */
  177. uint32_t DualTimer_Read_1(uint32_t timer)
  178. {
  179. uint32_t return_value = 0;
  180. /* Verify if the Timer is enabled */
  181. if (DualTimer_isEnabled(timer) == 1) {
  182. return_value = (DualTimers[timer].dualtimer1Reload
  183. - (DualTimers[timer].dualtimer1)->TimerValue)
  184. / DUALTIMER_TICKS_US;
  185. }
  186. return return_value;
  187. }
  188. /*
  189. * DualTimer_Read_2(): provides single timer 2 VALUE
  190. * timer: timer to be read
  191. * @return: timer VALUE
  192. */
  193. uint32_t DualTimer_Read_2(uint32_t timer)
  194. {
  195. uint32_t return_value = 0;
  196. /* Verify if the Timer is enabled */
  197. if (DualTimer_isEnabled(timer) == 1) {
  198. return_value = (DualTimers[timer].dualtimer2Reload
  199. - (DualTimers[timer].dualtimer2)->TimerValue)
  200. / DUALTIMER_TICKS_US;
  201. }
  202. return return_value;
  203. }
  204. /*
  205. * DualTimer_SetInterrupt_1(): sets timer 1 Interrupt
  206. * timer: timer on which interrupt is set
  207. * time_us: reloading value us
  208. * mode: enable mode
  209. */
  210. void DualTimer_SetInterrupt_1(uint32_t timer, uint32_t time_us,
  211. timerenable_t mode)
  212. {
  213. uint32_t dualtimerControl = 0;
  214. uint32_t load_time_us = 0;
  215. /* Verify if the Timer is enabled */
  216. if (DualTimer_isEnabled(timer) == 1) {
  217. /* Disable Timer */
  218. DualTimer_Disable(timer, SINGLETIMER1);
  219. /* Set up Dual Timer Control */
  220. dualtimerControl = DualTimer_ReturnMode(mode);
  221. (DualTimers[timer].dualtimer1)->TimerControl =
  222. CMSDK_DUALTIMER_CTRL_INTEN_Msk
  223. | dualtimerControl;
  224. /* Check time us condition */
  225. if(time_us == DUALTIMER_DEFAULT_RELOAD)
  226. load_time_us = DUALTIMER_MAX_VALUE;
  227. else
  228. load_time_us = time_us * DUALTIMER_TICKS_US;
  229. /* Reload Value */
  230. DualTimers[timer].dualtimer1Reload = load_time_us;
  231. (DualTimers[timer].dualtimer1)->TimerLoad =
  232. DualTimers[timer].dualtimer1Reload;
  233. /* Enable Counter */
  234. (DualTimers[timer].dualtimer1)->TimerControl |=
  235. CMSDK_DUALTIMER_CTRL_EN_Msk;
  236. /* Change timer state */
  237. DualTimers[timer].state |= DUALTIMER_ENABLED;
  238. }
  239. }
  240. /*
  241. * DualTimer_SetInterrupt_2(): sets timer 2 Interrupt
  242. * timer: timer on which interrupt is set
  243. * time_us: reloading value us
  244. * mode: enable mode
  245. */
  246. void DualTimer_SetInterrupt_2(uint32_t timer, uint32_t time_us,
  247. timerenable_t mode)
  248. {
  249. uint32_t dualtimerControl = 0;
  250. uint32_t load_time_us = 0;
  251. /* Verify if the Timer is enabled */
  252. if (DualTimer_isEnabled(timer) == 1) {
  253. /* Disable Timer */
  254. DualTimer_Disable(timer, SINGLETIMER2);
  255. /* Set up Dual Timer Control */
  256. dualtimerControl = DualTimer_ReturnMode(mode);
  257. (DualTimers[timer].dualtimer2)->TimerControl =
  258. CMSDK_DUALTIMER_CTRL_INTEN_Msk
  259. | dualtimerControl;
  260. /* Check time us condition */
  261. if(time_us == DUALTIMER_DEFAULT_RELOAD)
  262. load_time_us = DUALTIMER_MAX_VALUE;
  263. else
  264. load_time_us = time_us * DUALTIMER_TICKS_US;
  265. /* Reload Value */
  266. DualTimers[timer].dualtimer2Reload = load_time_us;
  267. (DualTimers[timer].dualtimer2)->TimerLoad =
  268. DualTimers[timer].dualtimer2Reload;
  269. /* Enable Counter */
  270. (DualTimers[timer].dualtimer2)->TimerControl |=
  271. CMSDK_DUALTIMER_CTRL_EN_Msk;
  272. /* Change timer state */
  273. DualTimers[timer].state |= DUALTIMER_ENABLED;
  274. }
  275. }
  276. /*
  277. * DualTimer_DisableInterrupt(): disables timer interrupt
  278. * timer: timer on which interrupt is disabled
  279. */
  280. void DualTimer_DisableInterrupt(uint32_t timer)
  281. {
  282. /* Verify if the Timer is enabled */
  283. if (DualTimer_isEnabled(timer) == 1) {
  284. /* Disable Interrupt */
  285. (DualTimers[timer].dualtimer1)->TimerControl &=
  286. CMSDK_DUALTIMER_CTRL_EN_Msk;
  287. (DualTimers[timer].dualtimer2)->TimerControl &=
  288. CMSDK_DUALTIMER_CTRL_EN_Msk;
  289. }
  290. }
  291. /*
  292. * DualTimer_ClearInterrupt(): clear timer interrupt
  293. * timer: timer on which interrupt needs to be cleared
  294. */
  295. void DualTimer_ClearInterrupt(uint32_t timer)
  296. {
  297. /* Verify if the Timer is enabled */
  298. if (DualTimer_isEnabled(timer) == 1) {
  299. /* Clear Interrupt */
  300. (DualTimers[timer].dualtimer1)->TimerIntClr =
  301. CMSDK_DUALTIMER_INTCLR_Msk;
  302. (DualTimers[timer].dualtimer2)->TimerIntClr =
  303. CMSDK_DUALTIMER_INTCLR_Msk;
  304. }
  305. }
  306. /*
  307. * DualTimer_GetIRQn(): returns IRQn of a DualTimer
  308. * timer: timer on which IRQn is defined - 0 if it is not defined
  309. */
  310. uint32_t DualTimer_GetIRQn(uint32_t timer)
  311. {
  312. /* Verify if the Timer is enabled */
  313. if (DualTimer_isEnabled(timer) == 1) {
  314. return DualTimers[timer].dualtimerIRQn;
  315. }
  316. return 0;
  317. }
  318. /*
  319. * DualTimer_GetIRQInfo(): provides the single timer who caused
  320. * the interrupt.
  321. * dualtimer: dualtimer that triggered the IRQ
  322. * @return: a single timer - 0 if it is not defined
  323. */
  324. uint32_t DualTimer_GetIRQInfo(uint32_t timer)
  325. {
  326. /* Verify if the Timer is enabled */
  327. if (DualTimer_isEnabled(timer) == 1) {
  328. if((DualTimers[timer].dualtimer1)->TimerRIS)
  329. return SINGLETIMER1;
  330. else
  331. return SINGLETIMER2;
  332. }
  333. return 0;
  334. }
  335. /*
  336. * DualTimer_GetTicksUS(): returns the Ticks per us
  337. * timer: timer associated with the Ticks per us
  338. * @return: Ticks per us - 0 if the timer is disables
  339. */
  340. uint32_t DualTimer_GetTicksUS(uint32_t timer)
  341. {
  342. /* Verify if the Timer is enabled */
  343. if (DualTimer_isEnabled(timer) == 1) {
  344. return DUALTIMER_TICKS_US;
  345. }
  346. return 0;
  347. }
  348. /*
  349. * DualTimer_GetReloadValue(): returns the load value of the selected
  350. * singletimer.
  351. * timer: timer associated with the Ticks per us
  352. * singletimer: selected singletimer
  353. * @return: reload value of the selected singletimer - 0 if timer is disabled
  354. */
  355. uint32_t DualTimer_GetReloadValue(uint32_t timer, uint32_t singletimer)
  356. {
  357. /* Verify if the Timer is enabled */
  358. if (DualTimer_isEnabled(timer) == 1) {
  359. if (singletimer == SINGLETIMER1)
  360. return DualTimers[timer].dualtimer1Reload / DUALTIMER_TICKS_US;
  361. else
  362. return DualTimers[timer].dualtimer2Reload / DUALTIMER_TICKS_US;
  363. }
  364. return 0;
  365. }