1 /*
2 * Copyright (c) 2023 - 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 #include <nrfx.h>
35
36 #if defined(LUMOS_XXAA)
37
38 #include "nrfx_interconnect_dppic_ppib.h"
39 #include <helpers/nrfx_flag32_allocator.h>
40 #include <haly/nrfy_dppi.h>
41
42 #include <soc/interconnect/dppic_ppib/nrfx_interconnect_dppic_ppib_lumos.h>
43
44 nrfx_interconnect_dppic_t interconnect_dppic[] = NRFX_INTERCONNECT_DPPIC_MAP;
45
46 /* Each PPIB must be connected with one DPPI. */
47 NRFX_STATIC_ASSERT(NRFX_INTERCONNECT_DPPIC_COUNT == NRFX_ARRAY_SIZE(interconnect_dppic));
48
49 nrfx_interconnect_ppib_t interconnect_ppib[] = NRFX_INTERCONNECT_PPIB_MAP;
50
51 /* One PPIB is connected to only one another PPIB directly. */
52 NRFX_STATIC_ASSERT(NRFX_INTERCONNECT_PPIB_COUNT == NRFX_ARRAY_SIZE(interconnect_ppib));
53
54 nrfx_interconnect_dppic_ppib_t interconnect_dppic_ppib[] = NRFX_INTERCONNECT_DPPIC_PPIB_MAP;
55
56 /* Each DPPIC needs to have its own properties structure. */
57 NRFX_STATIC_ASSERT(NRFX_INTERCONNECT_DPPIC_PPIB_COUNT == NRFX_ARRAY_SIZE(interconnect_dppic_ppib));
58
nrfx_interconnect_dppic_at_index_get(uint8_t index)59 nrfx_interconnect_dppic_t * nrfx_interconnect_dppic_at_index_get(uint8_t index)
60 {
61 NRFX_ASSERT(index < NRFX_INTERCONNECT_DPPIC_COUNT);
62
63 return &interconnect_dppic[index];
64 }
65
nrfx_interconnect_dppic_get(uint8_t apb_index)66 nrfx_interconnect_dppic_t * nrfx_interconnect_dppic_get(uint8_t apb_index)
67 {
68 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
69 {
70 if (interconnect_dppic[i].apb_index == apb_index)
71 {
72 return &interconnect_dppic[i];
73 }
74 }
75
76 return NULL;
77 }
78
nrfx_interconnect_dppic_main_get()79 nrfx_interconnect_dppic_t * nrfx_interconnect_dppic_main_get()
80 {
81 return nrfx_interconnect_dppic_get(NRF_APB_INDEX_PERI);
82 }
83
nrfx_interconnect_ppib_at_index_get(uint8_t index)84 nrfx_interconnect_ppib_t * nrfx_interconnect_ppib_at_index_get(uint8_t index)
85 {
86 NRFX_ASSERT(index < NRFX_INTERCONNECT_PPIB_COUNT);
87
88 return &interconnect_ppib[index];
89 }
90
nrfx_interconnect_direct_connection_check(nrfx_interconnect_dppic_to_dppic_path_t * p_path)91 bool nrfx_interconnect_direct_connection_check(nrfx_interconnect_dppic_to_dppic_path_t * p_path)
92 {
93 NRFX_ASSERT(p_path);
94 NRFX_ASSERT(p_path->src_dppic);
95 NRFX_ASSERT(p_path->dst_dppic);
96
97 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_PPIB_COUNT; i++)
98 {
99 NRF_DPPIC_Type *p_reg;
100 #if NRFX_API_VER_AT_LEAST(3, 8, 0)
101 p_reg = p_path->src_dppic->dppic.p_reg;
102 #else
103 p_reg = p_path->src_dppic->dppic;
104 #endif
105 if (interconnect_dppic_ppib[i].dppic != p_reg)
106 {
107 continue;
108 }
109
110 for (uint8_t j = 0; j < NRFX_INTERCONNECT_PPIB_COUNT; j++)
111 {
112 NRF_PPIB_Type * p_dst_ppib = NULL;
113
114 if (interconnect_ppib[j].ppib.left.p_reg == interconnect_dppic_ppib[i].ppib)
115 {
116 p_path->ppib = &interconnect_ppib[j];
117 p_path->ppib_inverted = false;
118 p_dst_ppib = interconnect_ppib[j].ppib.right.p_reg;
119 }
120
121 if (interconnect_ppib[j].ppib.right.p_reg == interconnect_dppic_ppib[i].ppib)
122 {
123 p_path->ppib = &interconnect_ppib[j];
124 p_path->ppib_inverted = true;
125 p_dst_ppib = interconnect_ppib[j].ppib.left.p_reg;
126 }
127
128 if (p_dst_ppib == NULL)
129 {
130 continue;
131 }
132
133 for (uint8_t k = 0; k < NRFX_ARRAY_SIZE(interconnect_dppic_ppib); k++)
134 {
135 NRF_DPPIC_Type *p_dst_reg;
136 #if NRFX_API_VER_AT_LEAST(3, 8, 0)
137 p_dst_reg = p_path->dst_dppic->dppic.p_reg;
138 #else
139 p_dst_reg = p_path->dst_dppic->dppic;
140 #endif
141 if ((interconnect_dppic_ppib[k].ppib == p_dst_ppib) &&
142 (interconnect_dppic_ppib[k].dppic == p_dst_reg))
143 {
144 return true;
145 }
146 }
147 }
148 }
149
150 return false;
151 }
152
nrfx_interconnect_apb_index_get(uint32_t addr)153 nrf_apb_index_t nrfx_interconnect_apb_index_get(uint32_t addr)
154 {
155 for (uint8_t i = 0; i < NRFX_INTERCONNECT_DPPIC_COUNT; i++)
156 {
157 nrfx_interconnect_dppic_t const * p_dppic = &interconnect_dppic[i];
158 uint8_t bus_address_area = nrf_address_bus_get(addr, p_dppic->apb_size);
159
160 NRF_DPPIC_Type *p_reg;
161 #if NRFX_API_VER_AT_LEAST(3, 8, 0)
162 p_reg = p_dppic->dppic.p_reg;
163 #else
164 p_reg = p_dppic->dppic;
165 #endif
166 if (bus_address_area == nrf_address_bus_get((uint32_t)p_reg, p_dppic->apb_size))
167 {
168 return (nrf_apb_index_t)bus_address_area;
169 }
170 }
171 return (nrf_apb_index_t)0;
172 }
173
174 #endif // defined(LUMOS_XXAA)
175