Loading...
Searching...
No Matches
irq.h
Go to the documentation of this file.
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=6 if using stdio_usb otherwise 4, advanced=true, group=hardware_irq
12#ifndef PICO_MAX_SHARED_IRQ_HANDLERS
13#define _PICO_MAX_SHARED_IRQ_HANDLERS 4
14#if LIB_PICO_STDIO_USB
15#define PICO_MAX_SHARED_IRQ_HANDLERS (_PICO_MAX_SHARED_IRQ_HANDLERS + 2)
16#else
17#define PICO_MAX_SHARED_IRQ_HANDLERS _PICO_MAX_SHARED_IRQ_HANDLERS
18#endif
19#endif
20
21// PICO_CONFIG: PICO_DISABLE_SHARED_IRQ_HANDLERS, Disable shared IRQ handlers, type=bool, default=0, group=hardware_irq
22#ifndef PICO_DISABLE_SHARED_IRQ_HANDLERS
23#define PICO_DISABLE_SHARED_IRQ_HANDLERS 0
24#endif
25
26// PICO_CONFIG: PICO_VTABLE_PER_CORE, User is using separate vector tables per core, type=bool, default=0, group=hardware_irq
27#ifndef PICO_VTABLE_PER_CORE
28#define PICO_VTABLE_PER_CORE 0
29#endif
30
31#ifndef __ASSEMBLER__
32
33#include "pico.h"
35#include "hardware/regs/intctrl.h"
36
37#include "pico/platform/cpu_regs.h"
38
171
172// PICO_CONFIG: PICO_DEFAULT_IRQ_PRIORITY, Define the default IRQ priority, default=0x80, group=hardware_irq
173#ifndef PICO_DEFAULT_IRQ_PRIORITY
174#define PICO_DEFAULT_IRQ_PRIORITY 0x80
175#endif
176
177#define PICO_LOWEST_IRQ_PRIORITY 0xff
178#define PICO_HIGHEST_IRQ_PRIORITY 0x00
179
180// PICO_CONFIG: PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY, Set default shared IRQ order priority, default=0x80, group=hardware_irq
181#ifndef PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY
182#define PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY 0x80
183#endif
184
185#define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
186#define PICO_SHARED_IRQ_HANDLER_LOWEST_ORDER_PRIORITY 0x00
187
188// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ, Enable/disable assertions in the hardware_irq module, type=bool, default=0, group=hardware_irq
189#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ
190#ifdef PARAM_ASSERTIONS_ENABLED_IRQ // backwards compatibility with SDK < 2.0.0
191#define PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ PARAM_ASSERTIONS_ENABLED_IRQ
192#else
193#define PARAM_ASSERTIONS_ENABLED_HARDWARE_IRQ 0
194#endif
195#endif
196
197#ifdef __cplusplus
198extern "C" {
199#endif
200
206typedef void (*irq_handler_t)(void);
207
208static inline void check_irq_param(__unused uint num) {
209 invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS);
210}
211
232void irq_set_priority(uint num, uint8_t hardware_priority);
233
255uint irq_get_priority(uint num);
256
263void irq_set_enabled(uint num, bool enabled);
264
271bool irq_is_enabled(uint num);
272
279void irq_set_mask_enabled(uint32_t mask, bool enabled);
280
288void irq_set_mask_n_enabled(uint n, uint32_t mask, bool enabled);
289
295 uint32_t irq_get_mask(void);
296
303 uint32_t irq_get_mask_n(uint n);
304
346void irq_set_exclusive_handler(uint num, irq_handler_t handler);
347
360
412void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority);
413
430void irq_remove_handler(uint num, irq_handler_t handler);
431
441bool irq_has_handler(uint num);
442
452bool irq_has_shared_handler(uint num);
453
462
472static inline void irq_clear(uint int_num) {
473#if PICO_RP2040
474 *((volatile uint32_t *) (PPB_BASE + M0PLUS_NVIC_ICPR_OFFSET)) = (1u << ((uint32_t) (int_num & 0x1F)));
475#elif defined(__riscv)
476 // External IRQs are not latched, but we should clear the IRQ force bit here
477 hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, int_num / 16, 1u << (int_num % 16));
478#else
479 nvic_hw->icpr[int_num/32] = 1 << (int_num % 32);
480#endif
481}
482
490void irq_set_pending(uint num);
491
492
498
499static __force_inline void irq_init_priorities(void) {
501}
502
515void user_irq_claim(uint irq_num);
516
531void user_irq_unclaim(uint irq_num);
532
546int user_irq_claim_unused(bool required);
547
548/*
549*! \brief Check if a user IRQ is in use on the calling core
550 * \ingroup hardware_irq
551 *
552 * User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by \ref irq_set_pending.
553 *
554 * \note User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions
555 * dealing with Uer IRQs affect only the calling core
556 *
557 * \param irq_num the irq irq_num
558 * \return true if the irq_num is claimed, false otherwise
559 * \sa user_irq_claim
560 * \sa user_irq_unclaim
561 * \sa user_irq_claim_unused
562 */
563bool user_irq_is_claimed(uint irq_num);
564
565void __unhandled_user_irq(void);
566
567#ifdef __riscv
568enum riscv_vector_num {
569 RISCV_VEC_MACHINE_EXCEPTION = 0,
570 RISCV_VEC_MACHINE_SOFTWARE_IRQ = 3,
571 RISCV_VEC_MACHINE_TIMER_IRQ = 7,
572 RISCV_VEC_MACHINE_EXTERNAL_IRQ = 11,
573};
574
575irq_handler_t irq_set_riscv_vector_handler(enum riscv_vector_num index, irq_handler_t handler);
576#endif
577
578#if PICO_SECURE
579static inline void irq_assign_to_ns(uint irq_num, bool ns) {
580 check_irq_param(irq_num);
581 if (ns) nvic_hw->itns[irq_num >> 5] |= 1u << (irq_num & 0x1fu);
582 else nvic_hw->itns[irq_num >> 5] &= ~(1u << (irq_num & 0x1fu));
583}
584#endif
585#ifdef __cplusplus
586}
587#endif
588
589#endif
590#endif
uint32_t irq_get_mask(void)
Get the current enabled mask on the executing core.
Definition irq.c:129
bool irq_is_enabled(uint num)
Determine if a specific interrupt is enabled on the executing core.
Definition irq.c:66
void user_irq_unclaim(uint irq_num)
Mark a user IRQ as no longer used on the calling core.
Definition irq.c:736
static void irq_clear(uint int_num)
Clear a specific interrupt on the executing core.
Definition irq.h:472
void irq_set_pending(uint num)
Force an interrupt to be pending on the executing core.
Definition irq.c:137
irq_handler_t irq_get_exclusive_handler(uint num)
Get the exclusive interrupt handler for an interrupt on the executing core.
Definition irq.c:281
irq_handler_t irq_get_vtable_handler(uint num)
Get the current IRQ handler for the specified IRQ from the currently installed hardware vector table ...
Definition irq.c:256
uint irq_get_priority(uint num)
Get specified interrupt's priority.
Definition irq.c:657
uint32_t irq_get_mask_n(uint n)
Get the current enabled mask on the executing core.
Definition irq.c:133
void irq_set_enabled(uint num, bool enabled)
Enable or disable a specific interrupt on the executing core.
Definition irq.c:60
void(* irq_handler_t)(void)
Interrupt handler function type.
Definition irq.h:206
bool irq_has_handler(uint num)
Determine if there is an installed IRQ handler for the given interrupt number.
Definition irq.c:261
void user_irq_claim(uint irq_num)
Claim ownership of a user IRQ on the calling core.
Definition irq.c:732
int user_irq_claim_unused(bool required)
Claim ownership of a free user IRQ on the calling core.
Definition irq.c:740
void irq_set_priority(uint num, uint8_t hardware_priority)
Set specified interrupt's priority.
Definition irq.c:640
void irq_remove_handler(uint num, irq_handler_t handler)
Remove a specific interrupt handler for the given irq number on the executing core.
Definition irq.c:521
void irq_set_mask_n_enabled(uint n, uint32_t mask, bool enabled)
Enable/disable multiple interrupts on the executing core.
Definition irq.c:112
bool irq_has_shared_handler(uint num)
Determine if the current IRQ andler for the given interrupt number is shared.
Definition irq.c:242
void irq_set_mask_enabled(uint32_t mask, bool enabled)
Enable/disable multiple interrupts on the executing core.
Definition irq.c:108
void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority)
Add a shared interrupt handler for an interrupt on the executing core.
Definition irq.c:405
void irq_set_exclusive_handler(uint num, irq_handler_t handler)
Set an exclusive interrupt handler for an interrupt on the executing core.
Definition irq.c:267
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition compiler.h:128
void runtime_init_per_core_irq_priorities(void)
Perform IRQ priority initialization for the current core.
Definition irq.c:704