Author Topic: PIC32 Timer Interrupt does not invokes [ Solved ]  (Read 4764 times)

0 Members and 1 Guest are viewing this topic.

Offline abrarbaigTopic starter

  • Contributor
  • Posts: 30
  • Country: sa
PIC32 Timer Interrupt does not invokes [ Solved ]
« on: February 26, 2018, 08:10:06 am »
Hi I am have this code written for PIC32MX795F512L. It does not work. Any idea?
 Config Bits
// PIC32MX795F512L Configuration Bit Settings

// 'C' source line config statements

// DEVCFG3
// USERID = No Setting
#pragma config FSRSSEL = PRIORITY_7     // SRS Select (SRS Priority 7)
#pragma config FMIIEN = ON              // Ethernet RMII/MII Enable (MII Enabled)
#pragma config FETHIO = ON              // Ethernet I/O Pin Select (Default Ethernet I/O)
#pragma config FCANIO = ON              // CAN I/O Pin Select (Default CAN I/O)
#pragma config FUSBIDIO = ON            // USB USID Selection (Controlled by the USB Module)
#pragma config FVBUSONIO = ON           // USB VBUS ON Selection (Controlled by USB Module)

// DEVCFG2
#pragma config FPLLIDIV = DIV_12        // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_24         // PLL Multiplier (24x Multiplier)
#pragma config UPLLIDIV = DIV_12        // USB PLL Input Divider (12x Divider)
#pragma config UPLLEN = OFF             // USB PLL Enable (Disabled and Bypassed)
#pragma config FPLLODIV = DIV_256       // System PLL Output Clock Divider (PLL Divide by 256)

// DEVCFG1
#pragma config FNOSC = FRCDIV           // Oscillator Selection Bits (Fast RC Osc w/Div-by-N (FRCDIV))
#pragma config FSOSCEN = ON             // Secondary Oscillator Enable (Enabled)
#pragma config IESO = ON                // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = OFF            // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_8           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))

// DEVCFG0
#pragma config DEBUG = OFF              // Background Debugger Enable (Debugger is disabled)
#pragma config ICESEL = ICS_PGx2        // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <p32xxxx.h>                // Include PIC32 specifics header file
#include <xc.h>                  // Include the PIC32 Peripheral Library
#include <stdlib.h>
#include <sys/attribs.h>
//#include <int.h>
// Defines
#define SYSCLK 40000000L            // System Clock Frequency
void __attribute__( (interrupt(ipl4srs),
vector(8))) Timer2Handler ( void );
 
void  Timer2Handler(void)
{
        LATBINV = 0X20;
        IFS0CLR = 0x0200;
    /* ISR code inserted here */
      // clear Timer2 int flag, IFS0<9>
}
 main (void){
     asm("ei");
   INTCONbits.MVEC=1;     
    AD1PCFG = 0XFFFF;
    TRISBbits.TRISB5 = 0;   // Set RB5 as digital output
    LATB = 0x20;
    T2CON = 0;
    PR2 = 65535;
    TMR2=0;
    T2CON = 0X8070;
    IEC0<9>=0;  // disable Timer2 int, IEC0<9>
    IFS0<9>=0;  // clear Timer2 int flag, IFS0<9>
    IPC2CLR = 0x001f; // clear Timer2 priority/subpriority fields IPC2<4:0>
    //IPC2 = 0x0010; // set Timer2 int priority = 4, IPC2<4:2>
    IPC2bits.T2IP=4;    //Priority 2
    //IEC0<9>=1;       // enable Timer2 int, IEC0<9>
    IEC0bits.T2IE=1;   //Enable interrup
    IFS0bits.T2IF=0;   //Clear the flag
     // Now we just wait in an infinite loop while interrupts do their thing!
    __asm__ volatile ("ei");
    while(1){
       //LATAINV = 0X20;
        __asm__ volatile ("nop");
    }
       }
« Last Edit: March 04, 2018, 10:57:43 am by abrarbaig »
 

Offline fourtytwo42

  • Super Contributor
  • ***
  • Posts: 1184
  • Country: gb
  • Interested in all things green/ECO NOT political
Re: PIC32 Timer Interrupt does not invokes
« Reply #1 on: February 26, 2018, 08:23:26 pm »
I would start by simplifying your code including deleting all the commented out stuff, it's hard to see the wood for the trees!
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: PIC32 Timer Interrupt does not invokes
« Reply #2 on: February 26, 2018, 09:43:26 pm »
IFS0CLR = 0x0200;
that is bit 9
datasheet shows T2IF is bit 8

(using the debugger would help you out- you could have seen you were stuck in the isr, you can also check if you are hitting all the right bits when setting up)
« Last Edit: February 27, 2018, 03:44:12 am by cv007 »
 

Offline abrarbaigTopic starter

  • Contributor
  • Posts: 30
  • Country: sa
Re: PIC32 Timer Interrupt does not invokes
« Reply #3 on: February 27, 2018, 12:04:36 pm »
 I have changed the Flag and Int bit to 8. Still, RB5 does not blink. Any idea. Am I missing something in my code?
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13742
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32 Timer Interrupt does not invokes
« Reply #4 on: February 27, 2018, 12:22:45 pm »
You're using the SRS  - I've only ever used one PIC32 that supports this so memory may be fuzzy - ISTR there is another register, PRISSS, that needs to be set to select which SRS to use, or tell it which interrupt to assign it to

Try changing to IPL4SOFT & see if that makes a difference
 
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: PIC32 Timer Interrupt does not invokes
« Reply #5 on: February 27, 2018, 01:37:19 pm »
#pragma config FVBUSONIO = ON           // USB VBUS ON Selection (Controlled by USB Module)

that is using RB5 (Vbuson), usb is controlling RB5 with that setting


