Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[SOLVED]PIC32 MIPS and Interrupt do not work together
12-06-2013, 10:20 AM, (This post was last modified: 12-06-2013, 02:45 PM by moreno.)
#1
[SOLVED]PIC32 MIPS and Interrupt do not work together
Hi

Today I updated my working version from 750 to 861 to use libraries I updated.


Easy program are compiled well with this version but programs which use Interrupt generate a lot of error like

interrupt handlers cannot be MIPS16 functions

A sample program is:

Code:
/*-----------------------------------------------------
Author:  --<>
Date: Wed Dec 19 11:24:07 2012
Description:

-----------------------------------------------------*/

// Using interrupt with Pinguino32
// Jean-Pierre MANDON 2011

#include <interrupt.c>

unsigned int counter=0;
unsigned int counter1=0;

u32 cpuFrequency;
u32 peripheralFrequency;

u32 zut;

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

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

void Tmr1Interrupt(void) __attribute__ ((interrupt));
// Tmr1Interrupt is declared as an interrupt routine


// define here the code to execute when an interrupt occure
void Tmr1Interrupt(void)
{

if (IFS0bits.T1IF)        // Timer Interrupt flag
    {
    TMR1=0;            // reset the timer register
    IFS0CLR=0x10;        // Clear the timer interrupt flag
    counter++;        // increment the counter
    }
}


// configure timer 1
void init_timer1(void)
{
IntConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);    // interrupt mode (interrupt.c)
T1CON=0;        // reset timer 1 configuration
TMR1=0;            // reset timer 1 counter register
//PR1=0x9999;        // define the preload register
PR1=0x0FFFF;        // define the preload register
IPC1SET=0x7;        // select interrupt priority and sub-priority
IFS0CLR=0x10;        // clear interrupt flag
IEC0SET=0x10;        // enable timer 1 interrupt
//T1CONSET=0x8010;    // start timer 1 and set prescaler
T1CONSET=0x8000;    // start timer 1 and set prescaler
}

void setup()
{
cpuFrequency = System.getCpuFrequency();
// CDC.printf("\nCPU       : %d MHz\r\n", cpuFrequency / 1000 / 1000);

peripheralFrequency = System.getPeripheralFrequency();
// CDC.printf("Peripheral: %d MHz\r\n", peripheralFrequency / 1000 / 1000);
  
  // Change current register settings
  
// System.setCpuFrequency(cpuFrequency / 2); // should be 40 MHz
// System.setPeripheralFrequency(peripheralFrequency / 4); // should be 10 MHz
System.setPeripheralFrequency(80000000); // should be 10 MHz
zut = OSCCONbits.PBDIV;
//OSCCONbits.PBDIV = 2;
//zut = OSCCONbits.PBDIV;

System.setCpuFrequency(80000000); // should be 80 MHz
System.setPeripheralFrequency(80000000); // should be 80 MHz

init_timer1();
}

void loop()
{
CDC.printf("%d - %d - %d\n\r",counter,counter1,zut);    // counter is incremented at each timer 1 overflow
counter = 0;
delay(1000);
counter1++;
}


To solve temporary the problem I commented the line

Code:
#__MIPS16_ENABLE__    = true
in Makefile32.win32

There is a better way to solve the problem??


Bye Bye, Moreno
Reply
12-06-2013, 02:45 PM,
#2
RE: PIC32 MIPS and Interrupt do not work together
Hi

After some research, I found the solution to the problem.
Is necessary use the __attribute__ ((nomips16)) attribute inside interrupt routine to obtain 32 bit code.
Is even necessary modify the definition order of the interrupt routines

Code:
// Using interrupt with Pinguino32
// Jean-Pierre MANDON 2011

// 2013/06/12 Manzini Moreno Use of __attribute__ ((nomips16)) for Interrupt call

#include <interrupt.c>

unsigned int counter=0;



//OLD CODE DEFINITION WITHOUT MIPS OPTION
/*
void ISR_wrapper_vector_4(void) __attribute__ ((section (".vector_4")));
// Put the ISR_wrapper in the good place

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

void Tmr1Interrupt(void) __attribute__ ((interrupt));
// Tmr1Interrupt is declared as an interrupt routine

// define here the code to execute when an interrupt occure
void Tmr1Interrupt(void)*/


//NEW CODE DEFINITION WITH MIPS AND __attribute__ ((nomips16))

//First Definition
void __attribute__ ((nomips16)) ISR_wrapper_vector_4(void) __attribute__ ((section (".vector_4")));
// Put the ISR_wrapper in the good place

//Second Definition
void __attribute__ ((nomips16))  Tmr1Interrupt(void) __attribute__ ((interrupt));
// Tmr1Interrupt is declared as an interrupt routine

//Third Definition
void __attribute__ ((nomips16)) ISR_wrapper_vector_4(void) { Tmr1Interrupt(); }
// ISR_wrapper will call the Tmr1Interrupt()


// define here the code to execute when an interrupt occure
void  __attribute__ ((nomips16))  Tmr1Interrupt(void)
{
if (IFS0bits.T1IF)        // Timer Interrupt flag
    {
    TMR1=0;            // reset the timer register
    IFS0CLR=0x10;        // Clear the timer interrupt flag
    counter++;        // increment the counter
    }
}

// configure timer 1
void init_timer1(void)
{
IntConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);    // interrupt mode (interrupt.c)
T1CON=0;        // reset timer 1 configuration
TMR1=0;            // reset timer 1 counter register
PR1=0x9999;        // define the preload register
IPC1SET=0x7;        // select interrupt priority and sub-priority
IFS0CLR=0x10;        // clear interrupt flag
IEC0SET=0x10;        // enable timer 1 interrupt
T1CONSET=0x8010;    // start timer 1 and set prescaler
}

void setup()
{
init_timer1();
}

void loop()
{
CDC.printf("%d\n\r",counter);    // counter is incremented at each timer 1 overflow
delay(1000);
}


Bye Bye, Moreno
Reply
26-06-2013, 09:14 AM,
#3
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
For the same reason, asm('wait') fails to compile with "unrecognized opcode 'wait'" message unless __MIPS16_ENABLE__ is disabled. Is there any way to disable MIPS16 for a block or line of code only?
Reply
26-06-2013, 11:51 AM,
#4
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
Is there a speed penalty for MIPS16?

John
Reply
26-06-2013, 05:15 PM,
#5
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
Hi

No, all my programs work well even with MIPS16.

I do not know if there is a way to disable MIPS16 for some lines of code.
A possible solution is create a function whit these lines inside and the option __attribute__ ((nomips16))


Bye Bye, Moreno
Reply
26-06-2013, 06:06 PM,
#6
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
Thanks, Moreno. It works fine.

Code:
__attribute__ ((nomips16)) void sleep()
{
        System.unlock();
        OSCCONbits.SLPEN = 1;
        System.lock();
        _wait();
}
Reply
26-06-2013, 06:08 PM,
#7
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
What I really meant was (because I won't be running your code only): is the CPU slower in mips16 mode?

I'm not near the flash size so why would I want mips16?

John
Reply
26-06-2013, 08:17 PM,
#8
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
According to Arvin's Easy Pack announcement:-

Note:
The MIPS16 option can dramatically reduce the flash size,
but it is simultaneouly reduced the execution speed of CPU about 30%.


Microchip's XC32 guide mentions about C library that may be also used by PDE (??):-

The available libraries have been optimized for: speed, size, integer arithmetic only and MIPS16® mode.

I don't need to squeeze the output size and speed is not the concern, either. I need to have the production environment that will surely work without spending lots of time to trace the problem. (Certainly Pinguino-OTG shouldn't be for the hobby projects only.)

For that reason, I stick to rev685 which uses no mips16 by default. Besides new rev fails to mount SD even after fixing diskio.c with the new rtccDate/Time def. No good for logger project.
Reply
26-06-2013, 11:11 PM,
#9
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
Thanks.

John
Reply
29-03-2014, 05:58 PM,
#10
RE: [SOLVED]PIC32 MIPS and Interrupt do not work together
I tried to apply the nomips attribute bin this code:

void __attribute__ ((nomips16)) ISR_wrapper_vector_19(void) __attribute__ ((section (".vector_19")));
// vector 19 is the external input 4 interrupt vector
void __attribute__ ((nomips16)) ISR_wrapper_vector_19(void) { Int4Interrupt(); }
void __attribute__ ((nomips16)) Int4Interrupt(void) __attribute__ ((interrupt));
void __attribute__ ((nomips16)) Int4Interrupt(void) // interrupt treatment
{
if (IFS0bits.INT4IF) // interrupt flag for INT4
{
wus.bits.ring = 1;
IFS0bits.INT4IF=0; // clear the interrupt flag
IEC0bits.INT4IE=0; // Interrupt disabled
}
}
but the compiler is generating an error:
error: 'Int4Interrupt' redeclared with conflicting 'nomips16' attributes
what is wrong in my code?
Thanks in advance for the help
Roberto
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)