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_GPIOTE_H__
35 #define NRFY_GPIOTE_H__
36 
37 #include <nrfx.h>
38 #include <hal/nrf_gpiote.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 NRFY_STATIC_INLINE void __nrfy_internal_gpiote_event_enabled_clear(NRF_GPIOTE_Type *  p_reg,
45                                                                    uint32_t           mask,
46                                                                    nrf_gpiote_event_t event);
47 
48 NRFY_STATIC_INLINE bool __nrfy_internal_gpiote_event_handle(NRF_GPIOTE_Type *  p_reg,
49                                                             uint32_t           mask,
50                                                             nrf_gpiote_event_t event,
51                                                             uint32_t *         p_evt_mask);
52 
53 NRFY_STATIC_INLINE uint32_t __nrfy_internal_gpiote_events_process(NRF_GPIOTE_Type * p_reg,
54                                                                   uint32_t          mask);
55 
56 /**
57  * @defgroup nrfy_gpiote GPIOTE HALY
58  * @{
59  * @ingroup nrf_gpiote
60  * @brief   Hardware access layer with cache and barrier support for managing the GPIOTE peripheral.
61  */
62 
63 #if NRF_GPIOTE_HAS_LATENCY || defined(__NRFX_DOXYGEN__)
64 /** @refhal{NRF_GPIOTE_HAS_LATENCY} */
65 #define NRFY_GPIOTE_HAS_LATENCY 1
66 #else
67 #define NRFY_GPIOTE_HAS_LATENCY 0
68 #endif
69 
70 /**
71  * @brief Function for initializing the specified GPIOTE interrupts.
72  *
73  * @param[in] p_reg        Pointer to the structure of registers of the peripheral.
74  * @param[in] mask         Mask of interrupts to be initialized.
75  * @param[in] irq_priority Interrupt priority.
76  * @param[in] enable       True if the interrupts are to be enabled, false otherwise.
77  */
nrfy_gpiote_int_init(NRF_GPIOTE_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)78 NRFY_STATIC_INLINE void nrfy_gpiote_int_init(NRF_GPIOTE_Type * p_reg,
79                                              uint32_t          mask,
80                                              uint8_t           irq_priority,
81                                              bool              enable)
82 {
83     for (uint8_t i = 0; i < GPIOTE_CH_NUM; i++)
84     {
85         __nrfy_internal_gpiote_event_enabled_clear(p_reg, mask, nrf_gpiote_in_event_get(i));
86     }
87 
88     __nrfy_internal_gpiote_event_enabled_clear(p_reg, mask, NRF_GPIOTE_EVENT_PORT);
89 
90 #if defined(NRF_GPIOTE_IRQn_EXT)
91     IRQn_Type irqn = NRF_GPIOTE_IRQn_EXT;
92 #else
93     IRQn_Type irqn = nrfx_get_irq_number(p_reg);
94 #endif
95     NRFX_IRQ_PRIORITY_SET(irqn, irq_priority);
96     NRFX_IRQ_ENABLE(irqn);
97     if (enable)
98     {
99         nrf_gpiote_int_enable(p_reg, mask);
100     }
101     nrf_barrier_w();
102 }
103 
104 /**
105  * @brief Function for processing the specified GPIOTE events.
106  *
107  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
108  * @param[in] mask  Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK().
109  *
110  * @return Mask of events that were generated and processed.
111  *         To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
112  */
nrfy_gpiote_events_process(NRF_GPIOTE_Type * p_reg,uint32_t mask)113 NRFY_STATIC_INLINE uint32_t nrfy_gpiote_events_process(NRF_GPIOTE_Type * p_reg,
114                                                        uint32_t          mask)
115 {
116     uint32_t evt_mask = __nrfy_internal_gpiote_events_process(p_reg, mask);
117     nrf_barrier_w();
118     return evt_mask;
119 }
120 
121 /** @refhal{nrf_gpiote_task_trigger} */
nrfy_gpiote_task_trigger(NRF_GPIOTE_Type * p_reg,nrf_gpiote_task_t task)122 NRFY_STATIC_INLINE void nrfy_gpiote_task_trigger(NRF_GPIOTE_Type * p_reg, nrf_gpiote_task_t task)
123 {
124     nrf_gpiote_task_trigger(p_reg, task);
125     nrf_barrier_w();
126 }
127 
128 /** @refhal{nrf_gpiote_task_address_get} */
nrfy_gpiote_task_address_get(NRF_GPIOTE_Type const * p_reg,nrf_gpiote_task_t task)129 NRFY_STATIC_INLINE uint32_t nrfy_gpiote_task_address_get(NRF_GPIOTE_Type const * p_reg,
130                                                          nrf_gpiote_task_t       task)
131 {
132     return nrf_gpiote_task_address_get(p_reg, task);
133 }
134 
135 /** @refhal{nrf_gpiote_event_check} */
nrfy_gpiote_event_check(NRF_GPIOTE_Type const * p_reg,nrf_gpiote_event_t event)136 NRFY_STATIC_INLINE bool nrfy_gpiote_event_check(NRF_GPIOTE_Type const * p_reg,
137                                                 nrf_gpiote_event_t      event)
138 {
139     nrf_barrier_r();
140     bool evt = nrf_gpiote_event_check(p_reg, event);
141     nrf_barrier_r();
142     return evt;
143 }
144 
145 /** @refhal{nrf_gpiote_event_clear} */
nrfy_gpiote_event_clear(NRF_GPIOTE_Type * p_reg,nrf_gpiote_event_t event)146 NRFY_STATIC_INLINE void nrfy_gpiote_event_clear(NRF_GPIOTE_Type * p_reg, nrf_gpiote_event_t event)
147 {
148     nrf_gpiote_event_clear(p_reg, event);
149     nrf_barrier_w();
150 }
151 
152 /** @refhal{nrf_gpiote_event_address_get} */
nrfy_gpiote_event_address_get(NRF_GPIOTE_Type const * p_reg,nrf_gpiote_event_t event)153 NRFY_STATIC_INLINE uint32_t nrfy_gpiote_event_address_get(NRF_GPIOTE_Type const * p_reg,
154                                                           nrf_gpiote_event_t      event)
155 {
156     return nrf_gpiote_event_address_get(p_reg, event);
157 }
158 
159 /** @refhal{nrf_gpiote_int_enable} */
nrfy_gpiote_int_enable(NRF_GPIOTE_Type * p_reg,uint32_t mask)160 NRFY_STATIC_INLINE void nrfy_gpiote_int_enable(NRF_GPIOTE_Type * p_reg, uint32_t mask)
161 {
162     nrf_gpiote_int_enable(p_reg, mask);
163     nrf_barrier_w();
164 }
165 
166 /** @refhal{nrf_gpiote_int_disable} */
nrfy_gpiote_int_disable(NRF_GPIOTE_Type * p_reg,uint32_t mask)167 NRFY_STATIC_INLINE void nrfy_gpiote_int_disable(NRF_GPIOTE_Type * p_reg, uint32_t mask)
168 {
169     nrf_gpiote_int_disable(p_reg, mask);
170     nrf_barrier_w();
171 }
172 
173 /** @refhal{nrf_gpiote_int_enable_check} */
nrfy_gpiote_int_enable_check(NRF_GPIOTE_Type const * p_reg,uint32_t mask)174 NRFY_STATIC_INLINE uint32_t nrfy_gpiote_int_enable_check(NRF_GPIOTE_Type const * p_reg,
175                                                          uint32_t                mask)
176 {
177     nrf_barrier_rw();
178     uint32_t enable = nrf_gpiote_int_enable_check(p_reg, mask);
179     nrf_barrier_r();
180     return enable;
181 }
182 
183 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
184 /** @refhal{nrf_gpiote_subscribe_set} */
nrfy_gpiote_subscribe_set(NRF_GPIOTE_Type * p_reg,nrf_gpiote_task_t task,uint8_t channel)185 NRFY_STATIC_INLINE void nrfy_gpiote_subscribe_set(NRF_GPIOTE_Type * p_reg,
186                                                   nrf_gpiote_task_t task,
187                                                   uint8_t           channel)
188 {
189     nrf_gpiote_subscribe_set(p_reg, task, channel);
190     nrf_barrier_w();
191 }
192 
193 /** @refhal{nrf_gpiote_subscribe_clear} */
nrfy_gpiote_subscribe_clear(NRF_GPIOTE_Type * p_reg,nrf_gpiote_task_t task)194 NRFY_STATIC_INLINE void nrfy_gpiote_subscribe_clear(NRF_GPIOTE_Type * p_reg,
195                                                     nrf_gpiote_task_t task)
196 {
197     nrf_gpiote_subscribe_clear(p_reg, task);
198     nrf_barrier_w();
199 }
200 
201 /** @refhal{nrf_gpiote_publish_set} */
nrfy_gpiote_publish_set(NRF_GPIOTE_Type * p_reg,nrf_gpiote_event_t event,uint8_t channel)202 NRFY_STATIC_INLINE void nrfy_gpiote_publish_set(NRF_GPIOTE_Type *  p_reg,
203                                                 nrf_gpiote_event_t event,
204                                                 uint8_t            channel)
205 {
206     nrf_gpiote_publish_set(p_reg, event, channel);
207     nrf_barrier_w();
208 }
209 
210 /** @refhal{nrf_gpiote_publish_clear} */
nrfy_gpiote_publish_clear(NRF_GPIOTE_Type * p_reg,nrf_gpiote_event_t event)211 NRFY_STATIC_INLINE void nrfy_gpiote_publish_clear(NRF_GPIOTE_Type *  p_reg,
212                                                   nrf_gpiote_event_t event)
213 {
214     nrf_gpiote_publish_clear(p_reg, event);
215     nrf_barrier_w();
216 }
217 #endif
218 
219 /** @refhal{nrf_gpiote_event_enable} */
nrfy_gpiote_event_enable(NRF_GPIOTE_Type * p_reg,uint32_t idx)220 NRFY_STATIC_INLINE void nrfy_gpiote_event_enable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
221 {
222     nrf_gpiote_event_enable(p_reg, idx);
223     nrf_barrier_w();
224 }
225 
226 /** @refhal{nrf_gpiote_event_disable} */
nrfy_gpiote_event_disable(NRF_GPIOTE_Type * p_reg,uint32_t idx)227 NRFY_STATIC_INLINE void nrfy_gpiote_event_disable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
228 {
229     nrf_gpiote_event_disable(p_reg, idx);
230     nrf_barrier_w();
231 }
232 
233 /** @refhal{nrf_gpiote_event_configure} */
nrfy_gpiote_event_configure(NRF_GPIOTE_Type * p_reg,uint32_t idx,uint32_t pin,nrf_gpiote_polarity_t polarity)234 NRFY_STATIC_INLINE void nrfy_gpiote_event_configure(NRF_GPIOTE_Type *     p_reg,
235                                                     uint32_t              idx,
236                                                     uint32_t              pin,
237                                                     nrf_gpiote_polarity_t polarity)
238 {
239     nrf_gpiote_event_configure(p_reg, idx, pin, polarity);
240     nrf_barrier_w();
241 }
242 
243 /** @refhal{nrf_gpiote_event_pin_get} */
nrfy_gpiote_event_pin_get(NRF_GPIOTE_Type const * p_reg,uint32_t idx)244 NRFY_STATIC_INLINE uint32_t nrfy_gpiote_event_pin_get(NRF_GPIOTE_Type const * p_reg, uint32_t idx)
245 {
246     nrf_barrier_rw();
247     uint32_t pin = nrf_gpiote_event_pin_get(p_reg, idx);
248     nrf_barrier_r();
249     return pin;
250 }
251 
252 /** @refhal{nrf_gpiote_event_polarity_get} */
253 NRFY_STATIC_INLINE
nrfy_gpiote_event_polarity_get(NRF_GPIOTE_Type const * p_reg,uint32_t idx)254 nrf_gpiote_polarity_t nrfy_gpiote_event_polarity_get(NRF_GPIOTE_Type const * p_reg,
255                                                      uint32_t                idx)
256 {
257     nrf_barrier_rw();
258     nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(p_reg, idx);
259     nrf_barrier_r();
260     return polarity;
261 }
262 
263 /** @refhal{nrf_gpiote_task_enable} */
nrfy_gpiote_task_enable(NRF_GPIOTE_Type * p_reg,uint32_t idx)264 NRFY_STATIC_INLINE void nrfy_gpiote_task_enable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
265 {
266     nrf_gpiote_task_enable(p_reg, idx);
267     nrf_barrier_w();
268 }
269 
270 /** @refhal{nrf_gpiote_task_disable} */
nrfy_gpiote_task_disable(NRF_GPIOTE_Type * p_reg,uint32_t idx)271 NRFY_STATIC_INLINE void nrfy_gpiote_task_disable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
272 {
273     nrf_gpiote_task_disable(p_reg, idx);
274     nrf_barrier_w();
275 }
276 
277 /** @refhal{nrf_gpiote_task_configure} */
nrfy_gpiote_task_configure(NRF_GPIOTE_Type * p_reg,uint32_t idx,uint32_t pin,nrf_gpiote_polarity_t polarity,nrf_gpiote_outinit_t init_val)278 NRFY_STATIC_INLINE void nrfy_gpiote_task_configure(NRF_GPIOTE_Type *     p_reg,
279                                                    uint32_t              idx,
280                                                    uint32_t              pin,
281                                                    nrf_gpiote_polarity_t polarity,
282                                                    nrf_gpiote_outinit_t  init_val)
283 {
284     nrf_gpiote_task_configure(p_reg, idx, pin, polarity, init_val);
285     nrf_barrier_w();
286 }
287 
288 /** @refhal{nrf_gpiote_task_force} */
nrfy_gpiote_task_force(NRF_GPIOTE_Type * p_reg,uint32_t idx,nrf_gpiote_outinit_t init_val)289 NRFY_STATIC_INLINE void nrfy_gpiote_task_force(NRF_GPIOTE_Type *    p_reg,
290                                                uint32_t             idx,
291                                                nrf_gpiote_outinit_t init_val)
292 {
293     nrf_gpiote_task_force(p_reg, idx, init_val);
294     nrf_barrier_w();
295 }
296 
297 /** @refhal{nrf_gpiote_te_default} */
nrfy_gpiote_te_default(NRF_GPIOTE_Type * p_reg,uint32_t idx)298 NRFY_STATIC_INLINE void nrfy_gpiote_te_default(NRF_GPIOTE_Type * p_reg, uint32_t idx)
299 {
300     nrf_gpiote_te_default(p_reg, idx);
301     nrf_barrier_w();
302 }
303 
304 /** @refhal{nrf_gpiote_te_is_enabled} */
nrfy_gpiote_te_is_enabled(NRF_GPIOTE_Type const * p_reg,uint32_t idx)305 NRFY_STATIC_INLINE bool nrfy_gpiote_te_is_enabled(NRF_GPIOTE_Type const * p_reg, uint32_t idx)
306 {
307     nrf_barrier_rw();
308     bool enabled = nrf_gpiote_te_is_enabled(p_reg, idx);
309     nrf_barrier_r();
310     return enabled;
311 }
312 
313 /** @refhal{nrf_gpiote_out_task_get} */
nrfy_gpiote_out_task_get(uint8_t index)314 NRFY_STATIC_INLINE nrf_gpiote_task_t nrfy_gpiote_out_task_get(uint8_t index)
315 {
316     return nrf_gpiote_out_task_get(index);
317 }
318 
319 #if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
320 /** @refhal{nrf_gpiote_set_task_get} */
nrfy_gpiote_set_task_get(uint8_t index)321 NRFY_STATIC_INLINE nrf_gpiote_task_t nrfy_gpiote_set_task_get(uint8_t index)
322 {
323     return nrf_gpiote_set_task_get(index);
324 }
325 #endif
326 
327 #if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
328 /** @refhal{nrf_gpiote_clr_task_get} */
nrfy_gpiote_clr_task_get(uint8_t index)329 NRFY_STATIC_INLINE nrf_gpiote_task_t nrfy_gpiote_clr_task_get(uint8_t index)
330 {
331     return nrf_gpiote_clr_task_get(index);
332 }
333 #endif
334 
335 /** @refhal{nrf_gpiote_in_event_get} */
nrfy_gpiote_in_event_get(uint8_t index)336 NRFY_STATIC_INLINE nrf_gpiote_event_t nrfy_gpiote_in_event_get(uint8_t index)
337 {
338     return nrf_gpiote_in_event_get(index);
339 }
340 
341 #if NRFY_GPIOTE_HAS_LATENCY
342 /** @refhal{nrf_gpiote_latency_set} */
nrfy_gpiote_latency_set(NRF_GPIOTE_Type * p_reg,nrf_gpiote_latency_t latency)343 NRFY_STATIC_INLINE void nrfy_gpiote_latency_set(NRF_GPIOTE_Type *    p_reg,
344                                                 nrf_gpiote_latency_t latency)
345 {
346     nrf_gpiote_latency_set(p_reg, latency);
347     nrf_barrier_w();
348 }
349 
350 /** @refhal{nrf_gpiote_latency_get} */
nrfy_gpiote_latency_get(NRF_GPIOTE_Type const * p_reg)351 NRFY_STATIC_INLINE nrf_gpiote_latency_t nrfy_gpiote_latency_get(NRF_GPIOTE_Type const * p_reg)
352 {
353     nrf_barrier_rw();
354     nrf_gpiote_latency_t latency = nrf_gpiote_latency_get(p_reg);
355     nrf_barrier_r();
356     return latency;
357 }
358 #endif
359 
360 /** @} */
361 
__nrfy_internal_gpiote_event_enabled_clear(NRF_GPIOTE_Type * p_reg,uint32_t mask,nrf_gpiote_event_t event)362 NRFY_STATIC_INLINE void __nrfy_internal_gpiote_event_enabled_clear(NRF_GPIOTE_Type *  p_reg,
363                                                                    uint32_t           mask,
364                                                                    nrf_gpiote_event_t event)
365 {
366     if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
367     {
368         nrf_gpiote_event_clear(p_reg, event);
369     }
370 }
371 
__nrfy_internal_gpiote_event_handle(NRF_GPIOTE_Type * p_reg,uint32_t mask,nrf_gpiote_event_t event,uint32_t * p_evt_mask)372 NRFY_STATIC_INLINE bool __nrfy_internal_gpiote_event_handle(NRF_GPIOTE_Type *  p_reg,
373                                                             uint32_t           mask,
374                                                             nrf_gpiote_event_t event,
375                                                             uint32_t *         p_evt_mask)
376 {
377     if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_gpiote_event_check(p_reg, event))
378     {
379         nrf_gpiote_event_clear(p_reg, event);
380         if (p_evt_mask)
381         {
382             *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
383         }
384         return true;
385     }
386     return false;
387 }
388 
__nrfy_internal_gpiote_events_process(NRF_GPIOTE_Type * p_reg,uint32_t mask)389 NRFY_STATIC_INLINE uint32_t __nrfy_internal_gpiote_events_process(NRF_GPIOTE_Type * p_reg,
390                                                                   uint32_t          mask)
391 {
392     uint32_t event_mask = 0;
393 
394     nrf_barrier_r();
395     for (uint8_t i = 0; i < GPIOTE_CH_NUM; i++)
396     {
397         (void)__nrfy_internal_gpiote_event_handle(p_reg,
398                                                   mask,
399                                                   nrf_gpiote_in_event_get(i),
400                                                   &event_mask);
401     }
402 
403     (void)__nrfy_internal_gpiote_event_handle(p_reg, mask, NRF_GPIOTE_EVENT_PORT, &event_mask);
404 
405     return event_mask;
406 }
407 
408 #ifdef __cplusplus
409 }
410 #endif
411 
412 #endif // NRFY_GPIOTE_H__
413