1 /*
2 * Copyright (c) 2023, 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 #ifndef NRF_VPR_CLIC_H_
35 #define NRF_VPR_CLIC_H_
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_vpr_clic_hal VPR CLIC HAL
45 * @{
46 * @ingroup nrf_vpr
47 * @brief Hardware access layer for managing the VPR RISC-V CPU Interrupt Controller (VPR CLIC).
48 */
49
50 /** @brief Interrupts count. */
51 #define NRF_VPR_CLIC_IRQ_COUNT CLIC_CLIC_CLICINT_MaxCount
52
53 /** @brief Interrupt privilege modes available. */
54 typedef enum
55 {
56 NRF_VPR_CLIC_MODE_M = CLIC_CLIC_CLICCFG_NMBITS_ModeM, /**< All interrupts are M-mode only. */
57 } nrf_vpr_clic_mode_t;
58
59 #if defined(NRF54H20_ENGA_XXAA) || defined(__NRFX_DOXYGEN__)
60 /** @brief Interrupt priority level. */
61 typedef enum
62 {
63 NRF_VPR_CLIC_PRIORITY_LEVEL0 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL0, /**< Priority level 0. */
64 NRF_VPR_CLIC_PRIORITY_LEVEL1 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL1, /**< Priority level 1. */
65 NRF_VPR_CLIC_PRIORITY_LEVEL2 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL2, /**< Priority level 2. */
66 NRF_VPR_CLIC_PRIORITY_LEVEL3 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL3, /**< Priority level 3. */
67 } nrf_vpr_clic_priority_t;
68 #else
69 typedef uint8_t nrf_vpr_clic_priority_t;
70 #endif
71
72 /** @brief VPR CLIC configuration structure. */
73 typedef struct
74 {
75 bool hw_vectoring; /**< Selective interrupt hardware vectoring. */
76 uint8_t level_encoding; /**< Interrupt level encoding. */
77 nrf_vpr_clic_mode_t privilege_mode; /**< Interrupt privilege mode. */
78 } nrf_vpr_clic_config_t;
79
80 /** @brief VPR CLIC information structure. */
81 typedef struct
82 {
83 uint16_t interrupt_count; /**< Maximum number of interrupts supported. */
84 uint8_t version; /**< Version of CLIC. */
85 uint8_t trigger_count; /**< Number of maximum interrupt triggers supported. */
86 } nrf_vpr_clic_info_t;
87
88 /** @brief Interrupt trigger and polarity types. */
89 typedef enum
90 {
91 NRF_VPR_CLIC_TRIGGER_EDGE_POS = CLIC_CLIC_CLICINT_TRIG_EdgeTriggered, /**< Interrupts are positive edge-triggered. */
92 } nrf_vpr_clic_trigger_t;
93
94 /** @brief Interrupt privilege. */
95 typedef enum
96 {
97 NRF_VPR_CLIC_PRIV_MACHINE = CLIC_CLIC_CLICINT_MODE_MachineMode, /**< Machine mode. */
98 } nrf_vpr_clic_priv_t;
99
100 /** @brief Interrupt attributes structure. */
101 typedef struct
102 {
103 bool hw_vectoring; /**< Selective interrupt hardware vectoring. */
104 nrf_vpr_clic_trigger_t trigger; /**< Trigger type and polarity for the interrupt. */
105 nrf_vpr_clic_priv_t privilege; /**< Privilege mode. */
106 } nrf_vpr_clic_attr_t;
107
108 /**
109 * @brief Function for getting the CLIC configuration.
110 *
111 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
112 * @param[out] p_config Pointer to the VPR CLIC configuration structure.
113 */
114 NRF_STATIC_INLINE void nrf_vpr_clic_config_get(NRF_CLIC_Type const * p_reg,
115 nrf_vpr_clic_config_t * p_config);
116
117 /**
118 * @brief Function for getting the CLIC information.
119 *
120 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
121 * @param[out] p_info Pointer to the VPR CLIC information structure.
122 */
123 NRF_STATIC_INLINE void nrf_vpr_clic_info_get(NRF_CLIC_Type const * p_reg,
124 nrf_vpr_clic_info_t * p_info);
125
126 /**
127 * @brief Function for setting the specified interrupt to be pending.
128 *
129 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
130 * @param[in] irq_num Number of interrupt to be triggered.
131 */
132 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_set(NRF_CLIC_Type * p_reg, uint32_t irq_num);
133
134 /**
135 * @brief Function for clearing the pending status for the specified interrupt.
136 *
137 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
138 * @param[in] irq_num Number of interrupt to be cleared.
139 */
140 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_clear(NRF_CLIC_Type * p_reg, uint32_t irq_num);
141
142 /**
143 * @brief Function for checking if the specified interrupt is pending.
144 *
145 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
146 * @param[in] irq_num Number of interrupt to be checked.
147 *
148 * @retval true Interrupt is pending.
149 * @retval false Interrupt is not pending.
150 */
151 NRF_STATIC_INLINE bool nrf_vpr_clic_int_pending_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num);
152
153 /**
154 * @brief Function for enabling or disabling the specified interrupt.
155 *
156 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
157 * @param[in] irq_num Number of interrupt to be enabled or disabled.
158 * @param[in] enable True if interrupt is to be enabled, false otherwise.
159 */
160 NRF_STATIC_INLINE void nrf_vpr_clic_int_enable_set(NRF_CLIC_Type * p_reg,
161 uint32_t irq_num,
162 bool enable);
163
164 /**
165 * @brief Function for checking if the specified interrupt is enabled.
166 *
167 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
168 * @param[in] irq_num Number of interrupt to be checked.
169 *
170 * @retval true Interrupt is enabled.
171 * @retval false Interrupt is disabled.
172 */
173 NRF_STATIC_INLINE bool nrf_vpr_clic_int_enable_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num);
174
175 /**
176 * @brief Function for setting the priority of the specified interrupt.
177 *
178 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
179 * @param[in] irq_num Number of interrupt.
180 * @param[in] priority Priority to be set.
181 */
182 NRF_STATIC_INLINE void nrf_vpr_clic_int_priority_set(NRF_CLIC_Type * p_reg,
183 uint32_t irq_num,
184 nrf_vpr_clic_priority_t priority);
185
186 /**
187 * @brief Function for getting the priority of the specified interrupt.
188 *
189 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
190 * @param[in] irq_num Number of interrupt.
191 *
192 * @return Priority of the specified interrupt.
193 */
194 NRF_STATIC_INLINE
195 nrf_vpr_clic_priority_t nrf_vpr_clic_int_priority_get(NRF_CLIC_Type const * p_reg,
196 uint32_t irq_num);
197
198 /**
199 * @brief Function for getting the CLIC attributes.
200 *
201 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
202 * @param[in] irq_num Number of interrupt.
203 * @param[out] p_attr Pointer to the structure to be filled with VPR CLIC attributes.
204 */
205 NRF_STATIC_INLINE void nrf_vpr_clic_int_attr_get(NRF_CLIC_Type const * p_reg,
206 uint32_t irq_num,
207 nrf_vpr_clic_attr_t * p_attr);
208
209 #ifndef NRF_DECLARE_ONLY
210
nrf_vpr_clic_config_get(NRF_CLIC_Type const * p_reg,nrf_vpr_clic_config_t * p_config)211 NRF_STATIC_INLINE void nrf_vpr_clic_config_get(NRF_CLIC_Type const * p_reg,
212 nrf_vpr_clic_config_t * p_config)
213 {
214 NRFX_ASSERT(p_config);
215 uint32_t cfg = p_reg->CLIC.CLICCFG;
216
217 p_config->hw_vectoring = (cfg & CLIC_CLIC_CLICCFG_NVBITS_Msk) >> CLIC_CLIC_CLICCFG_NVBITS_Pos;
218 p_config->level_encoding = (cfg & CLIC_CLIC_CLICCFG_NLBITS_Msk) >> CLIC_CLIC_CLICCFG_NLBITS_Pos;
219 p_config->privilege_mode = (nrf_vpr_clic_mode_t)((cfg & CLIC_CLIC_CLICCFG_NMBITS_Msk)
220 >> CLIC_CLIC_CLICCFG_NMBITS_Pos);
221 }
222
nrf_vpr_clic_info_get(NRF_CLIC_Type const * p_reg,nrf_vpr_clic_info_t * p_info)223 NRF_STATIC_INLINE void nrf_vpr_clic_info_get(NRF_CLIC_Type const * p_reg,
224 nrf_vpr_clic_info_t * p_info)
225 {
226 NRFX_ASSERT(p_info);
227 uint32_t inf = p_reg->CLIC.CLICINFO;
228
229 p_info->interrupt_count = (inf & CLIC_CLIC_CLICINFO_NUMINTERRUPTS_Msk)
230 >> CLIC_CLIC_CLICINFO_NUMINTERRUPTS_Pos;
231 p_info->version = (inf & CLIC_CLIC_CLICINFO_VERSION_Msk)
232 >> CLIC_CLIC_CLICINFO_VERSION_Pos;
233 p_info->trigger_count = (inf & CLIC_CLIC_CLICINFO_NUMTRIGGER_Msk)
234 >> CLIC_CLIC_CLICINFO_NUMTRIGGER_Pos;
235 }
236
nrf_vpr_clic_int_pending_set(NRF_CLIC_Type * p_reg,uint32_t irq_num)237 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_set(NRF_CLIC_Type * p_reg, uint32_t irq_num)
238 {
239 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
240 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_IP_Msk) |
241 (CLIC_CLIC_CLICINT_IP_Pending << CLIC_CLIC_CLICINT_IP_Pos);
242 }
243
nrf_vpr_clic_int_pending_clear(NRF_CLIC_Type * p_reg,uint32_t irq_num)244 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_clear(NRF_CLIC_Type * p_reg, uint32_t irq_num)
245 {
246 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
247 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_IP_Msk) |
248 (CLIC_CLIC_CLICINT_IP_NotPending << CLIC_CLIC_CLICINT_IP_Pos);
249 }
250
nrf_vpr_clic_int_pending_check(NRF_CLIC_Type const * p_reg,uint32_t irq_num)251 NRF_STATIC_INLINE bool nrf_vpr_clic_int_pending_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num)
252 {
253 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
254
255 return ((p_reg->CLIC.CLICINT[irq_num] & CLIC_CLIC_CLICINT_IP_Msk) >> CLIC_CLIC_CLICINT_IP_Pos)
256 ==
257 CLIC_CLIC_CLICINT_IP_Pending ? true : false;
258 }
259
nrf_vpr_clic_int_enable_set(NRF_CLIC_Type * p_reg,uint32_t irq_num,bool enable)260 NRF_STATIC_INLINE void nrf_vpr_clic_int_enable_set(NRF_CLIC_Type * p_reg,
261 uint32_t irq_num,
262 bool enable)
263 {
264 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
265 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_IE_Msk) |
266 ((enable ? CLIC_CLIC_CLICINT_IE_Enabled :
267 CLIC_CLIC_CLICINT_IE_Disabled)
268 << CLIC_CLIC_CLICINT_IE_Pos);
269 }
270
nrf_vpr_clic_int_enable_check(NRF_CLIC_Type const * p_reg,uint32_t irq_num)271 NRF_STATIC_INLINE bool nrf_vpr_clic_int_enable_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num)
272 {
273 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
274
275 return ((p_reg->CLIC.CLICINT[irq_num] & CLIC_CLIC_CLICINT_IE_Msk) >> CLIC_CLIC_CLICINT_IE_Pos)
276 == CLIC_CLIC_CLICINT_IE_Enabled ? true : false;
277 }
278
nrf_vpr_clic_int_priority_set(NRF_CLIC_Type * p_reg,uint32_t irq_num,nrf_vpr_clic_priority_t priority)279 NRF_STATIC_INLINE void nrf_vpr_clic_int_priority_set(NRF_CLIC_Type * p_reg,
280 uint32_t irq_num,
281 nrf_vpr_clic_priority_t priority)
282 {
283 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
284 #if !defined(NRF54H20_ENGA_XXAA)
285 NRFX_ASSERT(priority < VPR_CLIC_PRIO_COUNT);
286 #endif
287
288 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_PRIORITY_Msk)
289 | (priority << CLIC_CLIC_CLICINT_PRIORITY_Pos);
290 }
291
292 NRF_STATIC_INLINE
nrf_vpr_clic_int_priority_get(NRF_CLIC_Type const * p_reg,uint32_t irq_num)293 nrf_vpr_clic_priority_t nrf_vpr_clic_int_priority_get(NRF_CLIC_Type const * p_reg,
294 uint32_t irq_num)
295 {
296 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
297
298 return (nrf_vpr_clic_priority_t)((p_reg->CLIC.CLICINT[irq_num] & CLIC_CLIC_CLICINT_PRIORITY_Msk)
299 >> CLIC_CLIC_CLICINT_PRIORITY_Pos);
300 }
301
nrf_vpr_clic_int_attr_get(NRF_CLIC_Type const * p_reg,uint32_t irq_num,nrf_vpr_clic_attr_t * p_attr)302 NRF_STATIC_INLINE void nrf_vpr_clic_int_attr_get(NRF_CLIC_Type const * p_reg,
303 uint32_t irq_num,
304 nrf_vpr_clic_attr_t * p_attr)
305 {
306 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
307 NRFX_ASSERT(p_attr);
308 uint32_t att = p_reg->CLIC.CLICINT[irq_num];
309
310 p_attr->hw_vectoring = (att & CLIC_CLIC_CLICINT_SHV_Msk) >> CLIC_CLIC_CLICINT_SHV_Pos;
311 p_attr->trigger = (nrf_vpr_clic_trigger_t)((att & CLIC_CLIC_CLICINT_TRIG_Msk)
312 >> CLIC_CLIC_CLICINT_TRIG_Pos);
313 p_attr->privilege = (nrf_vpr_clic_priv_t)((att & CLIC_CLIC_CLICINT_MODE_Msk)
314 >> CLIC_CLIC_CLICINT_MODE_Pos);
315 }
316
317 #endif // NRF_DECLARE_ONLY
318
319 /** @} */
320
321 #ifdef __cplusplus
322 }
323 #endif
324
325 #endif /* NRF_VPR_CLIC_H_ */
326