Pico GPS Teseo I2C
Loading...
Searching...
No Matches
hardware_irq

Hardware interrupt handling. More...

Typedefs

typedef void(* irq_handler_t) (void)
 Interrupt handler function type.
 
typedef enum irq_num_rp2040 irq_num_t
 Interrupt numbers on RP2040 (used as typedef irq_num_t)
 
typedef enum irq_num_rp2350 irq_num_t
 Interrupt numbers on RP2350 (used as typedef irq_num_t)
 
typedef void(* irq_handler_t) (void)
 Interrupt handler function type.
 

Enumerations

enum  irq_num_rp2040 {
  TIMER_IRQ_0 = 0 , TIMER_IRQ_1 = 1 , TIMER_IRQ_2 = 2 , TIMER_IRQ_3 = 3 ,
  PWM_IRQ_WRAP = 4 , USBCTRL_IRQ = 5 , XIP_IRQ = 6 , PIO0_IRQ_0 = 7 ,
  PIO0_IRQ_1 = 8 , PIO1_IRQ_0 = 9 , PIO1_IRQ_1 = 10 , DMA_IRQ_0 = 11 ,
  DMA_IRQ_1 = 12 , IO_IRQ_BANK0 = 13 , IO_IRQ_QSPI = 14 , SIO_IRQ_PROC0 = 15 ,
  SIO_IRQ_PROC1 = 16 , CLOCKS_IRQ = 17 , SPI0_IRQ = 18 , SPI1_IRQ = 19 ,
  UART0_IRQ = 20 , UART1_IRQ = 21 , ADC_IRQ_FIFO = 22 , I2C0_IRQ = 23 ,
  I2C1_IRQ = 24 , RTC_IRQ = 25 , SPARE_IRQ_0 = 26 , SPARE_IRQ_1 = 27 ,
  SPARE_IRQ_2 = 28 , SPARE_IRQ_3 = 29 , SPARE_IRQ_4 = 30 , SPARE_IRQ_5 = 31 ,
  IRQ_COUNT
}
 Interrupt numbers on RP2040 (used as typedef irq_num_t) More...
 
enum  irq_num_rp2350 {
  TIMER0_IRQ_0 = 0 , TIMER0_IRQ_1 = 1 , TIMER0_IRQ_2 = 2 , TIMER0_IRQ_3 = 3 ,
  TIMER1_IRQ_0 = 4 , TIMER1_IRQ_1 = 5 , TIMER1_IRQ_2 = 6 , TIMER1_IRQ_3 = 7 ,
  PWM_IRQ_WRAP_0 = 8 , PWM_IRQ_WRAP_1 = 9 , DMA_IRQ_0 = 10 , DMA_IRQ_1 = 11 ,
  DMA_IRQ_2 = 12 , DMA_IRQ_3 = 13 , USBCTRL_IRQ = 14 , PIO0_IRQ_0 = 15 ,
  PIO0_IRQ_1 = 16 , PIO1_IRQ_0 = 17 , PIO1_IRQ_1 = 18 , PIO2_IRQ_0 = 19 ,
  PIO2_IRQ_1 = 20 , IO_IRQ_BANK0 = 21 , IO_IRQ_BANK0_NS = 22 , IO_IRQ_QSPI = 23 ,
  IO_IRQ_QSPI_NS = 24 , SIO_IRQ_FIFO = 25 , SIO_IRQ_BELL = 26 , SIO_IRQ_FIFO_NS = 27 ,
  SIO_IRQ_BELL_NS = 28 , SIO_IRQ_MTIMECMP = 29 , CLOCKS_IRQ = 30 , SPI0_IRQ = 31 ,
  SPI1_IRQ = 32 , UART0_IRQ = 33 , UART1_IRQ = 34 , ADC_IRQ_FIFO = 35 ,
  I2C0_IRQ = 36 , I2C1_IRQ = 37 , OTP_IRQ = 38 , TRNG_IRQ = 39 ,
  PROC0_IRQ_CTI = 40 , PROC1_IRQ_CTI = 41 , PLL_SYS_IRQ = 42 , PLL_USB_IRQ = 43 ,
  POWMAN_IRQ_POW = 44 , POWMAN_IRQ_TIMER = 45 , SPARE_IRQ_0 = 46 , SPARE_IRQ_1 = 47 ,
  SPARE_IRQ_2 = 48 , SPARE_IRQ_3 = 49 , SPARE_IRQ_4 = 50 , SPARE_IRQ_5 = 51 ,
  IRQ_COUNT
}
 Interrupt numbers on RP2350 (used as typedef irq_num_t) More...
 

