1 /*
2  * Copyright (c) 2021 - 2023, 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.
67     nrf_lpcomp_input_t  input;  ///< Input to be monitored.
68 } nrfy_lpcomp_config_t;
69 
70 /**
71  * @brief Function for configuring the LPCOMP.
72  *
73  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
74  * @param[in] p_config Pointer to the peripheral configuration structure.
75  */
nrfy_lpcomp_periph_configure(NRF_LPCOMP_Type * p_reg,nrfy_lpcomp_config_t const * p_config)76 NRFY_STATIC_INLINE void nrfy_lpcomp_periph_configure(NRF_LPCOMP_Type *            p_reg,
77                                                      nrfy_lpcomp_config_t const * p_config)
78 {
79     nrf_lpcomp_configure(p_reg, &p_config->config);
80     nrf_lpcomp_input_select(p_reg, p_config->input);
81     nrf_barrier_w();
82 }
83 
84 /**
85  * @brief Function for initializing the specified LPCOMP interrupts.
86  *
87  * @param[in] p_reg        Pointer to the structure of registers of the peripheral.
88  * @param[in] mask         Mask of interrupts to be initialized.
89  * @param[in] irq_priority Interrupt priority.
90  * @param[in] enable       True if the interrupts are to be enabled, false otherwise.
91  */
nrfy_lpcomp_int_init(NRF_LPCOMP_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)92 NRFY_STATIC_INLINE void nrfy_lpcomp_int_init(NRF_LPCOMP_Type * p_reg,
93                                              uint32_t          mask,
94                                              uint8_t           irq_priority,
95                                              bool              enable)
96 {
97 
98     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_READY);
99     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_DOWN);
100     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_UP);
101     __nrfy_internal_lpcomp_event_enabled_clear(p_reg, mask, NRF_LPCOMP_EVENT_CROSS);
102     nrf_barrier_w();
103 
104     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
105     NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
106     if (enable)
107     {
108         nrf_lpcomp_int_enable(p_reg, mask);
109     }
110     nrf_barrier_w();
111 }
112 
113 /**
114  * @brief Function for uninitializing the LPCOMP interrupts.
115  *
116  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
117  */
nrfy_lpcomp_int_uninit(NRF_LPCOMP_Type * p_reg)118  NRFY_STATIC_INLINE void nrfy_lpcomp_int_uninit(NRF_LPCOMP_Type * p_reg)
119  {
120     NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
121     nrf_barrier_w();
122  }
123 
124 /**
125  * @brief Function for processing the specified LPCOMP events.
126  *
127  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
128  * @param[in] mask  Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK().
129  *
130  * @return Mask of events that were generated and processed.
131  *         To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
132  */
nrfy_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,uint32_t mask)133 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,
134                                                        uint32_t          mask)
135 {
136     uint32_t evt_mask = __nrfy_internal_lpcomp_events_process(p_reg, mask);
137     nrf_barrier_w();
138     return evt_mask;
139 }
140 
141 /**
142  * @brief Function for reading the current state of the LPCOMP input.
143  *
144  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
145  *
146  * @retval false The input voltage is below the threshold.
147  * @retval true  The input voltage is above the threshold.
148  */
nrfy_lpcomp_sample_check(NRF_LPCOMP_Type * p_reg)149 NRFY_STATIC_INLINE bool nrfy_lpcomp_sample_check(NRF_LPCOMP_Type * p_reg)
150 {
151     nrf_lpcomp_task_trigger(p_reg, NRF_LPCOMP_TASK_SAMPLE);
152     nrf_barrier_rw();
153     bool sample = nrf_lpcomp_result_get(p_reg);
154     nrf_barrier_r();
155     return sample;
156 }
157 
158 /** @refhal{nrf_lpcomp_configure} */
nrfy_lpcomp_configure(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_config_t const * p_config)159 NRFY_STATIC_INLINE void nrfy_lpcomp_configure(NRF_LPCOMP_Type *           p_reg,
160                                               nrf_lpcomp_config_t const * p_config)
161 {
162     nrf_lpcomp_configure(p_reg, p_config);
163     nrf_barrier_w();
164 }
165 
166 /** @refhal{nrf_lpcomp_input_select} */
nrfy_lpcomp_input_select(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_input_t input)167 NRFY_STATIC_INLINE void nrfy_lpcomp_input_select(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_input_t input)
168 {
169     nrf_lpcomp_input_select(p_reg, input);
170     nrf_barrier_w();
171 }
172 
173 /** @refhal{nrf_lpcomp_enable} */
nrfy_lpcomp_enable(NRF_LPCOMP_Type * p_reg)174 NRFY_STATIC_INLINE void nrfy_lpcomp_enable(NRF_LPCOMP_Type * p_reg)
175 {
176     nrf_lpcomp_enable(p_reg);
177     nrf_barrier_w();
178 }
179 
180 /** @refhal{nrf_lpcomp_disable} */
nrfy_lpcomp_disable(NRF_LPCOMP_Type * p_reg)181 NRFY_STATIC_INLINE void nrfy_lpcomp_disable(NRF_LPCOMP_Type * p_reg)
182 {
183     nrf_lpcomp_disable(p_reg);
184     nrf_barrier_w();
185 }
186 
187 /** @refhal{nrf_lpcomp_result_get} */
nrfy_lpcomp_result_get(NRF_LPCOMP_Type const * p_reg)188 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_result_get(NRF_LPCOMP_Type const * p_reg)
189 {
190     nrf_barrier_rw();
191     uint32_t result = nrf_lpcomp_result_get(p_reg);
192     nrf_barrier_r();
193     return result;
194 }
195 
196 /** @refhal{nrf_lpcomp_int_enable} */
nrfy_lpcomp_int_enable(NRF_LPCOMP_Type * p_reg,uint32_t mask)197 NRFY_STATIC_INLINE void nrfy_lpcomp_int_enable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
198 {
199     nrf_lpcomp_int_enable(p_reg, mask);
200     nrf_barrier_w();
201 }
202 
203 /** @refhal{nrf_lpcomp_int_disable} */
nrfy_lpcomp_int_disable(NRF_LPCOMP_Type * p_reg,uint32_t mask)204 NRFY_STATIC_INLINE void nrfy_lpcomp_int_disable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
205 {
206     nrf_lpcomp_int_disable(p_reg, mask);
207     nrf_barrier_w();
208 }
209 
210 /** @refhal{nrf_lpcomp_int_enable_check} */
nrfy_lpcomp_int_enable_check(NRF_LPCOMP_Type const * p_reg,uint32_t mask)211 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_int_enable_check(NRF_LPCOMP_Type const * p_reg,
212                                                          uint32_t                mask)
213 {
214     nrf_barrier_rw();
215     uint32_t check = nrf_lpcomp_int_enable_check(p_reg, mask);
216     nrf_barrier_r();
217     return check;
218 }
219 
220 /** @refhal{nrf_lpcomp_task_address_get} */
nrfy_lpcomp_task_address_get(NRF_LPCOMP_Type const * p_reg,nrf_lpcomp_task_t task)221 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_task_address_get(NRF_LPCOMP_Type const * p_reg,
222                                                          nrf_lpcomp_task_t       task)
223 {
224     return nrf_lpcomp_task_address_get(p_reg, task);
225 }
226 
227 /** @refhal{nrf_lpcomp_event_address_get} */
nrfy_lpcomp_event_address_get(NRF_LPCOMP_Type const * p_reg,nrf_lpcomp_event_t event)228 NRFY_STATIC_INLINE uint32_t nrfy_lpcomp_event_address_get(NRF_LPCOMP_Type const * p_reg,
229                                                           nrf_lpcomp_event_t      event)
230 {
231     return nrf_lpcomp_event_address_get(p_reg, event);
232 }
233 
234 /** @refhal{nrf_lpcomp_shorts_enable} */
nrfy_lpcomp_shorts_enable(NRF_LPCOMP_Type * p_reg,uint32_t mask)235 NRFY_STATIC_INLINE void nrfy_lpcomp_shorts_enable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
236 {
237     nrf_lpcomp_shorts_enable(p_reg, mask);
238     nrf_barrier_w();
239 }
240 
241 /** @refhal{nrf_lpcomp_shorts_disable} */
nrfy_lpcomp_shorts_disable(NRF_LPCOMP_Type * p_reg,uint32_t mask)242 NRFY_STATIC_INLINE void nrfy_lpcomp_shorts_disable(NRF_LPCOMP_Type * p_reg, uint32_t mask)
243 {
244     nrf_lpcomp_shorts_disable(p_reg, mask);
245     nrf_barrier_w();
246 }
247 
248 /** @refhal{nrf_lpcomp_task_trigger} */
nrfy_lpcomp_task_trigger(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_task_t task)249 NRFY_STATIC_INLINE void nrfy_lpcomp_task_trigger(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_task_t task)
250 {
251     nrf_lpcomp_task_trigger(p_reg, task);
252     nrf_barrier_w();
253 }
254 
255 /** @refhal{nrf_lpcomp_event_clear} */
nrfy_lpcomp_event_clear(NRF_LPCOMP_Type * p_reg,nrf_lpcomp_event_t event)256 NRFY_STATIC_INLINE void nrfy_lpcomp_event_clear(NRF_LPCOMP_Type * p_reg, nrf_lpcomp_event_t event)
257 {
258     nrf_lpcomp_event_clear(p_reg, event);
259     nrf_barrier_w();
260 }
261 
262 /** @refhal{nrf_lpcomp_event_check} */
nrfy_lpcomp_event_check(NRF_LPCOMP_Type const * p_reg,nrf_lpcomp_event_t event)263 NRFY_STATIC_INLINE bool nrfy_lpcomp_event_check(NRF_LPCOMP_Type const * p_reg,
264                                                 nrf_lpcomp_event_t      event)
265 {
266     nrf_barrier_rw();
267     bool check = nrf_lpcomp_event_check(p_reg, event);
268     nrf_barrier_r();
269     return check;
270 }
271 
272 /** @} */
273 
__nrfy_internal_lpcomp_event_enabled_clear(NRF_LPCOMP_Type * p_reg,uint32_t mask,nrf_lpcomp_event_t event)274 NRFY_STATIC_INLINE void __nrfy_internal_lpcomp_event_enabled_clear(NRF_LPCOMP_Type *  p_reg,
275                                                                    uint32_t           mask,
276                                                                    nrf_lpcomp_event_t event)
277 {
278     if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
279     {
280         nrf_lpcomp_event_clear(p_reg, event);
281     }
282 }
283 
__nrfy_internal_lpcomp_event_handle(NRF_LPCOMP_Type * p_reg,uint32_t mask,nrf_lpcomp_event_t event,uint32_t * p_evt_mask)284 NRFY_STATIC_INLINE bool __nrfy_internal_lpcomp_event_handle(NRF_LPCOMP_Type *  p_reg,
285                                                             uint32_t           mask,
286                                                             nrf_lpcomp_event_t event,
287                                                             uint32_t *         p_evt_mask)
288 {
289     if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_lpcomp_event_check(p_reg, event))
290     {
291         nrf_lpcomp_event_clear(p_reg, event);
292         if (p_evt_mask)
293         {
294             *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
295         }
296         return true;
297     }
298     return false;
299 }
300 
__nrfy_internal_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,uint32_t mask)301 NRFY_STATIC_INLINE uint32_t __nrfy_internal_lpcomp_events_process(NRF_LPCOMP_Type * p_reg,
302                                                                   uint32_t          mask)
303 {
304     uint32_t event_mask = 0;
305 
306     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
307                                               mask,
308                                               NRF_LPCOMP_EVENT_READY,
309                                               &event_mask);
310     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
311                                               mask,
312                                               NRF_LPCOMP_EVENT_DOWN,
313                                               &event_mask);
314     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
315                                               mask,
316                                               NRF_LPCOMP_EVENT_UP,
317                                               &event_mask);
318     (void)__nrfy_internal_lpcomp_event_handle(p_reg,
319                                               mask,
320                                               NRF_LPCOMP_EVENT_CROSS,
321                                               &event_mask);
322     return event_mask;
323 }
324 
325 #ifdef __cplusplus
326 }
327 #endif
328 
329 #endif // NRFY_LPCOMP_H__
330