Summary
PIC32MZ Interrupt and Exception system configuration and status are managed through two sets of registers; one in the Interrupt Controller and the other in the CPU's Coprocessor0 (CP0) register set.
To avoid confusion, the PIC32MZ family documentation provides a typographic distinction for these registers:
- Interrupt Controller register names are signified by upper-case letters only (i.e. INTSTAT, INTCON).
- CP0 register names are signified by upper and lower-case letters (i.e. IntCtl, Ebase).
When taken, exception hardware preserves certain CPU states in the CP0 and Interrupt Controller registers, based on the exception type. See Chapter 6 - "MIPS® Architecture for Programmers Volume III: The MIPS32® and microMIPS32® Privileged Resource Architecture", Revision 6.02 for more details.
"PIC32MZ Exception Control Registers" covers key exception-related registers and associated control/status bits. Please review the following documentation for complete register and bit-field definitions:
Key CP0 Exception Registers
EPC Register
The Exception (Restart) Program Counter (EPC) (CP0 register 14, select 0) is a read/write register that contains the address at which processing resumes after a general exception (StatusEXL = 1) has been serviced. All bits of the EPC register are significant and are writable.
For synchronous (precise) exceptions, the EPC contains one of the following:
- The virtual address of the instruction that was the direct cause of the exception.
- The virtual address of the immediately preceding BRANCH or JUMP instruction, when the exception causing instruction is in a branch delay slot and the Branch Delay bit in the Cause register (CauseBD) is set.
Precise Exceptions:
A precise exception is one in which the EPC (CP0, register 14, select 0) can be used to identify the instruction that caused the exception. For imprecise exceptions, the instruction that caused the exception cannot be identified. Most exceptions are precise. Bus error exceptions may be imprecise.
ErrorEPC Register
The Error Exception Program Counter (ErrorEPC) (CP0 register 30, select 0) is a read/write register, similar to the EPC register, except that ErrorEPC is used on "error" exceptions (reset, soft reset, and Non-Maskable Interrupt (NMI) exceptions, where StatusERL = 1).
The ErrorEPC register contains the virtual address at which instruction processing can resume after servicing these error exception types.
Status Register
The read/write Status register (CP0 register 12, select 0) contains the operating mode, interrupt enabling, and the diagnostic states of the processor. The bits of this register combine to create operating modes for the processor.
Interrupt Enable:
Interrupt exceptions are enabled when all of the following conditions are true:
- StatusIE = 1
- StatusERL = 0
- StatusEXL = 0
- DebugDM = 0
If these conditions are met, the settings of the StatusIPL bits are enabled and functional.
Operating Modes:
If the DebugDM bit is 1, the processor is in Debug mode; otherwise, the processor is in either Kernel mode or User mode. The CP0 Status register bit settings shown below determine User or Kernel mode:
- User mode (requires all of the following bits and values):
- StatusUM = 1
- StatusEXL = 0
- StatusERL = 0
- Kernel mode (requires one or more of the following bit values):
- StatusUM = 0
- StatusEXL = 1
- StatusERL = 1
StatusEXL:
Exception Level: Set by the processor when any exception other than Reset, Soft Reset, NMI, or Cache Error exception is taken.
- StatusEXL = 0: Normal level
- StatusEXL = 1: Exception level; when EXL is set
- The processor is running in Kernel mode
- Hardware and Software Interrupts are disabled
- EPC, BD, and SRSCtl will not be updated if another exception is taken
Note: StatusEXL must be cleared by the exception handler in order to re-enable interrupts. MIPS CPUs have an instruction, eret, that both clears StatusEXL and returns control to the address stored in the EPC register.
StatusERL:
Error Level: Set by the processor when a Reset, Soft Reset, NMI, or Cache Error exception is taken.
- StatusERL = 0: Normal level
- StatusERL = 1: Error level; when ERL is set
- The processor is running in Kernel mode
- Hardware and Software Interrupts are disabled
- eret instruction will use return address held in ErrorEPC instead of EPC
Note: MPLAB® XC32 start-up code clears StatusERL.
StatusIPL<7:0>:
CPU Interrupt Priority Level (IPL):
This field is the encoded value of the current IPL. An interrupt will be signaled only if the requested IPL (provided by the interrupt controller) is greater than the current priority indicated by these bits.
StatusBEV:
MIPS32 architectures provide a Bootstrap mode (referred to as Boot-Exception Vector (BEV) mode) whereby exception entry points are reallocated into the uncached, start-up-safe KSEG1 region.
Bootstrap mode is controlled by the CP0 Status register flag StatusBEV.
- StatusBEV = 1: Exceptions vector to an uncached entry point in KSEG1: 0xBFC00xxx
- StatusBEV = 0: Exceptions vector to cached entry points in KSEG0: defined by CP0 Ebase register, plus some offset.
Note: StatusBEV = 1 at reset.
Cause Register
The Cause register (CP0 register 13, select 0) primarily describes the cause of the most recent exception. In addition, bits also control software interrupt requests and the vector through which interrupts are dispatched.
CauseEXCCODE<4:0>:
Exception Code Bits:
Indicates what kind of exception happened. Used by the _general_exception_handler() to determine the cause of the exception and branch to the appropriate handler code.
Note: On PIC32MZ, Interrupt Exceptions all have their own dedicated entry point, and therefore, their handlers do not need to need to consult CauseEXCCODE.
CauseBD:
Branch Delay Bit:
Indicates whether the last exception taken occurred in a branch delay slot:
- CauseBD = 0: Not in delay slot
- CauseBD = 1: In delay slot
The processor updates BD only if the EXL bit (StatusEXL) was 0 when the exception occurred.
Ebase Register
The Ebase register (CP0 register 15, select 1) is a read/write register containing the base address of the exception vectors used when StatusBEV=0.
The "PIC32MZ Exception Entry Points" covers PIC32MZ exception entry points and highlights the usage of the Ebase register.
IntCtl Register
The IntCtl register (CP0 register 12, select 1) controls the interrupt vector spacing of the PIC32 architecture.
IntCtlVS<4:0>:
These bits specify the spacing between each interrupt vector for CPUs supporting Computed Interrupt Vector Offsets (PIC32MX/MIPS M4K).
For CPUs supporting Variable Interrupt Vector Offset (PIC32MZ / MIPS microAptiv™ or M5150 MPU cores), these bits are not used (OFFx registers are used as described here).
Interrupt Controller Registers
INTCON Register
Interrupt exceptions on PIC32MZ can either all vector to a single handler, or to a unique handler for each interrupt.
The Interrupt Control (INTCON) register is used primarily to configure the Interrupt Controller Vector mode.
INTCONMVEC:
Multi-Vector Configuration Bit:
Indicates whether the last exception taken occurred in a branch delay slot:
- INTCONMVEC = 0: Interrupt controller configured for Single Vectored mode
- INTCONMVEC = 1: Interrupt controller configured for Multi-Vectored mode
This register has an associated clear, set, and invert register at an offset of 0x4, 0x8, and 0xC bytes, respectively. These registers have the same name with CLR, SET, or INV appended to the end of the register name (e.g., INTCONCLR). Writing a 1 to any bit position in these registers will clear/set/invert valid bits in the associated register.
IFSx Register
The Interrupt Flag Status (IFSx) registers indicate the current interrupt status for all of the peripheral/external interrupt sources.
For example, on PIC32MZ, Timer 1 has a period register (PR1) that, when properly initialized, will periodically trigger a Timer 1 interrupt signal on IFS0 as shown:
Firmware in the Interrupt Service Routine (ISR) must acknowledge the interrupt by clearing the associated IFSx flag.
Refer to the “Interrupt Controller” chapter in the specific device datasheet to learn exact bit definitions.
There are two types of interrupts found in PIC32 devices: persistent and non-persistent.
Persistent interrupts will remain active and the associated interrupt flag set until the issue causing the interrupt is serviced. An example would be an interrupt declaring data in a Universal Asynchronous Receiver Transmitter (UART) receive buffer. Until this data is read, the interrupt flag will remain set even if the flag is cleared in software.
ISRs for persistent interrupts should clear the interrupt flag after removing the condition that caused the interrupt to ensure that the interrupt flag actually clears.
Refer to the device datasheet for details on which peripheral interrupts are persistent/non-persistent.
IECx Register
The Interrupt Enable Control (IECx) register control bits are used to individually enable/disable peripheral interrupt requests (IFSx signals) from triggering interrupts.
Refer to the “Interrupt Controller” chapter in the specific device datasheet to learn exact bit definitions.
IPCx Register
The Interrupt Priority Control (IPCx) register control bits are used to individually control peripheral interrupt priority and sub-priority settings.
Refer to the “Interrupt Controller” chapter in the specific device datasheet to learn exact bit definitions.
OFFx Register
The Interrupt Vector Address Offset (OFFx) register is used to establish the entry point for interrupt exceptions on PIC32MZ.
MPLAB XC32 Compiler calculates & initializes the values of OFFx for each defined application interrupt service routine (see table 7.2 in the PIC32MZ datasheet for a listing of OFFx registers for each interrupt source).
Example (Timer 4):
Exception Base (Ebase) is 0x9D000000 (initialized by the C-Run-time startup)
Vector Offset register (OFF019) is 0x200 (initialized by the C-Run-time startup)
Vector Address (Timer 4) = 0x9D000000 + 0x200 = 0x9D000200
Assigning the Shadow Register Set
PRISS Register
PIC32MZ implements seven shadow register sets, enabling low latency to interrupt context save/restore.
The Priority Shadow Select (PRISS) register is used to associate a shadow register set (0-7) with a user-CPU-priority level (0-7).
PRISSPRIxSS<3:0>:
Interrupt Priority "x" Shadow Register Set:
Associate a shadow register set (0-7) to interrupt priority "x":
- PRISSPRIxSS<3:0> = 0x0000: Interrupt with a priority level of "x" uses Shadow Set 0
- PRISSPRIxSS<3:0> = 0x0001: Interrupt with a priority level of "x" uses Shadow Set 1
- PRISSPRIxSS<3:0> = 0x0010: Interrupt with a priority level of "x" uses Shadow Set 2
Note: These bits are ignored in Single Vector mode (INTCONMVEC = 0).
To assign a shadow register set while in Single Vector mode, set PRISSSS0 = 1.
If you configure an ISR to use a shadow register set, be sure to initialize PRISS accordingly.
The following example defines a Timer 5 ISR as a priority level 2 interrupt that uses a shadow register set.
Note: On Line 21, the PRISSPRI2SS bitfield is initialized accordingly to associate a specific shadow register set (#2 in this example) to priority level 2 interrupts.
On PIC32MZ devices, there are seven shadow register sets, so each priority level can be assigned a shadow register set to use via the PRIxSS<3:0> bits in the PRISS register, e.g. Line 10 as shown below.
Which Registers Are Relevant And When?
The "PIC32MZ Exception Operation" covers the PIC32MZ exception operation, highlighting which registers are relevant and when they are used in exception processing.
Table of Contents
|