Functions

void irq_set_priority (uint num, uint8_t hardware_priority)
 Set specified interrupt's priority.
 
uint irq_get_priority (uint num)
 Get specified interrupt's priority.
 
void irq_set_enabled (uint num, bool enabled)
 Enable or disable a specific interrupt on the executing core.
 
bool irq_is_enabled (uint num)
 Determine if a specific interrupt is enabled on the executing core.
 
void irq_set_mask_enabled (uint32_t mask, bool enabled)
 Enable/disable multiple interrupts on the executing core.
 
void irq_set_mask_n_enabled (uint n, uint32_t mask, bool enabled)
 Enable/disable multiple interrupts on the executing core.
 
void irq_set_exclusive_handler (uint num, irq_handler_t handler)
 Set an exclusive interrupt handler for an interrupt on the executing core.
 
irq_handler_t irq_get_exclusive_handler (uint num)
 Get the exclusive interrupt handler for an interrupt on the executing core.
 
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.
 
void irq_remove_handler (uint num, irq_handler_t handler)
 Remove a specific interrupt handler for the given irq number on the executing core.
 
bool irq_has_shared_handler (uint num)
 Determine if the current handler for the given number is shared.
 
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 (VTOR) of the execution core.
 
void irq_clear (uint int_num)
 Clear a specific interrupt on the executing core.
 
void irq_set_pending (uint num)
 Force an interrupt to be pending on the executing core.
 
void user_irq_claim (uint irq_num)
 Claim ownership of a user IRQ on the calling core.
 
void user_irq_unclaim (uint irq_num)
 Mark a user IRQ as no longer used on the calling core.
 
int user_irq_claim_unused (bool required)
 Claim ownership of a free user IRQ on the calling core.
 
bool irq_has_handler (uint num)
 Determine if there is an installed IRQ handler for the given interrupt number.
 

Detailed Description

Hardware interrupt handling.

Hardware interrupt handling API.

The RP2040 uses the standard ARM nested vectored interrupt controller (NVIC).

Interrupts are identified by a number from 0 to 31.

On the RP2040, only the lower 26 IRQ signals are connected on the NVIC; IRQs 26 to 31 are tied to zero (never firing).

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 where there is one IO interrupt per bank, per core. These are completely independent, so, for example, processor 0 can be interrupted by GPIO 0 in bank 0, and processor 1 by GPIO 1 in the same bank.

Note
That all IRQ APIs affect the executing core only (i.e. the core calling the function).
You should not enable the same (shared) IRQ number on both cores, as this will lead to race conditions or starvation of one of the cores. Additionally, don't forget that disabling interrupts on one core does not disable interrupts on the other core.

There are three different ways to set handlers for an IRQ:

Note
If an IRQ is enabled and fires with no handler installed, a breakpoint will be hit and the IRQ number will be in register r0.

Interrupt Numbers

Interrupts are numbered as follows, a set of defines is available (intctrl.h) with these names to avoid using the numbers directly.

IRQ Interrupt Source
0 TIMER_IRQ_0
1 TIMER_IRQ_1
2 TIMER_IRQ_2
3 TIMER_IRQ_3
4 PWM_IRQ_WRAP
5 USBCTRL_IRQ
6 XIP_IRQ
7 PIO0_IRQ_0
8 PIO0_IRQ_1
9 PIO1_IRQ_0
10 PIO1_IRQ_1
11 DMA_IRQ_0
12 DMA_IRQ_1
13 IO_IRQ_BANK0
14 IO_IRQ_QSPI
15 SIO_IRQ_PROC0
16 SIO_IRQ_PROC1
17 CLOCKS_IRQ
18 SPI0_IRQ
19 SPI1_IRQ
20 UART0_IRQ
21 UART1_IRQ
22 ADC0_IRQ_FIFO
23 I2C0_IRQ
24 I2C1_IRQ
25 RTC_IRQ

The RP2040 uses the standard ARM nested vectored interrupt controller (NVIC).

Interrupts are identified by a number from 0 to 31.

On the RP2040, only the lower 26 IRQ signals are connected on the NVIC; IRQs 26 to 31 are tied to zero (never firing).

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 where there is one IO interrupt per bank, per core. These are completely independent, so, for example, processor 0 can be interrupted by GPIO 0 in bank 0, and processor 1 by GPIO 1 in the same bank.

