nrf_lpcomp.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. /**
  13. * @file
  14. * @brief LPCOMP HAL API.
  15. */
  16. #ifndef NRF_LPCOMP_H_
  17. #define NRF_LPCOMP_H_
  18. /**
  19. * @defgroup nrf_lpcomp_hal LPCOMP HAL
  20. * @{
  21. * @ingroup nrf_lpcomp
  22. * @brief Hardware access layer for managing the Low Power Comparator (LPCOMP).
  23. */
  24. #include "nrf.h"
  25. #include <stdbool.h>
  26. #include <stddef.h>
  27. #include <stdint.h>
  28. /**
  29. * @enum nrf_lpcomp_ref_t
  30. * @brief LPCOMP reference selection.
  31. */
  32. typedef enum
  33. {
  34. #ifdef NRF51
  35. NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */
  36. NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */
  37. NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */
  38. NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling, /**< Use supply with a 4/8 prescaler as reference. */
  39. NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */
  40. NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */
  41. NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */
  42. #elif defined NRF52
  43. NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */
  44. NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */
  45. NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */
  46. NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_Ref4_8Vdd, /**< Use supply with a 4/8 prescaler as reference. */
  47. NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_Ref5_8Vdd, /**< Use supply with a 5/8 prescaler as reference. */
  48. NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */
  49. NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */
  50. NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */
  51. NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */
  52. NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */
  53. NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */
  54. NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */
  55. NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */
  56. NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */
  57. NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */
  58. #endif
  59. NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef |
  60. (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */
  61. NRF_LPCOMP_CONFIG_REF_EXT_REF1 = LPCOMP_REFSEL_REFSEL_ARef |
  62. (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 << 16), /**< External reference 1. */
  63. } nrf_lpcomp_ref_t;
  64. /**
  65. * @enum nrf_lpcomp_input_t
  66. * @brief LPCOMP input selection.
  67. */
  68. typedef enum
  69. {
  70. NRF_LPCOMP_INPUT_0 = LPCOMP_PSEL_PSEL_AnalogInput0, /**< Input 0. */
  71. NRF_LPCOMP_INPUT_1 = LPCOMP_PSEL_PSEL_AnalogInput1, /**< Input 1. */
  72. NRF_LPCOMP_INPUT_2 = LPCOMP_PSEL_PSEL_AnalogInput2, /**< Input 2. */
  73. NRF_LPCOMP_INPUT_3 = LPCOMP_PSEL_PSEL_AnalogInput3, /**< Input 3. */
  74. NRF_LPCOMP_INPUT_4 = LPCOMP_PSEL_PSEL_AnalogInput4, /**< Input 4. */
  75. NRF_LPCOMP_INPUT_5 = LPCOMP_PSEL_PSEL_AnalogInput5, /**< Input 5. */
  76. NRF_LPCOMP_INPUT_6 = LPCOMP_PSEL_PSEL_AnalogInput6, /**< Input 6. */
  77. NRF_LPCOMP_INPUT_7 = LPCOMP_PSEL_PSEL_AnalogInput7 /**< Input 7. */
  78. } nrf_lpcomp_input_t;
  79. /**
  80. * @enum nrf_lpcomp_detect_t
  81. * @brief LPCOMP detection type selection.
  82. */
  83. typedef enum
  84. {
  85. NRF_LPCOMP_DETECT_CROSS = LPCOMP_ANADETECT_ANADETECT_Cross, /**< Generate ANADETEC on crossing, both upwards and downwards crossing. */
  86. NRF_LPCOMP_DETECT_UP = LPCOMP_ANADETECT_ANADETECT_Up, /**< Generate ANADETEC on upwards crossing only. */
  87. NRF_LPCOMP_DETECT_DOWN = LPCOMP_ANADETECT_ANADETECT_Down /**< Generate ANADETEC on downwards crossing only. */
  88. } nrf_lpcomp_detect_t;
  89. /**
  90. * @enum nrf_lpcomp_task_t
  91. * @brief LPCOMP tasks.
  92. */
  93. typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
  94. {
  95. NRF_LPCOMP_TASK_START = offsetof(NRF_LPCOMP_Type, TASKS_START), /**< LPCOMP start sampling task. */
  96. NRF_LPCOMP_TASK_STOP = offsetof(NRF_LPCOMP_Type, TASKS_STOP), /**< LPCOMP stop sampling task. */
  97. NRF_LPCOMP_TASK_SAMPLE = offsetof(NRF_LPCOMP_Type, TASKS_SAMPLE) /**< Sample comparator value. */
  98. } nrf_lpcomp_task_t; /*lint -restore*/
  99. /**
  100. * @enum nrf_lpcomp_event_t
  101. * @brief LPCOMP events.
  102. */
  103. typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
  104. {
  105. NRF_LPCOMP_EVENT_READY = offsetof(NRF_LPCOMP_Type, EVENTS_READY), /**< LPCOMP is ready and output is valid. */
  106. NRF_LPCOMP_EVENT_DOWN = offsetof(NRF_LPCOMP_Type, EVENTS_DOWN), /**< Input voltage crossed the threshold going down. */
  107. NRF_LPCOMP_EVENT_UP = offsetof(NRF_LPCOMP_Type, EVENTS_UP), /**< Input voltage crossed the threshold going up. */
  108. NRF_LPCOMP_EVENT_CROSS = offsetof(NRF_LPCOMP_Type, EVENTS_CROSS) /**< Input voltage crossed the threshold in any direction. */
  109. } nrf_lpcomp_event_t; /*lint -restore*/
  110. /**
  111. * @enum nrf_lpcomp_short_mask_t
  112. * @brief LPCOMP shorts masks.
  113. */
  114. typedef enum
  115. {
  116. NRF_LPCOMP_SHORT_CROSS_STOP_MASK = LPCOMP_SHORTS_CROSS_STOP_Msk, /*!< Short between CROSS event and STOP task. */
  117. NRF_LPCOMP_SHORT_UP_STOP_MASK = LPCOMP_SHORTS_UP_STOP_Msk, /*!< Short between UP event and STOP task. */
  118. NRF_LPCOMP_SHORT_DOWN_STOP_MASK = LPCOMP_SHORTS_DOWN_STOP_Msk, /*!< Short between DOWN event and STOP task. */
  119. NRF_LPCOMP_SHORT_READY_STOP_MASK = LPCOMP_SHORTS_READY_STOP_Msk, /*!< Short between READY event and STOP task. */
  120. NRF_LPCOMP_SHORT_READY_SAMPLE_MASK = LPCOMP_SHORTS_READY_SAMPLE_Msk /*!< Short between READY event and SAMPLE task. */
  121. } nrf_lpcomp_short_mask_t;
  122. /** @brief LPCOMP configuration. */
  123. typedef struct
  124. {
  125. nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */
  126. nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */
  127. } nrf_lpcomp_config_t;
  128. /** Default LPCOMP configuration. */
  129. #define NRF_LPCOMP_CONFIG_DEFAULT { NRF_LPCOMP_REF_SUPPLY_FOUR_EIGHT, NRF_LPCOMP_DETECT_DOWN }
  130. /**
  131. * @brief Function for configuring LPCOMP.
  132. *
  133. * This function powers on LPCOMP and configures it. LPCOMP is in DISABLE state after configuration,
  134. * so it must be enabled before using it. All shorts are inactive, events are cleared, and LPCOMP is stopped.
  135. *
  136. * @param[in] p_config Configuration.
  137. */
  138. __STATIC_INLINE void nrf_lpcomp_configure(const nrf_lpcomp_config_t * p_config)
  139. {
  140. NRF_LPCOMP->TASKS_STOP = 1;
  141. NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
  142. NRF_LPCOMP->REFSEL =
  143. (p_config->reference << LPCOMP_REFSEL_REFSEL_Pos) & LPCOMP_REFSEL_REFSEL_Msk;
  144. //If external source is choosen extract analog reference index.
  145. if ((p_config->reference & LPCOMP_REFSEL_REFSEL_ARef)==LPCOMP_REFSEL_REFSEL_ARef)
  146. {
  147. uint32_t extref = p_config->reference >> 16;
  148. NRF_LPCOMP->EXTREFSEL = (extref << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) & LPCOMP_EXTREFSEL_EXTREFSEL_Msk;
  149. }
  150. NRF_LPCOMP->ANADETECT =
  151. (p_config->detection << LPCOMP_ANADETECT_ANADETECT_Pos) & LPCOMP_ANADETECT_ANADETECT_Msk;
  152. NRF_LPCOMP->SHORTS = 0;
  153. NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk |
  154. LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk;
  155. }
  156. /**
  157. * @brief Function for selecting the LPCOMP input.
  158. *
  159. * This function selects the active input of LPCOMP.
  160. *
  161. * @param[in] input Input to be selected.
  162. */
  163. __STATIC_INLINE void nrf_lpcomp_input_select(nrf_lpcomp_input_t input)
  164. {
  165. uint32_t lpcomp_enable_state = NRF_LPCOMP->ENABLE;
  166. NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
  167. NRF_LPCOMP->PSEL =
  168. ((uint32_t)input << LPCOMP_PSEL_PSEL_Pos) | (NRF_LPCOMP->PSEL & ~LPCOMP_PSEL_PSEL_Msk);
  169. NRF_LPCOMP->ENABLE = lpcomp_enable_state;
  170. }
  171. /**
  172. * @brief Function for enabling the Low Power Comparator.
  173. *
  174. * This function enables LPCOMP.
  175. *
  176. */
  177. __STATIC_INLINE void nrf_lpcomp_enable(void)
  178. {
  179. NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled << LPCOMP_ENABLE_ENABLE_Pos;
  180. NRF_LPCOMP->EVENTS_READY = 0;
  181. NRF_LPCOMP->EVENTS_DOWN = 0;
  182. NRF_LPCOMP->EVENTS_UP = 0;
  183. NRF_LPCOMP->EVENTS_CROSS = 0;
  184. }
  185. /**
  186. * @brief Function for disabling the Low Power Comparator.
  187. *
  188. * This function disables LPCOMP.
  189. *
  190. */
  191. __STATIC_INLINE void nrf_lpcomp_disable(void)
  192. {
  193. NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
  194. }
  195. /**
  196. * @brief Function for getting the last LPCOMP compare result.
  197. *
  198. * @return The last compare result. If 0 then VIN+ < VIN-, if 1 then the opposite.
  199. */
  200. __STATIC_INLINE uint32_t nrf_lpcomp_result_get(void)
  201. {
  202. return (uint32_t)NRF_LPCOMP->RESULT;
  203. }
  204. /**
  205. * @brief Function for enabling interrupts from LPCOMP.
  206. *
  207. * @param[in] lpcomp_int_mask Mask of interrupts to be enabled.
  208. *
  209. * @sa nrf_lpcomp_int_disable()
  210. * @sa nrf_lpcomp_int_enable_check()
  211. */
  212. __STATIC_INLINE void nrf_lpcomp_int_enable(uint32_t lpcomp_int_mask)
  213. {
  214. NRF_LPCOMP->INTENSET = lpcomp_int_mask;
  215. }
  216. /**
  217. * @brief Function for disabling interrupts from LPCOMP.
  218. *
  219. * @param[in] lpcomp_int_mask Mask of interrupts to be disabled.
  220. *
  221. * @sa nrf_lpcomp_int_enable()
  222. * @sa nrf_lpcomp_int_enable_check()
  223. */
  224. __STATIC_INLINE void nrf_lpcomp_int_disable(uint32_t lpcomp_int_mask)
  225. {
  226. NRF_LPCOMP->INTENCLR = lpcomp_int_mask;
  227. }
  228. /**
  229. * @brief Function for getting the enabled interrupts of LPCOMP.
  230. *
  231. * @param[in] lpcomp_int_mask Mask of interrupts to be checked.
  232. *
  233. * @retval true If any of interrupts of the specified mask are enabled.
  234. *
  235. * @sa nrf_lpcomp_int_enable()
  236. * @sa nrf_lpcomp_int_disable()
  237. */
  238. __STATIC_INLINE bool nrf_lpcomp_int_enable_check(uint32_t lpcomp_int_mask)
  239. {
  240. return (NRF_LPCOMP->INTENSET & lpcomp_int_mask); // when read this register will return the value of INTEN.
  241. }
  242. /**
  243. * @brief Function for getting the address of a specific LPCOMP task register.
  244. *
  245. * @param[in] lpcomp_task LPCOMP task.
  246. *
  247. * @return The address of the specified LPCOMP task.
  248. */
  249. __STATIC_INLINE uint32_t * nrf_lpcomp_task_address_get(nrf_lpcomp_task_t lpcomp_task)
  250. {
  251. return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_task);
  252. }
  253. /**
  254. * @brief Function for getting the address of a specific LPCOMP event register.
  255. *
  256. * @param[in] lpcomp_event LPCOMP event.
  257. *
  258. * @return The address of the specified LPCOMP event.
  259. */
  260. __STATIC_INLINE uint32_t * nrf_lpcomp_event_address_get(nrf_lpcomp_event_t lpcomp_event)
  261. {
  262. return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event);
  263. }
  264. /**
  265. * @brief Function for setting LPCOMP shorts.
  266. *
  267. * @param[in] lpcomp_short_mask LPCOMP shorts by mask.
  268. *
  269. */
  270. __STATIC_INLINE void nrf_lpcomp_shorts_enable(uint32_t lpcomp_short_mask)
  271. {
  272. NRF_LPCOMP->SHORTS |= lpcomp_short_mask;
  273. }
  274. /**
  275. * @brief Function for clearing LPCOMP shorts by mask.
  276. *
  277. * @param[in] lpcomp_short_mask LPCOMP shorts to be cleared.
  278. *
  279. */
  280. __STATIC_INLINE void nrf_lpcomp_shorts_disable(uint32_t lpcomp_short_mask)
  281. {
  282. NRF_LPCOMP->SHORTS &= ~lpcomp_short_mask;
  283. }
  284. /**
  285. * @brief Function for setting a specific LPCOMP task.
  286. *
  287. * @param[in] lpcomp_task LPCOMP task to be set.
  288. *
  289. */
  290. __STATIC_INLINE void nrf_lpcomp_task_trigger(nrf_lpcomp_task_t lpcomp_task)
  291. {
  292. *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_task) ) = 1;
  293. }
  294. /**
  295. * @brief Function for clearing a specific LPCOMP event.
  296. *
  297. * @param[in] lpcomp_event LPCOMP event to be cleared.
  298. *
  299. */
  300. __STATIC_INLINE void nrf_lpcomp_event_clear(nrf_lpcomp_event_t lpcomp_event)
  301. {
  302. *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event) ) = 0;
  303. }
  304. /**
  305. * @brief Function for getting the state of a specific LPCOMP event.
  306. *
  307. * @retval true If the specified LPCOMP event is active.
  308. *
  309. */
  310. __STATIC_INLINE bool nrf_lpcomp_event_check(nrf_lpcomp_event_t lpcomp_event)
  311. {
  312. return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event));
  313. }
  314. /**
  315. *@}
  316. **/
  317. #endif /* NRF_LPCOMP_H_ */