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 4
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 #include "pico.h"
27 #include "hardware/regs/intctrl.h"
28
29 /** \file irq.h
30 * \defgroup hardware_irq hardware_irq
31 *
32 * \brief Hardware interrupt handling
33 *
34 * The RP2040 uses the standard ARM nested vectored interrupt controller (NVIC).
35 *
36 * Interrupts are identified by a number from 0 to 31.
37 *
38 * On the RP2040, only the lower 26 IRQ signals are connected on the NVIC; IRQs 26 to 31 are tied to zero (never firing).
39 *
40 * 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
41 * where there is one IO interrupt per bank, per core. These are completely independent, so, for example, processor 0 can be
42 * interrupted by GPIO 0 in bank 0, and processor 1 by GPIO 1 in the same bank.
43 *
44 * \note That all IRQ APIs affect the executing core only (i.e. the core calling the function).
45 *
46 * \note You should not enable the same (shared) IRQ number on both cores, as this will lead to race conditions
47 * or starvation of one of the cores. Additionally, don't forget that disabling interrupts on one core does not disable interrupts
48 * on the other core.
49 *
50 * There are three different ways to set handlers for an IRQ:
51 * - 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
52 * - Calling irq_set_exclusive_handler() at runtime to install a single handler for the interrupt on the current core
53 * - 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
54 * 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).
55 *
56 * \note If an IRQ is enabled and fires with no handler installed, a breakpoint will be hit and the IRQ number will
57 * be in register r0.
58 *
59 * \section interrupt_nums Interrupt Numbers
60 *
61 * Interrupts are numbered as follows, a set of defines is available (intctrl.h) with these names to avoid using the numbers directly.
62 *
63 * IRQ | Interrupt Source
64 * ----|-----------------
65 * 0 | TIMER_IRQ_0
66 * 1 | TIMER_IRQ_1
67 * 2 | TIMER_IRQ_2
68 * 3 | TIMER_IRQ_3
69 * 4 | PWM_IRQ_WRAP
70 * 5 | USBCTRL_IRQ
71 * 6 | XIP_IRQ
72 * 7 | PIO0_IRQ_0
73 * 8 | PIO0_IRQ_1
74 * 9 | PIO1_IRQ_0
75 * 10 | PIO1_IRQ_1
76 * 11 | DMA_IRQ_0
77 * 12 | DMA_IRQ_1
78 * 13 | IO_IRQ_BANK0
79 * 14 | IO_IRQ_QSPI
80 * 15 | SIO_IRQ_PROC0
81 * 16 | SIO_IRQ_PROC1
82 * 17 | CLOCKS_IRQ
83 * 18 | SPI0_IRQ
84 * 19 | SPI1_IRQ
85 * 20 | UART0_IRQ
86 * 21 | UART1_IRQ
87 * 22 | ADC0_IRQ_FIFO
88 * 23 | I2C0_IRQ
89 * 24 | I2C1_IRQ
90 * 25 | RTC_IRQ
91 *
92 */
93
94 // PICO_CONFIG: PICO_DEFAULT_IRQ_PRIORITY, Define the default IRQ priority, default=0x80, group=hardware_irq
95 #ifndef PICO_DEFAULT_IRQ_PRIORITY
96 #define PICO_DEFAULT_IRQ_PRIORITY 0x80
97 #endif
98
99 #define PICO_LOWEST_IRQ_PRIORITY 0xff
100 #define PICO_HIGHEST_IRQ_PRIORITY 0x00
101
102 // PICO_CONFIG: PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY, Set default shared IRQ order priority, default=0x80, group=hardware_irq
103 #ifndef PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY
104 #define PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY 0x80
105 #endif
106
107 #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
108 #define PICO_SHARED_IRQ_HANDLER_LOWEST_ORDER_PRIORITY 0x00
109
110 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ, Enable/disable assertions in the hardware_irq module, type=bool, default=0, group=hardware_irq
111 #ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ
112 #ifdef PARAM_ASSERTIONS_ENABLED_IRQ // backwards compatibility with SDK < 2.0.0
113 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ PARAM_ASSERTIONS_ENABLED_IRQ
114 #else
115 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ 0
116 #endif
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(HARDWARE_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 Enable/disable multiple interrupts on the executing core
188 * \ingroup hardware_irq
189 *
190 * \param n the index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.
191 * \param mask 32-bit mask with one bits set for the interrupts to enable/disable \ref interrupt_nums
192 * \param enabled true to enable the interrupts, false to disable them.
193 */
194 void irq_set_mask_n_enabled(uint n, uint32_t mask, bool enabled);
195
196 /*! \brief Set an exclusive interrupt handler for an interrupt on the executing core.
197 * \ingroup hardware_irq
198 *
199 * Use this method to set a handler for single IRQ source interrupts, or when
200 * your code, use case or performance requirements dictate that there should
201 * no other handlers for the interrupt.
202 *
203 * This method will assert if there is already any sort of interrupt handler installed
204 * for the specified irq number.
205 *
206 * \param num Interrupt number \ref interrupt_nums
207 * \param handler The handler to set. See \ref irq_handler_t
208 * \see irq_add_shared_handler()
209 */
210 void irq_set_exclusive_handler(uint num, irq_handler_t handler);
211
212 /*! \brief Get the exclusive interrupt handler for an interrupt on the executing core.
213 * \ingroup hardware_irq
214 *
215 * This method will return an exclusive IRQ handler set on this core
216 * by irq_set_exclusive_handler if there is one.
217 *
218 * \param num Interrupt number \ref interrupt_nums
219 * \see irq_set_exclusive_handler()
220 * \return handler The handler if an exclusive handler is set for the IRQ,
221 * NULL if no handler is set or shared/shareable handlers are installed
222 */
223 irq_handler_t irq_get_exclusive_handler(uint num);
224
225 /*! \brief Add a shared interrupt handler for an interrupt on the executing core
226 * \ingroup hardware_irq
227 *
228 * Use this method to add a handler on an irq number shared between multiple distinct hardware sources (e.g. GPIO, DMA or PIO IRQs).
229 * Handlers added by this method will all be called in sequence from highest order_priority to lowest. The
230 * irq_set_exclusive_handler() method should be used instead if you know there will or should only ever be one handler for the interrupt.
231 *
232 * This method will assert if there is an exclusive interrupt handler set for this irq number on this core, or if
233 * the (total across all IRQs on both cores) maximum (configurable via PICO_MAX_SHARED_IRQ_HANDLERS) number of shared handlers
234 * would be exceeded.
235 *
236 * \param num Interrupt number \ref interrupt_nums
237 * \param handler The handler to set. See \ref irq_handler_t
238 * \param order_priority The order priority controls the order that handlers for the same IRQ number on the core are called.
239 * The shared irq handlers for an interrupt are all called when an IRQ fires, however the order of the calls is based
240 * on the order_priority (higher priorities are called first, identical priorities are called in undefined order). A good
241 * 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
242 * the priority range by default.
243 *
244 * \note The order_priority uses \em higher values for higher priorities which is the \em opposite of the CPU interrupt priorities passed
245 * to irq_set_priority() which use lower values for higher priorities.
246 *
247 * \see irq_set_exclusive_handler()
248 */
249 void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority);
250
251 /*! \brief Remove a specific interrupt handler for the given irq number on the executing core
252 * \ingroup hardware_irq
253 *
254 * This method may be used to remove an irq set via either irq_set_exclusive_handler() or
255 * irq_add_shared_handler(), and will assert if the handler is not currently installed for the given
256 * IRQ number
257 *
258 * \note This method may *only* be called from user (non IRQ code) or from within the handler
259 * itself (i.e. an IRQ handler may remove itself as part of handling the IRQ). Attempts to call
260 * from another IRQ will cause an assertion.
261 *
262 * \param num Interrupt number \ref interrupt_nums
263 * \param handler The handler to removed.
264 * \see irq_set_exclusive_handler()
265 * \see irq_add_shared_handler()
266 */
267 void irq_remove_handler(uint num, irq_handler_t handler);
268
269 /*! \brief Determine if the current handler for the given number is shared
270 * \ingroup hardware_irq
271 *
272 * \param num Interrupt number \ref interrupt_nums
273 * \return true if the specified IRQ has a shared handler
274 */
275 bool irq_has_shared_handler(uint num);
276
277 /*! \brief Get the current IRQ handler for the specified IRQ from the currently installed hardware vector table (VTOR)
278 * of the execution core
279 * \ingroup hardware_irq
280 *
281 * \param num Interrupt number \ref interrupt_nums
282 * \return the address stored in the VTABLE for the given irq number
283 */
284 irq_handler_t irq_get_vtable_handler(uint num);
285
286 /*! \brief Clear a specific interrupt on the executing core
287 * \ingroup hardware_irq
288 *
289 * This method is only useful for "software" IRQs that are not connected to hardware (i.e. IRQs 26-31)
290 * as the the NVIC always reflects the current state of the IRQ state of the hardware for hardware IRQs, and clearing
291 * of the IRQ state of the hardware is performed via the hardware's registers instead.
292 *
293 * \param int_num Interrupt number \ref interrupt_nums
294 */
295 void irq_clear(uint int_num);
296
297 /*! \brief Force an interrupt to be pending on the executing core
298 * \ingroup hardware_irq
299 *
300 * This should generally not be used for IRQs connected to hardware.
301 *
302 * \param num Interrupt number \ref interrupt_nums
303 */
304 void irq_set_pending(uint num);
305
306
307 /*! \brief Perform IRQ priority initialization for the current core
308 *
309 * \note This is an internal method and user should generally not call it.
310 */
311 void irq_init_priorities(void);
312
313 /*! \brief Claim ownership of a user IRQ on the calling core
314 * \ingroup hardware_irq
315 *
316 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
317 *
318 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions
319 * dealing with Uer IRQs affect only the calling core
320 *
321 * This method explicitly claims ownership of a user IRQ, so other code can know it is being used.
322 *
323 * \param irq_num the user IRQ to claim
324 */
325 void user_irq_claim(uint irq_num);
326
327 /*! \brief Mark a user IRQ as no longer used on the calling core
328 * \ingroup hardware_irq
329 *
330 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
331 *
332 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions
333 * dealing with Uer IRQs affect only the calling core
334 *
335 * This method explicitly releases ownership of a user IRQ, so other code can know it is free to use.
336 *
337 * \note it is customary to have disabled the irq and removed the handler prior to calling this method.
338 *
339 * \param irq_num the irq irq_num to unclaim
340 */
341 void user_irq_unclaim(uint irq_num);
342
343 /*! \brief Claim ownership of a free user IRQ on the calling core
344 * \ingroup hardware_irq
345 *
346 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
347 *
348 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions
349 * dealing with Uer IRQs affect only the calling core
350 *
351 * This method explicitly claims ownership of an unused user IRQ if there is one, so other code can know it is being used.
352 *
353 * \param required if true the function will panic if none are available
354 * \return the user IRQ number or -1 if required was false, and none were free
355 */
356 int user_irq_claim_unused(bool required);
357
358 /*
359 *! \brief Check if a user IRQ is in use on the calling core
360 * \ingroup hardware_irq
361 *
362 * User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by \ref irq_set_pending.
363 *
364 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions
365 * dealing with Uer IRQs affect only the calling core
366 *
367 * \param irq_num the irq irq_num
368 * \return true if the irq_num is claimed, false otherwise
369 * \sa user_irq_claim
370 * \sa user_irq_unclaim
371 * \sa user_irq_claim_unused
372 */
373 bool user_irq_is_claimed(uint irq_num);
374
375 void __unhandled_user_irq(void);
376
377 #ifdef __cplusplus
378 }
379 #endif
380
381 #endif
382