Note
All IRQ APIs affect the executing core only (i.e. the core calling the function).
You should not enable the same (shared) IRQ number on both cores, as this will lead to race conditions or starvation of one of the cores. Additionally, don't forget that disabling interrupts on one core does not disable interrupts on the other core.

There are three different ways to set handlers for an IRQ:

Note
If an IRQ is enabled and fires with no handler installed, a breakpoint will be hit and the IRQ number will be in register r0.

Interrupt Numbers

A set of defines is available (intctrl.h) with these names to avoid using the numbers directly.

Typedef Documentation

◆ irq_handler_t [1/2]

typedef void(* irq_handler_t) (void)

Interrupt handler function type.

All interrupts handlers should be of this type, and follow normal ARM EABI register saving conventions

Definition at line 128 of file irq.h.

◆ irq_handler_t [2/2]

typedef void(* irq_handler_t) (void)

Interrupt handler function type.

All interrupts handlers should be of this type, and follow normal ARM EABI register saving conventions

Definition at line 195 of file irq.h.

◆ irq_num_t [1/2]

typedef enum irq_num_rp2040 irq_num_t

Interrupt numbers on RP2040 (used as typedef irq_num_t)

◆ irq_num_t [2/2]

typedef enum irq_num_rp2350 irq_num_t

Interrupt numbers on RP2350 (used as typedef irq_num_t)

Enumeration Type Documentation

◆ irq_num_rp2040

Interrupt numbers on RP2040 (used as typedef irq_num_t)

Enumerator
TIMER_IRQ_0 

Select TIMER's IRQ 0 output.

TIMER_IRQ_1 

Select TIMER's IRQ 1 output.

TIMER_IRQ_2 

Select TIMER's IRQ 2 output.

TIMER_IRQ_3 

Select TIMER's IRQ 3 output.

PWM_IRQ_WRAP 

Select PWM's IRQ_WRAP output.

USBCTRL_IRQ 

Select USBCTRL's IRQ output.

XIP_IRQ 

Select XIP's IRQ output.

PIO0_IRQ_0 

Select PIO0's IRQ 0 output.

PIO0_IRQ_1 

Select PIO0's IRQ 1 output.

PIO1_IRQ_0 

Select PIO1's IRQ 0 output.

PIO1_IRQ_1 

Select PIO1's IRQ 1 output.

DMA_IRQ_0 

Select DMA's IRQ 0 output.

DMA_IRQ_1 

Select DMA's IRQ 1 output.

IO_IRQ_BANK0 

Select IO_BANK0's IRQ output.

IO_IRQ_QSPI 

Select IO_QSPI's IRQ output.

SIO_IRQ_PROC0 

Select SIO_PROC0's IRQ output.

SIO_IRQ_PROC1 

Select SIO_PROC1's IRQ output.

CLOCKS_IRQ 

Select CLOCKS's IRQ output.

SPI0_IRQ 

Select SPI0's IRQ output.

SPI1_IRQ 

Select SPI1's IRQ output.

UART0_IRQ 

Select UART0's IRQ output.

UART1_IRQ 

Select UART1's IRQ output.

ADC_IRQ_FIFO 

Select ADC's IRQ_FIFO output.

I2C0_IRQ 

Select I2C0's IRQ output.

I2C1_IRQ 

Select I2C1's IRQ output.

RTC_IRQ 

Select RTC's IRQ output.

SPARE_IRQ_0 

Select SPARE IRQ 0.

SPARE_IRQ_1 

Select SPARE IRQ 1.

SPARE_IRQ_2 

Select SPARE IRQ 2.

SPARE_IRQ_3 

Select SPARE IRQ 3.

SPARE_IRQ_4 

Select SPARE IRQ 4.

SPARE_IRQ_5 

Select SPARE IRQ 5.

IRQ_COUNT 

Definition at line 53 of file intctrl.h.

◆ irq_num_rp2350

Interrupt numbers on RP2350 (used as typedef irq_num_t)

Enumerator
TIMER0_IRQ_0 

Select TIMER0's IRQ 0 output.

TIMER0_IRQ_1 

Select TIMER0's IRQ 1 output.

TIMER0_IRQ_2 

Select TIMER0's IRQ 2 output.

TIMER0_IRQ_3 

Select TIMER0's IRQ 3 output.

