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_LPCOMP_H__
35 #define NRFY_LPCOMP_H__
36 
37 #include <nrfx.h>
38 #include <hal/nrf_lpcomp.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 NRFY_STATIC_INLINE void __nrfy_internal_lpcomp_event_enabled_clear(NRF_LPCOMP_Type *  p_reg,
45                                                                    uint32_t           mask,
46                                                                    nrf_lpcomp_event_t event);
47 
48 NRFY_STATIC_INLINE bool __nrfy_internal_lpcomp_event_handle(NRF_LPCOMP_Type *  p_reg,
49                                                             uint32_t           mask,
50                                                             nrf_lpcomp_event_t event,
51                                                             uint32_t *         p_evt_mask);
52 
53 NRFY_STATIC_INLINE uint32_t __nrfy_internal_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,
54                                                                   uint32_t          mask);
55 
56 /**
57  * @defgroup nrfy_lpcomp LPCOMP HALY
58  * @{
59  * @ingroup nrf_lpcomp
60  * @brief   Hardware access layer with cache and barrier support for managing the LPCOMP peripheral.
61  */
62 
63 /** @brief LPCOMP configuration structure. */
64 typedef struct
65 {
66     nrf_lpcomp_config_t  config;    ///< Peripheral configuration. @deprecated Use other fields instead.
67     nrf_lpcomp_ref_t     reference; ///< Reference selection.
68     nrf_lpcomp_ext_ref_t ext_ref;   ///< External analog reference selection.
69     nrf_lpcomp_detect_t  detection; ///< Detection type.
70 #if NRF_LPCOMP_HAS_HYST
71     nrf_lpcomp_hyst_t    hyst;      ///< Comparator hysteresis.
72 #endif
73     nrf_lpcomp_input_t   input;     ///< Input to be monitored.
74 } nrfy_lpcomp_config_t;
75 
76 /**
77  * @brief Function for configuring the LPCOMP.
78  *
79  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
80  * @param[in] p_config Pointer to the peripheral configuration structure.
81  */
nrfy_lpcomp_periph_configure(NRF_LPCOMP_Type * p_reg,nrfy_lpcomp_config_t const * p_config)82 NRFY_STATIC_INLINE void nrfy_lpcomp_periph_configure(NRF_LPCOMP_Type *            p_reg,
83                                                      nrfy_lpcomp_config_t const * p_config)
84 {
85     nrf_lpcomp_ref_set(p_reg, p_config->reference);
86     if (p_config->reference == NRF_LPCOMP_REF_EXT_REF)
87     {
88         nrf_lpcomp_ext_ref_set(p_reg, p_config->ext_ref);
89     }
90     nrf_lpcomp_detection_set(p_reg, p_config->detection);
91 #if defined(LPCOMP_FEATURE_HYST_PRESENT)
92     nrf_lpcomp_hysteresis_set(p_reg, p_config->hyst);
93 #endif
94 
95     nrf_lpcomp_input_select(p_reg, p_config->input);
96     nrf_barrier_w();
97 }
98 
99 /**
100  * @brief Function for initializing the specified LPCOMP interrupts.
101  *
102  * @param[in] p_reg        Pointer to the structure of registers of the peripheral.
103  * @param[in] mask         Mask of interrupts to be initialized.
104  * @param[in] irq_priority Interrupt priority.
105  * @param[in] enable       True if the interrupts are to be enabled, false otherwise.
106  */
nrfy_lpcomp_int_init(NRF_LPCOMP_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)107 NRFY_STATIC_INLINE void nrfy_lpcomp_int_init(NRF_LPCOMP_Type * p_reg,
108                                              uint32_t          mask,
109                                              uint8_t           irq_priority,
110                                              bool              enable)
111 {
112     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_READY);
113     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_DOWN);
114     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_UP);
115     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_CROSS);
116     nrf_barrier_w();
117 
118     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
119     NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
120     if (enable)
121     {
122         nrf_lpcomp_int_enable(p_reg, mask);
123     }
124     nrf_barrier_w();
125 }
126 
127 /**
128  * @brief Function for uninitializing the LPCOMP interrupts.
129  *
130  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
131  */
nrfy_lpcomp_int_uninit(NRF_LPCOMP_Type * p_reg)132 NRFY_STATIC_INLINE void nrfy_lpcomp_int_uninit(NRF_LPCOMP_Type * p_reg)
133 {
134     NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
135     nrf_barrier_w();
136 }
137 
138 /**
139  * @brief Function for processing the specified LPCOMP events.
140  *
141  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
142  * @param[in] mask  Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK().
143  *
144  * @return Mask of events that were generated and processed.
145  *         To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
146  */
nrfy_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,uint32_t mask)147 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,
148                                                        uint32_t          mask)
149 {
150     uint32_t evt_mask = __nrfy_internal_lpcomp_events_process(p_reg, mask);
151     nrf_barrier_w();
152     return evt_mask;
153 }
154 
155 /**
156  * @brief Function for reading the current state of the LPCOMP.
157  *
158  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
159  *
160  * @retval 0 The input voltage is below the threshold.
161  * @retval 1 The input voltage is above the threshold.
162  */
nrfy_lpcomp_sample(NRF_LPCOMP_Type * p_reg)163 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_sample(NRF_LPCOMP_Type * p_reg)
164 {
165     nrf_lpcomp_task_trigger(p_reg, NRF_LPCOMP_TASK_SAMPLE);
166     nrf_barrier_rw();
167     uint32_t sample = nrf_lpcomp_result_get(p_reg);
168     nrf_barrier_r();
169     return sample;
170 }
171 
172 /**
173  * @brief Function for reading the current state of the LPCOMP input.
174  *
175  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
176  *
177  * @retval false The input voltage is below the threshold.
178  * @retval true  The input voltage is above the threshold.
179  */
nrfy_lpcomp_sample_check(NRF_LPCOMP_Type * p_reg)180 NRFY_STATIC_INLINE bool nrfy_lpcomp_sample_check(NRF_LPCOMP_Type * p_reg)
181 {
182     return (bool)nrfy_lpcomp_sample(p_reg);
183 }
184 
185 /** @refhal{nrf_lpcomp_ref_set} */
nrfy_lpcomp_ref_set(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_ref_t reference)186 NRFY_STATIC_INLINE void nrfy_lpcomp_ref_set(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_ref_t reference)
187 {
188     nrf_lpcomp_ref_set(p_reg, reference);
189     nrf_barrier_w();
190 }
191 
192 /** @refhal{nrf_lpcomp_ext_ref_set} */
nrfy_lpcomp_ext_ref_set(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_ext_ref_t ext_ref)193 NRFY_STATIC_INLINE void nrfy_lpcomp_ext_ref_set(NRF_LPCOMP_Type *    p_reg,
194                                                 nrf_lpcomp_ext_ref_t ext_ref)
195 {
196     nrf_lpcomp_ext_ref_set(p_reg, ext_ref);
197     nrf_barrier_w();
198 }
199 
200 /** @refhal{nrf_lpcomp_detection_set} */
nrfy_lpcomp_detection_set(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_detect_t detection)201 NRFY_STATIC_INLINE void nrfy_lpcomp_detection_set(NRF_LPCOMP_Type *   p_reg,
202                                                   nrf_lpcomp_detect_t detection)
203 {
204     nrf_lpcomp_detection_set(p_reg, detection);
205     nrf_barrier_w();
206 }
207 
208 #if defined(LPCOMP_FEATURE_HYST_PRESENT) || defined(__NRFX_DOXYGEN__)
209 /** @refhal{nrf_lpcomp_hysteresis_set} */
nrfy_lpcomp_hysteresis_set(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_hyst_t hyst)210 NRFY_STATIC_INLINE void nrfy_lpcomp_hysteresis_set(NRF_LPCOMP_Type * p_reg,
211                                                    nrf_lpcomp_hyst_t hyst)
212 {
213     nrf_lpcomp_hysteresis_set(p_reg, hyst);
214     nrf_barrier_w();
215 }
216 #endif
217 
218 /** @refhal{nrf_lpcomp_configure} */
nrfy_lpcomp_configure(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_config_t const * p_config)219 NRFY_STATIC_INLINE void nrfy_lpcomp_configure(NRF_LPCOMP_Type *           p_reg,
220                                               nrf_lpcomp_config_t const * p_config)
221 {
222     nrf_lpcomp_configure(p_reg, p_config);
223     nrf_barrier_w();
224 }
225 
226 /** @refhal{nrf_lpcomp_input_select} */
nrfy_lpcomp_input_select(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_input_t input)227 NRFY_STATIC_INLINE void nrfy_lpcomp_input_select(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_input_t input)
228 {
229     nrf_lpcomp_input_select(p_reg, input);
230     nrf_barrier_w();
231 }
232 
233 /** @refhal{nrf_lpcomp_enable} */
nrfy_lpcomp_enable(NRF_LPCOMP_Type * p_reg)234 NRFY_STATIC_INLINE void nrfy_lpcomp_enable(NRF_LPCOMP_Type * p_reg)
235 {
236     nrf_lpcomp_enable(p_reg);
237     nrf_barrier_w();
238 }
239 
240 /** @refhal{nrf_lpcomp_disable} */
nrfy_lpcomp_disable(NRF_LPCOMP_Type * p_reg)241 NRFY_STATIC_INLINE void nrfy_lpcomp_disable(NRF_LPCOMP_Type * p_reg)
242 {
243     nrf_lpcomp_disable(p_reg);
244     nrf_barrier_w();
245 }
246 
247 /** @refhal{nrf_lpcomp_result_get} */
nrfy_lpcomp_result_get(NRF_LPCOMP_Type const * p_reg)248 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_result_get(NRF_LPCOMP_Type const * p_reg)
249 {
250     nrf_barrier_rw();
251     uint32_t result = nrf_lpcomp_result_get(p_reg);
252     nrf_barrier_r();
253     return result;
254 }
255 
256 /** @refhal{nrf_lpcomp_int_enable} */
nrfy_lpcomp_int_enable(NRF_LPCOMP_Type * p_reg,uint32_t mask)257 NRFY_STATIC_INLINE void nrfy_lpcomp_int_enable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
258 {
259     nrf_lpcomp_int_enable(p_reg, mask);
260     nrf_barrier_w();
261 }
262 
263 /** @refhal{nrf_lpcomp_int_disable} */
nrfy_lpcomp_int_disable(NRF_LPCOMP_Type * p_reg,uint32_t mask)264 NRFY_STATIC_INLINE void nrfy_lpcomp_int_disable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
265 {
266     nrf_lpcomp_int_disable(p_reg, mask);
267     nrf_barrier_w();
268 }
269 
270 /** @refhal{nrf_lpcomp_int_enable_check} */
nrfy_lpcomp_int_enable_check(NRF_LPCOMP_Type const * p_reg,uint32_t mask)271 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_int_enable_check(NRF_LPCOMP_Type const * p_reg,
272                                                          uint32_t                mask)
273 {
274     nrf_barrier_rw();
275     uint32_t check = nrf_lpcomp_int_enable_check(p_reg, mask);
276     nrf_barrier_r();
277     return check;
278 }
279 
280 /** @refhal{nrf_lpcomp_task_address_get} */
nrfy_lpcomp_task_address_get(NRF_LPCOMP_Type const * p_reg,nrf_lpcomp_task_t task)281 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_task_address_get(NRF_LPCOMP_Type const * p_reg,
282                                                          nrf_lpcomp_task_t       task)
283 {
284     return nrf_lpcomp_task_address_get(p_reg, task);
285 }
286 
287 /** @refhal{nrf_lpcomp_event_address_get} */
nrfy_lpcomp_event_address_get(NRF_LPCOMP_Type const * p_reg,nrf_lpcomp_event_t event)288 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_event_address_get(NRF_LPCOMP_Type const * p_reg,
289                                                           nrf_lpcomp_event_t      event)
290 {
291     return nrf_lpcomp_event_address_get(p_reg, event);
292 }
293 
294 /** @refhal{nrf_lpcomp_shorts_enable} */
nrfy_lpcomp_shorts_enable(NRF_LPCOMP_Type * p_reg,uint32_t mask)295 NRFY_STATIC_INLINE void nrfy_lpcomp_shorts_enable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
296 {
297     nrf_lpcomp_shorts_enable(p_reg, mask);
298     nrf_barrier_w();
299 }
300 
301 /** @refhal{nrf_lpcomp_shorts_disable} */
nrfy_lpcomp_shorts_disable(NRF_LPCOMP_Type * p_reg,uint32_t mask)302 NRFY_STATIC_INLINE void nrfy_lpcomp_shorts_disable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
303 {
304     nrf_lpcomp_shorts_disable(p_reg, mask);
305     nrf_barrier_w();
306 }
307 
308 /** @refhal{nrf_lpcomp_task_trigger} */
nrfy_lpcomp_task_trigger(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_task_t task)309 NRFY_STATIC_INLINE void nrfy_lpcomp_task_trigger(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_task_t task)
310 {
311     nrf_lpcomp_task_trigger(p_reg, task);
312     nrf_barrier_w();
313 }
314 
315 /** @refhal{nrf_lpcomp_event_clear} */
nrfy_lpcomp_event_clear(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_event_t event)316 NRFY_STATIC_INLINE void nrfy_lpcomp_event_clear(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_event_t event)
317 {
318     nrf_lpcomp_event_clear(p_reg, event);
319     nrf_barrier_w();
320 }
321 
322 /** @refhal{nrf_lpcomp_event_check} */
nrfy_lpcomp_event_check(NRF_LPCOMP_Type const * p_reg,nrf_lpcomp_event_t event)323 NRFY_STATIC_INLINE bool nrfy_lpcomp_event_check(NRF_LPCOMP_Type const * p_reg,
324                                                 nrf_lpcomp_event_t      event)
325 {
326     nrf_barrier_rw();
327     bool check = nrf_lpcomp_event_check(p_reg, event);
328     nrf_barrier_r();
329     return check;
330 }
331 
332 /** @} */
333 
__nrfy_internal_lpcomp_event_enabled_clear(NRF_LPCOMP_Type * p_reg,uint32_t mask,nrf_lpcomp_event_t event)334 NRFY_STATIC_INLINE void __nrfy_internal_lpcomp_event_enabled_clear(NRF_LPCOMP_Type *  p_reg,
335                                                                    uint32_t           mask,
336                                                                    nrf_lpcomp_event_t event)
337 {
338     if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
339     {
340         nrf_lpcomp_event_clear(p_reg, event);
341     }
342 }
343 
__nrfy_internal_lpcomp_event_handle(NRF_LPCOMP_Type * p_reg,uint32_t mask,nrf_lpcomp_event_t event,uint32_t * p_evt_mask)344 NRFY_STATIC_INLINE bool __nrfy_internal_lpcomp_event_handle(NRF_LPCOMP_Type *  p_reg,
345                                                             uint32_t           mask,
346                                                             nrf_lpcomp_event_t event,
347                                                             uint32_t *         p_evt_mask)
348 {
349     if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_lpcomp_event_check(p_reg, event))
350     {
351         nrf_lpcomp_event_clear(p_reg, event);
352         if (p_evt_mask)
353         {
354             *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
355         }
356         return true;
357     }
358     return false;
359 }
360 
__nrfy_internal_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,uint32_t mask)361 NRFY_STATIC_INLINE uint32_t __nrfy_internal_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,
362                                                                   uint32_t          mask)
363 {
364     uint32_t event_mask = 0;
365 
366     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
367                                               mask,
368                                               NRF_LPCOMP_EVENT_READY,
369                                               &event_mask);
370     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
371                                               mask,
372                                               NRF_LPCOMP_EVENT_DOWN,
373                                               &event_mask);
374     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
375                                               mask,
376                                               NRF_LPCOMP_EVENT_UP,
377                                               &event_mask);
378     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
379                                               mask,
380                                               NRF_LPCOMP_EVENT_CROSS,
381                                               &event_mask);
382     return event_mask;
383 }
384 
385 #ifdef __cplusplus
386 }
387 #endif
388 
389 #endif // NRFY_LPCOMP_H__
390