about the PIC32 Pascal Compilers handling of interrupts in the multivector mode. I set up Input Capture modules 1 and 3 for detecting rising edge of pulse inputs to both.
In this example, I set the multivector interrupt ics to ICS_OFF which according to the compiler HELP
should mean no context saving as shown below.
ics Interrupt Context Saving; Interrupt Context Saving can be performed in several ways :
ICS_SOFT - Context saving is carried out by the software.
ICS_SRS - Shadow Register set is use for context saving.
ICS_OFF - No context saving
ICS_AUTO - Compiler chooses whether the ICS_SOFT or ICS_SRS will be used.
and also then I also insert the command "disablecontextsaving" (which also indicates no context is saved).
I had expected those two actions would preclude a return from the Interrupt Handler to the Main loop. However, the code pointer did return to the main loop. How? I wondered. See remark after code listing.
These two actions resulted in the following code listing for IC1 and IC3 input capture modules. Note that there is no prologue or Epilogue code with context saving disabled (which is what one would expect with context saving disabled)
So this is sort of the base line.
Code: Select all
//R30 is a temporary Register used to temporarily hold data
//R0 is always zero - hardware enforced
//R2 is used for function return values from Co
//R23 Saved Temporally - caller must preserve value
//R24 Temporary - caller does not need to preserve contents
...
... //Input Capture Modules IHR code listing
_IC3:
;IC1_IC3_Test.mpas, 18 :: begin
;IC1_IC3_Test.mpas, 20 :: PORTBset := 0x00002000; //Turn on LED
// Following code sets bit 13 in register PORTBclr to turn on LED
0x9D000020 0x34022000 ORI R2, R0, 8192 // ORI Logical OR Immediate Rt = Rs | Immed 8192 (... 00100000 00000000) set bit 13 and put in R2
0x9D000024 0x3C1EBF88 LUI R30, 49032 //LUI Load Upper Immediate Rt = immediate << 16 49032 (... 10111111 10001000)
0x9D000028 0xAFC26058 SW R2, 24664(R30) // SW Store Word Mem[Rs+offset] = Rt
// Following code clears IFS0.IC3IF flag using IFS0clr and bit 13 in R0
;IC1_IC3_Test.mpas, 22 :: IFS0.IC3IF := 0; //clears interrupt flag (bit 13) at mem addr BF88xxxx +
0x9D00002C 0x34022000 ORI R2, R0, 8192 //set bit 13 in R2
0x9D000030 0x3C1EBF88 LUI R30, 49032 //put mem addr BF88 in R30 and **** to upper region of R30
0x9D000034 0xAFC21034 SW R2, 4148(R30)//Mem addr offset 1030 points to IFS0clr register and + 4 points to bit four, IFS0.IC1IF
;IC1_IC3_Test.mpas, 24 :: end;
L_end_IC3:
0x9D000038 0x42000018 ERET // Clear EXL bit(Enables Interrupts), restores Program Counter and
//reverts the current shadow set to the previous one
; end of _IC3
_IC1:
;IC1_IC3_Test.mpas, 8 :: begin
;IC1_IC3_Test.mpas, 10 :: PORTBSet := 0x00002000; //Turn on LED PORTB.RB13
0x9D00003C 0x34022000 ORI R2, R0, 8192
0x9D000040 0x3C1EBF88 LUI R30, 49032
0x9D000044 0xAFC26058 SW R2, 24664(R30)
;IC1_IC3_Test.mpas, 12 :: IFS0.IC1IF := 0; //Clear Flag
0x9D000048 0x34020020 ORI R2, R0, 32
0x9D00004C 0x3C1EBF88 LUI R30, 49032
0x9D000050 0xAFC21034 SW R2, 4148(R30)
;IC1_IC3_Test.mpas, 14 :: end;
L_end_IC1:
0x9D000054 0x42000018 ERET // Clear EXL bit(Enables Interrupts), restores Program Counter and
//reverts the current shadow set to the previous one
; end of _IC1
I then found generated by the compiler at the end of each interrupts code listing the instruction
"ERET" This instruction appears to do several things
1. It Clears the EXL bit(Which globally Enables Interrupts) in the CP0processor Status Register
2. Restores Program Counter (still not certain when the counter is saved but apparently before going into the IRH code)
3. Reverts the current shadow set to the previous one.
So this command appears to be adequate on its own to ensure return from the interrupt handler code, provided the interrupt condition is removed and the module's interrupt flag is cleared in the IHR. IF the flag is not cleared then it appears that the pointer remains pointing to the IRH and no return occurs.
Another item of interest is that whether or not the Input Capture Module has been interrupted enable, if it is turned on and the interrupt condition is met, then the interrupt flag is set. If the module also has its interrupt enabled, then in addition to turning the flag on, an IRQ (interrupt Request) is sent by the module to the Interrupt Controller.
The interrupt controller then checks various registers such as the Status and Cause registers (for such things as interrupt priority and source) of the CP0processor to
determine whether to instruct the main CPU to service the interrupt request.
I will report on results when I next turn context saving back on and generate code from the same source code.