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