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