1 /*
2 * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef NRF_COMP_H_
33 #define NRF_COMP_H_
34
35 #include <nrfx.h>
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 /**
42 * @defgroup nrf_comp_hal COMP HAL
43 * @{
44 * @ingroup nrf_comp
45 * @brief Hardware access layer for managing the Comparator (COMP) peripheral.
46 */
47
48 /**
49 * @enum nrf_comp_input_t
50 * @brief COMP analog pin selection.
51 */
52 typedef enum
53 {
54 NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */
55 NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */
56 NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */
57 NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */
58 NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */
59 NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */
60 NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */
61 #if defined (COMP_PSEL_PSEL_AnalogInput7) || defined (__NRFX_DOXYGEN__)
62 NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7, /*!< AIN7 selected as analog input. */
63 #endif
64 #if defined (COMP_PSEL_PSEL_VddDiv2) || defined (__NRFX_DOXYGEN__)
65 NRF_COMP_VDD_DIV2 = COMP_PSEL_PSEL_VddDiv2, /*!< VDD/2 selected as analog input. */
66 #endif
67 }nrf_comp_input_t;
68
69 /**
70 * @enum nrf_comp_ref_t
71 * @brief COMP reference selection.
72 */
73 typedef enum
74 {
75 NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */
76 NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */
77 NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */
78 NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */
79 NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */
80 }nrf_comp_ref_t;
81
82 /**
83 * @enum nrf_comp_ext_ref_t
84 * @brief COMP external analog reference selection.
85 */
86 typedef enum
87 {
88 NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */
89 NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */
90 }nrf_comp_ext_ref_t;
91
92 /**
93 * @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP.
94 */
95 typedef struct
96 {
97 uint8_t th_down; /*!< THDOWN value. */
98 uint8_t th_up; /*!< THUP value. */
99 }nrf_comp_th_t;
100
101 /**
102 * @enum nrf_comp_main_mode_t
103 * @brief COMP main operation mode.
104 */
105 typedef enum
106 {
107 NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */
108 NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */
109 }nrf_comp_main_mode_t;
110
111 /**
112 * @enum nrf_comp_sp_mode_t
113 * @brief COMP speed and power mode.
114 */
115 typedef enum
116 {
117 NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */
118 NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */
119 NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */
120 }nrf_comp_sp_mode_t;
121
122 /**
123 * @enum nrf_comp_hyst_t
124 * @brief COMP comparator hysteresis.
125 */
126 typedef enum
127 {
128 NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */
129 NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */
130 }nrf_comp_hyst_t;
131
132 #if defined (COMP_ISOURCE_ISOURCE_Msk) || defined (__NRFX_DOXYGEN__)
133 /**
134 * @brief COMP current source selection on analog input.
135 */
136 typedef enum
137 {
138 NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */
139 NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */
140 NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */
141 NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */
142 }nrf_isource_t;
143 #endif
144
145 /**
146 * @enum nrf_comp_task_t
147 * @brief COMP tasks.
148 */
149 typedef enum
150 {
151 /*lint -save -e30*/
152 NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */
153 NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */
154 NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */
155 /*lint -restore*/
156 }nrf_comp_task_t;
157
158 /**
159 * @enum nrf_comp_event_t
160 * @brief COMP events.
161 */
162 typedef enum
163 {
164 /*lint -save -e30*/
165 NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */
166 NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */
167 NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */
168 NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */
169 /*lint -restore*/
170 }nrf_comp_event_t;
171
172 /**
173 * @brief COMP reference configuration.
174 */
175 typedef struct
176 {
177 nrf_comp_ref_t reference; /*!< COMP reference selection. */
178 nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */
179 }nrf_comp_ref_conf_t;
180
181
182 /**
183 * @brief Function for enabling the COMP peripheral.
184 */
185 __STATIC_INLINE void nrf_comp_enable(void);
186
187
188 /**
189 * @brief Function for disabling the COMP peripheral.
190 */
191
192 __STATIC_INLINE void nrf_comp_disable(void);
193
194 /**
195 * @brief Function for checking if the COMP peripheral is enabled.
196 *
197 * @retval true If the COMP peripheral is enabled.
198 * @retval false If the COMP peripheral is not enabled.
199 */
200 __STATIC_INLINE bool nrf_comp_enable_check(void);
201
202 /**
203 * @brief Function for setting the reference source.
204 *
205 * @param[in] reference COMP reference selection.
206 */
207 __STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference);
208
209
210 /**
211 * @brief Function for setting the external analog reference source.
212 *
213 * @param[in] ext_ref COMP external analog reference selection.
214 */
215 __STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref);
216
217
218 /**
219 * @brief Function for setting threshold voltages.
220 *
221 * @param[in] threshold COMP VDOWN and VUP thresholds.
222 */
223 __STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold);
224
225
226 /**
227 * @brief Function for setting the main mode.
228 *
229 * @param[in] main_mode COMP main operation mode.
230 */
231 __STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode);
232
233
234 /**
235 * @brief Function for setting the speed mode.
236 *
237 * @param[in] speed_mode COMP speed and power mode.
238 */
239 __STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode);
240
241
242 /**
243 * @brief Function for setting the hysteresis.
244 *
245 * @param[in] hyst COMP comparator hysteresis.
246 */
247 __STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst);
248
249
250 #if defined (COMP_ISOURCE_ISOURCE_Msk) || defined (__NRFX_DOXYGEN__)
251 /**
252 * @brief Function for setting the current source on the analog input.
253 *
254 * @param[in] isource COMP current source selection on analog input.
255 */
256 __STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource);
257 #endif
258
259
260 /**
261 * @brief Function for selecting the active input of the COMP.
262 *
263 * @param[in] input Input to be selected.
264 */
265 __STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input);
266
267
268 /**
269 * @brief Function for getting the last COMP compare result.
270 *
271 * @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-.
272 *
273 * @note If VIN+ == VIN-, the return value depends on the previous result.
274 */
275 __STATIC_INLINE uint32_t nrf_comp_result_get(void);
276
277
278 /**
279 * @brief Function for enabling interrupts from COMP.
280 *
281 * @param[in] comp_int_mask Mask of interrupts to be enabled.
282 *
283 * @sa nrf_comp_int_enable_check()
284 */
285 __STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask);
286
287 /**
288 * @brief Function for disabling interrupts from COMP.
289 *
290 * @param[in] comp_int_mask Mask of interrupts to be disabled.
291 *
292 * @sa nrf_comp_int_enable_check()
293 */
294 __STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask);
295
296
297 /**
298 * @brief Function for getting the enabled interrupts of COMP.
299 *
300 * @param[in] comp_int_mask Mask of interrupts to be checked.
301 *
302 * @retval true If any interrupts of the specified mask are enabled.
303 */
304 __STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask);
305
306
307
308 /**
309 * @brief Function for getting the address of a specific COMP task register.
310 *
311 * @param[in] comp_task COMP task.
312 *
313 * @return Address of the specified COMP task.
314 */
315 __STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task);
316
317
318 /**
319 * @brief Function for getting the address of a specific COMP event register.
320 *
321 * @param[in] comp_event COMP event.
322 *
323 * @return Address of the specified COMP event.
324 */
325 __STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event);
326
327
328 /**
329 * @brief Function for setting COMP shorts.
330 *
331 * @param[in] comp_short_mask COMP shorts by mask.
332 *
333 */
334 __STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask);
335
336
337 /**
338 * @brief Function for clearing COMP shorts by mask.
339 *
340 * @param[in] comp_short_mask COMP shorts to be cleared.
341 *
342 */
343 __STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask);
344
345
346 /**
347 * @brief Function for setting a specific COMP task.
348 *
349 * @param[in] comp_task COMP task to be set.
350 *
351 */
352 __STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task);
353
354
355 /**
356 * @brief Function for clearing a specific COMP event.
357 *
358 * @param[in] comp_event COMP event to be cleared.
359 *
360 */
361 __STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event);
362
363
364 /**
365 * @brief Function for getting the state of a specific COMP event.
366 *
367 * @retval true If the specified COMP event is active.
368 *
369 */
370 __STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event);
371
372 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
373
nrf_comp_enable(void)374 __STATIC_INLINE void nrf_comp_enable(void)
375 {
376 NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos);
377 }
378
nrf_comp_disable(void)379 __STATIC_INLINE void nrf_comp_disable(void)
380 {
381 NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos);
382 }
383
nrf_comp_enable_check(void)384 __STATIC_INLINE bool nrf_comp_enable_check(void)
385 {
386 return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled);
387 }
388
nrf_comp_ref_set(nrf_comp_ref_t reference)389 __STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference)
390 {
391 NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos);
392 }
393
nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref)394 __STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref)
395 {
396 NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos);
397 }
398
nrf_comp_th_set(nrf_comp_th_t threshold)399 __STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold)
400 {
401 NRF_COMP->TH =
402 ((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) |
403 ((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk);
404 }
405
nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode)406 __STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode)
407 {
408 NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos);
409 }
410
nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode)411 __STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode)
412 {
413 NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos);
414 }
415
nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst)416 __STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst)
417 {
418 NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk;
419 }
420
421 #if defined (COMP_ISOURCE_ISOURCE_Msk)
nrf_comp_isource_set(nrf_isource_t isource)422 __STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource)
423 {
424 NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk;
425 }
426 #endif
427
nrf_comp_input_select(nrf_comp_input_t input)428 __STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input)
429 {
430 NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos);
431 }
432
nrf_comp_result_get(void)433 __STATIC_INLINE uint32_t nrf_comp_result_get(void)
434 {
435 return (uint32_t)NRF_COMP->RESULT;
436 }
437
nrf_comp_int_enable(uint32_t comp_int_mask)438 __STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask)
439 {
440 NRF_COMP->INTENSET = comp_int_mask;
441 }
442
nrf_comp_int_disable(uint32_t comp_int_mask)443 __STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask)
444 {
445 NRF_COMP->INTENCLR = comp_int_mask;
446 }
447
nrf_comp_int_enable_check(uint32_t comp_int_mask)448 __STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask)
449 {
450 return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN.
451 }
452
nrf_comp_task_address_get(nrf_comp_task_t comp_task)453 __STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task)
454 {
455 return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task);
456 }
457
nrf_comp_event_address_get(nrf_comp_event_t comp_event)458 __STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event)
459 {
460 return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event);
461 }
462
nrf_comp_shorts_enable(uint32_t comp_short_mask)463 __STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask)
464 {
465 NRF_COMP->SHORTS |= comp_short_mask;
466 }
467
nrf_comp_shorts_disable(uint32_t comp_short_mask)468 __STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask)
469 {
470 NRF_COMP->SHORTS &= ~comp_short_mask;
471 }
472
nrf_comp_task_trigger(nrf_comp_task_t comp_task)473 __STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task)
474 {
475 *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1;
476 }
477
nrf_comp_event_clear(nrf_comp_event_t comp_event)478 __STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event)
479 {
480 *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0;
481 #if __CORTEX_M == 0x04
482 volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event));
483 (void)dummy;
484 #endif
485 }
486
nrf_comp_event_check(nrf_comp_event_t comp_event)487 __STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event)
488 {
489 return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event));
490 }
491
492 #endif // SUPPRESS_INLINE_IMPLEMENTATION
493
494 /** @} */
495
496 #ifdef __cplusplus
497 }
498 #endif
499
500 #endif // NRF_COMP_H_
501