1 /*
2 * Copyright (c) 2023 - 2024, 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 #include <helpers/nrfx_gppi.h>
35
36 #if defined(LUMOS_XXAA)
37
38 #include <helpers/nrfx_flag32_allocator.h>
39 #include <hal/nrf_ppib.h>
40 #include <hal/nrf_dppi.h>
41
42 #include <soc/interconnect/dppic_ppib/nrfx_interconnect_dppic_ppib.h>
43
44 #include <soc/interconnect/dppic_ppib/nrfx_interconnect_dppic_ppib_lumos.h>
45
46 /** @brief Invalid channel number. */
47 #define NRFX_GPPI_CHANNEL_INVALID UINT8_MAX
48
49 #if defined(NRF54L15_ENGA_XXAA)
50 #define NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG 0
51 #else
52 #define NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG 1
53 #endif
54
55 static nrfx_atomic_t m_virtual_channels = NRFX_GPPI_PROG_APP_CHANNELS_MASK;
56
dppic_channel_get(nrfx_interconnect_dppic_t * p_dppic,uint8_t virtual_channel,uint8_t * p_dppic_channel)57 static nrfx_err_t dppic_channel_get(nrfx_interconnect_dppic_t * p_dppic,
58 uint8_t virtual_channel,
59 uint8_t * p_dppic_channel)
60 {
61 for (uint8_t i = 0; i < NRF_DPPI_CH_NUM_MAX; i++)
62 {
63 if (p_dppic->allocate_flag[i] == virtual_channel)
64 {
65 *p_dppic_channel = i;
66 return NRFX_SUCCESS;
67 }
68 }
69
70 return NRFX_ERROR_INVALID_PARAM;
71 }
72
dppic_virtual_channel_set(nrfx_interconnect_dppic_t * p_dppic,uint32_t dppi_channel,uint8_t virtual_channel)73 static nrfx_err_t dppic_virtual_channel_set(nrfx_interconnect_dppic_t * p_dppic,
74 uint32_t dppi_channel,
75 uint8_t virtual_channel)
76 {
77 p_dppic->allocate_flag[dppi_channel] = virtual_channel;
78
79 return NRFX_SUCCESS;
80 }
81
dppic_channel_alloc(nrfx_interconnect_dppic_t * p_dppic,uint8_t * p_channel)82 static nrfx_err_t dppic_channel_alloc(nrfx_interconnect_dppic_t * p_dppic, uint8_t * p_channel)
83 {
84 return nrfx_flag32_alloc(&p_dppic->channels_mask, p_channel);
85 }
86
dppic_channel_free(nrfx_interconnect_dppic_t * p_dppic,uint8_t channel)87 static nrfx_err_t dppic_channel_free(nrfx_interconnect_dppic_t * p_dppic, uint8_t channel)
88 {
89 return nrfx_flag32_free(&p_dppic->channels_mask, channel);
90 }
91
ppib_channel_get(nrfx_interconnect_ppib_t * p_ppib,uint8_t virtual_channel,uint8_t * p_ppib_channel)92 static nrfx_err_t ppib_channel_get(nrfx_interconnect_ppib_t * p_ppib,
93 uint8_t virtual_channel,
94 uint8_t * p_ppib_channel)
95 {
96 for (uint8_t i = 0; i < PPIB_CHANNEL_MAX_COUNT; i++)
97 {
98 if (p_ppib->allocate_flag[i] == virtual_channel)
99 {
100 *p_ppib_channel = i;
101 return NRFX_SUCCESS;
102 }
103 }
104
105 return NRFX_ERROR_INVALID_PARAM;
106 }
107
108 #if NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
ppib_channel_alloc(nrfx_interconnect_ppib_t * p_ppib,uint8_t * p_channel)109 static nrfx_err_t ppib_channel_alloc(nrfx_interconnect_ppib_t * p_ppib, uint8_t * p_channel)
110 {
111 return nrfx_flag32_alloc(&p_ppib->channels_mask, p_channel);
112 }
113 #endif
114
ppib_channel_free(nrfx_interconnect_ppib_t * p_ppib,uint8_t channel)115 static nrfx_err_t ppib_channel_free(nrfx_interconnect_ppib_t * p_ppib, uint8_t channel)
116 {
117 return nrfx_flag32_free(&p_ppib->channels_mask, channel);
118 }
119
ppib_virtual_channel_set(nrfx_interconnect_ppib_t * p_ppib,uint32_t ppib_channel,uint8_t virtual_channel)120 static nrfx_err_t ppib_virtual_channel_set(nrfx_interconnect_ppib_t * p_ppib,
121 uint32_t ppib_channel,
122 uint8_t virtual_channel)
123 {
124 p_ppib->allocate_flag[ppib_channel] = virtual_channel;
125
126 return NRFX_SUCCESS;
127 }
128
129 /* Enable or disable all channels for all involved DPPIC peripherals. */
virtual_channel_enable_set(uint8_t virtual_channel,bool enable)130 static void virtual_channel_enable_set(uint8_t virtual_channel, bool enable)
131 {
132 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
133 {
134 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_at_index_get(i);
135 uint8_t dppi_channel;
136 nrfx_err_t err = dppic_channel_get(dppic, virtual_channel, &dppi_channel);
137 if (err == NRFX_SUCCESS)
138 {
139 nrfy_dppi_channels_set(dppic->dppic, NRFX_BIT((uint32_t)dppi_channel), enable);
140 }
141 }
142 }
143
init(void)144 static void init(void)
145 {
146 static bool initialized = false;
147
148 if (initialized)
149 {
150 return;
151 }
152
153 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
154 {
155 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_at_index_get(i);
156 for (uint8_t j = 0; j < NRF_DPPI_CH_NUM_MAX; j++)
157 {
158 dppic_virtual_channel_set(dppic, j, NRFX_GPPI_CHANNEL_INVALID);
159 }
160 }
161
162 for (uint8_t i = 0; i < NRFX_INTERCONNECT_PPIB_COUNT; i++)
163 {
164 nrfx_interconnect_ppib_t * ppib = nrfx_interconnect_ppib_at_index_get(i);
165 for (uint8_t j = 0; j < PPIB_CHANNEL_MAX_COUNT; j++)
166 {
167 ppib_virtual_channel_set(ppib, j, NRFX_GPPI_CHANNEL_INVALID);
168 }
169 }
170
171 initialized = true;
172 }
173
create_ppib_connection(uint8_t virtual_channel,nrfx_interconnect_dppic_to_dppic_path_t * p_path,uint8_t src_dppi_channel,uint8_t dst_dppi_channel)174 static nrfx_err_t create_ppib_connection(uint8_t virtual_channel,
175 nrfx_interconnect_dppic_to_dppic_path_t * p_path,
176 uint8_t src_dppi_channel,
177 uint8_t dst_dppi_channel)
178 {
179 nrfx_interconnect_ppib_t * p_ppib = p_path->ppib;
180 uint8_t ppib_channel;
181 #if NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
182 nrfx_err_t err = ppib_channel_alloc(p_ppib, &ppib_channel);
183
184 if (err != NRFX_SUCCESS)
185 {
186 return err;
187 }
188 #else
189 NRFX_ASSERT(src_dppi_channel == dst_dppi_channel);
190 ppib_channel = src_dppi_channel;
191 #endif
192
193 ppib_virtual_channel_set(p_ppib, ppib_channel, virtual_channel);
194 nrf_ppib_task_t task = nrf_ppib_send_task_get(ppib_channel);
195 nrf_ppib_event_t event = nrf_ppib_receive_event_get(ppib_channel);
196 if (p_path->ppib_inverted == false)
197 {
198 nrf_ppib_subscribe_set(p_ppib->p_ppib1, task, src_dppi_channel);
199 nrf_ppib_publish_set(p_ppib->p_ppib2, event, dst_dppi_channel);
200 }
201 else
202 {
203 nrf_ppib_subscribe_set(p_ppib->p_ppib2, task, src_dppi_channel);
204 nrf_ppib_publish_set(p_ppib->p_ppib1, event, dst_dppi_channel);
205 }
206 return NRFX_SUCCESS;
207 }
208
clear_virtual_channel_path(uint8_t virtual_channel)209 static nrfx_err_t clear_virtual_channel_path(uint8_t virtual_channel)
210 {
211 // Clear all DPPI channel masks.
212 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
213 {
214 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_at_index_get(i);
215 uint8_t dppi_channel;
216 nrfx_err_t err = dppic_channel_get(dppic, virtual_channel, &dppi_channel);
217 if (err == NRFX_SUCCESS)
218 {
219 nrfy_dppi_channels_set(dppic->dppic, NRFX_BIT((uint32_t)dppi_channel), false);
220
221 err = dppic_channel_free(dppic, dppi_channel);
222 if (err != NRFX_SUCCESS)
223 {
224 return err;
225 }
226
227 err = dppic_virtual_channel_set(dppic,
228 (uint32_t)dppi_channel,
229 NRFX_GPPI_CHANNEL_INVALID);
230 if (err != NRFX_SUCCESS)
231 {
232 return err;
233 }
234 }
235 }
236
237 // Clear all PPIB channel masks.
238 for (uint8_t i = 0; i < NRFX_INTERCONNECT_PPIB_COUNT; i++)
239 {
240 nrfx_interconnect_ppib_t * p_ppib = nrfx_interconnect_ppib_at_index_get(i);
241 uint8_t ppib_channel;
242 nrfx_err_t err = ppib_channel_get(p_ppib, virtual_channel, &ppib_channel);
243 if (err == NRFX_SUCCESS)
244 {
245 nrf_ppib_task_t task = nrf_ppib_send_task_get((uint32_t)ppib_channel);
246 nrf_ppib_event_t event = nrf_ppib_receive_event_get((uint32_t)ppib_channel);
247
248 nrf_ppib_subscribe_clear(p_ppib->p_ppib1, task);
249 nrf_ppib_subscribe_clear(p_ppib->p_ppib2, task);
250
251 nrf_ppib_publish_clear(p_ppib->p_ppib1, event);
252 nrf_ppib_publish_clear(p_ppib->p_ppib2, event);
253
254 err = ppib_channel_free(p_ppib, ppib_channel);
255 if (err != NRFX_SUCCESS)
256 {
257 return err;
258 }
259
260 err = ppib_virtual_channel_set(p_ppib, (uint32_t)ppib_channel, NRFX_GPPI_CHANNEL_INVALID);
261 if (err != NRFX_SUCCESS)
262 {
263 return err;
264 }
265 }
266 }
267
268 return NRFX_SUCCESS;
269 }
270
nrfx_gppi_channel_alloc(uint8_t * p_channel)271 nrfx_err_t nrfx_gppi_channel_alloc(uint8_t * p_channel)
272 {
273 init();
274 return nrfx_flag32_alloc(&m_virtual_channels, p_channel);
275 }
276
nrfx_gppi_event_endpoint_setup(uint8_t channel,uint32_t eep)277 void nrfx_gppi_event_endpoint_setup(uint8_t channel, uint32_t eep)
278 {
279 (void)channel;
280 (void)eep;
281 // `tep` is also needed to decide whether `main_apb` is to be used.
282 NRFX_ASSERT(false);
283 }
284
nrfx_gppi_task_endpoint_setup(uint8_t channel,uint32_t tep)285 void nrfx_gppi_task_endpoint_setup(uint8_t channel, uint32_t tep)
286 {
287 (void)channel;
288 (void)tep;
289 // `eep` is also needed to decide whether `main_apb` is to be used.
290 NRFX_ASSERT(false);
291 }
292
nrfx_gppi_event_endpoint_clear(uint8_t channel,uint32_t eep)293 void nrfx_gppi_event_endpoint_clear(uint8_t channel, uint32_t eep)
294 {
295 (void)channel;
296 (void)eep;
297 // `tep` is also needed to decide whether `main_apb` is to be used.
298 NRFX_ASSERT(false);
299 }
300
nrfx_gppi_task_endpoint_clear(uint8_t channel,uint32_t tep)301 void nrfx_gppi_task_endpoint_clear(uint8_t channel, uint32_t tep)
302 {
303 (void)channel;
304 (void)tep;
305 // `eep` is also needed to decide whether `main_apb` is to be used.
306 NRFX_ASSERT(false);
307 }
308
nrfx_gppi_fork_endpoint_setup(uint8_t channel,uint32_t fork_tep)309 void nrfx_gppi_fork_endpoint_setup(uint8_t channel, uint32_t fork_tep)
310 {
311 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
312 {
313 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_at_index_get(i);
314 uint8_t dppi_channel;
315 nrfx_err_t err = dppic_channel_get(dppic, channel, &dppi_channel);
316 if (err == NRFX_SUCCESS)
317 {
318 NRF_DPPI_ENDPOINT_SETUP(fork_tep, (uint32_t)dppi_channel);
319 return;
320 }
321 }
322 NRFX_ASSERT(false);
323 }
324
nrfx_gppi_fork_endpoint_clear(uint8_t channel,uint32_t fork_tep)325 void nrfx_gppi_fork_endpoint_clear(uint8_t channel, uint32_t fork_tep)
326 {
327 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
328 {
329 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_at_index_get(i);
330 uint8_t dppi_channel;
331 nrfx_err_t err = dppic_channel_get(dppic, channel, &dppi_channel);
332 if (err == NRFX_SUCCESS)
333 {
334 NRF_DPPI_ENDPOINT_CLEAR(fork_tep);
335 return;
336 }
337 }
338 NRFX_ASSERT(false);
339 }
340
nrfx_gppi_channel_endpoints_setup(uint8_t channel,uint32_t eep,uint32_t tep)341 void nrfx_gppi_channel_endpoints_setup(uint8_t channel, uint32_t eep, uint32_t tep)
342 {
343 nrfx_err_t err = NRFX_SUCCESS;
344 nrf_apb_index_t src_domain = nrfx_interconnect_apb_index_get(eep);
345 nrf_apb_index_t dst_domain = nrfx_interconnect_apb_index_get(tep);
346
347 NRFX_ASSERT(src_domain);
348 NRFX_ASSERT(dst_domain);
349
350 uint8_t src_dppi_channel;
351 uint8_t dst_dppi_channel;
352
353 if (src_domain == dst_domain)
354 {
355 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_get(src_domain);
356 if (dppic_channel_alloc(dppic, &src_dppi_channel) == NRFX_SUCCESS)
357 {
358 dst_dppi_channel = src_dppi_channel;
359 dppic_virtual_channel_set(dppic, src_dppi_channel, channel);
360 }
361 else
362 {
363 clear_virtual_channel_path(channel);
364 NRFX_ASSERT(false);
365 return;
366 }
367 }
368 else
369 {
370 nrfx_interconnect_dppic_t * p_src_dppic = nrfx_interconnect_dppic_get(src_domain);
371 nrfx_interconnect_dppic_t * p_dst_dppic = nrfx_interconnect_dppic_get(dst_domain);
372
373 nrfx_interconnect_dppic_to_dppic_path_t path =
374 {
375 .src_dppic = p_src_dppic,
376 .dst_dppic = p_dst_dppic,
377 };
378
379 if (nrfx_interconnect_direct_connection_check(&path))
380 {
381 #if !NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
382 nrfx_atomic_t possible_mask = path.src_dppic->channels_mask;
383 possible_mask &= path.dst_dppic->channels_mask;
384 possible_mask &= path.ppib->channels_mask;
385
386 uint8_t common_channel;
387 nrfx_flag32_alloc(&possible_mask, &common_channel);
388 if (err != NRFX_SUCCESS)
389 {
390 clear_virtual_channel_path(channel);
391 NRFX_ASSERT(false);
392 return;
393 }
394
395 path.src_dppic->channels_mask &= ~NRFX_BIT(common_channel);
396 path.dst_dppic->channels_mask &= ~NRFX_BIT(common_channel);
397 path.ppib->channels_mask &= ~NRFX_BIT(common_channel);
398
399 src_dppi_channel = common_channel;
400 dst_dppi_channel = common_channel;
401 #else
402 err = dppic_channel_alloc(p_src_dppic, &src_dppi_channel);
403 if (err != NRFX_SUCCESS)
404 {
405 clear_virtual_channel_path(channel);
406 NRFX_ASSERT(false);
407 return;
408 }
409 #endif
410 dppic_virtual_channel_set(p_src_dppic, src_dppi_channel, channel);
411 #if NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
412 err = dppic_channel_alloc(p_dst_dppic, &dst_dppi_channel);
413 if (err != NRFX_SUCCESS)
414 {
415 clear_virtual_channel_path(channel);
416 NRFX_ASSERT(false);
417 return;
418 }
419 #endif
420 dppic_virtual_channel_set(p_dst_dppic, dst_dppi_channel, channel);
421
422 err = create_ppib_connection(channel,
423 &path,
424 src_dppi_channel,
425 dst_dppi_channel);
426 if (err != NRFX_SUCCESS)
427 {
428 clear_virtual_channel_path(channel);
429 NRFX_ASSERT(false);
430 return;
431 }
432 }
433 else
434 {
435 nrfx_interconnect_dppic_t * p_main_dppic = nrfx_interconnect_dppic_main_get();
436 p_src_dppic = nrfx_interconnect_dppic_get(src_domain);
437 p_dst_dppic = nrfx_interconnect_dppic_get(dst_domain);
438
439 nrfx_interconnect_dppic_to_dppic_path_t path_src_to_main =
440 {
441 .src_dppic = p_src_dppic,
442 .dst_dppic = p_main_dppic,
443 };
444
445 nrfx_interconnect_dppic_to_dppic_path_t path_main_to_dst =
446 {
447 .src_dppic = p_main_dppic,
448 .dst_dppic = p_dst_dppic,
449 };
450
451 if (nrfx_interconnect_direct_connection_check(&path_src_to_main) &&
452 nrfx_interconnect_direct_connection_check(&path_main_to_dst))
453 {
454 uint8_t main_dppi_channel;
455 #if !NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
456 nrfx_atomic_t possible_mask = p_src_dppic->channels_mask;
457 possible_mask &= p_main_dppic->channels_mask;
458 possible_mask &= p_dst_dppic->channels_mask;
459 possible_mask &= path_src_to_main.ppib->channels_mask;
460 possible_mask &= path_main_to_dst.ppib->channels_mask;
461
462 uint8_t common_channel;
463 nrfx_flag32_alloc(&possible_mask, &common_channel);
464 if (err != NRFX_SUCCESS)
465 {
466 clear_virtual_channel_path(channel);
467 NRFX_ASSERT(false);
468 return;
469 }
470
471 p_src_dppic->channels_mask &= ~NRFX_BIT(common_channel);
472 p_main_dppic->channels_mask &= ~NRFX_BIT(common_channel);
473 p_dst_dppic->channels_mask &= ~NRFX_BIT(common_channel);
474 path_src_to_main.ppib->channels_mask &= ~NRFX_BIT(common_channel);
475 path_main_to_dst.ppib->channels_mask &= ~NRFX_BIT(common_channel);
476
477 dppic_virtual_channel_set(p_src_dppic, common_channel, channel);
478 dppic_virtual_channel_set(p_main_dppic, common_channel, channel);
479 dppic_virtual_channel_set(p_dst_dppic, common_channel, channel);
480
481 src_dppi_channel = common_channel;
482 dst_dppi_channel = common_channel;
483 main_dppi_channel = common_channel;
484 #else
485 err = dppic_channel_alloc(p_src_dppic, &src_dppi_channel);
486 if (err != NRFX_SUCCESS)
487 {
488 clear_virtual_channel_path(channel);
489 NRFX_ASSERT(false);
490 return;
491 }
492 #endif
493 dppic_virtual_channel_set(p_src_dppic, src_dppi_channel, channel);
494 #if NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
495 err = dppic_channel_alloc(p_main_dppic, &main_dppi_channel);
496 if (err != NRFX_SUCCESS)
497 {
498 clear_virtual_channel_path(channel);
499 NRFX_ASSERT(false);
500 return;
501 }
502 #endif
503 dppic_virtual_channel_set(p_main_dppic, main_dppi_channel, channel);
504 #if NRFX_GPPI_PPIB_HAS_DYNAMIC_CONFIG
505 err = dppic_channel_alloc(p_dst_dppic, &dst_dppi_channel);
506 if (err != NRFX_SUCCESS)
507 {
508 clear_virtual_channel_path(channel);
509 NRFX_ASSERT(false);
510 return;
511 }
512 #endif
513 dppic_virtual_channel_set(p_dst_dppic, dst_dppi_channel, channel);
514
515 err = create_ppib_connection(channel,
516 &path_src_to_main ,
517 src_dppi_channel,
518 main_dppi_channel);
519 if (err != NRFX_SUCCESS)
520 {
521 clear_virtual_channel_path(channel);
522 NRFX_ASSERT(false);
523 return;
524 }
525
526 err = create_ppib_connection(channel,
527 &path_main_to_dst,
528 main_dppi_channel,
529 dst_dppi_channel);
530 if (err != NRFX_SUCCESS)
531 {
532 clear_virtual_channel_path(channel);
533 NRFX_ASSERT(false);
534 return;
535 }
536 }
537 else
538 {
539 clear_virtual_channel_path(channel);
540 NRFX_ASSERT(false);
541 return;
542 }
543 }
544 }
545
546 if (err == NRFX_SUCCESS)
547 {
548 NRF_DPPI_ENDPOINT_SETUP(eep, src_dppi_channel);
549 NRF_DPPI_ENDPOINT_SETUP(tep, dst_dppi_channel);
550 }
551 }
552
nrfx_gppi_channel_endpoints_clear(uint8_t channel,uint32_t eep,uint32_t tep)553 void nrfx_gppi_channel_endpoints_clear(uint8_t channel, uint32_t eep, uint32_t tep)
554 {
555 clear_virtual_channel_path(channel);
556
557 NRF_DPPI_ENDPOINT_CLEAR(eep);
558 NRF_DPPI_ENDPOINT_CLEAR(tep);
559 }
560
nrfx_gppi_channel_free(uint8_t channel)561 nrfx_err_t nrfx_gppi_channel_free(uint8_t channel)
562 {
563 nrfx_err_t err = nrfx_flag32_free(&m_virtual_channels, channel);
564
565 if(err != NRFX_SUCCESS)
566 {
567 return err;
568 }
569
570 return clear_virtual_channel_path(channel);
571 }
572
nrfx_gppi_channel_check(uint8_t channel)573 bool nrfx_gppi_channel_check(uint8_t channel)
574 {
575 NRFX_ASSERT(nrfx_flag32_is_allocated(m_virtual_channels, channel));
576
577 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
578 {
579 nrfx_interconnect_dppic_t * dppic = nrfx_interconnect_dppic_at_index_get(i);
580 uint8_t dppi_channel;
581 nrfx_err_t err = dppic_channel_get(dppic, channel, &dppi_channel);
582 if (err == NRFX_SUCCESS)
583 {
584 if (nrf_dppi_channel_check(dppic->dppic, (uint32_t)dppi_channel) == false)
585 {
586 return false;
587 }
588 break;
589 }
590 }
591
592 return true;
593 }
594
nrfx_gppi_channels_disable_all(void)595 void nrfx_gppi_channels_disable_all(void)
596 {
597 uint32_t mask = ~(uint32_t)m_virtual_channels;
598
599 while (mask)
600 {
601 uint8_t channel = (uint8_t)NRF_CTZ(mask);
602 virtual_channel_enable_set(channel, false);
603 mask &= ~NRFX_BIT(channel);
604 }
605 }
606
nrfx_gppi_channels_enable(uint32_t mask)607 void nrfx_gppi_channels_enable(uint32_t mask)
608 {
609 while (mask)
610 {
611 uint8_t channel = (uint8_t)NRF_CTZ(mask);
612 virtual_channel_enable_set(channel, true);
613 mask &= ~NRFX_BIT(channel);
614 }
615 }
616
nrfx_gppi_channels_disable(uint32_t mask)617 void nrfx_gppi_channels_disable(uint32_t mask)
618 {
619 // Remove all connections for all channels determined by mask.
620 while (mask)
621 {
622 // Remove assigned channels for all involved DPPICn peripherals.
623 uint8_t channel = (uint8_t)NRF_CTZ(mask);
624 virtual_channel_enable_set(channel, false);
625 mask &= ~NRFX_BIT(channel);
626 }
627 }
628
629 #endif // defined(LUMOS_XXAA)
630