Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pingiono32 OnTimer Error
15-12-2014, 05:36 AM,
#11
RE: Pingiono32 OnTimer Error
PIC32 is 32bit processor and it produces code and variable storage in 32bit alignment. That means u8 variable is also taking 4 bytes space in the memory. Compiler switch '-mips16' instructs the compiler to produce 16bit code and variable thus saving lots of flash and ram space requirement. However, the interrupt routines must be 32bit always and 'nomips16' attribute is used to tell the compiler to produce 32bit code while compiling in 16bit mode.

Earlier version of X4 for Windows had -mips16 option disabled, then later version enabled it as default. Now it is enabled for MX220 and MX250 only and disabled for the rest as default. But a bug in the Makefile32.win32 causes always compiling with -mips16 option. You need to fix the line 107 as below to make the default behavior working correctly.

Code:
#ifdef __MIPS16_ENABLE__
ifeq (__MIPS16_ENABLE__, true)

The interrupt declaration for 16bit and 32bit are slightly different. 16bit example is well used in your code. Here is working 32bit example without compiling error if the above bug is fixed.

Code:
// Put the ISR_wrapper in the good place
void ISR_wrapper_vector_4(void) __attribute__ ((section (".vector_4")));

// ISR_wrapper will call the Tmr1Interrupt()
void ISR_wrapper_vector_4(void) { Tmr1Interrupt(); }

// TMR1 Overflow Interrupt Function
void __attribute__ ((interrupt)) Tmr1Interrupt(void)
{
    if (IFS0bits.T1IF)   // Timer Interrupt flag
       {
        TMR1=0; // reset the timer register
        IFS0CLR=0x10; // Clear the timer interrupt flag

        toggle(YELLOWLED); // toggle yellow led
        toggle(GREENLED); // toggle green led    
    }
}

The best interrupt service routine examples are the core library of Pinguino assisted with ISP wrapper in ISRwrapper.S. For example, millis.c is a wonderful example of using timer 2 it should give you a better way to write timer interrupt if you are willing to modfy ISRwrapper.S file. Even you decide not to mess with ISRwrapper.S, stick to the above way, the library source gives good example of init and interrupt handling.

Another point, just toggling 2 leds won't hurt you, but you should not do much work within the interrupt service routine. Instead set the flag or counter and let the loop to do the actual job.

Code:
volatile u8 timer1_hit = 0;

// TMR1 Overflow Interrupt Function
void __attribute__ ((interrupt)) Tmr1Interrupt(void)
{
    TMR1=0;        // reset the timer register
    IFS0CLR=0x10;    // Clear the timer interrupt flag

    timer1_counter++;
}

loop()
{
    if (timer1_hit)
    {
        timer1_hit = 0;
        toggle(YELLOWLED); // toggle yellow led
        toggle(GREENLED); // toggle green led
    }
}

For curiosity sake, the PR1 value is kind of odd. With prescaler 256 * 39062 = 9999872 / 80000000 = 0.1249984 sec...

DJ
Reply
15-12-2014, 09:45 PM,
#12
RE: Pingiono32 OnTimer Error
(14-12-2014, 11:39 AM)moreno Wrote: Hi

Is very hard to explain and never I know all the history.

MIPS is a code optimization feature which reduce the compiled code size.

The problem is which the MIPS generated code is not compatible with interrupt routines, if you compile interrupt handler code without __attribute__ ((nomips16)) you obtain a lot of strange compiling errors.
Even the definition order of the routines is very important (I do not know why), if you change it nothing work.


Bye Bye, Moreno

Thanks... That makes sense. I read somewhere that mips16 will attempt
to store variables as internal registers to optimize speed. If an interrupt
occurs then the registers can get clobbered. When the interrupt returns
the cpu would have no way of knowing the registers where tampered with.
This must be a PIC issue because other processors that I have worked
with will store the registers before a subroutine call or interrupt.
Thanks for the reminder.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)