1 /*
2 * Copyright (c) 2021 - 2025, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRFY_COMP_H__
35 #define NRFY_COMP_H__
36
37 #include <nrfx.h>
38 #include <hal/nrf_comp.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 NRFY_STATIC_INLINE void __nrfy_internal_comp_event_enabled_clear(NRF_COMP_Type * p_reg,
45 uint32_t mask,
46 nrf_comp_event_t event);
47
48 NRFY_STATIC_INLINE bool __nrfy_internal_comp_event_handle(NRF_COMP_Type * p_reg,
49 uint32_t mask,
50 nrf_comp_event_t event,
51 uint32_t * p_evt_mask);
52
53 NRFY_STATIC_INLINE uint32_t __nrfy_internal_comp_events_process(NRF_COMP_Type * p_reg,
54 uint32_t mask);
55
56 /**
57 * @defgroup nrfy_comp COMP HALY
58 * @{
59 * @ingroup nrf_comp
60 * @brief Hardware access layer with cache and barrier support for managing the COMP peripheral.
61 */
62
63 #if NRF_COMP_HAS_ISOURCE || defined(__NRFX_DOXYGEN__)
64 /** @refhal{NRF_COMP_HAS_ISOURCE} */
65 #define NRFY_COMP_HAS_ISOURCE 1
66 #else
67 #define NRFY_COMP_HAS_ISOURCE 0
68 #endif
69
70 /** @brief COMP configuration structure. */
71 typedef struct
72 {
73 nrf_comp_ref_t reference; ///< Reference selection.
74 nrf_comp_ext_ref_t ext_ref; ///< External analog reference selection.
75 nrf_comp_main_mode_t main_mode; ///< Main operation mode.
76 nrf_comp_th_t threshold; ///< Structure holding THDOWN and THUP values needed by the COMP_TH register.
77 nrf_comp_sp_mode_t speed_mode; ///< Speed and power mode.
78 nrf_comp_hyst_t hyst; ///< Comparator hysteresis.
79 #if NRFY_COMP_HAS_ISOURCE
80 nrf_isource_t isource; ///< Current source selected on analog input.
81 #endif
82 nrf_comp_input_t input; ///< Input to be monitored.
83 } nrfy_comp_config_t;
84
85 /**
86 * @brief Function for configuring the COMP.
87 *
88 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
89 * @param[in] p_config Pointer to the peripheral configuration structure.
90 */
nrfy_comp_periph_configure(NRF_COMP_Type * p_reg,nrfy_comp_config_t const * p_config)91 NRFY_STATIC_INLINE void nrfy_comp_periph_configure(NRF_COMP_Type * p_reg,
92 nrfy_comp_config_t const * p_config)
93 {
94 nrf_comp_ref_set(p_reg, p_config->reference);
95 if (p_config->reference == NRF_COMP_REF_AREF)
96 {
97 nrf_comp_ext_ref_set(p_reg, p_config->ext_ref);
98 }
99 nrf_comp_th_set(p_reg, p_config->threshold);
100 nrf_comp_main_mode_set(p_reg, p_config->main_mode);
101 nrf_comp_speed_mode_set(p_reg, p_config->speed_mode);
102 nrf_comp_hysteresis_set(p_reg, p_config->hyst);
103 #if NRF_COMP_HAS_ISOURCE
104 nrf_comp_isource_set(p_reg, p_config->isource);
105 #endif
106 nrf_comp_input_select(p_reg, p_config->input);
107 nrf_barrier_w();
108 }
109
110 /**
111 * @brief Function for initializing the specified COMP interrupts.
112 *
113 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
114 * @param[in] mask Mask of interrupts to be initialized.
115 * @param[in] irq_priority Interrupt priority.
116 * @param[in] enable True if the interrupts are to be enabled, false otherwise.
117 */
nrfy_comp_int_init(NRF_COMP_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)118 NRFY_STATIC_INLINE void nrfy_comp_int_init(NRF_COMP_Type * p_reg,
119 uint32_t mask,
120 uint8_t irq_priority,
121 bool enable)
122 {
123
124 __nrfy_internal_comp_event_enabled_clear(p_reg, mask, NRF_COMP_EVENT_READY);
125 __nrfy_internal_comp_event_enabled_clear(p_reg, mask, NRF_COMP_EVENT_DOWN);
126 __nrfy_internal_comp_event_enabled_clear(p_reg, mask, NRF_COMP_EVENT_UP);
127 __nrfy_internal_comp_event_enabled_clear(p_reg, mask, NRF_COMP_EVENT_CROSS);
128 nrf_barrier_w();
129
130 NRFY_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
131 NRFY_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
132 if (enable)
133 {
134 nrf_comp_int_enable(p_reg, mask);
135 }
136 nrf_barrier_w();
137 }
138
139 /**
140 * @brief Function for uninitializing the COMP interrupts.
141 *
142 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
143 */
nrfy_comp_int_uninit(NRF_COMP_Type * p_reg)144 NRFY_STATIC_INLINE void nrfy_comp_int_uninit(NRF_COMP_Type * p_reg)
145 {
146 NRFY_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
147 nrf_barrier_w();
148 }
149
150 /**
151 * @brief Function for processing the specified COMP events.
152 *
153 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
154 * @param[in] mask Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK().
155 *
156 * @return Mask of events that were generated and processed.
157 * To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
158 */
nrfy_comp_events_process(NRF_COMP_Type * p_reg,uint32_t mask)159 NRFY_STATIC_INLINE uint32_t nrfy_comp_events_process(NRF_COMP_Type * p_reg,
160 uint32_t mask)
161 {
162 uint32_t evt_mask = __nrfy_internal_comp_events_process(p_reg, mask);
163 nrf_barrier_w();
164 return evt_mask;
165 }
166
167 /**
168 * @brief Function for reading the current state of the COMP.
169 *
170 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
171 *
172 * @retval 0 The input voltage is below the threshold.
173 * @retval 1 The input voltage is above the threshold.
174 */
nrfy_comp_sample(NRF_COMP_Type * p_reg)175 NRFY_STATIC_INLINE uint32_t nrfy_comp_sample(NRF_COMP_Type * p_reg)
176 {
177 nrf_comp_task_trigger(p_reg, NRF_COMP_TASK_SAMPLE);
178 nrf_barrier_rw();
179 uint32_t sample = nrf_comp_result_get(p_reg);
180 nrf_barrier_r();
181 return sample;
182 }
183
184 /** @refhal{nrf_comp_enable} */
nrfy_comp_enable(NRF_COMP_Type * p_reg)185 NRFY_STATIC_INLINE void nrfy_comp_enable(NRF_COMP_Type * p_reg)
186 {
187 nrf_comp_enable(p_reg);
188 nrf_barrier_w();
189 }
190
191 /** @refhal{nrf_comp_disable} */
nrfy_comp_disable(NRF_COMP_Type * p_reg)192 NRFY_STATIC_INLINE void nrfy_comp_disable(NRF_COMP_Type * p_reg)
193 {
194 nrf_comp_disable(p_reg);
195 nrf_barrier_w();
196 }
197
198 /** @refhal{nrf_comp_enable_check} */
nrfy_comp_enable_check(NRF_COMP_Type const * p_reg)199 NRFY_STATIC_INLINE bool nrfy_comp_enable_check(NRF_COMP_Type const * p_reg)
200 {
201 nrf_barrier_rw();
202 bool check = nrf_comp_enable_check(p_reg);
203 nrf_barrier_r();
204 return check;
205 }
206
207 /** @refhal{nrf_comp_ref_set} */
nrfy_comp_ref_set(NRF_COMP_Type * p_reg,nrf_comp_ref_t reference)208 NRFY_STATIC_INLINE void nrfy_comp_ref_set(NRF_COMP_Type * p_reg, nrf_comp_ref_t reference)
209 {
210 nrf_comp_ref_set(p_reg, reference);
211 nrf_barrier_w();
212 }
213
214 /** @refhal{nrf_comp_ext_ref_set} */
nrfy_comp_ext_ref_set(NRF_COMP_Type * p_reg,nrf_comp_ext_ref_t ext_ref)215 NRFY_STATIC_INLINE void nrfy_comp_ext_ref_set(NRF_COMP_Type * p_reg, nrf_comp_ext_ref_t ext_ref)
216 {
217 nrf_comp_ext_ref_set(p_reg, ext_ref);
218 nrf_barrier_w();
219 }
220
221 /** @refhal{nrf_comp_th_set} */
nrfy_comp_th_set(NRF_COMP_Type * p_reg,nrf_comp_th_t threshold)222 NRFY_STATIC_INLINE void nrfy_comp_th_set(NRF_COMP_Type * p_reg, nrf_comp_th_t threshold)
223 {
224 nrf_comp_th_set(p_reg, threshold);
225 nrf_barrier_w();
226 }
227
228 /** @refhal{nrf_comp_main_mode_set} */
nrfy_comp_main_mode_set(NRF_COMP_Type * p_reg,nrf_comp_main_mode_t main_mode)229 NRFY_STATIC_INLINE void nrfy_comp_main_mode_set(NRF_COMP_Type * p_reg,
230 nrf_comp_main_mode_t main_mode)
231 {
232 nrf_comp_main_mode_set(p_reg, main_mode);
233 nrf_barrier_w();
234 }
235
236 /** @refhal{nrf_comp_speed_mode_set} */
nrfy_comp_speed_mode_set(NRF_COMP_Type * p_reg,nrf_comp_sp_mode_t speed_mode)237 NRFY_STATIC_INLINE void nrfy_comp_speed_mode_set(NRF_COMP_Type * p_reg,
238 nrf_comp_sp_mode_t speed_mode)
239 {
240 nrf_comp_speed_mode_set(p_reg, speed_mode);
241 nrf_barrier_w();
242 }
243
244 /** @refhal{nrf_comp_hysteresis_set} */
nrfy_comp_hysteresis_set(NRF_COMP_Type * p_reg,nrf_comp_hyst_t hyst)245 NRFY_STATIC_INLINE void nrfy_comp_hysteresis_set(NRF_COMP_Type * p_reg, nrf_comp_hyst_t hyst)
246 {
247 nrf_comp_hysteresis_set(p_reg, hyst);
248 nrf_barrier_w();
249 }
250
251 #if NRFY_COMP_HAS_ISOURCE
252 /** @refhal{nrf_comp_isource_set} */
nrfy_comp_isource_set(NRF_COMP_Type * p_reg,nrf_isource_t isource)253 NRFY_STATIC_INLINE void nrfy_comp_isource_set(NRF_COMP_Type * p_reg, nrf_isource_t isource)
254 {
255 nrf_comp_isource_set(p_reg, isource);
256 nrf_barrier_w();
257 }
258 #endif
259
260 /** @refhal{nrf_comp_input_select} */
nrfy_comp_input_select(NRF_COMP_Type * p_reg,nrf_comp_input_t input)261 NRFY_STATIC_INLINE void nrfy_comp_input_select(NRF_COMP_Type * p_reg, nrf_comp_input_t input)
262 {
263 nrf_comp_input_select(p_reg, input);
264 nrf_barrier_w();
265 }
266
267 /** @refhal{nrf_comp_result_get} */
nrfy_comp_result_get(NRF_COMP_Type const * p_reg)268 NRFY_STATIC_INLINE uint32_t nrfy_comp_result_get(NRF_COMP_Type const * p_reg)
269 {
270 nrf_barrier_rw();
271 uint32_t result = nrf_comp_result_get(p_reg);
272 nrf_barrier_r();
273 return result;
274 }
275
276 /** @refhal{nrf_comp_int_enable} */
nrfy_comp_int_enable(NRF_COMP_Type * p_reg,uint32_t mask)277 NRFY_STATIC_INLINE void nrfy_comp_int_enable(NRF_COMP_Type * p_reg, uint32_t mask)
278 {
279 nrf_comp_int_enable(p_reg, mask);
280 nrf_barrier_w();
281 }
282
283 /** @refhal{nrf_comp_int_disable} */
nrfy_comp_int_disable(NRF_COMP_Type * p_reg,uint32_t mask)284 NRFY_STATIC_INLINE void nrfy_comp_int_disable(NRF_COMP_Type * p_reg, uint32_t mask)
285 {
286 nrf_comp_int_disable(p_reg, mask);
287 nrf_barrier_w();
288 }
289
290 /** @refhal{nrf_comp_int_enable_check} */
nrfy_comp_int_enable_check(NRF_COMP_Type const * p_reg,uint32_t mask)291 NRFY_STATIC_INLINE uint32_t nrfy_comp_int_enable_check(NRF_COMP_Type const * p_reg, uint32_t mask)
292 {
293 nrf_barrier_rw();
294 uint32_t check = nrf_comp_int_enable_check(p_reg, mask);
295 nrf_barrier_r();
296 return check;
297 }
298
299 /** @refhal{nrf_comp_task_address_get} */
nrfy_comp_task_address_get(NRF_COMP_Type const * p_reg,nrf_comp_task_t task)300 NRFY_STATIC_INLINE uint32_t nrfy_comp_task_address_get(NRF_COMP_Type const * p_reg,
301 nrf_comp_task_t task)
302 {
303 return nrf_comp_task_address_get(p_reg, task);
304 }
305
306 /** @refhal{nrf_comp_event_address_get} */
nrfy_comp_event_address_get(NRF_COMP_Type const * p_reg,nrf_comp_event_t event)307 NRFY_STATIC_INLINE uint32_t nrfy_comp_event_address_get(NRF_COMP_Type const * p_reg,
308 nrf_comp_event_t event)
309 {
310 return nrf_comp_event_address_get(p_reg, event);
311 }
312
313 /** @refhal{nrf_comp_shorts_enable} */
nrfy_comp_shorts_enable(NRF_COMP_Type * p_reg,uint32_t mask)314 NRFY_STATIC_INLINE void nrfy_comp_shorts_enable(NRF_COMP_Type * p_reg, uint32_t mask)
315 {
316 nrf_comp_shorts_enable(p_reg, mask);
317 nrf_barrier_w();
318 }
319
320 /** @refhal{nrf_comp_shorts_disable} */
nrfy_comp_shorts_disable(NRF_COMP_Type * p_reg,uint32_t mask)321 NRFY_STATIC_INLINE void nrfy_comp_shorts_disable(NRF_COMP_Type * p_reg, uint32_t mask)
322 {
323 nrf_comp_shorts_disable(p_reg, mask);
324 nrf_barrier_w();
325 }
326
327 /** @refhal{nrf_comp_task_trigger} */
nrfy_comp_task_trigger(NRF_COMP_Type * p_reg,nrf_comp_task_t task)328 NRFY_STATIC_INLINE void nrfy_comp_task_trigger(NRF_COMP_Type * p_reg, nrf_comp_task_t task)
329 {
330 nrf_comp_task_trigger(p_reg, task);
331 nrf_barrier_w();
332 }
333
334 /** @refhal{nrf_comp_event_clear} */
nrfy_comp_event_clear(NRF_COMP_Type * p_reg,nrf_comp_event_t event)335 NRFY_STATIC_INLINE void nrfy_comp_event_clear(NRF_COMP_Type * p_reg, nrf_comp_event_t event)
336 {
337 nrf_comp_event_clear(p_reg, event);
338 nrf_barrier_w();
339 }
340
341 /** @refhal{nrf_comp_event_check} */
nrfy_comp_event_check(NRF_COMP_Type const * p_reg,nrf_comp_event_t event)342 NRFY_STATIC_INLINE bool nrfy_comp_event_check(NRF_COMP_Type const * p_reg, nrf_comp_event_t event)
343 {
344 nrf_barrier_rw();
345 bool check = nrf_comp_event_check(p_reg, event);
346 nrf_barrier_r();
347 return check;
348 }
349
350 /** @} */
351
__nrfy_internal_comp_event_enabled_clear(NRF_COMP_Type * p_reg,uint32_t mask,nrf_comp_event_t event)352 NRFY_STATIC_INLINE void __nrfy_internal_comp_event_enabled_clear(NRF_COMP_Type * p_reg,
353 uint32_t mask,
354 nrf_comp_event_t event)
355 {
356 if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
357 {
358 nrf_comp_event_clear(p_reg, event);
359 }
360 }
361
__nrfy_internal_comp_event_handle(NRF_COMP_Type * p_reg,uint32_t mask,nrf_comp_event_t event,uint32_t * p_evt_mask)362 NRFY_STATIC_INLINE bool __nrfy_internal_comp_event_handle(NRF_COMP_Type * p_reg,
363 uint32_t mask,
364 nrf_comp_event_t event,
365 uint32_t * p_evt_mask)
366 {
367 if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_comp_event_check(p_reg, event))
368 {
369 nrf_comp_event_clear(p_reg, event);
370 if (p_evt_mask)
371 {
372 *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
373 }
374 return true;
375 }
376 return false;
377 }
378
__nrfy_internal_comp_events_process(NRF_COMP_Type * p_reg,uint32_t mask)379 NRFY_STATIC_INLINE uint32_t __nrfy_internal_comp_events_process(NRF_COMP_Type * p_reg,
380 uint32_t mask)
381 {
382 uint32_t event_mask = 0;
383
384 nrf_barrier_r();
385 (void)__nrfy_internal_comp_event_handle(p_reg,
386 mask,
387 NRF_COMP_EVENT_READY,
388 &event_mask);
389 (void)__nrfy_internal_comp_event_handle(p_reg,
390 mask,
391 NRF_COMP_EVENT_DOWN,
392 &event_mask);
393 (void)__nrfy_internal_comp_event_handle(p_reg,
394 mask,
395 NRF_COMP_EVENT_UP,
396 &event_mask);
397 (void)__nrfy_internal_comp_event_handle(p_reg,
398 mask,
399 NRF_COMP_EVENT_CROSS,
400 &event_mask);
401 return event_mask;
402 }
403
404 #ifdef __cplusplus
405 }
406 #endif
407
408 #endif // NRFY_COMP_H__
409