mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-25 06:37:35 -04:00
[docs] update XIRQ chapter
This commit is contained in:
parent
29711067e6
commit
e190ebefe2
1 changed files with 18 additions and 30 deletions
|
@ -28,22 +28,17 @@ The XIRQ provides up to 32 external interrupt channels configured via the `XIRQ_
|
||||||
`xirq_i` input signal vector represents one interrupt channel. If less than 32 channels are configured, only the
|
`xirq_i` input signal vector represents one interrupt channel. If less than 32 channels are configured, only the
|
||||||
LSB-aligned channels are used while the remaining ones are left unconnected internally.
|
LSB-aligned channels are used while the remaining ones are left unconnected internally.
|
||||||
|
|
||||||
The external interrupt controller features five interface registers:
|
The external interrupt controller features four interface registers:
|
||||||
|
|
||||||
[start=1]
|
[start=1]
|
||||||
. external interrupt channel enable (`EIE`)
|
. external interrupt channel enable (`EIE`)
|
||||||
. external interrupt channel pending (`EIP`)
|
|
||||||
. external interrupt source (`ESC`)
|
. external interrupt source (`ESC`)
|
||||||
. trigger type configuration (`TTYP`)
|
. trigger type configuration (`TTYP`)
|
||||||
. trigger polarity configuration (`TPOL`)
|
. trigger polarity configuration (`TPOL`)
|
||||||
|
|
||||||
[TIP]
|
|
||||||
From a functional point of view, the `EIE`, `EIP` and `ESC` registers follow the behavior
|
|
||||||
of the RISC-V <<_mie>>, <<_mip>> and <<_mcause>> CSRs.
|
|
||||||
|
|
||||||
The actual interrupt trigger type can be configured individually for each channel using the `TTYP` and `TPOL`
|
The actual interrupt trigger type can be configured individually for each channel using the `TTYP` and `TPOL`
|
||||||
registers. `TTYP` defines the actual trigger type (level-triggered or edge-triggered), while `TPOL` defines
|
registers. `TTYP` defines the actual trigger type (level-triggered or edge-triggered), while `TPOL` defines
|
||||||
the trigger's polarity (low-level/falling-edge or high-level_/rising-edge). The position of each bit in these
|
the trigger's polarity (low-level/falling-edge or high-level/rising-edge). The position of each bit in these
|
||||||
registers corresponds the according XIRQ channel.
|
registers corresponds the according XIRQ channel.
|
||||||
|
|
||||||
.XIRQ Trigger Configuration
|
.XIRQ Trigger Configuration
|
||||||
|
@ -57,24 +52,19 @@ registers corresponds the according XIRQ channel.
|
||||||
| `1` | `1` | rising-edge
|
| `1` | `1` | rising-edge
|
||||||
|=======================
|
|=======================
|
||||||
|
|
||||||
When the configured trigger of an interrupt channel fires the according interrupt channel becomes _pending_
|
Each interrupt channel can be enabled or disabled individually using the `EIE` register. If the trigger of a
|
||||||
which is indicated by the according channel bit being set in the `EIP` register. This pending interrupt can
|
disabled channel fires the interrupt request is entirely ignored.
|
||||||
be manually cleared at any time by writing zero to the according `EIP` bit.
|
|
||||||
|
|
||||||
A pending interrupt can only generate a CPU interrupt if the according channel is enabled by the `EIE`
|
If the configured trigger of an _enabled_ channels fires, the according interrupt request is buffered internally
|
||||||
register. Once triggered, disabled channels that **were already triggered** remain pending until explicitly
|
and an interrupt request is sent to the CPU. If more than one trigger fires at one a prioritization is used:
|
||||||
(= manually) cleared. The channels are prioritized in a static order, i.e. channel 0 (`xirq_i(0)`) has the
|
the channels are prioritized in a static order, i.e. channel 0 (`xirq_i(0)`) has the highest priority and channel
|
||||||
highest priority and channel 31 (`xirq_i(31)`) has the lowest priority. If **any** pending interrupt channel is
|
31 (`xirq_i(31)`) has the lowest priority.
|
||||||
also enabled, an interrupt request is sent to the CPU.
|
|
||||||
|
|
||||||
The CPU can determine the most prioritized external interrupt request either by checking the bits in the `EIP`
|
The CPU can determine the most prioritized external interrupt request by reading the interrupt source register `ESC`.
|
||||||
register or by reading the interrupt source register `ESC`. This register provides a 5-bit wide ID (0..31)
|
This register provides a 5-bit wide ID (0..31) identifying the currently firing external interrupt source channel as
|
||||||
identifying the currently firing external interrupt source channel. Writing _any_ value to this register will
|
well as a single bit (the MSB) that
|
||||||
acknowledge and clear the _current_ CPU interrupt (so the XIRQ controller can issue a new CPU interrupt).
|
Writing _any_ value to this register will acknowledge and clear the _current_ CPU interrupt (so the XIRQ controller
|
||||||
|
can issue a new CPU interrupt).
|
||||||
In order to acknowledge an XIRQ interrupt, the interrupt handler has to...
|
|
||||||
* clear the pending XIRQ channel by clearing the according `EIP` bit
|
|
||||||
* writing _any_ value to `ESC` to acknowledge the XIRQ CPU interrupt
|
|
||||||
|
|
||||||
|
|
||||||
**Register Map**
|
**Register Map**
|
||||||
|
@ -85,11 +75,9 @@ In order to acknowledge an XIRQ interrupt, the interrupt handler has to...
|
||||||
|=======================
|
|=======================
|
||||||
| Address | Name [C] | Bit(s) | R/W | Description
|
| Address | Name [C] | Bit(s) | R/W | Description
|
||||||
| `0xfffff300` | `EIE` | `31:0` | r/w | External interrupt enable register (one bit per channel, LSB-aligned)
|
| `0xfffff300` | `EIE` | `31:0` | r/w | External interrupt enable register (one bit per channel, LSB-aligned)
|
||||||
| `0xfffff304` | `EIP` | `31:0` | r/w | External interrupt pending register (one bit per channel, LSB-aligned); writing 0 to a bit clears the according pending interrupt
|
.3+^| `0xfffff304` .3+<| `ESC` ^| `31` ^| r/c <| XIRQ interrupt when set; write any value to this register to acknowledge the current XIRQ interrupt
|
||||||
| `0xfffff308` | `ESC` | `4:0` | r/w | Interrupt source ID (0..31) of firing IRQ (prioritized!); writing _any_ value will acknowledge the current XIRQ CPU interrupt
|
^| `30:5` ^| r/- <| _reserved_, read as zero
|
||||||
| `0xfffff30c` | `TTYP` | `31:0` | r/w | Trigger type select (`0` = level trigger, `1` = edge trigger); each bit corresponds to the according channel number
|
^| `4:0` ^| r/c <| Interrupt source ID (0..31) of firing IRQ (prioritized!)
|
||||||
| `0xfffff310` | `TPOL` | `31:0` | r/w | Trigger polarity select (`0` = low-level/falling-edge, `1` = high-level/rising-edge); each bit corresponds to the according channel number
|
| `0xfffff308` | `TTYP` | `31:0` | r/w | Trigger type select (`0` = level trigger, `1` = edge trigger); each bit corresponds to the according channel number
|
||||||
| `0xfffff314` | - | `31:0` | r/- | _reserved_, read as zero
|
| `0xfffff30c` | `TPOL` | `31:0` | r/w | Trigger polarity select (`0` = low-level/falling-edge, `1` = high-level/rising-edge); each bit corresponds to the according channel number
|
||||||
| `0xfffff318` | - | `31:0` | r/- | _reserved_, read as zero
|
|
||||||
| `0xfffff31c` | - | `31:0` | r/- | _reserved_, read as zero
|
|
||||||
|=======================
|
|=======================
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue