efm32_pcnt.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /***************************************************************************//**
  2. * @file
  3. * @brief Pulse Counter (PCNT) 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_PCNT_H
  29. #define __EFM32_PCNT_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 PCNT
  41. * @{
  42. ******************************************************************************/
  43. /*******************************************************************************
  44. ******************************* DEFINES ***********************************
  45. ******************************************************************************/
  46. /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
  47. /** PCNT counter width mask. */
  48. /* TBD: Remove use with efm32 include file defines when corrected */
  49. #define PCNT_WIDTH_MASK 0xff
  50. /** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
  51. /*******************************************************************************
  52. ******************************** ENUMS ************************************
  53. ******************************************************************************/
  54. /** Mode selection. */
  55. typedef enum
  56. {
  57. /** Disable pulse counter. */
  58. pcntModeDisable = _PCNT_CTRL_MODE_DISABLE,
  59. /** Single input LFACLK oversampling mode (available in EM0-EM2). */
  60. pcntModeOvsSingle = _PCNT_CTRL_MODE_OVSSINGLE,
  61. /** Externally clocked single input counter mode (available in EM0-EM3). */
  62. pcntModeExtSingle = _PCNT_CTRL_MODE_EXTCLKSINGLE,
  63. /** Externally clocked quadrature decoder mode (available in EM0-EM3). */
  64. pcntModeExtQuad = _PCNT_CTRL_MODE_EXTCLKQUAD
  65. } PCNT_Mode_TypeDef;
  66. /*******************************************************************************
  67. ******************************* STRUCTS ***********************************
  68. ******************************************************************************/
  69. /** Init structure. */
  70. typedef struct
  71. {
  72. /** Mode to operate in. */
  73. PCNT_Mode_TypeDef mode;
  74. /**
  75. * Initial counter value (refer to reference manual for max value allowed).
  76. * Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
  77. * If using #pcntModeExtSingle or #pcntModeExtQuad modes, the counter
  78. * value is reset to HW reset value.
  79. */
  80. uint32_t counter;
  81. /**
  82. * Initial top value (refer to reference manual for max value allowed).
  83. * Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
  84. * If using #pcntModeExtSingle or #pcntModeExtQuad modes, the top
  85. * value is reset to HW reset value.
  86. */
  87. uint32_t top;
  88. /**
  89. * Polarity of incoming edge.
  90. * @li #pcntModeExtSingle mode - if false, positive edges are counted,
  91. * otherwise negative edges.
  92. * @li #pcntModeExtQuad mode - if true, counting direction is inverted.
  93. */
  94. bool negEdge;
  95. /**
  96. * Counting direction, only applicable for #pcntModeOvsSingle and
  97. * #pcntModeExtSingle modes.
  98. */
  99. bool countDown;
  100. /** Enable filter, only available in #pcntModeOvsSingle mode. */
  101. bool filter;
  102. } PCNT_Init_TypeDef;
  103. /** Default config for PCNT init structure. */
  104. /* TBD: Remove PCNT_WIDTH_MASK use when _PCNT_TOP_RESETVALUE corrected */
  105. #define PCNT_INIT_DEFAULT \
  106. { pcntModeDisable, /* Disabled by default. */ \
  107. _PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \
  108. _PCNT_TOP_RESETVALUE & PCNT_WIDTH_MASK, /* Default counter HW reset value. */ \
  109. false, /* Use positive edge. */ \
  110. false, /* Up-counting. */ \
  111. false /* Filter disabled. */ \
  112. }
  113. /*******************************************************************************
  114. ***************************** PROTOTYPES **********************************
  115. ******************************************************************************/
  116. /***************************************************************************//**
  117. * @brief
  118. * Get pulse counter value.
  119. *
  120. * @param[in] pcnt
  121. * Pointer to PCNT peripheral register block.
  122. *
  123. * @return
  124. * Current pulse counter value.
  125. ******************************************************************************/
  126. static __INLINE uint32_t PCNT_CounterGet(PCNT_TypeDef *pcnt)
  127. {
  128. return(pcnt->CNT);
  129. }
  130. void PCNT_CounterReset(PCNT_TypeDef *pcnt);
  131. void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top);
  132. /***************************************************************************//**
  133. * @brief
  134. * Set counter value.
  135. *
  136. * @details
  137. * The pulse counter is disabled while changing counter value, and reenabled
  138. * (if originally enabled) when counter value has been set.
  139. *
  140. * @note
  141. * This function will stall until synchronization to low frequency domain is
  142. * completed. For that reason, it should normally not be used when using
  143. * an external clock to clock the PCNT module, since stall time may be
  144. * undefined in that case. The counter should normally only be set when
  145. * operating in (or about to enable) #pcntModeOvsSingle mode.
  146. *
  147. * @param[in] pcnt
  148. * Pointer to PCNT peripheral register block.
  149. *
  150. * @param[in] count
  151. * Value to set in counter register.
  152. ******************************************************************************/
  153. static __INLINE void PCNT_CounterSet(PCNT_TypeDef *pcnt, uint32_t count)
  154. {
  155. PCNT_CounterTopSet(pcnt, count, pcnt->TOP);
  156. }
  157. void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode);
  158. void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable);
  159. void PCNT_Init(PCNT_TypeDef *pcnt, PCNT_Init_TypeDef *init);
  160. /***************************************************************************//**
  161. * @brief
  162. * Clear one or more pending PCNT interrupts.
  163. *
  164. * @param[in] pcnt
  165. * Pointer to PCNT peripheral register block.
  166. *
  167. * @param[in] flags
  168. * Pending PCNT interrupt source to clear. Use a logical OR combination
  169. * of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
  170. ******************************************************************************/
  171. static __INLINE void PCNT_IntClear(PCNT_TypeDef *pcnt, uint32_t flags)
  172. {
  173. pcnt->IFC = flags;
  174. }
  175. /***************************************************************************//**
  176. * @brief
  177. * Disable one or more PCNT interrupts.
  178. *
  179. * @param[in] pcnt
  180. * Pointer to PCNT peripheral register block.
  181. *
  182. * @param[in] flags
  183. * PCNT interrupt sources to disable. Use a logical OR combination of
  184. * valid interrupt flags for the PCNT module (PCNT_IF_nnn).
  185. ******************************************************************************/
  186. static __INLINE void PCNT_IntDisable(PCNT_TypeDef *pcnt, uint32_t flags)
  187. {
  188. pcnt->IEN &= ~(flags);
  189. }
  190. /***************************************************************************//**
  191. * @brief
  192. * Enable one or more PCNT interrupts.
  193. *
  194. * @note
  195. * Depending on the use, a pending interrupt may already be set prior to
  196. * enabling the interrupt. Consider using PCNT_IntClear() prior to enabling
  197. * if such a pending interrupt should be ignored.
  198. *
  199. * @param[in] pcnt
  200. * Pointer to PCNT peripheral register block.
  201. *
  202. * @param[in] flags
  203. * PCNT interrupt sources to enable. Use a logical OR combination of
  204. * valid interrupt flags for the PCNT module (PCNT_IF_nnn).
  205. ******************************************************************************/
  206. static __INLINE void PCNT_IntEnable(PCNT_TypeDef *pcnt, uint32_t flags)
  207. {
  208. pcnt->IEN |= flags;
  209. }
  210. /***************************************************************************//**
  211. * @brief
  212. * Get pending PCNT interrupt flags.
  213. *
  214. * @note
  215. * The event bits are not cleared by the use of this function.
  216. *
  217. * @param[in] pcnt
  218. * Pointer to PCNT peripheral register block.
  219. *
  220. * @return
  221. * PCNT interrupt sources pending. A logical OR combination of valid
  222. * interrupt flags for the PCNT module (PCNT_IF_nnn).
  223. ******************************************************************************/
  224. static __INLINE uint32_t PCNT_IntGet(PCNT_TypeDef *pcnt)
  225. {
  226. return(pcnt->IF);
  227. }
  228. /***************************************************************************//**
  229. * @brief
  230. * Set one or more pending PCNT interrupts from SW.
  231. *
  232. * @param[in] pcnt
  233. * Pointer to PCNT peripheral register block.
  234. *
  235. * @param[in] flags
  236. * PCNT interrupt sources to set to pending. Use a logical OR combination
  237. * of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
  238. ******************************************************************************/
  239. static __INLINE void PCNT_IntSet(PCNT_TypeDef *pcnt, uint32_t flags)
  240. {
  241. pcnt->IFS = flags;
  242. }
  243. void PCNT_Reset(PCNT_TypeDef *pcnt);
  244. /***************************************************************************//**
  245. * @brief
  246. * Get pulse counter top buffer value.
  247. *
  248. * @param[in] pcnt
  249. * Pointer to PCNT peripheral register block.
  250. *
  251. * @return
  252. * Current pulse counter top buffer value.
  253. ******************************************************************************/
  254. static __INLINE uint32_t PCNT_TopBufferGet(PCNT_TypeDef *pcnt)
  255. {
  256. return(pcnt->TOPB);
  257. }
  258. void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val);
  259. /***************************************************************************//**
  260. * @brief
  261. * Get pulse counter top value.
  262. *
  263. * @param[in] pcnt
  264. * Pointer to PCNT peripheral register block.
  265. *
  266. * @return
  267. * Current pulse counter top value.
  268. ******************************************************************************/
  269. static __INLINE uint32_t PCNT_TopGet(PCNT_TypeDef *pcnt)
  270. {
  271. return(pcnt->TOP);
  272. }
  273. void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val);
  274. /** @} (end addtogroup PCNT) */
  275. /** @} (end addtogroup EFM32_Library) */
  276. #ifdef __cplusplus
  277. }
  278. #endif
  279. #endif /* __EFM32_PCNT_H */