1

I am using MPLABX + Harmony framework to write code for a PIC32MZ1024EFK064.

My goal is, to trigger the ISR every microsecond. In order to test this, I toggle a LED after 1000000 cycles of the ISR:

uint32_t xxx = 0;

void __ISR(_TIMER_2_VECTOR, ipl1AUTO) IntHandlerDrvTmrInstance0(void)
{

    xxx++;

    if(xxx > 1000000){

        xxx = 0;
        blink();

    }

    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_2);

}

Timer2 runs at 80MHz with a prescaler of 1 with a timer period of 80.

At my first attempt, the LED toggled every 4 seconds (ISR = every 4us).

I figured out that I can reach 2 seconds by changing the Postscaler of PBCLK7 from 2 to 1. (now the CPU-core runs at 160MHz instead of 80MHz).

But even when I change the timer period to 1, I only get my LED toggled every 2 seconds.

Any idea how to speed things up further here?

UPDATE:

The subroutine blink() was too slow. By manipulating the Register directly, it works at 1us

void __ISR(_TIMER_2_VECTOR, ipl1AUTO) IntHandlerDrvTmrInstance0(void)
{
    LATBINV = 1<<8;
    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_2);
}
Ivar
  • 6,138
  • 12
  • 49
  • 61
Oliver
  • 31
  • 7
  • I'm not totally familiar with your setup, However, code takes a while to occur and a interrupt can take (at least) one clock to occur, and 1 clock to return so the chip, even at 160mhz is not fast enough to handle a interrupt at 1usec intervals. – user3629249 Jul 05 '17 at 23:38
  • thank you for you answer in my opinion, 160MHz should be more than enough to drive an interrupt with 1us (this would be 160 clock cycles for one interrupt) – Oliver Jul 09 '17 at 11:46

1 Answers1

1

I am not very familiar with that specific microcontroller but have worked a lot with Microchip PICs, so here are some points you might want to look at:

1- First make sure your clocks (CPU and PBCLK) really run at the speed you think they run. You can usually output some of your internal clocks on an external pin (usually REFCLKO on PIC32s). That way you can measure them with an oscilloscope and make sure they are correctly configured.

2- Make sure you minimize the internal execution time of your interrupt. Check if PLIB_INT_SourceFlagClear() is a macro-like function or an actual function call. If this is a function call, you might want to work at the register level to avoid this overhead.

3- Enable compiler optimization. By the way, it is also a good practice when working with a global variable from within an interrupt to declare it as volatile (or declare it static inside your interrupt handler function).

4- Unless it is explicitely documented by Microchip, verify if you should clear your interrupt at the beginning of your interrupt handler instead of the end. What might happen in your case, especially if you set its period to a very short period of time, is that your timer expires again while you are still inside your interrupt handler but BEFORE you clear its flag. That would result in an extra delay before your interrupt fires again. What you want is to clear the flag as soon as possible so if the timer expires again, it sets the flag which will result in your interrupt handler to fire again as soon as it completes its execution. Of course that would not give any time for your background application to execute though...

5- I am also assuming that your timer is correctly configured, that is it reloads its internal count to 0 when the period expires, but take a look to make sure it is the case.

Franck

Franck D.
  • 36
  • 4
  • thank you very much for your thoughts! 1) I was able to verify the clocks with my oscilloscope by enabling the OSC2 output 2) I reduced the ISR to only toggle the pin (full speed) and still measured a speed of 2us :/ 3) Not possible with the free version 4) I tried it - no difference – Oliver Jul 09 '17 at 10:35
  • I now also tried the compiler optimization level 3 with the 60-day-demo version of the xc32 pro compiler - unfortunately this does not help either – Oliver Jul 09 '17 at 17:24
  • I replaced my blink() function by: LATBINV = 1<<8 and now it works at 1us! – Oliver Jul 09 '17 at 19:35
  • Great, looks like you made progress. Another thing you can do to help you debug timings like this is to simply toggle a GPIO at the very beginning and the end of your ISR and look at the result on your oscilloscope. That way you can more easily see the effect of your different settings or code optimizations. You should see your ISR execution time reduced as you optimize your code. – Franck D. Jul 11 '17 at 12:29