TIMER1_IRQ_0 

Select TIMER1's IRQ 0 output.

TIMER1_IRQ_1 

Select TIMER1's IRQ 1 output.

TIMER1_IRQ_2 

Select TIMER1's IRQ 2 output.

TIMER1_IRQ_3 

Select TIMER1's IRQ 3 output.

PWM_IRQ_WRAP_0 

Select PWM's IRQ_WRAP 0 output.

PWM_IRQ_WRAP_1 

Select PWM's IRQ_WRAP 1 output.

DMA_IRQ_0 

Select DMA's IRQ 0 output.

DMA_IRQ_1 

Select DMA's IRQ 1 output.

DMA_IRQ_2 

Select DMA's IRQ 2 output.

DMA_IRQ_3 

Select DMA's IRQ 3 output.

USBCTRL_IRQ 

Select USBCTRL's IRQ output.

PIO0_IRQ_0 

Select PIO0's IRQ 0 output.

PIO0_IRQ_1 

Select PIO0's IRQ 1 output.

PIO1_IRQ_0 

Select PIO1's IRQ 0 output.

PIO1_IRQ_1 

Select PIO1's IRQ 1 output.

PIO2_IRQ_0 

Select PIO2's IRQ 0 output.

PIO2_IRQ_1 

Select PIO2's IRQ 1 output.

IO_IRQ_BANK0 

Select IO_BANK0's IRQ output.

IO_IRQ_BANK0_NS 

Select IO_BANK0_NS's IRQ output.

IO_IRQ_QSPI 

Select IO_QSPI's IRQ output.

IO_IRQ_QSPI_NS 

Select IO_QSPI_NS's IRQ output.

SIO_IRQ_FIFO 

Select SIO's IRQ_FIFO output.

SIO_IRQ_BELL 

Select SIO's IRQ_BELL output.

SIO_IRQ_FIFO_NS 

Select SIO_NS's IRQ_FIFO output.

SIO_IRQ_BELL_NS 

Select SIO_NS's IRQ_BELL output.

SIO_IRQ_MTIMECMP 

Select SIO_IRQ_MTIMECMP's IRQ output.

CLOCKS_IRQ 

Select CLOCKS's IRQ output.

SPI0_IRQ 

Select SPI0's IRQ output.

SPI1_IRQ 

Select SPI1's IRQ output.

UART0_IRQ 

Select UART0's IRQ output.

UART1_IRQ 

Select UART1's IRQ output.

ADC_IRQ_FIFO 

Select ADC's IRQ_FIFO output.

I2C0_IRQ 

Select I2C0's IRQ output.

I2C1_IRQ 

Select I2C1's IRQ output.

OTP_IRQ 

Select OTP's IRQ output.

TRNG_IRQ 

Select TRNG's IRQ output.

PROC0_IRQ_CTI 

Select PROC0's IRQ_CTI output.

PROC1_IRQ_CTI 

Select PROC1's IRQ_CTI output.

PLL_SYS_IRQ 

Select PLL_SYS's IRQ output.

PLL_USB_IRQ 

Select PLL_USB's IRQ output.

POWMAN_IRQ_POW 

Select POWMAN's IRQ_POW output.

POWMAN_IRQ_TIMER 

Select POWMAN's IRQ_TIMER output.

SPARE_IRQ_0 

Select SPARE IRQ 0.

SPARE_IRQ_1 

Select SPARE IRQ 1.

SPARE_IRQ_2 

Select SPARE IRQ 2.

SPARE_IRQ_3 

Select SPARE IRQ 3.

SPARE_IRQ_4 

Select SPARE IRQ 4.

SPARE_IRQ_5 

Select SPARE IRQ 5.

IRQ_COUNT 

Definition at line 73 of file intctrl.h.

Function Documentation

◆ irq_add_shared_handler()

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.

Use this method to add a handler on an irq number shared between multiple distinct hardware sources (e.g. GPIO, DMA or PIO IRQs). Handlers added by this method will all be called in sequence from highest order_priority to lowest. The irq_set_exclusive_handler() method should be used instead if you know there will or should only ever be one handler for the interrupt.

This method will assert if there is an exclusive interrupt handler set for this irq number on this core, or if the (total across all IRQs on both cores) maximum (configurable via PICO_MAX_SHARED_IRQ_HANDLERS) number of shared handlers would be exceeded.

