1 /*
2 * Copyright (c) 2023 - 2024, 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 /** @brief Interrupt priority level. */
60 typedef enum
61 {
62 NRF_VPR_CLIC_PRIORITY_LEVEL0 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL0, /**< Priority level 0. */
63 NRF_VPR_CLIC_PRIORITY_LEVEL1 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL1, /**< Priority level 1. */
64 NRF_VPR_CLIC_PRIORITY_LEVEL2 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL2, /**< Priority level 2. */
65 NRF_VPR_CLIC_PRIORITY_LEVEL3 = CLIC_CLIC_CLICINT_PRIORITY_PRIOLEVEL3, /**< Priority level 3. */
66 } nrf_vpr_clic_priority_t;
67
68 /** @brief Macro for converting integer priority level to @ref nrf_vpr_clic_priority_t. */
69 #define NRF_VPR_CLIC_INT_TO_PRIO(x) ((x) == 0 ? NRF_VPR_CLIC_PRIORITY_LEVEL0 : \
70 ((x) == 1 ? NRF_VPR_CLIC_PRIORITY_LEVEL1 : \
71 ((x) == 2 ? NRF_VPR_CLIC_PRIORITY_LEVEL2 : \
72 ((x) == 3 ? NRF_VPR_CLIC_PRIORITY_LEVEL3 : 0))))
73
74 /** @brief VPR CLIC configuration structure. */
75 typedef struct
76 {
77 bool hw_vectoring; /**< Selective interrupt hardware vectoring. */
78 uint8_t level_encoding; /**< Interrupt level encoding. */
79 nrf_vpr_clic_mode_t privilege_mode; /**< Interrupt privilege mode. */
80 } nrf_vpr_clic_config_t;
81
82 /** @brief VPR CLIC information structure. */
83 typedef struct
84 {
85 uint16_t interrupt_count; /**< Maximum number of interrupts supported. */
86 uint8_t version; /**< Version of CLIC. */
87 uint8_t trigger_count; /**< Number of maximum interrupt triggers supported. */
88 } nrf_vpr_clic_info_t;
89
90 /** @brief Interrupt trigger and polarity types. */
91 typedef enum
92 {
93 NRF_VPR_CLIC_TRIGGER_EDGE_POS = CLIC_CLIC_CLICINT_TRIG_EdgeTriggered, /**< Interrupts are positive edge-triggered. */
94 } nrf_vpr_clic_trigger_t;
95
96 /** @brief Interrupt privilege. */
97 typedef enum
98 {
99 NRF_VPR_CLIC_PRIV_MACHINE = CLIC_CLIC_CLICINT_MODE_MachineMode, /**< Machine mode. */
100 } nrf_vpr_clic_priv_t;
101
102 /** @brief Interrupt attributes structure. */
103 typedef struct
104 {
105 bool hw_vectoring; /**< Selective interrupt hardware vectoring. */
106 nrf_vpr_clic_trigger_t trigger; /**< Trigger type and polarity for the interrupt. */
107 nrf_vpr_clic_priv_t privilege; /**< Privilege mode. */
108 } nrf_vpr_clic_attr_t;
109
110 /**
111 * @brief Function for getting the CLIC configuration.
112 *
113 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
114 * @param[out] p_config Pointer to the VPR CLIC configuration structure.
115 */
116 NRF_STATIC_INLINE void nrf_vpr_clic_config_get(NRF_CLIC_Type const * p_reg,
117 nrf_vpr_clic_config_t * p_config);
118
119 /**
120 * @brief Function for getting the CLIC information.
121 *
122 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
123 * @param[out] p_info Pointer to the VPR CLIC information structure.
124 */
125 NRF_STATIC_INLINE void nrf_vpr_clic_info_get(NRF_CLIC_Type const * p_reg,
126 nrf_vpr_clic_info_t * p_info);
127
128 /**
129 * @brief Function for setting the specified interrupt to be pending.
130 *
131 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
132 * @param[in] irq_num Number of interrupt to be triggered.
133 */
134 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_set(NRF_CLIC_Type * p_reg, uint32_t irq_num);
135
136 /**
137 * @brief Function for clearing the pending status for the specified interrupt.
138 *
139 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
140 * @param[in] irq_num Number of interrupt to be cleared.
141 */
142 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_clear(NRF_CLIC_Type * p_reg, uint32_t irq_num);
143
144 /**
145 * @brief Function for checking if the specified interrupt is pending.
146 *
147 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
148 * @param[in] irq_num Number of interrupt to be checked.
149 *
150 * @retval true Interrupt is pending.
151 * @retval false Interrupt is not pending.
152 */
153 NRF_STATIC_INLINE bool nrf_vpr_clic_int_pending_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num);
154
155 /**
156 * @brief Function for enabling or disabling the specified interrupt.
157 *
158 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
159 * @param[in] irq_num Number of interrupt to be enabled or disabled.
160 * @param[in] enable True if interrupt is to be enabled, false otherwise.
161 */
162 NRF_STATIC_INLINE void nrf_vpr_clic_int_enable_set(NRF_CLIC_Type * p_reg,
163 uint32_t irq_num,
164 bool enable);
165
166 /**
167 * @brief Function for checking if the specified interrupt is enabled.
168 *
169 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
170 * @param[in] irq_num Number of interrupt to be checked.
171 *
172 * @retval true Interrupt is enabled.
173 * @retval false Interrupt is disabled.
174 */
175 NRF_STATIC_INLINE bool nrf_vpr_clic_int_enable_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num);
176
177 /**
178 * @brief Function for setting the priority of the specified interrupt.
179 *
180 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
181 * @param[in] irq_num Number of interrupt.
182 * @param[in] priority Priority to be set.
183 */
184 NRF_STATIC_INLINE void nrf_vpr_clic_int_priority_set(NRF_CLIC_Type * p_reg,
185 uint32_t irq_num,
186 nrf_vpr_clic_priority_t priority);
187
188 /**
189 * @brief Function for getting the priority of the specified interrupt.
190 *
191 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
192 * @param[in] irq_num Number of interrupt.
193 *
194 * @return Priority of the specified interrupt.
195 */
196 NRF_STATIC_INLINE
197 nrf_vpr_clic_priority_t nrf_vpr_clic_int_priority_get(NRF_CLIC_Type const * p_reg,
198 uint32_t irq_num);
199
200 /**
201 * @brief Function for getting the CLIC attributes.
202 *
203 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
204 * @param[in] irq_num Number of interrupt.
205 * @param[out] p_attr Pointer to the structure to be filled with VPR CLIC attributes.
206 */
207 NRF_STATIC_INLINE void nrf_vpr_clic_int_attr_get(NRF_CLIC_Type const * p_reg,
208 uint32_t irq_num,
209 nrf_vpr_clic_attr_t * p_attr);
210
211 #ifndef NRF_DECLARE_ONLY
212
nrf_vpr_clic_config_get(NRF_CLIC_Type const * p_reg,nrf_vpr_clic_config_t * p_config)213 NRF_STATIC_INLINE void nrf_vpr_clic_config_get(NRF_CLIC_Type const * p_reg,
214 nrf_vpr_clic_config_t * p_config)
215 {
216 NRFX_ASSERT(p_config);
217 uint32_t cfg = p_reg->CLIC.CLICCFG;
218
219 p_config->hw_vectoring = (cfg & CLIC_CLIC_CLICCFG_NVBITS_Msk) >> CLIC_CLIC_CLICCFG_NVBITS_Pos;
220 p_config->level_encoding = (cfg & CLIC_CLIC_CLICCFG_NLBITS_Msk) >> CLIC_CLIC_CLICCFG_NLBITS_Pos;
221 p_config->privilege_mode = (nrf_vpr_clic_mode_t)((cfg & CLIC_CLIC_CLICCFG_NMBITS_Msk)
222 >> CLIC_CLIC_CLICCFG_NMBITS_Pos);
223 }
224
nrf_vpr_clic_info_get(NRF_CLIC_Type const * p_reg,nrf_vpr_clic_info_t * p_info)225 NRF_STATIC_INLINE void nrf_vpr_clic_info_get(NRF_CLIC_Type const * p_reg,
226 nrf_vpr_clic_info_t * p_info)
227 {
228 NRFX_ASSERT(p_info);
229 uint32_t inf = p_reg->CLIC.CLICINFO;
230
231 p_info->interrupt_count = (inf & CLIC_CLIC_CLICINFO_NUMINTERRUPTS_Msk)
232 >> CLIC_CLIC_CLICINFO_NUMINTERRUPTS_Pos;
233 p_info->version = (inf & CLIC_CLIC_CLICINFO_VERSION_Msk)
234 >> CLIC_CLIC_CLICINFO_VERSION_Pos;
235 p_info->trigger_count = (inf & CLIC_CLIC_CLICINFO_NUMTRIGGER_Msk)
236 >> CLIC_CLIC_CLICINFO_NUMTRIGGER_Pos;
237 }
238
nrf_vpr_clic_int_pending_set(NRF_CLIC_Type * p_reg,uint32_t irq_num)239 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_set(NRF_CLIC_Type * p_reg, uint32_t irq_num)
240 {
241 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
242 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_IP_Msk) |
243 (CLIC_CLIC_CLICINT_IP_Pending << CLIC_CLIC_CLICINT_IP_Pos);
244 }
245
nrf_vpr_clic_int_pending_clear(NRF_CLIC_Type * p_reg,uint32_t irq_num)246 NRF_STATIC_INLINE void nrf_vpr_clic_int_pending_clear(NRF_CLIC_Type * p_reg, uint32_t irq_num)
247 {
248 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
249 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_IP_Msk) |
250 (CLIC_CLIC_CLICINT_IP_NotPending << CLIC_CLIC_CLICINT_IP_Pos);
251 }
252
nrf_vpr_clic_int_pending_check(NRF_CLIC_Type const * p_reg,uint32_t irq_num)253 NRF_STATIC_INLINE bool nrf_vpr_clic_int_pending_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num)
254 {
255 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
256
257 return ((p_reg->CLIC.CLICINT[irq_num] & CLIC_CLIC_CLICINT_IP_Msk) >> CLIC_CLIC_CLICINT_IP_Pos)
258 ==
259 CLIC_CLIC_CLICINT_IP_Pending ? true : false;
260 }
261
nrf_vpr_clic_int_enable_set(NRF_CLIC_Type * p_reg,uint32_t irq_num,bool enable)262 NRF_STATIC_INLINE void nrf_vpr_clic_int_enable_set(NRF_CLIC_Type * p_reg,
263 uint32_t irq_num,
264 bool enable)
265 {
266 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
267 p_reg->CLIC.CLICINT[irq_num] = (p_reg->CLIC.CLICINT[irq_num] & ~CLIC_CLIC_CLICINT_IE_Msk) |
268 ((enable ? CLIC_CLIC_CLICINT_IE_Enabled :
269 CLIC_CLIC_CLICINT_IE_Disabled)
270 << CLIC_CLIC_CLICINT_IE_Pos);
271 }
272
nrf_vpr_clic_int_enable_check(NRF_CLIC_Type const * p_reg,uint32_t irq_num)273 NRF_STATIC_INLINE bool nrf_vpr_clic_int_enable_check(NRF_CLIC_Type const * p_reg, uint32_t irq_num)
274 {
275 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
276
277 return ((p_reg->CLIC.CLICINT[irq_num] & CLIC_CLIC_CLICINT_IE_Msk) >> CLIC_CLIC_CLICINT_IE_Pos)
278 == CLIC_CLIC_CLICINT_IE_Enabled ? true : false;
279 }
280
nrf_vpr_clic_int_priority_set(NRF_CLIC_Type * p_reg,uint32_t irq_num,nrf_vpr_clic_priority_t priority)281 NRF_STATIC_INLINE void nrf_vpr_clic_int_priority_set(NRF_CLIC_Type * p_reg,
282 uint32_t irq_num,
283 nrf_vpr_clic_priority_t priority)
284 {
285 NRFX_ASSERT(irq_num < NRF_VPR_CLIC_IRQ_COUNT);
286 NRFX_ASSERT(priority != 0);
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