PRUSSv2 Interrupt Controller
The PRUSS Interrupt Controller sits on the SCR 32-bit bus that interconnects elements of the PRUSS. It also has a direct outgoing connection to the ARM Interrupt Controller, EDMA and TSC_ADC Event triggers, allowing interrupts to these units to be dispatched by various components of the PRUSS. The controller also has a direct incoming connection, allowing it to receive events from various SoC external peripherals.
Important Note: It is vital to clear all system interrupts before the PRUSS is halted, else the PRUSS will not power down.
Contents
Features
- A list of 64 possible interrupt events.
- 10 interrupt channels (Channel-0 to Channel-9), allowing for 10 separate active triggers, which may be triggered by one or more specified interrupts from the above list.
- If more than one interrupt arrives at the same time, those assigned to a lower channel number will be given priority. If more than one interrupt arrives at the same time on the same channel, again, the interrupt with the lowest interrupt number from the above table is given priority.
- 10 host channels (Host-0 to Host-9), allowing for one or more interrupt channels to be directed to up to 10 different locations, either within or outside of the PRUSS.
- The first two channels, Host-0 and Host-1, always directly point to Register R31 bit 30 and bit 31 respectively of the two PRU units, enabling PRUs to receive interrupts by checking these register bits.
- Other locations a host channel may point to will typically be local peripherals, external components such as the EDMA for triggering a DMA transfer and the ARM Interrupt Controller for interrupting an operating system, allowing for software intervention.
Enabling the Interrupt Controller
Instruction | Location Name | Location Number |
---|---|---|
1. Globally enable interrupts by setting the Global Enable Register (GER) to 1 | PRUSS_INTC + GER | 0x0002_0000 + 10h |
2. Set polarity of all incoming events through the System Interrupt Polarity Registers (SIPR0 and SIPR1) to Active High (set all bits to 1) | PRUSS_INTC + SIPR0
PRUSS_INTC + SIPR1 |
0x0002_0000 + D00h
0x0002_0000 + D04h |
3. Set the type of all incoming events through the System Interrupt Type Registers (SITR0 and SITR1) to 'pulse' (set all bits to 0) | PRUSS_INTC + SITR0
PRUSS_INTC + SITR1 |
0x0002_0000 + D80h
0x0002_0000 + D84h |
Although the Interrupt Controller supports settings for individual interrupt polarities and types, in the AM335X (BeagleBone) processor, these settings are ALWAYS Active High and Pulsed and as such can be configured as part of the global set-up as opposed to configuration for individual interrupts.
Configuring and enabling an Interrupt
Instruction | Location Name | Location Number |
---|---|---|
1. Map the chosen system event to an interrupt channel by inserting the channel number into the appropriate Channel Map Register (CMR0::15 - each register represents 4 system interrupts) | PRUSS_INTC + CMR0 ...
PRUSS_INTC + CMR15 |
0x0002_0000 + 400h ...
0x0002_0000 + 43Ch |
2. Map the configured interrupt channel to the chosen host channel by inserting the host channel number into the appropriate Host Map Register (HMR0::2 - each register represents 4 interrupt channels)
It is recommend to assign interrupt channel X to host channel X (Interrupt Channel 1 -> Host Channel 1 etc.) |
PRUSS_INTC + HMR0 ...
PRUSS_INTC + HMR2 |
0x0002_0000 + 800h ...
0x0002_0000 + 808h |
3. Clear the system interrupt's status by setting the appropriate bit in the System Interrupt Status Register to 1 (SECR0::1 - each register represents 32 interrupts) | PRUSS_INTC + SECR0
PRUSS_INTC + SECR1 |
0x0002_0000 + 280h
0x0002_0000 + 284h |
4. Enable the individual host channel by writing the host channel number to the Host Interrupt Enable Indexed Set Register (HIEISR)
Individual interrupts can be disabled by following the above step but by instead writing to the Host Interrupt Enable Indexed Clear Register (HIDISR) |
PRUSS_INTC + HIEISR | 0x0002_0000 + 34h |
5. Enable the individual system interrupt (system event) by writing the interrupt number to the System Interrupt Enable Indexed Set Register (EISR)
Individual system interrupts can be disabled by following the above step but by instead writing to the System Interrupt Enable Indexed Clear Register (EICR) |
PRUSS_INTC + EISR | 0x0002_0000 + 28h |
Servicing (clearing) an Interrupt
Instruction | Location Name | Location Number |
---|---|---|
1a. Clear the interrupt's status by setting the bit at the location of the interrupt number in the System Interrupt Status Enabled/Clear Register (SECR0::1 - for example, to clear Interrupt 12, write 1 to bit 12 in SECR0). | PRUSS_INTC + SECR0
PRUSS_INTC + SECR1 |
0x0002_0000 + 280h
0x0002_0000 + 284h |
1b. Alternatively, clear the interrupt's status by writing the interrupt number to the System Interrupt Status Enabled Indexed Clear Register (EICR). | PRUSS_INTC + EICR | 0x0002_0000 + 2Ch |
Once an interrupt has been acted upon it should always be cleared to ensure the correct receipt of future interrupts.
Interrupt Nesting
Interrupt nesting allows various priorities of interrupts to be disabled when an interrupt event, with nesting configured, is received. Disabled interrupts are then re-enabled by the user writing to the ISR register.
There are three types of supported nesting:
- Nesting of all host channels of the same or lower priority when an interrupt event is received
- The nesting level can be set by placing the channel number in the Global Nesting Level Register (GNLR).
- Nesting of an individual host channel, the individual host may not be interrupted by interrupt events on interrupt channels of the same or lower priority
- The nesting level can be set individually by placing the channel number in the Host Interrupt Nesting Level Registers (HINLR0::1)
- Software nesting, whereby the software disables all host channels on receipt of an interrupt, proceeded by enabling/disabling individual host channels and finally re-enabling all host channels, allowing only those manually enabled to continue processing interrupts. The changes are reversed once the interrupt request has been serviced by the software.
- Requires the most CPU intervention and should be avoided if either of the first two nesting solutions are applicable.