Parameters
numInterrupt number Interrupt Numbers
handlerThe handler to set. See irq_handler_t
order_priorityThe order priority controls the order that handlers for the same IRQ number on the core are called. The shared irq handlers for an interrupt are all called when an IRQ fires, however the order of the calls is based on the order_priority (higher priorities are called first, identical priorities are called in undefined order). A good 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 the priority range by default.
Note
The order_priority uses higher values for higher priorities which is the opposite of the CPU interrupt priorities passed to irq_set_priority() which use lower values for higher priorities.
See also
irq_set_exclusive_handler()

Use this method to add a handler on an irq number shared between multiple distinct hardware sources (e.g. GPIO, DMA or PIO IRQs). Handlers added by this method will all be called in sequence from highest order_priority to lowest. The irq_set_exclusive_handler() method should be used instead if you know there will or should only ever be one handler for the interrupt.

This method will assert if there is an exclusive interrupt handler set for this irq number on this core, or if the (total across all IRQs on both cores) maximum (configurable via PICO_MAX_SHARED_IRQ_HANDLERS) number of shared handlers would be exceeded.

NOTE: By default, the SDK uses a single shared vector table for both cores, and the currently installed IRQ handlers are effectively a linked list starting a vector table entry for a particular IRQ number. Therefore, this method (when using the same vector table for both cores) add the same interrupt handler for both cores.

On RP2040 this was never really a cause of any confusion, because it rarely made sense to enable the same interrupt number in the NVIC on both cores (see irq_set_enabled()), because the interrupt would then fire on both cores, and the interrupt handlers would race.

The problem does exist however when dealing with interrupts which are independent on the two cores.

This includes:

  • the core local "spare" IRQs
  • on RP2350 the SIO FIFO IRQ which is now the same irq number for both cores (vs RP2040 where it was two)

In the cases where you want to enable the same IRQ on both cores, and both cores are sharing the same vector table, you should install the IRQ handler once - it will be used on both cores - and check the core number (via get_core_num()) on each core.

NOTE: It is not thread safe to add/remove/handle IRQs for the same irq number in the same vector table from both cores concurrently.

NOTE: The SDK has a PICO_VTABLE_PER_CORE define indicating whether the two vector tables are separate, however as of version 2.1.1 the user cannot set this value, and expect the vector table duplication to be handled for them. This functionality will be added in a future SDK version

Parameters
numInterrupt number Interrupt Numbers
handlerThe handler to set. See irq_handler_t
order_priorityThe order priority controls the order that handlers for the same IRQ number on the core are called. The shared irq handlers for an interrupt are all called when an IRQ fires, however the order of the calls is based on the order_priority (higher priorities are called first, identical priorities are called in undefined order). A good 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 the priority range by default.
Note
The order_priority uses higher values for higher priorities which is the opposite of the CPU interrupt priorities passed to irq_set_priority() which use lower values for higher priorities.
See also
irq_set_exclusive_handler()

Definition at line 70 of file irq.c.

◆ irq_clear()

static void irq_clear ( uint int_num)
inline

Clear a specific interrupt on the executing core.

This method is only useful for "software" IRQs that are not connected to hardware (i.e. IRQs 26-31) as the the NVIC always reflects the current state of the IRQ state of the hardware for hardware IRQs, and clearing of the IRQ state of the hardware is performed via the hardware's registers instead.

Parameters
int_numInterrupt number Interrupt Numbers

This method is only useful for "software" IRQs that are not connected to hardware (e.g. IRQs 26-31 on RP2040) as the the NVIC always reflects the current state of the IRQ state of the hardware for hardware IRQs, and clearing of the IRQ state of the hardware is performed via the hardware's registers instead.

Parameters
int_numInterrupt number Interrupt Numbers

Definition at line 446 of file irq.h.

◆ irq_get_exclusive_handler()

irq_handler_t irq_get_exclusive_handler ( uint num)

Get the exclusive interrupt handler for an interrupt on the executing core.

This method will return an exclusive IRQ handler set on this core by irq_set_exclusive_handler if there is one.

Parameters
numInterrupt number Interrupt Numbers
See also
irq_set_exclusive_handler()
Returns
handler The handler if an exclusive handler is set for the IRQ, NULL if no handler is set or shared/shareable handlers are installed

Definition at line 65 of file irq.c.

◆ irq_get_priority()

uint irq_get_priority ( uint num)

Get specified interrupt's priority.

Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority) though only the top 2 bits are significant on ARM Cortex-M0+. To make it easier to specify higher or lower priorities than the default, all IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup. PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80

