efm32_timer.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /***************************************************************************//**
  2. * @file
  3. * @brief Timer/counter (TIMER) peripheral API for EFM32.
  4. * @author Energy Micro AS
  5. * @version 1.3.0
  6. *******************************************************************************
  7. * @section License
  8. * <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
  9. *******************************************************************************
  10. *
  11. * This source code is the property of Energy Micro AS. The source and compiled
  12. * code may only be used on Energy Micro "EFM32" microcontrollers.
  13. *
  14. * This copyright notice may not be removed from the source code nor changed.
  15. *
  16. * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
  17. * obligation to support this Software. Energy Micro AS is providing the
  18. * Software "AS IS", with no express or implied warranties of any kind,
  19. * including, but not limited to, any implied warranties of merchantability
  20. * or fitness for any particular purpose or warranties against infringement
  21. * of any proprietary rights of a third party.
  22. *
  23. * Energy Micro AS will not be liable for any consequential, incidental, or
  24. * special damages, or any other relief, or for any claim by any third party,
  25. * arising from your use of this Software.
  26. *
  27. ******************************************************************************/
  28. #ifndef __EFM32_TIMER_H
  29. #define __EFM32_TIMER_H
  30. #include <stdbool.h>
  31. #include "efm32.h"
  32. #ifdef __cplusplus
  33. extern "C" {
  34. #endif
  35. /***************************************************************************//**
  36. * @addtogroup EFM32_Library
  37. * @{
  38. ******************************************************************************/
  39. /***************************************************************************//**
  40. * @addtogroup TIMER
  41. * @{
  42. ******************************************************************************/
  43. /*******************************************************************************
  44. ******************************** ENUMS ************************************
  45. ******************************************************************************/
  46. /** Timer compare/capture mode. */
  47. typedef enum
  48. {
  49. timerCCModeOff = _TIMER_CC_CTRL_MODE_OFF, /**< Channel turned off. */
  50. timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE, /**< Input capture. */
  51. timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Output compare. */
  52. timerCCModePWM = _TIMER_CC_CTRL_MODE_PWM /**< Pulse-Width modulation. */
  53. } TIMER_CCMode_TypeDef;
  54. /** Clock select. */
  55. typedef enum
  56. {
  57. /** Prescaled HFPER clock. */
  58. timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,
  59. /** Prescaled HFPER clock. */
  60. timerClkSelCC1 = _TIMER_CTRL_CLKSEL_CC1,
  61. /**
  62. * Cascaded, clocked by underflow (down-counting) or overflow (up-counting)
  63. * by lower numbered timer.
  64. */
  65. timerClkSelCascade = _TIMER_CTRL_CLKSEL_TIMEROUF
  66. } TIMER_ClkSel_TypeDef;
  67. /** Input capture edge select. */
  68. typedef enum
  69. {
  70. /** Rising edges detected. */
  71. timerEdgeRising = _TIMER_CC_CTRL_ICEDGE_RISING,
  72. /** Falling edges detected. */
  73. timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,
  74. /** Both edges detected. */
  75. timerEdgeBoth = _TIMER_CC_CTRL_ICEDGE_BOTH,
  76. /** No edge detection, leave signal as is. */
  77. timerEdgeNone = _TIMER_CC_CTRL_ICEDGE_NONE
  78. } TIMER_Edge_TypeDef;
  79. /** Input capture event control. */
  80. typedef enum
  81. {
  82. /** PRS output pulse, interrupt flag and DMA request set on every capture. */
  83. timerEventEveryEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,
  84. /** PRS output pulse, interrupt flag and DMA request set on every second capture. */
  85. timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,
  86. /**
  87. * PRS output pulse, interrupt flag and DMA request set on rising edge (if
  88. * input capture edge = BOTH).
  89. */
  90. timerEventRising = _TIMER_CC_CTRL_ICEVCTRL_RISING,
  91. /**
  92. * PRS output pulse, interrupt flag and DMA request set on falling edge (if
  93. * input capture edge = BOTH).
  94. */
  95. timerEventFalling = _TIMER_CC_CTRL_ICEVCTRL_FALLING
  96. } TIMER_Event_TypeDef;
  97. /** Input edge action. */
  98. typedef enum
  99. {
  100. /** No action taken. */
  101. timerInputActionNone = _TIMER_CTRL_FALLA_NONE,
  102. /** Start counter without reload. */
  103. timerInputActionStart = _TIMER_CTRL_FALLA_START,
  104. /** Stop counter without reload. */
  105. timerInputActionStop = _TIMER_CTRL_FALLA_STOP,
  106. /** Reload and start counter. */
  107. timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART
  108. } TIMER_InputAction_TypeDef;
  109. /** Timer mode. */
  110. typedef enum
  111. {
  112. timerModeUp = _TIMER_CTRL_MODE_UP, /**< Up-counting. */
  113. timerModeDown = _TIMER_CTRL_MODE_DOWN, /**< Down-counting. */
  114. timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, /**< Up/down-counting. */
  115. timerModeQDec = _TIMER_CTRL_MODE_QDEC /**< Quadrature decoder. */
  116. } TIMER_Mode_TypeDef;
  117. /** Compare/capture output action. */
  118. typedef enum
  119. {
  120. /** No action. */
  121. timerOutputActionNone = _TIMER_CC_CTRL_CUFOA_NONE,
  122. /** Toggle on event. */
  123. timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,
  124. /** Clear on event. */
  125. timerOutputActionClear = _TIMER_CC_CTRL_CUFOA_CLEAR,
  126. /** Set on event. */
  127. timerOutputActionSet = _TIMER_CC_CTRL_CUFOA_SET
  128. } TIMER_OutputAction_TypeDef;
  129. /** Prescaler. */
  130. typedef enum
  131. {
  132. timerPrescale1 = _TIMER_CTRL_PRESC_DIV1, /**< Divide by 1. */
  133. timerPrescale2 = _TIMER_CTRL_PRESC_DIV2, /**< Divide by 2. */
  134. timerPrescale4 = _TIMER_CTRL_PRESC_DIV4, /**< Divide by 4. */
  135. timerPrescale8 = _TIMER_CTRL_PRESC_DIV8, /**< Divide by 8. */
  136. timerPrescale16 = _TIMER_CTRL_PRESC_DIV16, /**< Divide by 16. */
  137. timerPrescale32 = _TIMER_CTRL_PRESC_DIV32, /**< Divide by 32. */
  138. timerPrescale64 = _TIMER_CTRL_PRESC_DIV64, /**< Divide by 64. */
  139. timerPrescale128 = _TIMER_CTRL_PRESC_DIV128, /**< Divide by 128. */
  140. timerPrescale256 = _TIMER_CTRL_PRESC_DIV256, /**< Divide by 256. */
  141. timerPrescale512 = _TIMER_CTRL_PRESC_DIV512, /**< Divide by 512. */
  142. timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024 /**< Divide by 1024. */
  143. } TIMER_Prescale_TypeDef;
  144. /** Peripheral Reflex System signal. */
  145. typedef enum
  146. {
  147. timerPRSSELCh0 = _ADC_SINGLECTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
  148. timerPRSSELCh1 = _ADC_SINGLECTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
  149. timerPRSSELCh2 = _ADC_SINGLECTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
  150. timerPRSSELCh3 = _ADC_SINGLECTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
  151. timerPRSSELCh4 = _ADC_SINGLECTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
  152. timerPRSSELCh5 = _ADC_SINGLECTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
  153. timerPRSSELCh6 = _ADC_SINGLECTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
  154. timerPRSSELCh7 = _ADC_SINGLECTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
  155. } TIMER_PRSSEL_TypeDef;
  156. /*******************************************************************************
  157. ******************************* STRUCTS ***********************************
  158. ******************************************************************************/
  159. /** TIMER initialization structure. */
  160. typedef struct
  161. {
  162. /** Start counting when init completed. */
  163. bool enable;
  164. /** Counter shall keep running during debug halt. */
  165. bool debugRun;
  166. /** Prescaling factor, if HFPER clock used. */
  167. TIMER_Prescale_TypeDef prescale;
  168. /** Clock selection. */
  169. TIMER_ClkSel_TypeDef clkSel;
  170. /** Action on falling input edge. */
  171. TIMER_InputAction_TypeDef fallAction;
  172. /** Action on rising input edge. */
  173. TIMER_InputAction_TypeDef riseAction;
  174. /** Counting mode. */
  175. TIMER_Mode_TypeDef mode;
  176. /** DMA request clear on active. */
  177. bool dmaClrAct;
  178. /** Select X2 or X4 quadrature decode mode (if used). */
  179. bool quadModeX4;
  180. /** Determines if only counting up or down once. */
  181. bool oneShot;
  182. /** Timer start/stop/reload by other timers. */
  183. bool sync;
  184. } TIMER_Init_TypeDef;
  185. /** Default config for TIMER init structure. */
  186. #define TIMER_INIT_DEFAULT \
  187. { true, /* Enable timer when init complete. */ \
  188. false, /* Stop counter during debug halt. */ \
  189. timerPrescale1, /* No prescaling. */ \
  190. timerClkSelHFPerClk, /* Select HFPER clock. */ \
  191. timerInputActionNone, /* No action on falling input edge. */ \
  192. timerInputActionNone, /* No action on rising input edge. */ \
  193. timerModeUp, /* Up-counting. */ \
  194. false, /* Do not clear DMA requests when DMA channel is active. */ \
  195. false, /* Select X2 quadrature decode mode (if used). */ \
  196. false, /* Disable one shot. */ \
  197. false /* Not started/stopped/reloaded by other timers. */ \
  198. }
  199. /** TIMER compare/capture initialization structure. */
  200. typedef struct
  201. {
  202. /** Input capture event control. */
  203. TIMER_Event_TypeDef eventCtrl;
  204. /** Input capture edge select. */
  205. TIMER_Edge_TypeDef edge;
  206. /**
  207. * Peripheral reflex system trigger selection. Only applicable if @p prsInput
  208. * is enabled.
  209. */
  210. TIMER_PRSSEL_TypeDef prsSel;
  211. /** Counter underflow output action. */
  212. TIMER_OutputAction_TypeDef cufoa;
  213. /** Counter overflow output action. */
  214. TIMER_OutputAction_TypeDef cofoa;
  215. /** Counter match output action. */
  216. TIMER_OutputAction_TypeDef cmoa;
  217. /** Compare/capture channel mode. */
  218. TIMER_CCMode_TypeDef mode;
  219. /** Enable digital filter. */
  220. bool filter;
  221. /** Select TIMERnCCx (false) or PRS input (true). */
  222. bool prsInput;
  223. /**
  224. * Compare output initial state. Only used in Output Compare and PWM mode.
  225. * When true, the compare/PWM output is set high when the counter is
  226. * disabled. When counting resumes, this value will represent the initial
  227. * value for the compare/PWM output. If the bit is cleared, the output
  228. * will be cleared when the counter is disabled.
  229. */
  230. bool coist;
  231. /** Invert output from compare/capture channel. */
  232. bool outInvert;
  233. } TIMER_InitCC_TypeDef;
  234. /** Default config for TIMER compare/capture init structure. */
  235. #define TIMER_INITCC_DEFAULT \
  236. { timerEventEveryEdge, /* Event on every capture. */ \
  237. timerEdgeRising, /* Input capture edge on rising edge. */ \
  238. timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
  239. timerOutputActionNone, /* No action on underflow. */ \
  240. timerOutputActionNone, /* No action on overflow. */ \
  241. timerOutputActionNone, /* No action on match. */ \
  242. timerCCModeOff, /* Disable compare/capture channel. */ \
  243. false, /* Disable filter. */ \
  244. false, /* Select TIMERnCCx input. */ \
  245. false, /* Clear output when countre disabled. */ \
  246. false /* Do not invert output. */ \
  247. }
  248. /*******************************************************************************
  249. ***************************** PROTOTYPES **********************************
  250. ******************************************************************************/
  251. /***************************************************************************//**
  252. * @brief
  253. * Get capture value for compare/capture channel when operating in capture
  254. * mode.
  255. *
  256. * @param[in] timer
  257. * Pointer to TIMER peripheral register block.
  258. *
  259. * @param[in] ch
  260. * Compare/capture channel to access.
  261. *
  262. * @return
  263. * Current capture value.
  264. ******************************************************************************/
  265. static __INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
  266. {
  267. return(timer->CC[ch].CCV);
  268. }
  269. /***************************************************************************//**
  270. * @brief
  271. * Set compare value buffer for compare/capture channel when operating in
  272. * compare or PWM mode.
  273. *
  274. * @details
  275. * The compare value buffer holds the value which will be written to
  276. * TIMERn_CCx_CCV on an update event if the buffer has been updated since
  277. * the last event.
  278. *
  279. * @param[in] timer
  280. * Pointer to TIMER peripheral register block.
  281. *
  282. * @param[in] ch
  283. * Compare/capture channel to access.
  284. *
  285. * @param[in] val
  286. * Value to set in compare value buffer register.
  287. ******************************************************************************/
  288. static __INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
  289. unsigned int ch,
  290. uint32_t val)
  291. {
  292. timer->CC[ch].CCVB = val;
  293. }
  294. /***************************************************************************//**
  295. * @brief
  296. * Set compare value for compare/capture channel when operating in compare
  297. * or PWM mode.
  298. *
  299. * @param[in] timer
  300. * Pointer to TIMER peripheral register block.
  301. *
  302. * @param[in] ch
  303. * Compare/capture channel to access.
  304. *
  305. * @param[in] val
  306. * Value to set in compare value register.
  307. ******************************************************************************/
  308. static __INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
  309. unsigned int ch,
  310. uint32_t val)
  311. {
  312. timer->CC[ch].CCV = val;
  313. }
  314. /***************************************************************************//**
  315. * @brief
  316. * Get TIMER counter value.
  317. *
  318. * @param[in] timer
  319. * Pointer to TIMER peripheral register block.
  320. *
  321. * @return
  322. * Current TIMER counter value.
  323. ******************************************************************************/
  324. static __INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
  325. {
  326. return(timer->CNT);
  327. }
  328. /***************************************************************************//**
  329. * @brief
  330. * Set TIMER counter value.
  331. *
  332. * @param[in] timer
  333. * Pointer to TIMER peripheral register block.
  334. *
  335. * @param[in] val
  336. * Value to set counter to.
  337. ******************************************************************************/
  338. static __INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
  339. {
  340. timer->CNT = val;
  341. }
  342. void TIMER_Enable(TIMER_TypeDef *rtc, bool enable);
  343. void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
  344. void TIMER_InitCC(TIMER_TypeDef *timer,
  345. unsigned int ch,
  346. const TIMER_InitCC_TypeDef *init);
  347. /***************************************************************************//**
  348. * @brief
  349. * Clear one or more pending TIMER interrupts.
  350. *
  351. * @param[in] timer
  352. * Pointer to TIMER peripheral register block.
  353. *
  354. * @param[in] flags
  355. * Pending TIMER interrupt source to clear. Use a logical OR combination
  356. * of valid interrupt flags for the TIMER module (TIMER_IF_nnn).
  357. ******************************************************************************/
  358. static __INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
  359. {
  360. timer->IFC = flags;
  361. }
  362. /***************************************************************************//**
  363. * @brief
  364. * Disable one or more TIMER interrupts.
  365. *
  366. * @param[in] timer
  367. * Pointer to TIMER peripheral register block.
  368. *
  369. * @param[in] flags
  370. * TIMER interrupt sources to disable. Use a logical OR combination of
  371. * valid interrupt flags for the TIMER module (TIMER_IF_nnn).
  372. ******************************************************************************/
  373. static __INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
  374. {
  375. timer->IEN &= ~(flags);
  376. }
  377. /***************************************************************************//**
  378. * @brief
  379. * Enable one or more TIMER interrupts.
  380. *
  381. * @note
  382. * Depending on the use, a pending interrupt may already be set prior to
  383. * enabling the interrupt. Consider using TIMER_IntClear() prior to enabling
  384. * if such a pending interrupt should be ignored.
  385. *
  386. * @param[in] timer
  387. * Pointer to TIMER peripheral register block.
  388. *
  389. * @param[in] flags
  390. * TIMER interrupt sources to enable. Use a logical OR combination of
  391. * valid interrupt flags for the TIMER module (TIMER_IF_nnn).
  392. ******************************************************************************/
  393. static __INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
  394. {
  395. timer->IEN |= flags;
  396. }
  397. /***************************************************************************//**
  398. * @brief
  399. * Get pending TIMER interrupt flags.
  400. *
  401. * @note
  402. * The event bits are not cleared by the use of this function.
  403. *
  404. * @param[in] timer
  405. * Pointer to TIMER peripheral register block.
  406. *
  407. * @return
  408. * TIMER interrupt sources pending. A logical OR combination of valid
  409. * interrupt flags for the TIMER module (TIMER_IF_nnn).
  410. ******************************************************************************/
  411. static __INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
  412. {
  413. return(timer->IF);
  414. }
  415. /***************************************************************************//**
  416. * @brief
  417. * Set one or more pending TIMER interrupts from SW.
  418. *
  419. * @param[in] timer
  420. * Pointer to TIMER peripheral register block.
  421. *
  422. * @param[in] flags
  423. * TIMER interrupt sources to set to pending. Use a logical OR combination
  424. * of valid interrupt flags for the TIMER module (TIMER_IF_nnn).
  425. ******************************************************************************/
  426. static __INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
  427. {
  428. timer->IFS = flags;
  429. }
  430. void TIMER_Lock(TIMER_TypeDef *timer);
  431. void TIMER_Reset(TIMER_TypeDef *timer);
  432. /***************************************************************************//**
  433. * @brief
  434. * Set top value buffer for timer.
  435. *
  436. * @details
  437. * When the top value buffer register is updated, the value is loaded into
  438. * the top value register at the next wrap around. This feature is useful
  439. * in order to update the top value safely when the timer is running.
  440. *
  441. * @param[in] timer
  442. * Pointer to TIMER peripheral register block.
  443. *
  444. * @param[in] val
  445. * Value to set in top value buffer register.
  446. ******************************************************************************/
  447. static __INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
  448. {
  449. timer->TOPB = val;
  450. }
  451. /***************************************************************************//**
  452. * @brief
  453. * Get top value setting for timer.
  454. *
  455. * @param[in] timer
  456. * Pointer to TIMER peripheral register block.
  457. *
  458. * @return
  459. * Current top value.
  460. ******************************************************************************/
  461. static __INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
  462. {
  463. return(timer->TOP);
  464. }
  465. /***************************************************************************//**
  466. * @brief
  467. * Set top value for timer.
  468. *
  469. * @param[in] timer
  470. * Pointer to TIMER peripheral register block.
  471. *
  472. * @param[in] val
  473. * Value to set in top value register.
  474. ******************************************************************************/
  475. static __INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
  476. {
  477. timer->TOP = val;
  478. }
  479. void TIMER_Unlock(TIMER_TypeDef *timer);
  480. /** @} (end addtogroup TIMER) */
  481. /** @} (end addtogroup EFM32_Library) */
  482. #ifdef __cplusplus
  483. }
  484. #endif
  485. #endif /* __EFM32_TIMER_H */