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