1 /*
2 * Copyright (c) 2024 - 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 NRFX_CHECK(NRFX_PPIB_ENABLED)
37
38 #include <nrfx_ppib.h>
39 #include <helpers/nrfx_flag32_allocator.h>
40
41 #define NRFX_LOG_MODULE PPIB
42 #include <nrfx_log.h>
43
44 #if !defined(__NRFX_DOXYGEN__)
45
46 #if defined(NRF54L_SERIES) || defined(NRF7120_ENGA_XXAA)
47
48 #if !defined(NRFX_PPIB_INTERCONNECT_00_10_CHANNELS_USED)
49 /**
50 * Bitmask that defines PPIB00 and PPIB10 channels that are
51 * reserved for use outside of the nrfx library.
52 */
53 #define NRFX_PPIB_INTERCONNECT_00_10_CHANNELS_USED 0UL
54 #endif
55
56 #if !defined(NRFX_PPIB_INTERCONNECT_01_20_CHANNELS_USED)
57 /**
58 * Bitmask that defines PPIB01 and PPIB20 channels that are
59 * reserved for use outside of the nrfx library.
60 */
61 #define NRFX_PPIB_INTERCONNECT_01_20_CHANNELS_USED 0UL
62 #endif
63
64 #if !defined(NRFX_PPIB_INTERCONNECT_11_21_CHANNELS_USED)
65 /**
66 * Bitmask that defines PPIB11 and PPIB21 channels that are
67 * reserved for use outside of the nrfx library.
68 */
69 #define NRFX_PPIB_INTERCONNECT_11_21_CHANNELS_USED 0UL
70 #endif
71
72 #if !defined(NRFX_PPIB_INTERCONNECT_22_30_CHANNELS_USED)
73 /**
74 * Bitmask that defines PPIB022 and PPIB30 channels that are
75 * reserved for use outside of the nrfx library.
76 */
77 #define NRFX_PPIB_INTERCONNECT_22_30_CHANNELS_USED 0UL
78 #endif
79
80 #endif
81
82 #if defined(NRF54L20_ENGA_XXAA)
83
84 #if !defined(NRFX_PPIB_INTERCONNECT_02_03_CHANNELS_USED)
85 /**
86 * Bitmask that defines PPIB022 and PPIB30 channels that are
87 * reserved for use outside of the nrfx library.
88 */
89 #define NRFX_PPIB_INTERCONNECT_02_03_CHANNELS_USED 0UL
90 #endif
91
92 #if !defined(NRFX_PPIB_INTERCONNECT_04_12_CHANNELS_USED)
93 /**
94 * Bitmask that defines PPIB022 and PPIB30 channels that are
95 * reserved for use outside of the nrfx library.
96 */
97 #define NRFX_PPIB_INTERCONNECT_04_12_CHANNELS_USED 0UL
98 #endif
99
100 #endif
101
102 #if defined(HALTIUM_XXAA)
103
104 #if !defined(NRFX_PPIB_INTERCONNECT_020_030_CHANNELS_USED)
105 /**
106 * Bitmask that defines PPIB020 and PPIB030 channels that are
107 * reserved for use outside of the nrfx library.
108 */
109 #define NRFX_PPIB_INTERCONNECT_020_030_CHANNELS_USED 0UL
110 #endif
111
112 #endif
113
114 #endif // !defined(__NRFX_DOXYGEN__)
115
116 #define PPIB_CHANNELS_NUM(idx) (NRFX_CONCAT(PPIB, idx, _NTASKSEVENTS_MAX) + 1UL)
117 #define PPIB_CHANNELS_MASK(left, right) \
118 NRFX_BIT_MASK(NRFX_MIN(PPIB_CHANNELS_NUM(left), PPIB_CHANNELS_NUM(right))
119 #define PPIB_CHANNELS_USED(left, right) \
120 NRFX_CONCAT(NRFX_PPIB_INTERCONNECT_, left, _, right, _CHANNELS_USED)
121 #define PPIB_AVAILABLE_CHANNELS_MASK(left, right) \
122 ((uint32_t)(PPIB_CHANNELS_MASK(left, right)) & ~(PPIB_CHANNELS_USED(left, right))))
123
124 /* Structure holding state of the PPIB instance. */
125 typedef struct
126 {
127 /**< Bitmap representing channels availability. */
128 nrfx_atomic_t allocated_channels;
129 /**< Bitmap representing available channels. */
130 const uint32_t available_channels;
131 } ppib_control_block_t;
132
133 #define _NRFX_PPIBC_CB_INITIALIZER(left_idx, right_idx) \
134 [NRFX_CONCAT(NRFX_PPIB_INTERCONNECT_, left_idx, _, right_idx, _INST_IDX)] = { \
135 .allocated_channels = (nrfx_atomic_t)PPIB_AVAILABLE_CHANNELS_MASK(left_idx, right_idx), \
136 .available_channels = PPIB_AVAILABLE_CHANNELS_MASK(left_idx, right_idx), \
137 },
138
139 static ppib_control_block_t m_cb[NRFX_PPIB_INTERCONNECT_COUNT] = {
140 #if defined(NRF54L_SERIES) || defined(NRF7120_ENGA_XXAA)
141 #if NRFX_CHECK(NRFX_PPIB00_ENABLED) && NRFX_CHECK(NRFX_PPIB10_ENABLED)
142 _NRFX_PPIBC_CB_INITIALIZER(00, 10)
143 #endif
144 #if NRFX_CHECK(NRFX_PPIB01_ENABLED) && NRFX_CHECK(NRFX_PPIB20_ENABLED)
145 _NRFX_PPIBC_CB_INITIALIZER(01, 20)
146 #endif
147 #if NRFX_CHECK(NRFX_PPIB11_ENABLED) && NRFX_CHECK(NRFX_PPIB21_ENABLED)
148 _NRFX_PPIBC_CB_INITIALIZER(11, 21)
149 #endif
150 #if NRFX_CHECK(NRFX_PPIB22_ENABLED) && NRFX_CHECK(NRFX_PPIB30_ENABLED)
151 _NRFX_PPIBC_CB_INITIALIZER(22, 30)
152 #endif
153 #endif
154 #if defined(NRF54L20_ENGA_XXAA)
155 #if NRFX_CHECK(NRFX_PPIB02_ENABLED) && NRFX_CHECK(NRFX_PPIB03_ENABLED)
156 _NRFX_PPIBC_CB_INITIALIZER(02, 03)
157 #endif
158 #if NRFX_CHECK(NRFX_PPIB04_ENABLED) && NRFX_CHECK(NRFX_PPIB12_ENABLED)
159 _NRFX_PPIBC_CB_INITIALIZER(04, 12)
160 #endif
161 #endif
162 #if defined(HALTIUM_XXAA)
163 #if NRFX_CHECK(NRFX_PPIB020_ENABLED) && NRFX_CHECK(NRFX_PPIB030_ENABLED)
164 _NRFX_PPIBC_CB_INITIALIZER(020, 030)
165 #endif
166 #endif
167 };
168
nrfx_ppib_free(nrfx_ppib_interconnect_t const * p_instance)169 void nrfx_ppib_free(nrfx_ppib_interconnect_t const * p_instance)
170 {
171 ppib_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
172 uint32_t mask = p_cb->available_channels & ~p_cb->allocated_channels;
173 uint8_t channel_idx = 0;
174
175 // Clear all channel configurations
176 while (mask)
177 {
178 if (mask & NRFX_BIT(channel_idx))
179 {
180 nrfx_ppib_channel_free(p_instance, channel_idx);
181 mask &= ~NRFX_BIT(channel_idx);
182 }
183 channel_idx++;
184 }
185 }
186
nrfx_ppib_channel_alloc(nrfx_ppib_interconnect_t const * p_instance,uint8_t * p_channel)187 nrfx_err_t nrfx_ppib_channel_alloc(nrfx_ppib_interconnect_t const * p_instance, uint8_t * p_channel)
188 {
189 ppib_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
190
191 return nrfx_flag32_alloc(&p_cb->allocated_channels, p_channel);
192 }
193
nrfx_ppib_channel_free(nrfx_ppib_interconnect_t const * p_instance,uint8_t channel)194 nrfx_err_t nrfx_ppib_channel_free(nrfx_ppib_interconnect_t const * p_instance, uint8_t channel)
195 {
196 ppib_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
197
198 if ((p_cb->available_channels & NRFX_BIT(channel)) == 0)
199 {
200 return NRFX_ERROR_INVALID_PARAM;
201 }
202
203 nrf_ppib_subscribe_clear(p_instance->left.p_reg, nrf_ppib_send_task_get(channel));
204 nrf_ppib_subscribe_clear(p_instance->right.p_reg, nrf_ppib_send_task_get(channel));
205 nrf_ppib_publish_clear(p_instance->left.p_reg, nrf_ppib_receive_event_get(channel));
206 nrf_ppib_publish_clear(p_instance->right.p_reg, nrf_ppib_receive_event_get(channel));
207
208 return nrfx_flag32_free(&p_cb->allocated_channels, channel);
209 }
210
211 #endif // defined(PPIB_PRESENT)
212