Stuck in Single vector interrupt

General discussion on mikroC PRO for PIC32.
Post Reply
Author
Message
Wapayk
Posts: 12
Joined: 18 Feb 2013 13:41

Stuck in Single vector interrupt

#1 Post by Wapayk » 12 May 2017 00:30

Hi all,

I am knocking my head for some time now. It seams that I cant get multi vector interrupt to work, like it has stuck to single vector interrupt ie. no priority.

This code triggers timer 2 and then loops for some time inside.. Timer1 should interrupt Timer2 routine because it is much faster but it never does. Only when Timer2 ISR exits Timer1 ISR enters.

Code: Select all


unsigned int br;

void Timer1Interrupt() iv IVT_TIMER_1 ilevel 7 ics ICS_SOFT {
     LATB.B15 = !LATB.B15;
     T1IF_bit = 0;             // Clear T1IF
     }

void Timer2Interrupt() iv IVT_TIMER_2 ilevel 6 ics ICS_SOFT {
     LATB.B12 = 1;
     for (br=0;br<0xFFFF;br++){asm nop;}
     LATB.B12 = 0;
     T2IF_bit = 0;             // Clear T2IF
     }

void InitMCU(){
     /////Unlock writing to registers
     SYSKEY = 0x0; // ensure OSCCON is locked
     SYSKEY = 0xAA996655; // Write Key1 to SYSKEY
     SYSKEY = 0x556699AA; // Write Key2 to SYSKEY

     INTCONbits.MVEC = 1; //turn on multi vector interrupts
      
     TRISB = 0b0010100010010011;
     TRISA = 0b00111;

     ANSELA = 0;
     ANSELB = 0b1100; //analog inputs AN2 i AN3
     CNPUA = 0; // turn off pullups
     CNPUB = 0;
     CNPDA = 0; // turn off pulldowns
     CNPDB = 0;
      
///////////////////////////////////////////////////////configure Timer1/////////////////////////////////////////////////////////////////////
     PMD4bits.T1MD  = 0;    
     T1CONbits.ON    = 1;
     T1CONbits.TCKPS = 0b00; //prescaler 0b11 -> 256, 0b10 -> 64, 0b01 -> 8, 0b00 -> 1
     IPC1bits.T1IP   = 7;    //set priority to 7
     IPC1bits.T1IS   = 2;
     IEC0bits.T1IE   = 1;    
     IFS0bits.T1IF   = 0;   
     TMR1            = 0;

///////////////////////////////////////////////////////configure Timer2/////////////////////////////////////////////////////////////////////
     PMD4bits.T2MD  = 0;
     T2CONbits.ON    = 1;
     T2CONbits.TCKPS = 0b11; //prescaler 0b11 -> 256, 0b10 -> 64, 0b01 -> 8, 0b00 -> 1
     IPC2bits.T2IP   = 6;    //set priority to 6
     IPC2bits.T2IS   = 2;
     IEC0bits.T2IE   = 1;
     IFS0bits.T2IF   = 0;
     TMR2            = 0;

     EnableInterrupts();       // Enable all interrupts
     }

void main() {
     InitMCU();
     while(1);
     }

What am I doing wrong?
Maybe I am not initializing multi vector interrupts properly.

I have attached whole project if anybody has time and this MCU to test it.

P.S.
I have written same program in MPLABx and it works fine.
Attachments
interrupt priority test.rar
Whole project
(72.27 KiB) Downloaded 269 times
config window
config window
config.png (27.05 KiB) Viewed 7943 times

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Stuck in Single vector interrupt

#2 Post by hexreader » 12 May 2017 01:46

Your zipped project works for me.

I only have PIC32MX270256B, but if I ignore warning about wrong chip, it works just the same.

My chip has no RB12, but swapping code RB12 and RB14 shows good.

Oscilloscope shows the following traces from RB15 (cyan) and RB14 (yellow), which suggest to me that both interrupts are working.

I see no problem, other than a general observation that using a delay within an interrupt is often a bad idea.

..... or could it be that you should have set a new timer value on each of the interrupts? - maybe that is where your mistake is? - I suspect that this is where your mistake lies

Maybe comment your code much, much better so we know what crystal you use, how often the interrupt is meant to fire, what delay you ASM code is meant to produce and what waveforms you want to produce. I am very unclear as to what you are doing, but I am confident that both interrupts are firing.
Attachments
DS1Z_QuickPrint1.png
DS1Z_QuickPrint1.png (40.1 KiB) Viewed 7886 times
Start every day with a smile...... (get it over with) :)

Wapayk
Posts: 12
Joined: 18 Feb 2013 13:41

Re: Stuck in Single vector interrupt

#3 Post by Wapayk » 12 May 2017 10:01

Hexreader,

I am sorry but you didn't understand my problem. I will explain again.

That waveform that you posted is the one that shows problem with priority of interrupts and is example what would waveform look like in single vector interrupt setting.

I attached waveform that it should look like for same code and settings compiled in MPLABX.

So what needs to happen is interrupt for Timer1 should fire while loop in ISR of Timer2 is working and after Timer1 ISR finishes it returns to Timer2 Routine to finish and after that returns to main.

That is based on Interrupt priority settings!

What we see in your waveform is that while Timer2 ISR is running there is NO jumping to higher order priority, only when it finishes then Timer1 ISR triggers. This kind of waveform you posted you would get if you used single vector interrupt settings.

I hope that now my question is clearer and that is: How to make multi vector interrupts with priority work correctly in mikroC PRO for PIC32 v.3.6.0?

Br,
Marjan
Attachments
screenshot.png
screenshot.png (66.99 KiB) Viewed 7667 times

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Stuck in Single vector interrupt

#4 Post by hexreader » 12 May 2017 15:27

After tidying up your code, and adding comments to help me, I think I see the problem....

Timer 1 interrupt is priority 7, so you would think that T1 interrupt would always happen, but in this example, the priority 6 T2 loop seems to prevent T1 interrupt from happening.

Sadly I have no idea how to fix this, despite trawling through datasheets for clues :(
Start every day with a smile...... (get it over with) :)

p.erasmus
Posts: 3391
Joined: 05 Mar 2009 10:28

Re: Stuck in Single vector interrupt

#5 Post by p.erasmus » 12 May 2017 17:53

In my understanding setting the interrupt context saving to Soft you need to handle the context saving in your code( there is nothing in your code)
try to set the context saving to auto let the compiler handle the context and re-entry for you
P.Erasmus
Saratov,Russia
--------------------------------------------------------------

Wapayk
Posts: 12
Joined: 18 Feb 2013 13:41

Re: Stuck in Single vector interrupt

#6 Post by Wapayk » 13 May 2017 12:16

Thank you hexreader for all the help with interrupt priority. Now I know i am not missing something here (two heads are smarter than one). Also Sorry for bad commenting of code.

p.erasmus, any other settings other than ICS_SOFT and ICS_OFF won't compile so I am stuck with it. Sadly this mcu doesn't have Shadow register set neither.

I tried implement manual context saving and nothing helped (assuming I did it right :? ) except when I put "asm ei;" in first line of lower priority interrupt.

Well that is logical looking just wrong. Why is global interrupt disabled when entering interrupt? That seems to me like compiler error.
Also very important when using "asm ei;" sub priority settings don't work at all!

And i imagine that when I build complex program with loots of interrupts there will be mayor problems if I have to re enable interrupt every time it enters one of it.

Can any of mikroelektronika developers confirm this issue?

Code that fixed priority interrupts (but seems really bad fix):

Code: Select all

unsigned int br;

void Timer1Interrupt() iv IVT_TIMER_1 ilevel 7 ics ICS_SOFT {
     LATB.B15 = !LATB.B15; //toggle port for visual inspection on logic analyzer
     T1IF_bit = 0;             // Clear T1IF
     }

void Timer2Interrupt() iv IVT_TIMER_2 ilevel 6 ics ICS_SOFT {
     asm ei;   //re enable global interrupts!!!!!!
     LATB.B12 = 1;   //toggle port for visual inspection on logic analyzer
     for (br=0;br<0xFFFF;br++){asm nop;}  //loop for some time to allow higher priority interrupt to trigger while in this ISR
     LATB.B12 = 0;  //toggle port for visual inspection on logic analyzer
     T2IF_bit = 0;             // Clear T2IF
     }
Also can somebody explain little about context saving, what to do with relevant important registers (I know it is somewhat lazy question). It should help other people that are facing this problem :)

Br,
Marjan

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Stuck in Single vector interrupt

#7 Post by hexreader » 13 May 2017 12:46

Here is partially commented and minimised code in case somebody clever wants to progress with this:
Attachments
interrupt priority test.zip
(39.53 KiB) Downloaded 209 times
Start every day with a smile...... (get it over with) :)

Wapayk
Posts: 12
Joined: 18 Feb 2013 13:41

Re: Stuck in Single vector interrupt

#8 Post by Wapayk » 14 May 2017 14:21

Hi all,

I have come to the end off this interrupt priority problem :)

Here is modified and commented assembler code that "mikroc PRO for PIC32 V3.6.1" compiler makes and everything is clear now.

I put only section of interrupt routine because there lies bug.

Code: Select all

//////Start of interupt routine////
//void Timer1Interrupt() iv IVT_TIMER_1 ilevel 7 ics ICS_OFF{
/////Saving relevant registers to RAM memory!!!!!!!!!
RDPGPR        SP, SP            //Read GPR shadow set register to "SP" -> this is memory address where context will be stored
ADDIU        SP, SP, -16        //subtract 16 from "SP" 
SW        R30, 12(SP)           //write value stored in R30 to memory address "SP"+12
MFC0        R30, 12, 2          //write value stored in Coprocesor0 register SRSCtl to R30
SW        R30, 8(SP)            //write value from R30 to RAM address "SP"+8
MFC0        R30, 14, 0          //write value stored in Coprocesor0 register EPC to R30
SW        R30, 4(SP)            //write value from R30 to RAM address "SP"+4
MFC0        R30, 12, 0          //write value stored in Coprocesor0 register STATUS to R30
SW        R30, 0(SP)            //write value from R30 to RAM address "SP"+4
INS        R30, R0, 1, 15       //clears bit 1 (Exception level bit) in R30 (that now holds STATUS register) to normal level -> necessary to allow interrupts and it is set when interrupt is generated.
ORI        R30, R0, 7168        //HERE IS REAL PROBLEM!!!!! modifies R30 that now holds STATUS register and writes IPL (bits 12..10) to value 0xC0 = 7. This holds priority level for this interrupt.
//But what it also does and it shouldn't is to clear bit 0 (this is Interrupt enable bit) and effectively disables all interrupts.  
MTC0        R30, 12, 0          //write STATUS register with modified R30

/////some user code to execute in ISR////
// 		LATB.B15 = ~LATB.B15;  //toggle portb port 15 on and off
LBU	R2, Offset(LATB+1)(GP)
EXT	R2, R2, 7, 1
XORI	R3, R2, 1
LBU	R2, Offset(LATB+1)(GP)
INS	R2, R3, 7, 1
SB	R2, Offset(LATB+1)(GP)

////Start of restore context and exit
DI                        //disables all interupts -> bit0 of STATUS register
EHB                       //clear execution hazard bit
LW       R30, 8(SP)       //Read from ram memory address "SP"+8 and write it to R30 (this address holds Coprocesor0 SRSCtl register)
MTC0     R30, 12, 2       //Write R30 to SRSCtl register
LW       R30, 4(SP)       //Read from ram memory address "SP"+4 and write it to R30 (this address holds Coprocesor0 EPC register)
MTC0     R30, 14, 0       //Write R30 to EPC register
LW       R30, 0(SP)       //Read from ram memory address "SP"+0 and write it to R30 (this address holds Coprocesor0 STATUS register) -> here it also restores global interrupt enable!!!!!
MTC0     R30, 12, 0       //Write R30 to STATUS register
LW       R30, 12(SP)      //Read from ram memory address "SP"+12 and write it to R30 (this actually holds nothing) 
ADDIU    SP, SP, 16       //SP = SP+16
WRPGPR   SP, SP           //Write "SP" to GPR shadow set register
ERET                           //exit from interrupt
As you can see it seams that ORI instruction is not used properly (if I understand it correctly).
What it does is this:

In Asembly
ORI R30, R0, 7168

in C language
R30 = R0 | 7168; //Since R0 = 0, R30 = 7168. Here we lose STATUS interrupt enable

It should be written like this:
asembly:
ORI R30, R30, 7168

C language:
R30 = R30 | 1768;

Conclusion:

Use asm ei; or InterruptEnable(); on first line of all interrupt routines you have in your code like this:

Code: Select all


void Timer1Interrupt() iv IVT_TIMER_1 ilevel 6 ics ICS_SOFT {
     asm EI //Reenable global interrupts
     T1IF_bit = 0;             // clear interrupt flag
/*
do something here 
...
...
*/
     }

I hope that I explained issue well for average programmer to understand.

Also I would like for mikroelektronika to correct this bug in next update!!!!

Br,
Marjan

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

Re: Stuck in Single vector interrupt

#9 Post by filip » 15 May 2017 16:26

Hi,

I apologize for the reported issue, we will inspect what is going on here.


Regards,
Filip.

icowie
Posts: 1
Joined: 31 Jul 2019 18:21

Re: Stuck in Single vector interrupt

#10 Post by icowie » 31 Jul 2019 18:55

I have the same problem. Except, your fixes do not work.
I am using PIC32MX795F512L, with compiler 4.0.0
I have played with every combination of ics, including the srs and saving my own context.
I have tried your code directly.
I conclude, that an interrupt service routine that is running, gets interrupted by a higher level one, refuses to return to the lower level one, but instead returns directly to main. This implies that the context saving does not pick up the return program counter and register saves, from the lower level interrupt. This is why I worked so hard on the context. I have confirmed that multi-level interrupts are enabled.
I am at a loss now to figure out what else to try.
I hope that the development team is aware of this, and has a workaround? I realize that the original problem was an older revision compiler.
I noticed that looking at the assembler output, compiling his code, has exactly the same offending instructions. I assume that this issue has not been solved because of that. However, his workaround does not work for me on this processor and revision of compiler.
Can someone shed some light on this? Am I behind the times on this?
Thank you.

pwdixon
Posts: 1431
Joined: 13 Apr 2005 11:14
Location: UK

Re: Stuck in Single vector interrupt

#11 Post by pwdixon » 25 Sep 2019 13:11

Looked like the same problem I've been having, see " Post subject: Interrupt priorities".

Tried the asm ei fix and it appears to work, don't really like it though, looks like a bodge.

pwdixon
Posts: 1431
Joined: 13 Apr 2005 11:14
Location: UK

Re: Stuck in Single vector interrupt

#12 Post by pwdixon » 25 Sep 2019 13:14

Does asm ei override previously disabled interrupts eg if I disable a timer interrupt then call asm ei is the timer interrupt now enabled again?

Post Reply

Return to “mikroC PRO for PIC32 General”