am_hal_stimer.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. //*****************************************************************************
  2. //
  3. // am_hal_stimer.c
  4. //! @file
  5. //!
  6. //! @brief Functions for interfacing with the system timer (STIMER).
  7. //!
  8. //! @addtogroup stimer2 System Timer (STIMER)
  9. //! @ingroup apollo2hal
  10. //! @{
  11. //
  12. //*****************************************************************************
  13. //*****************************************************************************
  14. //
  15. // Copyright (c) 2017, Ambiq Micro
  16. // All rights reserved.
  17. //
  18. // Redistribution and use in source and binary forms, with or without
  19. // modification, are permitted provided that the following conditions are met:
  20. //
  21. // 1. Redistributions of source code must retain the above copyright notice,
  22. // this list of conditions and the following disclaimer.
  23. //
  24. // 2. Redistributions in binary form must reproduce the above copyright
  25. // notice, this list of conditions and the following disclaimer in the
  26. // documentation and/or other materials provided with the distribution.
  27. //
  28. // 3. Neither the name of the copyright holder nor the names of its
  29. // contributors may be used to endorse or promote products derived from this
  30. // software without specific prior written permission.
  31. //
  32. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  36. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  37. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  38. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  39. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  40. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42. // POSSIBILITY OF SUCH DAMAGE.
  43. //
  44. // This is part of revision 1.2.9 of the AmbiqSuite Development Package.
  45. //
  46. //*****************************************************************************
  47. #include <stdint.h>
  48. #include <stdbool.h>
  49. #include "am_mcu_apollo.h"
  50. //*****************************************************************************
  51. //
  52. //! @brief Set up the stimer.
  53. //!
  54. //! @param ui32STimerConfig is the value to load into the configuration reg.
  55. //!
  56. //! This function should be used to perform the initial set-up of the
  57. //! stimer.
  58. //!
  59. //! @return The 32-bit current config of the STimer Config register
  60. //
  61. //*****************************************************************************
  62. uint32_t
  63. am_hal_stimer_config(uint32_t ui32STimerConfig)
  64. {
  65. uint32_t ui32CurrVal;
  66. //
  67. // Read the current config
  68. //
  69. ui32CurrVal = AM_REG(CTIMER, STCFG);
  70. //
  71. // Write our configuration value.
  72. //
  73. AM_REG(CTIMER, STCFG) = ui32STimerConfig;
  74. //
  75. // If all of the clock sources are not HFRC, disable LDO when sleeping if timers are enabled.
  76. //
  77. if ( (AM_BFR(CTIMER, STCFG, CLKSEL) == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16) ||
  78. (AM_BFR(CTIMER, STCFG, CLKSEL) == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256) )
  79. {
  80. AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 0);
  81. }
  82. else
  83. {
  84. AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 1);
  85. }
  86. return ui32CurrVal;
  87. }
  88. //*****************************************************************************
  89. //
  90. //! @brief Get the current stimer value.
  91. //!
  92. //! This function can be used to read, uninvasively, the value in the stimer.
  93. //!
  94. //! @return The 32-bit value from the STimer counter register.
  95. //
  96. //*****************************************************************************
  97. uint32_t
  98. am_hal_stimer_counter_get(void)
  99. {
  100. return AM_REG(CTIMER, STTMR);
  101. }
  102. //*****************************************************************************
  103. //
  104. //! @brief Clear the stimer counter.
  105. //!
  106. //! This function clears the STimer Counter and leaves the stimer running.
  107. //!
  108. //! @return None.
  109. //
  110. //*****************************************************************************
  111. void
  112. am_hal_stimer_counter_clear(void)
  113. {
  114. //
  115. // Set the clear bit
  116. //
  117. AM_REG(CTIMER, STCFG) |= AM_REG_CTIMER_STCFG_CLEAR_M;
  118. //
  119. // Reset the clear bit
  120. //
  121. AM_REG(CTIMER, STCFG) &= ~AM_REG_CTIMER_STCFG_CLEAR_M;
  122. }
  123. //*****************************************************************************
  124. //
  125. //! @brief Set the compare value.
  126. //!
  127. //! @param ui32CmprInstance is the compare register instance number (0-7).
  128. //! @param ui32Delta is the value to add to the STimer counter and load into
  129. //! the comparator register.
  130. //!
  131. //! NOTE: There is no way to set an absolute value into a comparator register.
  132. //! Only deltas added to the STimer counter can be written to the compare
  133. //! registers.
  134. //!
  135. //! @return None.
  136. //
  137. //*****************************************************************************
  138. void
  139. am_hal_stimer_compare_delta_set(uint32_t ui32CmprInstance, uint32_t ui32Delta)
  140. {
  141. if ( ui32CmprInstance > 7 )
  142. {
  143. return;
  144. }
  145. AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance)) = ui32Delta;
  146. }
  147. //*****************************************************************************
  148. //
  149. //! @brief Get the current stimer compare register value.
  150. //!
  151. //! @param ui32CmprInstance is the compare register instance number (0-7).
  152. //!
  153. //! This function can be used to read the value in an stimer compare register.
  154. //!
  155. //!
  156. //! @return None.
  157. //
  158. //*****************************************************************************
  159. uint32_t
  160. am_hal_stimer_compare_get(uint32_t ui32CmprInstance)
  161. {
  162. if ( ui32CmprInstance > 7 )
  163. {
  164. return 0;
  165. }
  166. return AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance));
  167. }
  168. //*****************************************************************************
  169. //
  170. //! @brief Start capturing data with the specified capture register.
  171. //!
  172. //! @param ui32CaptureNum is the Capture Register Number to read (0-3).
  173. //! ui32GPIONumber is the pin number.
  174. //! bPolarity: false (0) = Capture on low to high transition.
  175. //! true (1) = Capture on high to low transition.
  176. //!
  177. //! Use this function to start capturing.
  178. //!
  179. //! @return None.
  180. //
  181. //*****************************************************************************
  182. void
  183. am_hal_stimer_capture_start(uint32_t ui32CaptureNum,
  184. uint32_t ui32GPIONumber,
  185. bool bPolarity)
  186. {
  187. uint32_t ui32CapCtrl;
  188. if ( ui32GPIONumber > (AM_HAL_GPIO_MAX_PADS-1) )
  189. {
  190. return;
  191. }
  192. //
  193. // Set the polarity and pin selection in the GPIO block.
  194. //
  195. switch (ui32CaptureNum)
  196. {
  197. case 0:
  198. AM_BFW(GPIO, STMRCAP, STPOL0, bPolarity);
  199. AM_BFW(GPIO, STMRCAP, STSEL0, ui32GPIONumber);
  200. ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M;
  201. break;
  202. case 1:
  203. AM_BFW(GPIO, STMRCAP, STPOL1, bPolarity);
  204. AM_BFW(GPIO, STMRCAP, STSEL1, ui32GPIONumber);
  205. ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_M;
  206. break;
  207. case 2:
  208. AM_BFW(GPIO, STMRCAP, STPOL2, bPolarity);
  209. AM_BFW(GPIO, STMRCAP, STSEL2, ui32GPIONumber);
  210. ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_M;
  211. break;
  212. case 3:
  213. AM_BFW(GPIO, STMRCAP, STPOL3, bPolarity);
  214. AM_BFW(GPIO, STMRCAP, STSEL3, ui32GPIONumber);
  215. ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_M;
  216. break;
  217. default:
  218. return; // error concealment.
  219. }
  220. //
  221. // Enable it in the CTIMER Block
  222. //
  223. AM_REG(CTIMER, CAPTURE_CONTROL) |= ui32CapCtrl;
  224. }
  225. //*****************************************************************************
  226. //
  227. //! @brief Start capturing data with the specified capture register.
  228. //!
  229. //! @param ui32CaptureNum is the Capture Register Number to read.
  230. //!
  231. //! Use this function to start capturing.
  232. //!
  233. //! @return None.
  234. //
  235. //*****************************************************************************
  236. void am_hal_stimer_capture_stop(uint32_t ui32CaptureNum)
  237. {
  238. //
  239. // Disable it in the CTIMER block.
  240. //
  241. AM_REG(CTIMER, CAPTURE_CONTROL) &=
  242. ~(AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M <<
  243. ((AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_S -
  244. AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_S) * ui32CaptureNum));
  245. }
  246. //*****************************************************************************
  247. //
  248. //! @brief Get the current stimer capture register value.
  249. //!
  250. //! @param ui32CaptureNum is the Capture Register Number to read.
  251. //!
  252. //! This function can be used to read the value in an stimer capture register.
  253. //!
  254. //!
  255. //! @return None.
  256. //
  257. //*****************************************************************************
  258. uint32_t am_hal_stimer_capture_get(uint32_t ui32CaptureNum)
  259. {
  260. if ( ui32CaptureNum > 7 )
  261. {
  262. return 0;
  263. }
  264. return AM_REGVAL(AM_REG_STIMER_CAPTURE(0, ui32CaptureNum));
  265. }
  266. //*****************************************************************************
  267. //
  268. //! @brief Enables the selected system timer interrupt.
  269. //!
  270. //! @param ui32Interrupt is the interrupt to be used.
  271. //!
  272. //! This function will enable the selected interrupts in the STIMER interrupt
  273. //! enable register. In order to receive an interrupt from an stimer component,
  274. //! you will need to enable the interrupt for that component in this main
  275. //! register, as well as in the stimer configuration register (accessible though
  276. //! am_hal_stimer_config()), and in the NVIC.
  277. //!
  278. //! ui32Interrupt should be the logical OR of one or more of the following
  279. //! values:
  280. //!
  281. //! AM_HAL_STIMER_INT_COMPAREA
  282. //! AM_HAL_STIMER_INT_COMPAREB
  283. //! AM_HAL_STIMER_INT_COMPAREC
  284. //! AM_HAL_STIMER_INT_COMPARED
  285. //! AM_HAL_STIMER_INT_COMPAREE
  286. //! AM_HAL_STIMER_INT_COMPAREF
  287. //! AM_HAL_STIMER_INT_COMPAREG
  288. //! AM_HAL_STIMER_INT_COMPAREH
  289. //!
  290. //! AM_HAL_STIMER_INT_OVERFLOW
  291. //!
  292. //! AM_HAL_STIMER_INT_CAPTUREA
  293. //! AM_HAL_STIMER_INT_CAPTUREB
  294. //! AM_HAL_STIMER_INT_CAPTUREC
  295. //! AM_HAL_STIMER_INT_CAPTURED
  296. //!
  297. //! @return None.
  298. //
  299. //*****************************************************************************
  300. void
  301. am_hal_stimer_int_enable(uint32_t ui32Interrupt)
  302. {
  303. //
  304. // Enable the interrupt at the module level.
  305. //
  306. AM_REGn(CTIMER, 0, STMINTEN) |= ui32Interrupt;
  307. }
  308. //*****************************************************************************
  309. //
  310. //! @brief Return the enabled stimer interrupts.
  311. //!
  312. //! This function will return all enabled interrupts in the STIMER
  313. //! interrupt enable register.
  314. //!
  315. //! @return return enabled interrupts. This will be a logical or of:
  316. //!
  317. //! AM_HAL_STIMER_INT_COMPAREA
  318. //! AM_HAL_STIMER_INT_COMPAREB
  319. //! AM_HAL_STIMER_INT_COMPAREC
  320. //! AM_HAL_STIMER_INT_COMPARED
  321. //! AM_HAL_STIMER_INT_COMPAREE
  322. //! AM_HAL_STIMER_INT_COMPAREF
  323. //! AM_HAL_STIMER_INT_COMPAREG
  324. //! AM_HAL_STIMER_INT_COMPAREH
  325. //!
  326. //! AM_HAL_STIMER_INT_OVERFLOW
  327. //!
  328. //! AM_HAL_STIMER_INT_CAPTUREA
  329. //! AM_HAL_STIMER_INT_CAPTUREB
  330. //! AM_HAL_STIMER_INT_CAPTUREC
  331. //! AM_HAL_STIMER_INT_CAPTURED
  332. //!
  333. //! @return Return the enabled timer interrupts.
  334. //
  335. //*****************************************************************************
  336. uint32_t
  337. am_hal_stimer_int_enable_get(void)
  338. {
  339. //
  340. // Return enabled interrupts.
  341. //
  342. return AM_REGn(CTIMER, 0, STMINTEN);
  343. }
  344. //*****************************************************************************
  345. //
  346. //! @brief Disables the selected stimer interrupt.
  347. //!
  348. //! @param ui32Interrupt is the interrupt to be used.
  349. //!
  350. //! This function will disable the selected interrupts in the STIMER
  351. //! interrupt register.
  352. //!
  353. //! ui32Interrupt should be the logical OR of one or more of the following
  354. //! values:
  355. //!
  356. //! AM_HAL_STIMER_INT_COMPAREA
  357. //! AM_HAL_STIMER_INT_COMPAREB
  358. //! AM_HAL_STIMER_INT_COMPAREC
  359. //! AM_HAL_STIMER_INT_COMPARED
  360. //! AM_HAL_STIMER_INT_COMPAREE
  361. //! AM_HAL_STIMER_INT_COMPAREF
  362. //! AM_HAL_STIMER_INT_COMPAREG
  363. //! AM_HAL_STIMER_INT_COMPAREH
  364. //!
  365. //! AM_HAL_STIMER_INT_OVERFLOW
  366. //!
  367. //! AM_HAL_STIMER_INT_CAPTUREA
  368. //! AM_HAL_STIMER_INT_CAPTUREB
  369. //! AM_HAL_STIMER_INT_CAPTUREC
  370. //! AM_HAL_STIMER_INT_CAPTURED
  371. //!
  372. //! @return None.
  373. //
  374. //*****************************************************************************
  375. void
  376. am_hal_stimer_int_disable(uint32_t ui32Interrupt)
  377. {
  378. //
  379. // Disable the interrupt at the module level.
  380. //
  381. AM_REGn(CTIMER, 0, STMINTEN) &= ~ui32Interrupt;
  382. }
  383. //*****************************************************************************
  384. //
  385. //! @brief Sets the selected stimer interrupt.
  386. //!
  387. //! @param ui32Interrupt is the interrupt to be used.
  388. //!
  389. //! This function will set the selected interrupts in the STIMER
  390. //! interrupt register.
  391. //!
  392. //! ui32Interrupt should be the logical OR of one or more of the following
  393. //! values:
  394. //!
  395. //! AM_HAL_STIMER_INT_COMPAREA
  396. //! AM_HAL_STIMER_INT_COMPAREB
  397. //! AM_HAL_STIMER_INT_COMPAREC
  398. //! AM_HAL_STIMER_INT_COMPARED
  399. //! AM_HAL_STIMER_INT_COMPAREE
  400. //! AM_HAL_STIMER_INT_COMPAREF
  401. //! AM_HAL_STIMER_INT_COMPAREG
  402. //! AM_HAL_STIMER_INT_COMPAREH
  403. //!
  404. //! AM_HAL_STIMER_INT_OVERFLOW
  405. //!
  406. //! AM_HAL_STIMER_INT_CAPTUREA
  407. //! AM_HAL_STIMER_INT_CAPTUREB
  408. //! AM_HAL_STIMER_INT_CAPTUREC
  409. //! AM_HAL_STIMER_INT_CAPTURED
  410. //!
  411. //! @return None.
  412. //
  413. //*****************************************************************************
  414. void
  415. am_hal_stimer_int_set(uint32_t ui32Interrupt)
  416. {
  417. //
  418. // Set the interrupts.
  419. //
  420. AM_REGn(CTIMER, 0, STMINTSET) = ui32Interrupt;
  421. }
  422. //*****************************************************************************
  423. //
  424. //! @brief Clears the selected stimer interrupt.
  425. //!
  426. //! @param ui32Interrupt is the interrupt to be used.
  427. //!
  428. //! This function will clear the selected interrupts in the STIMER
  429. //! interrupt register.
  430. //!
  431. //! ui32Interrupt should be the logical OR of one or more of the following
  432. //! values:
  433. //!
  434. //! AM_HAL_STIMER_INT_COMPAREA
  435. //! AM_HAL_STIMER_INT_COMPAREB
  436. //! AM_HAL_STIMER_INT_COMPAREC
  437. //! AM_HAL_STIMER_INT_COMPARED
  438. //! AM_HAL_STIMER_INT_COMPAREE
  439. //! AM_HAL_STIMER_INT_COMPAREF
  440. //! AM_HAL_STIMER_INT_COMPAREG
  441. //! AM_HAL_STIMER_INT_COMPAREH
  442. //!
  443. //! AM_HAL_STIMER_INT_OVERFLOW
  444. //!
  445. //! AM_HAL_STIMER_INT_CAPTUREA
  446. //! AM_HAL_STIMER_INT_CAPTUREB
  447. //! AM_HAL_STIMER_INT_CAPTUREC
  448. //! AM_HAL_STIMER_INT_CAPTURED
  449. //!
  450. //! @return None.
  451. //
  452. //*****************************************************************************
  453. void
  454. am_hal_stimer_int_clear(uint32_t ui32Interrupt)
  455. {
  456. //
  457. // Disable the interrupt at the module level.
  458. //
  459. AM_REGn(CTIMER, 0, STMINTCLR) = ui32Interrupt;
  460. }
  461. //*****************************************************************************
  462. //
  463. //! @brief Returns either the enabled or raw stimer interrupt status.
  464. //!
  465. //! This function will return the stimer interrupt status.
  466. //!
  467. //! @bEnabledOnly if true returns the status of the enabled interrupts
  468. //! only.
  469. //!
  470. //! The return value will be the logical OR of one or more of the following
  471. //! values:
  472. //!
  473. //!
  474. //! @return Returns the stimer interrupt status.
  475. //
  476. //*****************************************************************************
  477. uint32_t
  478. am_hal_stimer_int_status_get(bool bEnabledOnly)
  479. {
  480. //
  481. // Return the desired status.
  482. //
  483. uint32_t ui32RetVal = AM_REGn(CTIMER, 0, STMINTSTAT);
  484. if ( bEnabledOnly )
  485. {
  486. ui32RetVal &= AM_REGn(CTIMER, 0, STMINTEN);
  487. }
  488. return ui32RetVal;
  489. }
  490. //*****************************************************************************
  491. //
  492. // End Doxygen group.
  493. //! @}
  494. //
  495. //*****************************************************************************