Author Topic: How is this PIC32 ISR tied to the Timer1 interrupt?  (Read 4926 times)

0 Members and 1 Guest are viewing this topic.

Offline OsirusTopic starter

  • Newbie
  • Posts: 5
  • Country: us
How is this PIC32 ISR tied to the Timer1 interrupt?
« on: February 25, 2017, 11:51:01 pm »
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 understand why it works. What actually assigns the Timer1 interrupt to this particular ISR?

The ISR function:
Code: [Select]
#pragma interrupt InterruptHandler ipl1 vector 0
void InterruptHandler(void)
{
    // Do stuff...
   
    IFS0bits.T1IF = 0;
}

And the Timer1 config:

Code: [Select]
    T1CON = 0x8010; //Timer1 ON, Prescaler 8
    PR1 = GetPeripheralClock() / 60;

    __asm__("EI");
   
    IFS0bits.T1IF = 0; // Timer1 Interrupt Flag cleared
    IPC1bits.T1IP = 1; // Timer1 Interrupt Priority 1
    IEC0bits.T1IE = 1; // Timer1 Interrupt Enable

Aside from the priority level matching, I don't see what it is that defines this ISR for Timer1.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #1 on: February 26, 2017, 12:06:05 am »
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.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 
The following users thanked this post: Osirus

Offline OsirusTopic starter

  • Newbie
  • Posts: 5
  • Country: us
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #2 on: February 26, 2017, 12:07:33 am »
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.

I see. Thanks, that's kinda what I thought, that it was just a ISR for everything.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #3 on: February 26, 2017, 12:10:43 am »
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.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #4 on: February 26, 2017, 01:18:11 am »
Code: [Select]
#pragma interrupt InterruptHandler ipl1 vector 0
void InterruptHandler(void)
{
}
This 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.
 