Parameters
numInterrupt number Interrupt Numbers
Returns
the IRQ priority

Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority). To make it easier to specify higher or lower priorities than the default, all IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup. PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80

Parameters
numInterrupt number Interrupt Numbers
Returns
the IRQ priority

Definition at line 85 of file irq.c.

◆ irq_get_vtable_handler()

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 (VTOR) of the execution core.

Parameters
numInterrupt number Interrupt Numbers
Returns
the address stored in the VTABLE for the given irq number

Definition at line 55 of file irq.c.

◆ irq_has_handler()

bool irq_has_handler ( uint num)

Determine if there is an installed IRQ handler for the given interrupt number.

See irq_set_exclusive_handler() for discussion on the scope of handlers when using both cores.

Parameters
numInterrupt number Interrupt Numbers
Returns
true if the specified IRQ has a handler

Definition at line 225 of file irq.c.

◆ irq_has_shared_handler()

bool irq_has_shared_handler ( uint num)

Determine if the current handler for the given number is shared.

Determine if the current IRQ andler for the given interrupt number is shared.

Parameters
numInterrupt number Interrupt Numbers
Returns
true if the specified IRQ has a shared handler

See irq_set_exclusive_handler() for discussion on the scope of handlers when using both cores.

Parameters
numInterrupt number Interrupt Numbers
Returns
true if the specified IRQ has a shared handler

Definition at line 50 of file irq.c.

◆ irq_is_enabled()

bool irq_is_enabled ( uint num)

Determine if a specific interrupt is enabled on the executing core.

Parameters
numInterrupt number Interrupt Numbers
Returns
true if the interrupt is enabled

Definition at line 30 of file irq.c.

◆ irq_remove_handler()

void irq_remove_handler ( uint num,
irq_handler_t handler )

Remove a specific interrupt handler for the given irq number on the executing core.

This method may be used to remove an irq set via either irq_set_exclusive_handler() or irq_add_shared_handler(), and will assert if the handler is not currently installed for the given IRQ number

Note
This method may only be called from user (non IRQ code) or from within the handler itself (i.e. an IRQ handler may remove itself as part of handling the IRQ). Attempts to call from another IRQ will cause an assertion.
Parameters
numInterrupt number Interrupt Numbers
handlerThe handler to removed.
See also
irq_set_exclusive_handler()
irq_add_shared_handler()

Definition at line 75 of file irq.c.

◆ irq_set_enabled()

void irq_set_enabled ( uint num,
bool enabled )

Enable or disable a specific interrupt on the executing core.

Parameters
numInterrupt number Interrupt Numbers
enabledtrue to enable the interrupt, false to disable

Definition at line 25 of file irq.c.

◆ irq_set_exclusive_handler()

void irq_set_exclusive_handler ( uint num,
irq_handler_t handler )

Set an exclusive interrupt handler for an interrupt on the executing core.

Use this method to set a handler for single IRQ source interrupts, or when your code, use case or performance requirements dictate that there should no other handlers for the interrupt.

This method will assert if there is already any sort of interrupt handler installed for the specified irq number.

Parameters
numInterrupt number Interrupt Numbers
handlerThe handler to set. See irq_handler_t
See also
irq_add_shared_handler()

Use this method to set a handler for single IRQ source interrupts, or when your code, use case or performance requirements dictate that there should be no other handlers for the interrupt.

This method will assert if there is already any sort of interrupt handler installed for the specified irq number.

NOTE: By default, the SDK uses a single shared vector table for both cores, and the currently installed IRQ handlers are effectively a linked list starting a vector table entry for a particular IRQ number. Therefore, this method (when using the same vector table for both cores) sets the same interrupt handler for both cores.

On RP2040 this was never really a cause of any confusion, because it rarely made sense to enable the same interrupt number in the NVIC on both cores (see irq_set_enabled()), because the interrupt would then fire on both cores, and the interrupt handlers would race.

The problem does exist however when dealing with interrupts which are independent on the two cores.

This includes:

  • the core local "spare" IRQs
  • on RP2350 the SIO FIFO IRQ which is now the same irq number for both cores (vs RP2040 where it was two)

In the cases where you want to enable the same IRQ on both cores, and both cores are sharing the same vector table, you should install the IRQ handler once - it will be used on both cores - and check the core number (via get_core_num()) on each core.

