Interrupt Block Icon
The Interrupt block creates interrupt-driven subsystems by connecting peripheral interrupt sources to Simulink triggered subsystems. The block automatically manages interrupt vector configuration, priority levels, and timing synchronization. Key Capabilities: - Automatic interrupt detection - Discovers all peripheral interrupts in model - Dynamic interrupt list - Popup shows only available interrupts from active peripherals - Priority management - Configure interrupt priority levels (device-dependent) - Multiple timing modes - Base rate, periodic trigger, or hardware timer-based - Context preservation - Automatic FPU context save/restore (PIC32 with FPU)

When to use:

When to use:

  • Hardware event must trigger Simulink subsystem (ADC done, UART RX, encoder overflow)
  • Need lowest latency response to peripheral event (faster than polling)
  • PWM-synchronized control loop (ADC interrupt after PWM trigger)
  • Asynchronous communication (UART/SPI/I2C receive events)
  • Extending encoder range with overflow/underflow interrupts

When NOT to use:

  • Timer-based periodic tasks suffice โ€” use Simulink sample times instead
  • Polling peripheral status is fast enough for application timing
  • Adding complexity without latency benefit โ€” interrupts add overhead
  • Peripheral block does not define interrupt source (check dropdown list)

Block Dialog

interrupt โ€” Tab 1: Main
interrupt โ€” Tab 2: Advanced
Screenshots taken with chip 33AK512MPS512

Parameters

Interrupt Selection

ParameterVariableDescriptionValues
InterruptionInterruptionSelect interrupt source from a dynamic list. The list contains, in order: (1) Class A โ€” Driver-Owned and Class B โ€” Peripheral-Exposed entries declared by peripheral blocks present in the model, then (2) a --- Chip Interrupt Vectors --- separator, then (3) Class C โ€” Raw Chip Vectors read from the chip’s IVT database. See Interrupt Sources below.โ€ข Not defined | โ€ข peripheral-declared entries (e.g. UART1 RX, ADC1 Ch0 Data Ready, QEI1POS, T2) | โ€ข --- Chip Interrupt Vectors --- | โ€ข raw chip vectors (e.g. [Timer] Timer 5 Interrupt, [CAN] CAN1 Error)
Interrupt PriorityIntPriorityInterrupt priority level. Editable for Class B and Class C entries. Locked (read-only) for Class A entries โ€” the priority is owned by the declaring peripheral block (CN, SPI / I2C bus sequence, Comparator, โ€ฆ). Higher number = higher priority on dsPIC/PIC32; 0 = highest on ARM.1-7 (dsPIC/PIC24) | 1-7 (PIC32) | 0-15 (ARM - 0=highest)
Disable FPU Context SaveFPUNoSave(PIC32 with FPU only) Disable automatic FPU context save if ISR does not use floating-point operations (optimization).on / off
Execute at StartupStartupExecuteExecute subsystem once during initialization (before first interrupt).on / off

Changed in v3.63.x โ€” The legacy fire-every-step fallback has been removed. A triggered subsystem connected to an Interrupt block whose source is never raised at run-time is now reported as a build-time configuration error instead of silently firing at the model base rate. If an older model relied on that behaviour, connect the subsystem to a Timer-based trigger instead, or mark StartupExecute=on when a one-shot initialisation is all that is needed. The Change Notification (CN) callback also emits a warning when EVT_EN is empty but at least one channel is configured, to catch the same misconfiguration on CN-driven interrupts.

Timing Configuration

ParameterVariableDescriptionUse Case
Time SourceTriggered_Sub_TimeSourceTiming reference for triggered subsystem sample time.โ€ข Base rate: Synchronized to model base rate | โ€ข Periodic trigs: User-specified period | โ€ข Hardware timer: Dedicated timer resource
Trigger PeriodTrigsPeriod(Periodic trigs mode) Subsystem sample time when using periodic trigger mode.Any value matching trigger rate (e.g., 100e-6 for 10 kHz)
Timer ResolutionTIMER_Resolution(Hardware timer mode) Select timer prescaler for desired resolution and max period.Dynamic list based on device: | โ€ข dsPIC: 1, 8, 64, 256 prescalers | โ€ข PIC32: 1, 2, 4, 8, 16, 32, 64, 256 | โ€ข SAM: 8, 32, 128 divisors

Interrupt Sources

The Interruption popup is built dynamically every time the dialog opens. It is populated from two passes over the model:

  1. Phase 1 โ€” Peripheral declarations. Every block whose mask exposes a non-empty MCHP_USER_INTERRUPTS parameter contributes one or more entries (ADC, PWM, UART, QEI, Timer Config, CN, Comparator, I2C/SPI sequence-Interrupt actions, โ€ฆ).
  2. Phase 2 โ€” Chip IVT database. After the peripheral pass, the callback queries MCHP_Fun.MCHP_IVT_FromDB(chipName) and appends every IVT vector defined for the actual target chip that has not already been claimed in Phase 1. These appear under the popup separator --- Chip Interrupt Vectors ---.

What ends up in the Interrupt block dialog therefore falls into three classes with very different responsibilities for the user.

The three classes of interrupts

ClassPopup label looks likeWhere it comes fromPriority fieldWiring an Interrupt block to itWhat you (the user) must still do
A โ€” Driver-Owned InterruptCN1, SPI1 โ€ฆ, I2C1 โ€ฆ, CMP1r, (future: UART1 RX)A peripheral block declares the entry with Priority(N) where N โ‰ฅ 0Locked / read-only โ€” the priority is owned by the declaring peripheral block (CN, SPI, I2C, โ€ฆ).Optional and chained โ€” if you wire one, your triggered subsystem runs after the peripheral driver has finished servicing the interrupt, inside the same ISR. The Interrupt block emits no vector of its own; it only contributes the subsystem body, which the driver invokes (Tier 1 inline for CN, Tier 3 hardcoded #ifdef Flag_โ€ฆ call-site for SPI/I2C/Comparator). If you do not wire one, the driver-only ISR runs as-is.Nothing for the flag handshake. The driver’s ISR clears xxIF, reads any required register, and then โ€” if you wired an Interrupt block โ€” calls your subsystem.
B โ€” Peripheral-Exposed InterruptADC1 Ch0 Data Ready, QEI1POS, T2, PWM1 Period, โ€ฆ (no [โ€ฆ] prefix)A peripheral block declares the entry with Priority(-1)EditableWiring an Interrupt block is what enables the interrupt. The Interrupt block emits a full __attribute__((interrupt)) vector that
โ‘  sets xxIP to your priority,
โ‘ก sets xxIE = 1,
โ‘ข sets the Config_BitSet (e.g. QEI1CONbits.CNTERIE = 1) if the peripheral block provided one,
โ‘ฃ on entry reads RegisterReadClear (captured into MCHP_ISR_<IE>_ReadValue),
โ‘ค writes xxIF = 0,
โ‘ฅ then calls your triggered subsystem. Without a wired Interrupt block, the entry is dormant โ€” no IE bit is set, no ISR is generated.
Nothing for the basic flag handshake. Only application-specific work (read FIFO words, advance state machine, etc.).
C โ€” Raw Chip Vector[GROUP] Description (group tag from the chip database, e.g. [Timer] Timer 5 Interrupt, [DMA] DMA Channel 3, [CAN] CAN1 Error)The chip’s IVT database โ€” no peripheral block declared itEditableSame auto-generated vector as Class B (xxIP, xxIE = 1, xxIF = 0, optional RegisterReadClear if the database provides one, then your subsystem call).Anything beyond IE/IF/IP. The peripheral itself is not configured by any MCHP block โ€” you must initialise it by writing the relevant SFRs in your model (typically with the Reg Write block or a custom S-Function), enable any sub-event flags, drain any FIFO, etc. The Interrupt block only handles the vector wrapper.

Classes A and B both stem from MCHP_USER_INTERRUPTS; their distinction is only the value of Priority. Class C bypasses MCHP_USER_INTERRUPTS entirely.

Class A โ€” chaining a user subsystem after the driver. This is the deliberate “hook” pattern: e.g. on a CN interrupt, the CN block writes the ISR (debounce, edge-detect, register read), and your wired Interrupt subsystem runs at the end of that same ISR โ€” you only see the post-processed event. Same for SPI / I2C sequence-step interrupts, Comparator, UART RX/TX (Circular Buffer / DMA), DMA, and QEI in turn-counting mode. The chaining is automatic; the only signal that an entry is Class A is the locked priority field.

Implementation tiers. The hook is realised by three slightly different code-generation paths โ€” Tier 1 inline for CN, Tier 2 callable function via MCHP_CallUserISR for UART / QEI / DMA, and Tier 3 hardcoded #ifdef Flag_โ€ฆ / func(); / #endif call-site for SPI / I2C / Comparator. From the user’s point of view all three are identical: pick the entry, wire the subsystem, the driver invokes it. See Driver / User ISR Coexistence below if you are authoring a new peripheral TLC.

What the block clears for you, by class

ActionClass A (CN, SPI, I2C, Comparator, UART driver-owned, DMA, QEI turn-counting)Class BClass C
xxIE = 1 (enable bit)by the peripheral driverby the Interrupt blockby the Interrupt block
xxIP = priorityby the peripheral driver (fixed)by the Interrupt block (user value)by the Interrupt block (user value)
Config_BitSet (peripheral-side enable bits, e.g. CNTERIE, ADIELbits.IE0)by the driver (it knows what to enable)automatic if the peripheral block provided onenot provided โ€” IVT database has no Config_BitSet; configure via Reg Write if needed
Read-data register (RegisterReadClear) โ€” captures the value into MCHP_ISR_<IE_ref>_ReadValueby the driver’s ISR (and the cleaned value is what your subsystem sees)automatic if the peripheral block provided oneautomatic if the IVT database has one for that vector; otherwise omitted
xxIF = 0 (clear interrupt flag)by the driver’s ISRautomatic (always)automatic (always)
Other peripheral SFRs (clear status, advance FIFO, ack errata, โ€ฆ)by the driver before chaining your subsystemby your subsystem code if neededby your subsystem code, every time
Order in which your subsystem runsafter all of the above (driver hands you a clean event)after xxIF=0 and RegisterReadClear, but before any peripheral-specific cleanupafter xxIF=0, you do the rest

In other words: you almost never have to clear xxIF yourself โ€” the Interrupt block does it on entry โ€” unless the silicon has a separate sub-event flag that the IVT database does not surface. Class A: nothing to do, the driver gives you a post-processed event; Class B: fully managed end-to-end as long as the peripheral block declared its RegisterReadClear; Class C: may need extra clears that you have to add to the subsystem.

How peripherals declare interrupts โ€” MCHP_USER_INTERRUPTS

Class A and Class B entries both come from the MCHP_USER_INTERRUPTS hidden mask parameter. The Interrupt block’s callback scans every block in the model with a non-empty value and concatenates them into one list.

Declaration format โ€” one or more semicolon-separated entries, each with four {โ€ฆ} fields:

{InterruptFlagRef}{ShortDescription}{LongDescription}{Parameters};
FieldPurposeExample
InterruptFlagRefC symbol stem of the IE bit (e.g. CN1IE, U1RX, AD1CH0). The Interrupt block writes xxIP/xxIE/xxIF from this stem.U1RX
ShortDescriptionLabel shown in the popup.UART1 RX
LongDescriptionTooltip / display annotation.UART1 Receive Data Ready
ParametersSpace-separated Name(Value) tokens โ€” see below. A bare number is accepted as legacy shorthand for Priority(N).VectorName(U1RXInterrupt) Priority(-1) RegisterReadClear(U1RXREG)

Parameter tokens (inside the fourth field)

TokenMeaning
VectorName(txt)Name of the ISR vector. If empty, the peripheral driver owns the __attribute__((interrupt)) and the Interrupt block emits a callable function (Tier 1 / Tier 3 below). If non-empty, the Interrupt block emits the full __attribute__((interrupt)) vector itself (Tier 2 โ€” typical Class B path, and also Tier 2 driver-owned).
Config_BitSet(txt)Extra peripheral-side enable bit to set when the Interrupt block configures the vector (e.g. QEI1CONbits.CNTERIE, ADFL0CONbits.IE).
RegisterReadClear(txt)Data register to read on ISR entry to clear the data-ready flag (captured into MCHP_ISR_<IE_ref>_ReadValue for use by the subsystem).
Priority(N)-1 โ‡’ Class B (user-editable priority). N โ‰ฅ 0 โ‡’ Class A (locked priority, set by the declaring peripheral). The block setting Priority is responsible for programming the IPC bits; other blocks must leave priority at -1.

Example โ€” Change Notification (single channel) (from MCHP_CN_Callback.m):

NewMask.Values.MCHP_USER_INTERRUPTS = ...
    ['{CN1IE}{CN1}{Change Notification - 1}{' NewMask.Values.IntPriority '};'];

The fourth field is a bare number โ‡’ treated as Priority(N); VectorName is empty โ‡’ Tier 1 inline (see below).

Driver / User ISR Coexistence (dsPIC / PIC32) โ€” three tiers

When the same vector is needed by both the peripheral driver and a user-attached Interrupt block, the blockset selects one of three code-generation tiers automatically. This is an implementation detail of how Class A is realised; users do not pick it โ€” it is fixed per peripheral.

TierTriggerWhat is generatedUsed by
Tier 1 โ€” InlineVectorName empty, Priority present (numeric)The peripheral TLC emits the ISR directly; the Interrupt block contributes its body inline at the end of the ISR.Change Notification (CN).
Tier 2 โ€” Function callVectorName non-emptyWhen Priority(Nโ‰ฅ0) (Class A): the peripheral’s driver owns the __attribute__((interrupt)) and calls MCHP_CallUserISR(IE_ref) at the end of its ISR; the Interrupt block emits a plain callable function with the subsystem body. When Priority(-1) (Class B): the Interrupt block emits the full __attribute__((interrupt)) itself.UART, ADC, Timer, QEI, PWM events.
Tier 3 โ€” HardcodedVectorName empty, fixed Priority(0)Driver embeds the ISR with a hardcoded call-site; the Interrupt block only supplies the body.SPI, I2C.

Why this matters โ€” declaring an interrupt in MCHP_USER_INTERRUPTS without wiring an Interrupt block is safe: it only adds an option to the dropdown. No IE bit is set and no ISR is emitted. The blockset enforces the tier rules automatically; you only need them when authoring a new peripheral TLC.

Which peripherals declare which class โ€” quick reference

Peripheral blockClass A entries (driver-owned, locked priority)Class B entries (peripheral-exposed, user-priority)Notes
CN (Change Notification)one per enabled CN port โ€” Tier 1 inline, user subsystem chains transparently after the CN block’s debounce/read codenoneClass A is the standard usage.
I2C Master / SPI Masterone per Interrupt action you place in the I2C/SPI sequence GUI โ€” Tier 3 hardcoded #ifdef, user subsystem chains after the bus stepnoneClass A is opt-in: the entry exists only because the user added an Interrupt action to the bus sequence.
Comparator / HS Analog Comparatorone per enabled comparator (rising / falling / any-edge variants) โ€” Tier 3 hardcodednoneClass A by design (legacy code-path).
UART Config (Simplest / polled)noneRX, TX (one each)User must clear xxIF if needed inside subsystem? No โ€” the Interrupt block does it.
UART Config (Circular Buffer / DMA Single / DMA Circular)RX, TX, DMA, Event vectors (driver-owned at fixed priority โ€” Tier 2)noneWiring an Interrupt block chains the user subsystem after the driver has filled / drained the buffer. Priority is set by the UART block (RX_INT_PRIORITY / TX_INT_PRIORITY).
ADC (HS 12b dsPIC33A, HS SAR dsPIC, HS SAR PIC32)noneone per assigned channel + one per active digital filterThe driver itself enables only one channel โ€” the time-step trigger channel โ€” and emits its own ISR for it. The other channels’ Class B entries are dormant until you wire an Interrupt block. Do not wire one to the trigger channel (it would collide with the driver’s scheduler ISR).
PWM HS / PWM HS FEPnoneone per enabled PWM channel (period / fault / current-limit / event)All Class B โ€” driver does not own any PWM ISR.
QEIone per QEI module when the QEI block is configured for driver-side turn-counting (QEI_IntPri field visible โ€” Tier 2)one per QEI module when turn-counting is disabled (Priority(-1) mode)In turn-counting mode the driver increments / decrements the software counter on each compare event; the wired user subsystem runs after that. In Priority(-1) mode the user fully owns the ISR.
Timer Confignoneone per configured timerAll Class B.

Anything else exposed by the silicon โ€” CRC, NVM, ECC, CAN error vectors, unused DMA channels, secondary timers, etc. โ€” does not go through any peripheral block and arrives via Phase 2 as a Class C โ€” Raw Chip Vector under the --- Chip Interrupt Vectors --- separator.

When you would actually pick a Class A entry

  • CN (digital edge-detect): the CN block does the debounce / pin-state read; your subsystem reacts to the cleaned event.
  • I2C / SPI sequence-step Interrupt action: you placed the Interrupt step inside the bus sequence; your subsystem runs at that point of the transfer.
  • Comparator: the analog comparator block reads CMSTAT and arms the next edge; your subsystem decides what to do with the event.

For those three, Class A is the normal way to use the interrupt, not an exception.

Device-Specific Interrupt Configuration

dsPIC30F/33F/33E/33C/33A

FeatureConfigurationNotes
Priority Levels1-7 (7 = highest)Default is level 4
NestingAutomatic if priorities differHigher priority can preempt lower
Vector TableAuto-managed by blocksetIVT and AIVT support
Context SaveW0-W15, RCOUNT, SRAutomatic register preservation

PIC32 (MIPS)

FeatureConfigurationNotes
Priority Levels1-7 (7 = highest)Sub-priority 0-3 also available
Shadow RegistersAutomatic if configuredFast context switch (no save)
FPU ContextOptional save/restoreOnly if FP ops used in ISR
Multi-Vector ModeEnabled by blocksetEach peripheral has dedicated vector

SAM (ARM Cortex-M)

FeatureConfigurationNotes
Priority Levels0-15 (0 = highest)NVIC priority grouping
Tail-ChainingAutomatic hardware optimizationBack-to-back ISRs without full context restore
Late ArrivalHardware-managed preemptionHigher priority can preempt during stacking
FPU Lazy StackingConditional FP context saveOnly saved if FP registers used

Timing Modes Explained

Mode 1: Derived from Model Base Rate

  • Subsystem sample time = model base rate
  • Timing analysis uses base rate for schedulability
  • Best for interrupts synchronized with main control loop
  • Example: ADC conversion complete after PWM trigger

Mode 2: Derived from Periodic Trigs

  • User specifies expected interrupt rate in TrigsPeriod
  • Allows timing analysis for asynchronous interrupts
  • Subsystem scheduled assuming periodic behavior
  • Example: UART receive (assume max message rate)

Mode 3: Hardware Timer-Based

  • Dedicated timer resource automatically allocated
  • Timer configured with selected prescaler
  • True periodic interrupt independent of Simulink rates
  • Example: Custom 1 kHz update loop

Examples

Programmatic Setup

% Add block to model
add_block('MCHP_Blockset/System Functions/Interrupt', [mdl '/ISR']);

% Configure key parameters
set_param([mdl '/ISR'], 'Interruption', 'ADC1 Interrupt');
set_param([mdl '/ISR'], 'IntPriority', '6');

Example 1: ADC Interrupt-Driven Current Loop

// PWM triggers ADC, ADC interrupt executes control loop

Simulink Model:
1. Add PWM_HS block with ADC trigger output
2. Add ADC block with interrupt enabled
3. Add Interrupt block
4. Configure interrupt block:
   Interruption: 'ADC1 - Conversion Complete'
   Triggered_Sub_TimeSource: 'is derived from model base rate'
   IntPriority: 7  (highest - critical for motor control)

5. Create triggered subsystem connected to interrupt block
6. Add current control algorithm inside subsystem

Result: Current loop executes synchronously with PWM/ADC

Example 2: UART Receive Interrupt

// Process received data asynchronously

Configuration:
   Interruption: 'UART1 - RX'
   Triggered_Sub_TimeSource: 'is derived from trigs; trigs must be periodic'
   TrigsPeriod: 1e-3  % 1 ms assumed for timing (actual rate is async)
   IntPriority: 3  (medium priority)
   StartupExecute: on  (initialize buffers)

Subsystem:
- Read UART data from peripheral block
- Parse protocol
- Update command registers

Example 3: Hardware Timer Periodic Interrupt

// Custom periodic task independent of base rate

Configuration:
   Interruption: 'User Timer1'  (created by peripheral block)
   Triggered_Sub_TimeSource: 'is derived from a hardware timer'
   TIMER_Resolution: 'Resol: 32us - MaxPer: 2.1s'  (prescaler 256)
   IntPriority: 5

Result:
- Dedicated timer allocated automatically
- Interrupt triggers at specified rate
- Independent of Simulink sample times

Example 4: QEI Position Overflow Event

// Extend encoder range with software counter

Configuration:
   Interruption: 'QEI1 - Position Counter Overflow'
   Triggered_Sub_TimeSource: 'is derived from model base rate'
   IntPriority: 6  (high - timing critical)

Subsystem Logic:
if (QEI_DIR == FORWARD)
    ExtendedPosition += 65536;
else
    ExtendedPosition -= 65536;
end

Troubleshooting

ProblemCauseSolution
Interrupt not listedPeripheral block not in model, or peripheral disabled the channel that would declare the entry (e.g. ADC channel without an assigned pin, CN port not enabled)Add the peripheral block, enable the relevant channel / feature. If the silicon has the vector but no peripheral block surfaces it, scroll past --- Chip Interrupt Vectors --- and pick it as a Class C Raw Chip Vector.
Subsystem never executes (Class A)Selected vector does not match the actual silicon channel servicing the event, or the peripheral block disabled the source (e.g. UART set to a mode that doesn’t own that vector)Verify in the source block (CN block, SPI/I2C sequence, Comparator, UART block, QEI block) that the driver actually generates an ISR for the picked vector and calls MCHP_CallUserISR for it. Class A subsystems run after the driver has serviced the event.
Subsystem never executes (Class B)Peripheral block did not enable the underlying source (e.g. ADC channel not assigned to a pin, no PWM event configured)Confirm in the peripheral block that the source emits an interrupt request. The Interrupt block already sets xxIE, xxIP, Config_BitSet, and clears xxIF โ€” the missing link is the peripheral being silent.
Subsystem never executes (Class C)The peripheral that drives the vector has not been initialised โ€” no MCHP block configures itInitialise the SFRs yourself (Reg Write block or custom S-Function), enable any sub-event flag the IVT database does not surface.
System hangs in ISR (Class C)A status / sub-event flag in addition to xxIF must be cleared, but the IVT database carries no RegisterReadClear for itAdd the appropriate register clear inside the triggered subsystem. The Interrupt block clears xxIF automatically; secondary flags are your responsibility.
Build error / linker collision when wiring an Interrupt block to an ADC channelYou picked the ADC channel that the ADC block uses to schedule the model base rate (the time-step trigger channel)Pick a different ADC channel, or pick the ADC trigger event from the PWM block instead of from the ADC channel.
Priority field grayed outThe selected entry is Class A โ€” Driver-Owned: priority is set by the declaring peripheral (CN block, SPI/I2C bus, Comparator, future UART)Edit priority in the peripheral block, not here.
Priority not workingArchitecture limitation or value out of rangeCheck device datasheet for valid priority range.
FPU corruption (PIC32)FPUNoSave enabled but FP ops in ISRDisable FPUNoSave or remove FP operations from ISR.
        Keep ISR execution time short - long ISRs can cause overload
        Higher priority ISRs can preempt lower priority - ensure reentrancy
        Hardware timer mode consumes one timer resource
        StartupExecute useful for initializing communication protocols