as Mike pointed out, you need to match the fuse SRS setting with the irq
#pragma config FSRSSEL = PRIORITY_7     // SRS Select (SRS Priority 7) <-fuse
void __attribute__( (interrupt(ipl4srs),  <-code

although I don't think in this case it causes a problem (since the main loop does nothing).

In fact, I just use (via macro) -
__attribute__((vector(VECTOR_NUM),interrupt))
and let the isr code figure it out- I think its worth the few extra cycles
« Last Edit: February 27, 2018, 02:05:58 pm by cv007 »
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 5317
  • Country: gb
Re: PIC32 Timer Interrupt does not invokes
« Reply #6 on: February 27, 2018, 02:39:48 pm »
Some working code below with two ISRs, runs on the ESK II, one ISR is IPL5AUTO and the other IPL7SRS.

Code: [Select]
// Include dir: c:/microchip/harmony/v2_05_01/framework/
// Lib: C:\microchip\harmony\v2_05_01\bin\framework\peripheral\PIC32MX795F512L_peripherals.a

// PIC32MX795F512L Configuration Bit Settings

// 'C' source line config statements

// DEVCFG3
// USERID = No Setting
#pragma config FSRSSEL = PRIORITY_7     // SRS Select (SRS Priority 7)
#pragma config FMIIEN = OFF             // Ethernet RMII/MII Enable (RMII Enabled)
#pragma config FETHIO = OFF             // Ethernet I/O Pin Select (Alternate Ethernet I/O)
#pragma config FCANIO = OFF             // CAN I/O Pin Select (Alternate CAN I/O)
#pragma config FUSBIDIO = OFF           // USB USID Selection (Controlled by Port Function)
#pragma config FVBUSONIO = OFF          // USB VBUS ON Selection (Controlled by Port Function)

// DEVCFG2
#pragma config FPLLIDIV = DIV_12        // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_24         // PLL Multiplier (24x Multiplier)
#pragma config UPLLIDIV = DIV_12        // USB PLL Input Divider (12x Divider)
#pragma config UPLLEN = OFF             // USB PLL Enable (Disabled and Bypassed)
#pragma config FPLLODIV = DIV_256       // System PLL Output Clock Divider (PLL Divide by 256)

// DEVCFG1
#pragma config FNOSC = FRC              // Oscillator Selection Bits (Fast RC Osc (FRC))
#pragma config FSOSCEN = OFF            // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF               // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = OFF            // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = ON            // CLKO Output Signal Active on the OSCO Pin (Enabled)
#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSECMD           // Clock Switching and Monitor Selection (Clock Switch Enable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))

// DEVCFG0
#pragma config DEBUG = ON               // Background Debugger Enable (Debugger is enabled)
#pragma config ICESEL = ICS_PGx2        // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <sys/attribs.h>
#include "peripheral/peripheral.h"
#include <stdint.h>

#define SYS_CLK_FREQUENCY 8000000 // Basic FRC frequency is 8MHz

void __attribute__((vector(_TIMER_2_VECTOR),interrupt(IPL7SRS))) __Timer2Interrupt(void)
{
    static int i=0;
   
    IFS0CLR=0x100; // Atomic version of IFS0bits.T2IF=0;
   
    i++;
   
    if (i>=500)
    {
        i=0;
        LATDINV=1; // Toggle LED
    }
}

void __attribute__((vector(_TIMER_3_VECTOR),interrupt(IPL5AUTO))) __Timer3Interrupt(void)
{
    static int i=0;
   
    IFS0CLR=0x1000; // Atomic version of IFS0bits.T3IF=0;
   
    i++;
   
    if (i>=400)
    {
        i=0;
        LATDINV=2; // Toggle LED
    }
}

static void CPUInit(void)
{
    // Note that cache is already configured by startup code
    // C:\Program Files\Microchip\xc32\v1.42\pic32-libs\libpic32\stubs\pic32_init_cache.S
   
    // Set up wait states
    PLIB_PCACHE_WaitStateSet(PCACHE_ID_0,0); // Adjust as appropriate for memory and clock
   
    // Set up prefetch
    if (PLIB_PCACHE_ExistsPrefetchEnable(PCACHE_ID_0))
    {
        PLIB_PCACHE_PrefetchEnableSet(PCACHE_ID_0, PLIB_PCACHE_PREFETCH_ENABLE_ALL);
    }
   
    // Set up interrupt controller
    PLIB_INT_MultiVectorSelect(INT_ID_0);
    PLIB_INT_Enable(INT_ID_0);
}

int main(void)
{
    CPUInit();
   
    TRISDbits.TRISD0=0;
    TRISDbits.TRISD1=0;
    TRISDbits.TRISD2=0;
   
    // Set up timer 2
    T2CON=0;
    TMR2=0;
    PR2=SYS_CLK_FREQUENCY/1000; // 1 millisecond
    IPC2bits.T2IP=7;
    IPC2bits.T2IS=0;
    IFS0CLR=0x100; // Atomic version of IFS0bits.T2IF=0;
    IEC0bits.T2IE=1;
    T2CONbits.ON=1;
   
    // Set up timer 3
    T3CON=0;
    TMR3=0;
    PR3=SYS_CLK_FREQUENCY/1000; // 1 millisecond
    IPC3bits.T3IP=5;
    IPC3bits.T3IS=0;
    IFS0CLR=0x1000; // Atomic version of IFS0bits.T3IF=0;
    IEC0bits.T3IE=1;
    T3CONbits.ON=1;
   
    while (1)
    {
        Nop();
    }
    return 0;
}

 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13742
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32 Timer Interrupt does not invokes
« Reply #7 on: February 27, 2018, 02:48:03 pm »
Howar'd example reminded me that one annoyance is that using bitfields like IFS0bits.T2IF do not compile to atomic operations ( this has bitten me a couple of times) , but there are some masks defined in the compiler include files to make atomic ops more readable. From memory these are something like 

IFS0CLR=_IFS0_T2IF_MASK;
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 5317
  • Country: gb
Re: PIC32 Timer Interrupt does not invokes
« Reply #8 on: February 27, 2018, 03:02:30 pm »
Howar'd example reminded me that one annoyance is that using bitfields like IFS0bits.T2IF do not compile to atomic operations ( this has bitten me a couple of times) , but there are some masks defined in the compiler include files to make atomic ops more readable. From memory these are something like 

IFS0CLR=_IFS0_T2IF_MASK;

I had a mental block and couldn't immediately find them in the header file so I hacked it for this quick example, but they are indeed there in the p32mx795f512l.h file, e.g.:

Code: [Select]
#define _IFS0_T2IF_MASK                          0x00000100


« Last Edit: February 27, 2018, 03:10:37 pm by Howardlong »
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: PIC32 Timer Interrupt does not invokes
« Reply #9 on: February 27, 2018, 04:57:02 pm »
The op's  code runs ok in the simulator (when using correct timer2 bits), and B5 toggles in the irq, but with the usb in control of B5 by the fuse setting, no output.

I posted this earlier, but deleted. I'll post again even though this may be incorrect place to post this.
I created c++ 'drivers' for all pic32mm peripherals, and am quite happy to use that instead of what we have to normally go through to get things working on these micros. Compare the code in above posts with something like this-
Code: [Select]
//pic32mm0256gpm064
#include "Osc.hpp"
#include "Timer23.hpp"
#include "Pins.hpp"
#include "Irq.hpp"
//config pragma settings put in config_bits.c

Pins led(Pins::B5, Pins::OUT);
Timer23 t2(Timer23::TMR2);

ISRautoflag(TIMER_2){
    led.invert();
}} //<-yes, two of them :)

int main (void){
    Osc::pll_set(Osc::MUL12, Osc::DIV4);
    Irq::init(Irq::TIMER_2, 4, 0, true);
    t2.prescale(Timer23::PS256);
    t2.on();
    Irq::enable_all();
    for(;;);
}
I use no xc includes, no Harmony, no MCC, no defines (ok, 2 for my isr macros), and everything becomes more readable and easy to use. Most reg access will end up using CLR/SET also.
If anyone wants to take a look for ideas, I can post the github url.

 

Offline abrarbaigTopic starter

  • Contributor
  • Posts: 30
  • Country: sa
Re: PIC32 Timer Interrupt does not invokes
« Reply #10 on: February 27, 2018, 06:37:39 pm »
Here is the updated code with incorporating few suggestions in the forum. No luck yet. I am testing it in debug mode . Using MPLABXIDE v 4.05 XC32 v 1.43 simulator (I/O Pins, and Logic Analyzer)
/ Configuration Bits
#pragma config FNOSC = FRCPLL       // Internal Fast RC oscillator (8 MHz) w/ PLL
#pragma config FPLLIDIV = DIV_2     // Divide FRC before PLL (now 4 MHz)
#pragma config FPLLMUL = MUL_20     // PLL Multiply (now 80 MHz)
#pragma config FPLLODIV = DIV_2     // Divide After PLL (now 40 MHz)
                                    // see figure 8.1 in datasheet for more info
#pragma config FWDTEN = OFF         // Watchdog Timer Disabled
#pragma config ICESEL = ICS_PGx1    // ICE/ICD Comm Channel Select
//#pragma config JTAGEN = OFF         // Disable JTAG
#pragma config FSOSCEN = OFF        // Disable Secondary Oscillator
#include <p32xxxx.h>
#include <xc.h>
#include <sys/attribs.h>

 void main(void){
     INTCONbits.MVEC=1;
     AD1PCFGbits.PCFG5 = 1;
    TRISBbits.TRISB5 = 0;   // Set RB5 as digital output
    LATBbits.LATB5 = 1;
   
    // Setting up Timer 2
    T2CON = 0;
    T2CONbits.TCKPS = 7;
    PR2 = 65535;
    TMR2=0;
    T2CONbits.ON = 1; // Enable Timer2
   
    // Setting Timer2 interrupt 
    //IFS0bits.T2IF = 0;  // clear Timer2 int flag
    IFS0CLR=_IFS0_T2IF_MASK;
    IEC0bits.T2IE = 0;  // disable Timer2 int
    IPC2bits.T2IP = 4; // set Timer2 priority = 4
    IEC0bits.T2IE = 1;       // enable Timer2 int
    while(1);
    // Now we just wait in an infinite loop while interrupts do their thing!
     }
 // Timer2 Interrupt Service Routine
void __attribute__( (interrupt(ipl4auto),
vector(_TIMER_2_VECTOR))) Timer2Handler (void);
void Timer2Handler(void)
{
/* ISR code inserted here */
    LATBbits.LATB5 = ~LATBbits.LATB5;
    //IFS0bits.T2IF = 0;  // clear Timer2 int flag
    IFS0CLR=_IFS0_T2IF_MASK;
}
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: PIC32 Timer Interrupt does not invokes
« Reply #11 on: February 27, 2018, 07:23:21 pm »
1. use correct timer2 bits

2. use correct fuse settings for B5/Vbuson (we will assume FVBUSONIO is correct now, but we cannot see)

3. you need to enable global interrupts <-you are here

4. ? ? ?



I copied your code, put in project, ran debug (simulator), put breakpoint in isr, no get to isr. Why. Oh, I see, no global irq enable. Add global irq enable, run again, now getting to isr, see that b5 is changing each time. That took a minute or two to do all that.
« Last Edit: February 27, 2018, 07:36:40 pm by cv007 »
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 5317
  • Country: gb
Re: PIC32 Timer Interrupt does not invokes
« Reply #12 on: February 27, 2018, 08:43:53 pm »
Here you go

Code: [Select]
...
void main(void){
     INTCONbits.MVEC=1;
     __builtin_mtc0(12, 0,(__builtin_mfc0(12, 0) | 0x0001)); //  <-- Add this line.
     AD1PCFGbits.PCFG5 = 1;
...

or

Code: [Select]
...
 void main(void){
     INTCONbits.MVEC=1;
     asm("ei"); //  <------------------- Add this line.
     AD1PCFGbits.PCFG5 = 1;
...

or

Code: [Select]
...
 void main(void){
     INTCONbits.MVEC=1;
     __builtin_enable_interrupts(void); //  <--------- Add this line.
     AD1PCFGbits.PCFG5 = 1;
...

All three work.

As an aside, you might want to speed it up a bit though, the device is running at 40MHz, but the PBCLK is at its default div-by-8.

40MHz ---> pbclk /8 ---> TMR2 prescale /256 ---> PR2 /65536 ===> 3.36s.

At only 40MHz, you can run the PBCLK at SYSCLK frequencies:

Code: [Select]
    SYSKEY = 0x00000000;
    SYSKEY = 0xAA996655;
    SYSKEY = 0x556699AA;     
    OSCCONbits.PBDIV=0b00;

 

Offline abrarbaigTopic starter

  • Contributor
  • Posts: 30
  • Country: sa
Re: PIC32 Timer Interrupt does not invokes
« Reply #13 on: March 03, 2018, 05:15:42 pm »
Thanks everybody , who have replied and gave your inputs. Finally Mr Howardlong's inputs worked for me.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13742
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32 Timer Interrupt does not invokes
« Reply #14 on: March 03, 2018, 05:29:37 pm »
Here you go
Code: [Select]

 void main(void){
     INTCONbits.MVEC=1;
     asm("ei"); //  <------------------- Add this line.
     AD1PCFGbits.PCFG5 = 1;
...
...
 void main(void){
     INTCONbits.MVEC=1;
     __builtin_enable_interrupts(void); //  <--------- Add this line.
   
That reminds me of an undocumented and very nasty bug I spent a day finding a while ago. I don't know if it applies to all PIC32s - I was using a 32MX170

If there is a pending enabled interrupt, the above code will cause a reset. (Most of the time you'll have cleared pending ints first, but in the case of an external INT input, it can get re-asserted at any time - my code was resetting if the INT input happenned to be active at startup)

It seems that it takes more than one cycle for the MVEC setting to fully happen, so enabling ints immediately afterwads sends it into the weeds ( and doesn't generate a general exception)

To avoid future heartaches, I always add a NOP before the  asm("ei");

I did submit a support ticket, and they acknowledged they were able to repeat it, but I never heard anything back.


Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: PIC32 Timer Interrupt does not invokes
« Reply #15 on: March 03, 2018, 06:25:55 pm »
In the pic32mm they set MVEC in the startup code (source- crt0.S), but do not for the others, but I'm not sure why.
Quote
I did submit a support ticket, and they acknowledged they were able to repeat it, but I never heard anything back.
They need to move the people designing light pipes into more useful positions so they can take care of more important issues.



 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf