PIC 32 Test for Return from Interrupt Handler

Beta Testing discussion on mikroPascal PRO for PIC32.
Post Reply
Author
Message
Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

PIC 32 Test for Return from Interrupt Handler

#1 Post by Rotary_Ed » 26 Aug 2013 23:14

I have been wrestling with trying to understand and use the External Interrupt Module concept in the PIC32. I have a fair amount of experience with interrupts in the PIC18F world, but new to the PIC32.

What I really need at the moment- is some simple foolproof method of determining whether the pointer returns from the interrupt handler code to the main loop. I am having problems when two similar modules (Input capture in this case) both have an identical pulse train (in time) on there input pin - the problem is the pointer never seems to return to the main code.

The means I have come up with to show whether the pointer has returned to the main loop is shown in the code below. Basically a loop that alternately enables and disables the two input capture modules (IC1 and IC3). The interrupt handler code for both of these turn on an LED whereas the main loop turns it off (if there is a return of the pointer from the IRH). IF my concept is valid the LED should blink as the pointer alternates between the IRH code and the main loop.

It does this (LED blinks), but only when one module is active. IF two are active (with pulse train on both input pin) then the LED simply stays on and never blinks.

So these leads me to conclude either that:
1. The pointer never returns to the main loop and therefore the LED never goes off
2. My approach is flawed and does not convey accurately whether the pointer has returned or not.

Naturally, if my "test" of the pointer returning to the main loop is flawed then all of my conclusions drawn from my experimenting are flawed.

my main loop

Code: Select all

 

var Empty_buf:dword;
...
...
EnableInterrupts() //Globally enable interrupts (EI) 
   repeat      //Main Loop 
       delay_MS(100); 
       //Enable IC modules for interrupt and turn on LED in IRH code when interrupt occurs 
       IEC0.IC1IE := 1; //Enable Interrupt 
       IFS0.IC1IF := 0; //clear any spurious Flag 
      
       IEC0.IC3IE := 1; //Enable Interrupt 
       IFS0.IC3IF := 0; //clear any spurious Flag 

       Delay_MS(100);    //Leave LED on for a time 

 //Now if pointer returns from IRH to Main loop then code disables further Interrupts until the LED     turns off 
       //This turns off the LED, otherwise the pointer stays hung in the IRH with repeated interrupts 
       //NOTE: To check this code, IF interrupt flag is not cleared in IRH code, the pointer never returns 
       //to this main loop.  Otherwise, if it does return, it causes LED to blink 

       IEC0.IC1IE := 0; //Disable Interrupt 
       Empty_buf  := IC1buf; //clear cause of Persistent Interrupt 
       IFS0.IC1IF := 0; // clear flag 
       IEC0.IC3IE := 0; //Disable Interrupt 
       Empty_buf  := IC3buf; //clear cause of Persistent Interrupt 
       IFS0.IC3IF := 0; // clear flag 
       PORTBclr := 0x00002000;    // LED Should blink if pointer returns from IRH otherwise 
                               //if it does not then the pointer never returns from IRH 
       //Repeat loop by Re-Enabling Interrupts 
       
   until 1 = 2; 
 


I thought of simpler means such as simple loop with or without a delay, but decided that it might be alternating too fast for my eyeball to see it - or the delay may well get shortened by having an interrupt occur while it was delaying. So I ended up with the above.

Repeat
PORTB.RB13 := 0; //Turn OFF LED
Delay_MS(200);
until 1 = 2;

So if anyone has a fool proof (and simple) method for testing whether the pointer has return to the main loop, I would appreciate it greatly if you would share it.

Thanks
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: PIC 32 Test for Return from Interrupt Handler

#2 Post by filip » 03 Sep 2013 15:36

Hi,

If I'm correct, you have found a solution for this issue ?

Regards,
Filip.

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Re: PIC 32 Test for Return from Interrupt Handler

#3 Post by Rotary_Ed » 03 Sep 2013 16:45

Hi Filip

Yes, thanks for checking.

After a couple of weeks of tearing my hair out, research more than I ever wanted about the MIPS M4K PIC 32 interrupt handler, janni with his sharp attention to detail pointed out the problem. It turns out it was the compiler, but not in the way I had expected. It was not a compiler bug, but an overly eager optimizer