The following users thanked this post: jesuscf

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #5 on: February 26, 2017, 12:00:53 pm »
Code: [Select]
#pragma interrupt InterruptHandler ipl1 vector 0
void InterruptHandler(void)
{
}
This 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.
This is one of the reasons I like Cortex-M a lot  :blah:: 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.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline jaromir

  • Supporter
  • ****
  • Posts: 338
  • Country: sk
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #6 on: February 26, 2017, 12:48:58 pm »
EEVblog forum rule 27:
In every PIC thread, somebody must explain how much better is some other MCU.
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #7 on: February 26, 2017, 01:34:42 pm »
EEVblog forum rule 27:
In every PIC thread, somebody must explain how much better is some other MCU.
I was not PICking specifically on MIPS, :-[: the last I programmed on a MIPS was with this, "some" time ago.
More like something I noticed with most other archs I dealt with, and totally a personal opinion.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline Luminax

  • Regular Contributor
  • *
  • Posts: 159
  • Country: my
    • Electronesk
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #8 on: March 01, 2017, 04:30:18 am »
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
Jack of all trade - Master of some... I hope...
 

Offline jesuscf

  • Frequent Contributor
  • **
  • Posts: 499
  • Country: ca
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #9 on: March 01, 2017, 07:39:38 am »
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.

Here is a portion of the output "xc32-objdump -D -S TimerIRQ.o" for a piece of code similar to OP's code.
Code: [Select]
IFS0bits.T1IF=0; // Clear timer 1 interrupt flag
  54: 3c020000 lui v0,0x0
  58: 8c430000 lw v1,0(v0)
  5c: 7c032104 ins v1,zero,0x4,0x1
  60: ac430000 sw v1,0(v0)

Can anybody fluent in MIPS assembly explain what is going on?  Why isn't the assignment atomic?  Thanks in advance.
Homer: Kids, there's three ways to do things; the right way, the wrong way and the Max Power way!
Bart: Isn't that the wrong way?
Homer: Yeah, but faster!
 

Offline Luminax

  • Regular Contributor
  • *
  • Posts: 159
  • Country: my
    • Electronesk
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #10 on: March 01, 2017, 08:00:22 am »
Probably due to the fact that TMR register's upper 8-bit can't be directly written?

Quote
A write to the high byte of Timer1 must also take place
through the TMR1H Buffer register. The Timer1 high
byte is updated with the contents of TMR1H when a
write occurs to TMR1L. This allows a user to write all
16 bits to both the high and low bytes of Timer1 at once.
The high byte of Timer1 is not directly readable or
writable in this mode. All reads and writes must take
place through the Timer1 High Byte Buffer register.
Writes to TMR1H do not clear the Timer1 prescaler.
The prescaler is only cleared on writes to TMR1L.
Jack of all trade - Master of some... I hope...
 
The following users thanked this post: jesuscf

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #11 on: March 01, 2017, 02:45:29 pm »
Code: [Select]
IFS0bits.T1IF=0; // Clear timer 1 interrupt flag
  54: 3c020000 lui v0,0x0 # Load upper 16 bits of IFS0 address
  58: 8c430000 lw v1,0(v0) # Load IFS0 to CPU register
  5c: 7c032104 ins v1,zero,0x4,0x1 # Clear bit
  60: ac430000 sw v1,0(v0) # Store CPU register to IFS0

Can anybody fluent in MIPS assembly explain what is going on?  Why isn't the assignment atomic?  Thanks in advance.
MIPS 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.
 
The following users thanked this post: jesuscf

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #12 on: March 01, 2017, 03:18:53 pm »
Code: [Select]
IFS0bits.T1IF=0; // Clear timer 1 interrupt flag
  54: 3c020000 lui v0,0x0 # Load upper 16 bits of IFS0 address
  58: 8c430000 lw v1,0(v0) # Load IFS0 to CPU register
  5c: 7c032104 ins v1,zero,0x4,0x1 # Clear bit
  60: ac430000 sw v1,0(v0) # Store CPU register to IFS0

Can anybody fluent in MIPS assembly explain what is going on?  Why isn't the assignment atomic?  Thanks in advance.
MIPS 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.
There 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.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 
The following users thanked this post: jesuscf

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #13 on: March 01, 2017, 03:42:26 pm »
There is no reason it couldn't though.
No, 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.

Quote
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.
Using C bit fields to alias hardware registers has never been a good idea.

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #14 on: March 01, 2017, 04:11:26 pm »
There is no reason it couldn't though.
No, but there's also no reason it should.

Yes there is - optimisation.
It's the sort of thing that can easily be done as a peephole optimisation in the device-specific code generator
« Last Edit: March 01, 2017, 04:13:20 pm by mikeselectricstuff »
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline jesuscf

  • Frequent Contributor
  • **
  • Posts: 499
  • Country: ca
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #15 on: March 01, 2017, 04:33:54 pm »
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.

100% agree.  Anyhow, I changed the line in my code:

IFS0bits.T1IF=0; // Clear timer 1 interrupt flag

to:

IFS0CLR=0x00000010; // Clear timer 1 interrupt flag, bit 4 of IFS0

Thanks 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 typo :-DD

Code: [Select]
/*
The following code example demonstrates a simple interrupt service routine for Timer
interrupts. The user’s code at this ISR handler should perform any application
specific operations and must clear the corresponding Timer interrupt status flag
before exiting.
*/
void __ISR(_Timer_1_Vector,ipl3)Timer1Handler(void)
{
    ... perform application specific operations in response to the interrupt
    IFS0CLR = 0x00000010; // Be sure to clear the Timer 2 interrupt status
}
Homer: Kids, there's three ways to do things; the right way, the wrong way and the Max Power way!
Bart: Isn't that the wrong way?
Homer: Yeah, but faster!
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #16 on: March 01, 2017, 05:10:16 pm »
IFS0CLR=0x00000010; // Clear timer 1 interrupt flag, bit 4 of IFS0
The mask is defined in the header file :
IFS0CLR=_IFS0_T1IF_MASK;
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 
The following users thanked this post: jesuscf

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: How is this PIC32 ISR tied to the Timer1 interrupt?
« Reply #17 on: March 07, 2017, 06:44:06 pm »
Yes there is - optimisation.
It's the sort of thing that can easily be done as a peephole optimisation in the device-specific code generator
It would only work with single-bit registers, and having them work differently from others would be insane.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf