1 /*
2 * Copyright (c) 2017 - 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_PRS_ENABLED)
37 #include "nrfx_prs.h"
38
39 #define NRFX_LOG_MODULE PRS
40 #include <nrfx_log.h>
41
42 #define LOG_FUNCTION_EXIT(level, ret_code) \
43 NRFX_LOG_##level("Function: %s, error code: %s.", \
44 __func__, \
45 NRFX_LOG_ERROR_STRING_GET(ret_code))
46
47
48 typedef struct {
49 nrfx_irq_handler_t handler;
50 bool acquired;
51 } prs_box_t;
52
53 #define PRS_BOX_DEFINE(n) \
54 static prs_box_t m_prs_box_##n = { .handler = NULL, .acquired = false }; \
55 void nrfx_prs_box_##n##_irq_handler(void) \
56 { \
57 NRFX_ASSERT(m_prs_box_##n.handler); \
58 m_prs_box_##n.handler(); \
59 }
60
61 #if defined(NRFX_PRS_BOX_0_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_0_ENABLED)
62 PRS_BOX_DEFINE(0)
63 #endif
64 #if defined(NRFX_PRS_BOX_1_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_1_ENABLED)
65 PRS_BOX_DEFINE(1)
66 #endif
67 #if defined(NRFX_PRS_BOX_2_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_2_ENABLED)
68 PRS_BOX_DEFINE(2)
69 #endif
70 #if defined(NRFX_PRS_BOX_3_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_3_ENABLED)
71 PRS_BOX_DEFINE(3)
72 #endif
73 #if defined(NRFX_PRS_BOX_4_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_4_ENABLED)
74 PRS_BOX_DEFINE(4)
75 #endif
76 #if defined(NRFX_PRS_BOX_5_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_5_ENABLED)
77 PRS_BOX_DEFINE(5)
78 #endif
79 #if defined(NRFX_PRS_BOX_6_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_6_ENABLED)
80 PRS_BOX_DEFINE(6)
81 #endif
82 #if defined(NRFX_PRS_BOX_7_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_7_ENABLED)
83 PRS_BOX_DEFINE(7)
84 #endif
85 #if defined(NRFX_PRS_BOX_8_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_8_ENABLED)
86 PRS_BOX_DEFINE(8)
87 #endif
88 #if defined(NRFX_PRS_BOX_9_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_9_ENABLED)
89 PRS_BOX_DEFINE(9)
90 #endif
91
prs_box_get(void const * p_base_addr)92 static prs_box_t * prs_box_get(void const * p_base_addr)
93 {
94 #if !defined(IS_PRS_BOX)
95 #define IS_PRS_BOX(n, p_base_addr) ((p_base_addr) == NRFX_PRS_BOX_##n##_ADDR)
96 #endif
97
98 #if defined(NRFX_PRS_BOX_0_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_0_ENABLED)
99 if (IS_PRS_BOX(0, p_base_addr)) { return &m_prs_box_0; }
100 else
101 #endif
102 #if defined(NRFX_PRS_BOX_1_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_1_ENABLED)
103 if (IS_PRS_BOX(1, p_base_addr)) { return &m_prs_box_1; }
104 else
105 #endif
106 #if defined(NRFX_PRS_BOX_2_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_2_ENABLED)
107 if (IS_PRS_BOX(2, p_base_addr)) { return &m_prs_box_2; }
108 else
109 #endif
110 #if defined(NRFX_PRS_BOX_3_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_3_ENABLED)
111 if (IS_PRS_BOX(3, p_base_addr)) { return &m_prs_box_3; }
112 else
113 #endif
114 #if defined(NRFX_PRS_BOX_4_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_4_ENABLED)
115 if (IS_PRS_BOX(4, p_base_addr)) { return &m_prs_box_4; }
116 else
117 #endif
118 #if defined(NRFX_PRS_BOX_5_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_5_ENABLED)
119 if (IS_PRS_BOX(5, p_base_addr)) { return &m_prs_box_5; }
120 else
121 #endif
122 #if defined(NRFX_PRS_BOX_6_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_6_ENABLED)
123 if (IS_PRS_BOX(6, p_base_addr)) { return &m_prs_box_6; }
124 else
125 #endif
126 #if defined(NRFX_PRS_BOX_7_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_7_ENABLED)
127 if (IS_PRS_BOX(7, p_base_addr)) { return &m_prs_box_7; }
128 else
129 #endif
130 #if defined(NRFX_PRS_BOX_8_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_8_ENABLED)
131 if (IS_PRS_BOX(8, p_base_addr)) { return &m_prs_box_8; }
132 else
133 #endif
134 #if defined(NRFX_PRS_BOX_9_ADDR) && NRFX_CHECK(NRFX_PRS_BOX_9_ENABLED)
135 if (IS_PRS_BOX(9, p_base_addr)) { return &m_prs_box_9; }
136 else
137 #endif
138 {
139 return NULL;
140 }
141 }
142
nrfx_prs_acquire(void const * p_base_addr,nrfx_irq_handler_t irq_handler)143 nrfx_err_t nrfx_prs_acquire(void const * p_base_addr,
144 nrfx_irq_handler_t irq_handler)
145 {
146 NRFX_ASSERT(p_base_addr);
147
148 nrfx_err_t ret_code;
149
150 prs_box_t * p_box = prs_box_get(p_base_addr);
151 if (p_box != NULL)
152 {
153 bool busy = false;
154
155 NRFX_CRITICAL_SECTION_ENTER();
156 if (p_box->acquired)
157 {
158 busy = true;
159 }
160 else
161 {
162 p_box->handler = irq_handler;
163 p_box->acquired = true;
164 }
165 NRFX_CRITICAL_SECTION_EXIT();
166
167 if (busy)
168 {
169 ret_code = NRFX_ERROR_BUSY;
170 LOG_FUNCTION_EXIT(WARNING, ret_code);
171 return ret_code;
172 }
173 }
174
175 ret_code = NRFX_SUCCESS;
176 LOG_FUNCTION_EXIT(INFO, ret_code);
177 return ret_code;
178 }
179
nrfx_prs_release(void const * p_base_addr)180 void nrfx_prs_release(void const * p_base_addr)
181 {
182 NRFX_ASSERT(p_base_addr);
183
184 prs_box_t * p_box = prs_box_get(p_base_addr);
185 if (p_box != NULL)
186 {
187 p_box->handler = NULL;
188 p_box->acquired = false;
189 }
190 }
191
192
193 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
194