1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef _HARDWARE_IRQ_H
8 #define _HARDWARE_IRQ_H
9
10 // These two config items are also used by assembler, so keeping separate
11 // PICO_CONFIG: PICO_MAX_SHARED_IRQ_HANDLERS, Maximum number of shared IRQ handlers, default=4, advanced=true, group=hardware_irq
12 #ifndef PICO_MAX_SHARED_IRQ_HANDLERS
13 #define PICO_MAX_SHARED_IRQ_HANDLERS 4u
14 #endif
15
16 // PICO_CONFIG: PICO_DISABLE_SHARED_IRQ_HANDLERS, Disable shared IRQ handlers, type=bool, default=0, group=hardware_irq
17 #ifndef PICO_DISABLE_SHARED_IRQ_HANDLERS
18 #define PICO_DISABLE_SHARED_IRQ_HANDLERS 0
19 #endif
20
21 // PICO_CONFIG: PICO_VTABLE_PER_CORE, user is using separate vector tables per core, type=bool, default=0, group=hardware_irq
22 #ifndef PICO_VTABLE_PER_CORE
23 #define PICO_VTABLE_PER_CORE 0
24 #endif
25
26 #ifndef __ASSEMBLER__
27
28 #include "pico.h"
29 #include "hardware/address_mapped.h"
30 #include "hardware/regs/intctrl.h"
31 #include "hardware/regs/m0plus.h"
32
33 /** \file irq.h
34 * \defgroup hardware_irq hardware_irq
35 *
36 * Hardware interrupt handling
37 *
38 * The RP2040 uses the standard ARM nested vectored interrupt controller (NVIC).
39 *
40 * Interrupts are identified by a number from 0 to 31.
41 *
42 * On the RP2040, only the lower 26 IRQ signals are connected on the NVIC; IRQs 26 to 31 are tied to zero (never firing).
43 *
44 * There is one NVIC per core, and each core's NVIC has the same hardware interrupt lines routed to it, with the exception of the IO interrupts
45 * where there is one IO interrupt per bank, per core. These are completely independent, so, for example, processor 0 can be
46 * interrupted by GPIO 0 in bank 0, and processor 1 by GPIO 1 in the same bank.
47 *
48 * \note That all IRQ APIs affect the executing core only (i.e. the core calling the function).
49 *
50 * \note You should not enable the same (shared) IRQ number on both cores, as this will lead to race conditions
51 * or starvation of one of the cores. Additionally, don't forget that disabling interrupts on one core does not disable interrupts
52 * on the other core.
53 *
54 * There are three different ways to set handlers for an IRQ:
55 * - Calling irq_add_shared_handler() at runtime to add a handler for a multiplexed interrupt (e.g. GPIO bank) on the current core. Each handler, should check and clear the relevant hardware interrupt source
56 * - Calling irq_set_exclusive_handler() at runtime to install a single handler for the interrupt on the current core
57 * - Defining the interrupt handler explicitly in your application (e.g. by defining void `isr_dma_0` will make that function the handler for the DMA_IRQ_0 on core 0, and
58 * you will not be able to change it using the above APIs at runtime). Using this method can cause link conflicts at runtime, and offers no runtime performance benefit (i.e, it should not generally be used).
59 *
60 * \note If an IRQ is enabled and fires with no handler installed, a breakpoint will be hit and the IRQ number will
61 * be in register r0.
62 *
63 * \section interrupt_nums Interrupt Numbers
64 *
65 * Interrupts are numbered as follows, a set of defines is available (intctrl.h) with these names to avoid using the numbers directly.
66 *
67 * IRQ | Interrupt Source
68 * ----|-----------------
69 * 0 | TIMER_IRQ_0
70 * 1 | TIMER_IRQ_1
71 * 2 | TIMER_IRQ_2
72 * 3 | TIMER_IRQ_3
73 * 4 | PWM_IRQ_WRAP
74 * 5 | USBCTRL_IRQ
75 * 6 | XIP_IRQ
76 * 7 | PIO0_IRQ_0
77 * 8 | PIO0_IRQ_1
78 * 9 | PIO1_IRQ_0
79 * 10 | PIO1_IRQ_1
80 * 11 | DMA_IRQ_0
81 * 12 | DMA_IRQ_1
82 * 13 | IO_IRQ_BANK0
83 * 14 | IO_IRQ_QSPI
84 * 15 | SIO_IRQ_PROC0
85 * 16 | SIO_IRQ_PROC1
86 * 17 | CLOCKS_IRQ
87 * 18 | SPI0_IRQ
88 * 19 | SPI1_IRQ
89 * 20 | UART0_IRQ
90 * 21 | UART1_IRQ
91 * 22 | ADC0_IRQ_FIFO
92 * 23 | I2C0_IRQ
93 * 24 | I2C1_IRQ
94 * 25 | RTC_IRQ
95 *
96 */
97
98 // PICO_CONFIG: PICO_DEFAULT_IRQ_PRIORITY, Define the default IRQ priority, default=0x80, group=hardware_irq
99 #ifndef PICO_DEFAULT_IRQ_PRIORITY
100 #define PICO_DEFAULT_IRQ_PRIORITY 0x80
101 #endif
102
103 #define PICO_LOWEST_IRQ_PRIORITY 0xff
104 #define PICO_HIGHEST_IRQ_PRIORITY 0x00
105
106 // PICO_CONFIG: PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY, Set default shared IRQ order priority, default=0x80, group=hardware_irq
107 #ifndef PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY
108 #define PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY 0x80
109 #endif
110
111 #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
112 #define PICO_SHARED_IRQ_HANDLER_LOWEST_ORDER_PRIORITY 0x00
113
114 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_IRQ, Enable/disable assertions in the IRQ module, type=bool, default=0, group=hardware_irq
115 #ifndef PARAM_ASSERTIONS_ENABLED_IRQ
116 #define PARAM_ASSERTIONS_ENABLED_IRQ 0
117 #endif
118
119 #ifdef __cplusplus
120 extern "C" {
121 #endif
122
123 /*! \brief Interrupt handler function type
124 * \ingroup hardware_irq
125 *
126 * All interrupts handlers should be of this type, and follow normal ARM EABI register saving conventions
127 */
128 typedef void (*irq_handler_t)(void);
129
check_irq_param(__unused uint num)130 static inline void check_irq_param(__unused uint num) {
131 invalid_params_if(IRQ, num >= NUM_IRQS);
132 }
133
134 /*! \brief Set specified interrupt's priority
135 * \ingroup hardware_irq
136 *
137 * \param num Interrupt number \ref interrupt_nums
138 * \param hardware_priority Priority to set.
139 * Numerically-lower values indicate a higher priority. Hardware priorities
140 * range from 0 (highest priority) to 255 (lowest priority) though only the
141 * top 2 bits are significant on ARM Cortex-M0+. To make it easier to specify
142 * higher or lower priorities than the default, all IRQ priorities are
143 * initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup.
144 * PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80
145 */
146 void irq_set_priority(uint num, uint8_t hardware_priority);
147
148 /*! \brief Get specified interrupt's priority
149 * \ingroup hardware_irq
150 *
151 * Numerically-lower values indicate a higher priority. Hardware priorities
152 * range from 0 (highest priority) to 255 (lowest priority) though only the
153 * top 2 bits are significant on ARM Cortex-M0+. To make it easier to specify
154 * higher or lower priorities than the default, all IRQ priorities are
155 * initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup.
156 * PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80
157 *
158 * \param num Interrupt number \ref interrupt_nums
159 * \return the IRQ priority
160 */
161 uint irq_get_priority(uint num);
162
163 /*! \brief Enable or disable a specific interrupt on the executing core
164 * \ingroup hardware_irq
165 *
166 * \param num Interrupt number \ref interrupt_nums
167 * \param enabled true to enable the interrupt, false to disable
168 */
169 void irq_set_enabled(uint num, bool enabled);
170
171 /*! \brief Determine if a specific interrupt is enabled on the executing core
172 * \ingroup hardware_irq
173 *
174 * \param num Interrupt number \ref interrupt_nums
175 * \return true if the interrupt is enabled
176 */
177 bool pico_irq_is_enabled(uint num);
178
179 /*! \brief Enable/disable multiple interrupts on the executing core
180 * \ingroup hardware_irq
181 *
182 * \param mask 32-bit mask with one bits set for the interrupts to enable/disable \ref interrupt_nums
183 * \param enabled true to enable the interrupts, false to disable them.
184 */
185 void irq_set_mask_enabled(uint32_t mask, bool enabled);
186
187 /*! \brief Set an exclusive interrupt handler for an interrupt on the executing core.
188 * \ingroup hardware_irq
189 *
190 * Use this method to set a handler for single IRQ source interrupts, or when
191 * your code, use case or performance requirements dictate that there should
192 * no other handlers for the interrupt.
193 *
194 * This method will assert if there is already any sort of interrupt handler installed
195 * for the specified irq number.
196 *
197 * \param num Interrupt number \ref interrupt_nums
198 * \param handler The handler to set. See \ref irq_handler_t
199 * \see irq_add_shared_handler()
200 */
201 void irq_set_exclusive_handler(uint num, irq_handler_t handler);
202
203 /*! \brief Get the exclusive interrupt handler for an interrupt on the executing core.
204 * \ingroup hardware_irq
205 *
206 * This method will return an exclusive IRQ handler set on this core
207 * by irq_set_exclusive_handler if there is one.
208 *
209 * \param num Interrupt number \ref interrupt_nums
210 * \see irq_set_exclusive_handler()
211 * \return handler The handler if an exclusive handler is set for the IRQ,
212 * NULL if no handler is set or shared/shareable handlers are installed
213 */
214 irq_handler_t irq_get_exclusive_handler(uint num);
215
216 /*! \brief Add a shared interrupt handler for an interrupt on the executing core
217 * \ingroup hardware_irq
218 *
219 * Use this method to add a handler on an irq number shared between multiple distinct hardware sources (e.g. GPIO, DMA or PIO IRQs).
220 * Handlers added by this method will all be called in sequence from highest order_priority to lowest. The
221 * irq_set_exclusive_handler() method should be used instead if you know there will or should only ever be one handler for the interrupt.
222 *
223 * This method will assert if there is an exclusive interrupt handler set for this irq number on this core, or if
224 * the (total across all IRQs on both cores) maximum (configurable via PICO_MAX_SHARED_IRQ_HANDLERS) number of shared handlers
225 * would be exceeded.
226 *
227 * \param num Interrupt number \ref interrupt_nums
228 * \param handler The handler to set. See \ref irq_handler_t
229 * \param order_priority The order priority controls the order that handlers for the same IRQ number on the core are called.
230 * The shared irq handlers for an interrupt are all called when an IRQ fires, however the order of the calls is based
231 * on the order_priority (higher priorities are called first, identical priorities are called in undefined order). A good
232 * rule of thumb is to use PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY if you don't much care, as it is in the middle of
233 * the priority range by default.
234 *
235 * \note The order_priority uses \em higher values for higher priorities which is the \em opposite of the CPU interrupt priorities passed
236 * to irq_set_priority() which use lower values for higher priorities.
237 *
238 * \see irq_set_exclusive_handler()
239 */
240 void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority);
241
242 /*! \brief Remove a specific interrupt handler for the given irq number on the executing core
243 * \ingroup hardware_irq
244 *
245 * This method may be used to remove an irq set via either irq_set_exclusive_handler() or
246 * irq_add_shared_handler(), and will assert if the handler is not currently installed for the given
247 * IRQ number
248 *
249 * \note This method may *only* be called from user (non IRQ code) or from within the handler
250 * itself (i.e. an IRQ handler may remove itself as part of handling the IRQ). Attempts to call
251 * from another IRQ will cause an assertion.
252 *
253 * \param num Interrupt number \ref interrupt_nums
254 * \param handler The handler to removed.
255 * \see irq_set_exclusive_handler()
256 * \see irq_add_shared_handler()
257 */
258 void irq_remove_handler(uint num, irq_handler_t handler);
259
260 /*! \brief Determine if the current handler for the given number is shared
261 * \ingroup hardware_irq
262 *
263 * \param num Interrupt number \ref interrupt_nums
264 * \return true if the specified IRQ has a shared handler
265 */
266 bool irq_has_shared_handler(uint num);
267
268 /*! \brief Get the current IRQ handler for the specified IRQ from the currently installed hardware vector table (VTOR)
269 * of the execution core
270 * \ingroup hardware_irq
271 *
272 * \param num Interrupt number \ref interrupt_nums
273 * \return the address stored in the VTABLE for the given irq number
274 */
275 irq_handler_t irq_get_vtable_handler(uint num);
276
277 /*! \brief Clear a specific interrupt on the executing core
278 * \ingroup hardware_irq
279 *
280 * This method is only useful for "software" IRQs that are not connected to hardware (i.e. IRQs 26-31)
281 * as the the NVIC always reflects the current state of the IRQ state of the hardware for hardware IRQs, and clearing
282 * of the IRQ state of the hardware is performed via the hardware's registers instead.
283 *
284 * \param int_num Interrupt number \ref interrupt_nums
285 */
irq_clear(uint int_num)286 static inline void irq_clear(uint int_num) {
287 *((volatile uint32_t *) (PPB_BASE + M0PLUS_NVIC_ICPR_OFFSET)) = (1u << ((uint32_t) (int_num & 0x1F)));
288 }
289
290 /*! \brief Force an interrupt to be pending on the executing core
291 * \ingroup hardware_irq
292 *
293 * This should generally not be used for IRQs connected to hardware.
294 *
295 * \param num Interrupt number \ref interrupt_nums
296 */
297 void irq_set_pending(uint num);
298
299
300 /*! \brief Perform IRQ priority initialization for the current core
301 *
302 * \note This is an internal method and user should generally not call it.
303 */
304 void irq_init_priorities(void);
305
306 /*! \brief Claim ownership of a user IRQ on the calling core
307 * \ingroup hardware_irq
308 *
309 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
310 *
311 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therfore all functions
312 * dealing with Uer IRQs affect only the calling core
313 *
314 * This method explicitly claims ownership of a user IRQ, so other code can know it is being used.
315 *
316 * \param irq_num the user IRQ to claim
317 */
318 void user_irq_claim(uint irq_num);
319
320 /*! \brief Mark a user IRQ as no longer used on the calling core
321 * \ingroup hardware_irq
322 *
323 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
324 *
325 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therfore all functions
326 * dealing with Uer IRQs affect only the calling core
327 *
328 * This method explicitly releases ownership of a user IRQ, so other code can know it is free to use.
329 *
330 * \note it is customary to have disabled the irq and removed the handler prior to calling this method.
331 *
332 * \param irq_num the irq irq_num to unclaim
333 */
334 void user_irq_unclaim(uint irq_num);
335
336 /*! \brief Claim ownership of a free user IRQ on the calling core
337 * \ingroup hardware_irq
338 *
339 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
340 *
341 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therfore all functions
342 * dealing with Uer IRQs affect only the calling core
343 *
344 * This method explicitly claims ownership of an unused user IRQ if there is one, so other code can know it is being used.
345 *
346 * \param required if true the function will panic if none are available
347 * \return the user IRQ number or -1 if required was false, and none were free
348 */
349 int user_irq_claim_unused(bool required);
350
351 /*
352 *! \brief Check if a user IRQ is in use on the calling core
353 * \ingroup hardware_irq
354 *
355 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
356 *
357 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therfore all functions
358 * dealing with Uer IRQs affect only the calling core
359 *
360 * \param irq_num the irq irq_num
361 * \return true if the irq_num is claimed, false otherwise
362 * \sa user_irq_claim
363 * \sa user_irq_unclaim
364 * \sa user_irq_claim_unused
365 */
366 bool user_irq_is_claimed(uint irq_num);
367
368 #ifdef __cplusplus
369 }
370 #endif
371
372 #endif
373 #endif
374