[Introduction]
The basic operations of interrupt servicing are broadly carried out by 4 parts.
The first part is the part that
generates the interrupt source,
the second part is
the interrupt request flag,
the third part is
the interrupt controller that controls the interrupt,
and the fourth part is
the CPU that actually executes the interrupt servicing.
An interrupt is serviced via these 4 parts.
[Interrupt source generator]
Parts that generate interrupt sources include the timer block, serial block, and external signal edge detector
(these parts differ depending on the device).
Once an interrupt generation condition, such as a timer match or completion of serial data reception, has been met,
the corresponding interrupt request flag is set in these parts.
](int_1st.gif)
The first stage of interrupt servicing involves the satisfaction of a specified condition in each peripheral function block.
When a condition such as a match with a compare register in the timer block, completion of communication in the serial block,
or detection of an edge via an external interrupt is satisfied, the corresponding interrupt request flag is set.
Interrupt request flags can also be set by program.
When an interrupt source is used as a DMA start source, a request flag other than the interrupt request flags described above is used.
During a DMA transfer, these interrupt request flags are set (to 1), so interrupts should be masked to prevent unnecessary interrupt servicing.
|
|
[Interrupt request flag]
In this way, each interrupt source simply sets the corresponding interrupt request flag; the interrupt source generator
and interrupt controller operate independently.
The interrupt request flag is what connects these two parts.
Note that there is only one interrupt request flag (1 bit) for each interrupt source.
Therefore, even if the same interrupt request occurs more than once before the interrupt is acknowledged,
it will only be recognized as having occurred once.
Interrupt request flags can also be set and cleared by program.
When using this function, all UART transmission processing, including transmission of the first data,
can be executed via interrupts.
In this case, however, be sure to set the relevant interrupt request flag using a single bit manipulation instruction.
Example of UART transmission processing
When transmitting multiple bytes of data, the main program usually writes the first byte of the output data to UART,
and at the same time, information on the second and subsequent bytes of data is passed to the interrupt servicing program.
The interrupt servicing program then writes the second and subsequent bytes of data to UART based on the information passed
from the main program.
The processing therefore differs between the first and subsequent bytes of data.
](int_uart1.gif)
The main program passes information on the transmit data to the interrupt servicing program and the interrupt request flag is set.
All of the processing to actually write data to UART is carried out by the interrupt servicing program, so the entire processing flow is more visible.
](int_uart2.gif)
|
|
< Interrupt controller >
Operations subsequent to the interrupt request flag are executed by the interrupt controller.
Whether to enable (not mask) or disable (mask) an interrupt request flag is determined by the interrupt controller according
to the setting of the interrupt mask register.
An interrupt request flag that has been set to disabled is ignored in all subsequent operations.
However, because the request flag itself is not cleared, once the mask is cancelled,
the interrupt request becomes enabled again from that point.
In particular, when the interrupt is used as a DMA start trigger,
it is necessary to clear the interrupt request flag (to 0) after the DMA operation is completed.
Unmasked interrupt requests are sent to the standby controller and are used for releasing standby.
Interrupt requests are also sent to the CPU via the interrupt priority circuit.
When the CPU receives an interrupt, the corresponding interrupt request flag is cleared.
If the CPU is in the interrupt-disabled state, the received interrupt is simply used to release standby
(if the system is not in the standby state, the interrupt is simply held pending).
If the CPU is in the interrupt-enabled state, interrupt servicing is executed after standby is released
and control branches to the corresponding handler address.
](int_flag.gif)
Interrupt request flags can be used in the following three ways.
- They can be polled (read out) by the program to check whether the processing that prompted the interrupt request is completed.
In this case, set the interrupt mask to ensure the interrupt is not sent to the CPU.
After confirming that an interrupt mask has been set,
the interrupt request flag must be cleared by separate processing.
- They can be used to release standby.
If an unmasked interrupt request flag is set in the standby state, standby is released.
At this time, if the CPU is in the interrupt-disabled state, vector interrupt servicing is not performed after standby is released, and execution resumes after the standby instruction.
The interrupt request flag must be cleared by separate processing since it is not cleared automatically.
- They can be used as vector interrupt requests to be sent to the CPU.
In this case, the status of other interrupt request flags and the interrupt currently being executed by the CPU is checked by the interrupt priority circuit,
and the interrupt request with the highest priority is sent to the CPU.
In this event, it is not necessary to clear the interrupt request flag by program, since it is automatically cleared after the CPU acknowledges
the interrupt and control is branched to the handler.
|
|
The interrupt priority circuit compares the priority level of interrupt requests generated at the same time,
as well as the priority of the interrupt currently being serviced.
This is why the status of the interrupt currently being processed by the CPU is stored to the ISPR register.
Once this interrupt servicing is completed and a RETI instruction is executed, the bit in the ISPR register that corresponds to the interrupt with
the highest priority is cleared (to 0) and the current interrupt processing is completed.
Note that the ISPR register cannot be written by program.
In V850/S products, the operation of the interrupt priority circuit is stopped when the CPU is in the interrupt-enabled state.
Consequently, even when the CPU status is switched from the interrupt-disabled state to the interrupt-enabled state, interrupt signals are not issued to the CPU immediately.
Interrupt request signals are not issued to the CPU until the priority comparisons have been completed.
Therefore, any interrupts cannot be acknowledged if the interrupt-enabled period is 7 clock cycles or shorter.
Caution
Bits that control the interrupt priority levels and interrupt masks are assigned to the same registers as the interrupt request flags.
Therefore, if bit manipulation instructions are not used to control the manipulation of interrupt masks,
interrupt request flags that have been set may be cleared by such mask manipulations.
Similar caution must be taken when manipulating interrupt priority levels.
Refer to the following FAQ item for further discussion of this issue:
Interrupts and manipulation of the interrupt control register [All V850]
< CPU >
If the CPU is in the interrupt-enabled state, it acknowledges the interrupt with the highest priority (as
determined by the interrupt priority circuit), saves the PC and PSW values to the EIPC and EIPSW registers
respectively, and the control branches to the interrupt handler. At this time (when the corresponding
interrupt request flag is cleared), the CPU enters the interrupt-disabled state.
Since there is only one set of EIPC and EIPSW registers, when using multiple interrupts, the contents of these
registers must be saved (such as to a stack) before enabling interrupts. Before recovery from interrupt
servicing, acknowledgment of multiple interrupts must be prohibited and the EIPC and EIPSW values that were
saved (to a stack, etc.) must be restored.
Note that the timing at which the CPU acknowledges an interrupt and branches to the interrupt handler differs
depending on the execution state, so it is not always the same.
This timing varies greatly if an instruction that holds an interrupt pending is executed, or if there is a
period in which interrupts are disabled.
Consequently, if detailed timing is an issue, you should use hardware functions such as the timer output
function or real-time output function instead of interrupt servicing.
Once interrupt servicing is completed, the program returns to the original processing via the RETI instruction.
At this time, the PSW value that has been saved to the EIPSW register (original value before interrupt acknowledgment)
is written back to the PSW, so there is no need to execute the EI instruction immediately before executing the RETI instruction.