How is this PIC32 ISR tied to the Timer1 interrupt? - Page 1
Forum section: electronics / general

author: Osirus
author_rank: Newbie
timestamp: February 25, 2017, 11:51:01 pm
content: Hi, new poster here.I'm learning to use the PIC32 with the assistance of a textbook, datasheets, and anything else I can get my hands on. I'm trying to do as much as possible directly with registers instead of peripheral libs, etc.I needed an interrupt every 1/60 of a second, and I got it working with Timer1 following some instructions, however I don't understandwhyit works. What actually assigns the Timer1 interrupt to this particular ISR?The ISR function:Code:#pragma interrupt InterruptHandler ipl1 vector 0void InterruptHandler(void){// Do stuff...IFS0bits.T1IF = 0;}And the Timer1 config:Code:T1CON = 0x8010; //Timer1 ON, Prescaler 8PR1 = GetPeripheralClock() / 60;__asm__("EI");IFS0bits.T1IF = 0; // Timer1 Interrupt Flag clearedIPC1bits.T1IP = 1; // Timer1 Interrupt Priority 1IEC0bits.T1IE = 1; // Timer1 Interrupt EnableAside from the priority level matching, I don't see what it is that defines this ISR for Timer1.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 26, 2017, 12:06:05 am
content: You haven't put it into multi-vector mode, so any interrupt will call your code, you just only happen to have one source enabled, so it works.Until you enable another interrupt source.

author: Osirus
author_rank: Newbie
timestamp: February 26, 2017, 12:07:33 am
content: Quote from: mikeselectricstuff on February 26, 2017, 12:06:05 amI see. Thanks, that's kinda what I thought, that it was just a ISR for everything.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 26, 2017, 12:10:43 am
content: BTW you should use IFSxCLR = <mask> to clear int flags, as the compiler does not compile <flag=0> into an atomic operation, so if you have multiple things accessing flags in the same register (Especially a mix of foreground & background tasks) you can get some horrifically hard to debug "fails once in a blue moon" type situations.

author: andersm
author_rank: Super Contributor
timestamp: February 26, 2017, 01:18:11 am
content: Quote from: Osirus on February 25, 2017, 11:51:01 pmThis format for decorating ISRs is deprecated. The current way is to use a function attribute, or the convenience macros in sys/attribs.h. See chapter 14 of the XC32 manual for full details.

author: newbrain
author_rank: Super Contributor
timestamp: February 26, 2017, 12:00:53 pm
content: Quote from: andersm on February 26, 2017, 01:18:11 amThis is one of the reasons I like Cortex-M a lot: ISRs are just regular C functions, no magic spells outside standard C for the user and the compiler, even if hidden in a #pragma or a convenience macro.

author: jaromir
author_rank: Unknown
timestamp: February 26, 2017, 12:48:58 pm
content: EEVblog forum rule 27:In every PIC thread, somebody must explain how much better is some other MCU.

author: newbrain
author_rank: Super Contributor
timestamp: February 26, 2017, 01:34:42 pm
content: Quote from: jaromir on February 26, 2017, 12:48:58 pmI was not PICking specifically on MIPS,: the last I programmed on a MIPS was withthis, "some" time ago.More like something I noticed with most other archs I dealt with, and totally a personal opinion.

author: Luminax
author_rank: Regular Contributor
timestamp: March 01, 2017, 04:30:18 am
content: Just a clarification, is that a code generated by the likes of Harmony and/or MPLab Code Configurator? because it seems a lot like it.In the event that it does, there's an ISR handler routine that passes any matching interrupt to its matching ISR to be passed to their own specific callbacks somewhere inside the generated codes

author: jesuscf
author_rank: Frequent Contributor
timestamp: March 01, 2017, 07:39:38 am
content: Quote from: mikeselectricstuff on February 26, 2017, 12:10:43 amHere is a portion of the output "xc32-objdump -D -S TimerIRQ.o" for a piece of code similar to OP's code.Code:IFS0bits.T1IF=0; // Clear timer 1 interrupt flag54:3c020000luiv0,0x058:8c430000lwv1,0(v0)5c:7c032104insv1,zero,0x4,0x160:ac430000swv1,0(v0)Can anybody fluent in MIPS assembly explain what is going on? Why isn't the assignment atomic? Thanks in advance.

author: Luminax
author_rank: Regular Contributor
timestamp: March 01, 2017, 08:00:22 am
content: Probably due to the fact that TMR register's upper 8-bit can't be directly written?Quote

author: andersm
author_rank: Super Contributor
timestamp: March 01, 2017, 02:45:29 pm
content: Quote from: jesuscf on March 01, 2017, 07:39:38 amMIPS is a load-store architecture. The PIC32 has extra hardware registers for atomic bit set/clear/invert, but the compiler doesn't automatically transform accesses of one register to a different one.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 01, 2017, 03:18:53 pm
content: Quote from: andersm on March 01, 2017, 02:45:29 pmThere is no reason it couldn't though. I'd go as far as to say they shouldn't even define the bits in the header file, or at least make them read-only.

author: andersm
author_rank: Super Contributor
timestamp: March 01, 2017, 03:42:26 pm
content: Quote from: mikeselectricstuff on March 01, 2017, 03:18:53 pmNo, but there's also no reason it should. It would be surprising if the compiler generated an access to a different address than what you specified.QuoteUsing C bit fields to alias hardware registers has never been a good idea.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 01, 2017, 04:11:26 pm
content: Quote from: andersm on March 01, 2017, 03:42:26 pmYes there is - optimisation.It's the sort of thing that can easily be done as a peephole optimisation in the device-specific code generator

author: jesuscf
author_rank: Frequent Contributor
timestamp: March 01, 2017, 04:33:54 pm
content: Quote from: mikeselectricstuff on March 01, 2017, 03:18:53 pm100% agree. Anyhow, I changed the line in my code:IFS0bits.T1IF=0; // Clear timer 1 interrupt flagto:IFS0CLR=0x00000010; // Clear timer 1 interrupt flag, bit 4 of IFS0Thanks again everybody, specially Mike for pointing this out. I think this is really important because every example I found on the internet uses IFS0xbits to clear the interrupt flag. On the other hand the PIC32MX Family Reference Manual examples always use IFSxCLR.By the way, Example 14-9 in the user manual (http://ww1.microchip.com/downloads/en/DeviceDoc/61132B.pdf) has a copy/paste typoCode:/*The following code example demonstrates a simple interrupt service routine for Timerinterrupts. The user’s code at this ISR handler should perform any applicationspecific operations and must clear the corresponding Timer interrupt status flagbefore exiting.*/void __ISR(_Timer_1_Vector,ipl3)Timer1Handler(void){... perform application specific operations in response to the interruptIFS0CLR = 0x00000010; // Be sure to clear the Timer 2 interrupt status}

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 01, 2017, 05:10:16 pm
content: Quote from: jesuscf on March 01, 2017, 04:33:54 pmThe mask is defined in the header file :IFS0CLR=_IFS0_T1IF_MASK;

author: andersm
author_rank: Super Contributor
timestamp: March 07, 2017, 06:44:06 pm
content: Quote from: mikeselectricstuff on March 01, 2017, 04:11:26 pmIt would only work with single-bit registers, and having them work differently from others would be insane.