NOTE: It is not thread safe to add/remove/handle IRQs for the same irq number in the same vector table from both cores concurrently.

NOTE: The SDK has a PICO_VTABLE_PER_CORE define indicating whether the two vector tables are separate, however as of version 2.1.1 the user cannot set this value, and expect the vector table duplication to be handled for them. This functionality will be added in a future SDK version

Parameters
numInterrupt number Interrupt Numbers
handlerThe handler to set. See irq_handler_t
See also
irq_add_shared_handler()

Definition at line 60 of file irq.c.

◆ irq_set_mask_enabled()

void irq_set_mask_enabled ( uint32_t mask,
bool enabled )

Enable/disable multiple interrupts on the executing core.

Parameters
mask32-bit mask with one bits set for the interrupts to enable/disable Interrupt Numbers
enabledtrue to enable the interrupts, false to disable them.

Definition at line 35 of file irq.c.

◆ irq_set_mask_n_enabled()

void irq_set_mask_n_enabled ( uint n,
uint32_t mask,
bool enabled )

Enable/disable multiple interrupts on the executing core.

Parameters
nthe index of the mask to update. n == 0 means 0->31, n == 1 mean 32->63 etc.
mask32-bit mask with one bits set for the interrupts to enable/disable Interrupt Numbers
enabledtrue to enable the interrupts, false to disable them.

Definition at line 40 of file irq.c.

◆ irq_set_pending()

void irq_set_pending ( uint num)

Force an interrupt to be pending on the executing core.

This should generally not be used for IRQs connected to hardware.

Parameters
numInterrupt number Interrupt Numbers

Definition at line 45 of file irq.c.

◆ irq_set_priority()

void irq_set_priority ( uint num,
uint8_t hardware_priority )

Set specified interrupt's priority.

Parameters
numInterrupt number Interrupt Numbers
hardware_priorityPriority to set. Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority) though only the top 2 bits are significant on ARM Cortex-M0+. To make it easier to specify higher or lower priorities than the default, all IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup. PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80
numInterrupt number Interrupt Numbers
hardware_priorityPriority to set. Numerically-lower values indicate a higher priority. Hardware priorities range from 0 (highest priority) to 255 (lowest priority). To make it easier to specify higher or lower priorities than the default, all IRQ priorities are initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup. PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80

Definition at line 80 of file irq.c.

◆ user_irq_claim()

void user_irq_claim ( uint irq_num)

Claim ownership of a user IRQ on the calling core.

User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by irq_set_pending.

Note
User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly claims ownership of a user IRQ, so other code can know it is being used.

Parameters
irq_numthe user IRQ to claim

User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by irq_set_pending.

Note
User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly claims ownership of a user IRQ, so other code can know it is being used.

Parameters
irq_numthe user IRQ to claim

Definition at line 106 of file irq.c.

◆ user_irq_claim_unused()

int user_irq_claim_unused ( bool required)

Claim ownership of a free user IRQ on the calling core.

User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by irq_set_pending.

Note
User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly claims ownership of an unused user IRQ if there is one, so other code can know it is being used.

Parameters
requiredif true the function will panic if none are available
Returns
the user IRQ number or -1 if required was false, and none were free

User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by irq_set_pending.

Note
User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly claims ownership of an unused user IRQ if there is one, so other code can know it is being used.

Parameters
requiredif true the function will panic if none are available
Returns
the user IRQ number or -1 if required was false, and none were free

Definition at line 116 of file irq.c.

◆ user_irq_unclaim()

void user_irq_unclaim ( uint irq_num)

Mark a user IRQ as no longer used on the calling core.

User IRQs are numbered 26-31 and are not connected to any hardware, but can be triggered by irq_set_pending.

Note
User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly releases ownership of a user IRQ, so other code can know it is free to use.

Note
it is customary to have disabled the irq and removed the handler prior to calling this method.
Parameters
irq_numthe irq irq_num to unclaim

User IRQs starting from FIRST_USER_IRQ are not connected to any hardware, but can be triggered by irq_set_pending.

Note
User IRQs are a core local feature; they cannot be used to communicate between cores. Therefore all functions dealing with Uer IRQs affect only the calling core

This method explicitly releases ownership of a user IRQ, so other code can know it is free to use.

Note
it is customary to have disabled the irq and removed the handler prior to calling this method.
Parameters
irq_numthe irq irq_num to unclaim

Definition at line 111 of file irq.c.