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