The Input Capture module generates a persistent interrupt condition, in that so long as the capture buffer is full, it will continue to generate an interrupt. So the buffer must be emptied before the interrupt flag can be cleared, otherwise the full buffer will continue to issue an interrupt.

Well, I knew that fact and took account of it in my code. I had a variable "Empty_buf:dword" and I would
assign Empty_buf := ICXBuf;" in my source code - like I should.

What I failed to notice (but, thankfully janni did notice) in my many reviews of the listing generated by the compiler was that all of my interrupt handler code was present in the listing - EXCEPT the code for emptying the buffer!!!

It turns out the compiler apparently decided that since I did nothing with the data transferred to the "Empty_buf" variable, that it was not needed and the compiler's optimizer deleted that variable. So naturally without the variable, the capture buffer was not being emptied, so it continued to interrupt and indeed the program counter would never return to the main code loop. But, of course in my mind, I had taken care of emptying the buffer in my source code, so it never crossed my mind to look for it in the listing and indeed I repeatedly failed to notice its absence. :x

The solution was simple, declare the variable "volatile" and the compiler left it along, the variable appeared in the code listing, emptied the buffer and the interrupt would return to the main loop - problem solved.

There should be some type of warning about this - or the compiler should leave variables assigned to buffers alone - it makes me wonder how many other variables in my code should be declared "volatile" but I just don't know it yet.

Next favorite topic -Definition File Inconsistencies and deviation from Data Sheet

Also, I still find a number of inconsistencies and omissions in the definition file for the PIC32MX795F512H.

For instance to clear the SPI2 interrupt flag, you can't state.IFS1.SPI2EIF := 0 as you might think from looking at the data sheet ------
because there is NO bit identified as "SPI1EIF" for bit 5 of that IFS1 register in the definition file. Instead you are (after finding out what the definition file shows) forced to use IFS1.U3EIF := 0 to clear the SPI2EIF flag - who would have guessed that?? Just makes no sense and there is still no mention that the definition file has these problems.

Here for example is what you find looking at the IFS1 register in the definition file for bit 5

Code: Select all

  const U2EIF = 8; register;
    var   U2EIF_bit : sbit at IFS1.B8;
    const U3TXIF = 7; register;
    var   U3TXIF_bit : sbit at IFS1.B7;
    const U3RXIF = 6; register;
    var   U3RXIF_bit : sbit at IFS1.B6;

    const U3EIF = 5; register;   //This is the only definition for a bit that has three different users
    var   U3EIF_bit : sbit at IFS1.B5;

//There should be two additional bit declarations such as
    const SPI2EIF = 5; register;
    Var   SPI2EIF_bit: sbit at IFS1.B5;
     const I2C4BIF = 5;register;
    var I2C4BIF_bit: sbit at IFS1.B//

//What makes it worst, is no mention is made of this variation from the data sheet or the many others
//Now perhaps, if you only use the compiler libraries, then the designers takes these differences into //account - but, many of use write our own code for these modules and don't use the library.
    const CMP2IF = 4; register;
    var   CMP2IF_bit : sbit at IFS1.B4;
    const CMP1IF = 3; register;
    var   CMP1IF_bit : sbit at IFS1.B3;
As you can see, there is only bit definition declared for bit IFS1.B5. But as you can see in the data sheet that bit is also used for:
I2C4BIF
SPI2EIF
and well as U3EIF
No place in the definition file will you find SPI2EIF nor I2C4BIF

Well, enough of my grousing over this variation from the datasheet, I've learned I have to check the definition file and I am now doing that on all my code.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

LGR
Posts: 3204
Joined: 23 Sep 2004 20:07

Re: PIC 32 Test for Return from Interrupt Handler

#4 Post by LGR » 13 Jan 2014 22:28

Sometimes I wish that there was an easy switch to defeat the optimizer for testing purposes. When you have one of these mysteries, that would be an easy thing to try, and you could confirm where to start looking.
If you know what you're doing, you're not learning anything.

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Re: PIC 32 Test for Return from Interrupt Handler

#5 Post by Rotary_Ed » 14 Jan 2014 00:18

I agree, LGR.

I must admit, I am still a bit embarrassed for looking at my code in the list for a couple of weeks and checking everything - but the one variable I needed to check. janni pointed out its omission and once the problem was know the fix was trival. BUT, now you wonder where else is some crucial variable being optimized out - but, its not yet apparent.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

Post Reply

Return to “mikroPascal PRO for PIC32 Beta Testing”