PIC32 Timer Interrupt does not invokes [ Solved ] - Page 1
Forum section: electronics / general

author: abrarbaig
author_rank: Contributor
timestamp: February 26, 2018, 08:10:06 am
content: 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 Frequencyvoid __attribute__( (interrupt(ipl4srs),vector()) 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 outputLATB = 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 interrupIFS0bits.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");}}

author: fourtytwo42
author_rank: Super Contributor
timestamp: February 26, 2018, 08:23:26 pm
content: I would start by simplifying your code including deleting all the commented out stuff, it's hard to see the wood for the trees!

author: cv007
author_rank: Frequent Contributor
timestamp: February 26, 2018, 09:43:26 pm
content: IFS0CLR = 0x0200;that is bit 9datasheet 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)

author: abrarbaig
author_rank: Contributor
timestamp: February 27, 2018, 12:04:36 pm
content: I have changed the Flag and Int bit to 8. Still, RB5 does not blink. Any idea. Am I missing something in my code?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 27, 2018, 12:22:45 pm
content: 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 toTry changing to IPL4SOFT & see if that makes a difference

author: cv007
author_rank: Frequent Contributor
timestamp: February 27, 2018, 01:37:19 pm
content: #pragma config FVBUSONIO = ON // USB VBUS ON Selection (Controlled by USB Module)that is using RB5 (Vbuson), usb is controlling RB5 with that settingas Mike pointed out, you need to match the fuse SRS setting with the irq#pragma config FSRSSEL = PRIORITY_7 // SRS Select (SRS Priority 7) <-fusevoid __attribute__( (interrupt(ipl4srs), <-codealthough 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

author: Howardlong
author_rank: Super Contributor
timestamp: February 27, 2018, 02:39:48 pm
content: Some working code below with two ISRs, runs on the ESK II, one ISR is IPL5AUTO and the other IPL7SRS.Code:// 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 8MHzvoid __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 statesPLIB_PCACHE_WaitStateSet(PCACHE_ID_0,0); // Adjust as appropriate for memory and clock// Set up prefetchif (PLIB_PCACHE_ExistsPrefetchEnable(PCACHE_ID_0)){PLIB_PCACHE_PrefetchEnableSet(PCACHE_ID_0, PLIB_PCACHE_PREFETCH_ENABLE_ALL);}// Set up interrupt controllerPLIB_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 2T2CON=0;TMR2=0;PR2=SYS_CLK_FREQUENCY/1000; // 1 millisecondIPC2bits.T2IP=7;IPC2bits.T2IS=0;IFS0CLR=0x100; // Atomic version of IFS0bits.T2IF=0;IEC0bits.T2IE=1;T2CONbits.ON=1;// Set up timer 3T3CON=0;TMR3=0;PR3=SYS_CLK_FREQUENCY/1000; // 1 millisecondIPC3bits.T3IP=5;IPC3bits.T3IS=0;IFS0CLR=0x1000; // Atomic version of IFS0bits.T3IF=0;IEC0bits.T3IE=1;T3CONbits.ON=1;while (1){Nop();}return 0;}

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 27, 2018, 02:48:03 pm
content: 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 likeIFS0CLR=_IFS0_T2IF_MASK;

author: Howardlong
author_rank: Super Contributor
timestamp: February 27, 2018, 03:02:30 pm
content: Quote from: mikeselectricstuff on February 27, 2018, 02:48:03 pmI 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:#define _IFS0_T2IF_MASK 0x00000100

author: cv007
author_rank: Frequent Contributor
timestamp: February 27, 2018, 04:57:02 pm
content: 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://pic32mm0256gpm064#include "Osc.hpp"#include "Timer23.hpp"#include "Pins.hpp"#include "Irq.hpp"//config pragma settings put in config_bits.cPins 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.

author: abrarbaig
author_rank: Contributor
timestamp: February 27, 2018, 06:37:39 pm
content: 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 outputLATBbits.LATB5 = 1;// Setting up Timer 2T2CON = 0;T2CONbits.TCKPS = 7;PR2 = 65535;TMR2=0;T2CONbits.ON = 1; // Enable Timer2// Setting Timer2 interrupt//IFS0bits.T2IF = 0; // clear Timer2 int flagIFS0CLR=_IFS0_T2IF_MASK;IEC0bits.T2IE = 0; // disable Timer2 intIPC2bits.T2IP = 4; // set Timer2 priority = 4IEC0bits.T2IE = 1; // enable Timer2 intwhile(1);// Now we just wait in an infinite loop while interrupts do their thing!}// Timer2 Interrupt Service Routinevoid __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 flagIFS0CLR=_IFS0_T2IF_MASK;}

author: cv007
author_rank: Frequent Contributor
timestamp: February 27, 2018, 07:23:21 pm
content: 1. use correct timer2 bits2. 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 here4. ? ? ?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.

author: Howardlong
author_rank: Super Contributor
timestamp: February 27, 2018, 08:43:53 pm
content: Here you goCode:...void main(void){INTCONbits.MVEC=1;__builtin_mtc0(12, 0,(__builtin_mfc0(12, 0) | 0x0001)); // <-- Add this line.AD1PCFGbits.PCFG5 = 1;...orCode:...void main(void){INTCONbits.MVEC=1;asm("ei"); // <------------------- Add this line.AD1PCFGbits.PCFG5 = 1;...orCode:...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:SYSKEY = 0x00000000;SYSKEY = 0xAA996655;SYSKEY = 0x556699AA;OSCCONbits.PBDIV=0b00;

author: abrarbaig
author_rank: Contributor
timestamp: March 03, 2018, 05:15:42 pm
content: Thanks everybody , who have replied and gave your inputs. Finally Mr Howardlong's inputs worked for me.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 03, 2018, 05:29:37 pm
content: Quote from: Howardlong on February 27, 2018, 08:43:53 pmThat 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 32MX170If 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.

author: cv007
author_rank: Frequent Contributor
timestamp: March 03, 2018, 06:25:55 pm
content: 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.QuoteThey need to move the people designing light pipes into more useful positions so they can take care of more important issues.