PIC32 Multiple interrupts issue

Discussion in 'Embedded Systems and Microcontrollers' started by kasula4, Apr 21, 2010.

  1. kasula4

    kasula4 Thread Starter New Member

    Joined:
    Apr 9, 2010
    4
    0
    Hello,
    I am trying to use multiple interrupts in PIC32 microcontroller. When I use 2 interrupts lets say UART and 1 timer the microcontroller is working fine but when I use UART and 2 timer interrupts the microcontroller freezes. I have the following code in the interrupts.

    #include "Tao4ch_defs.h"
    // UART 2 interrupt handler
    // it is set at priority level 2

    void __ISR(_UART_2A_VECTOR, ipl3) _U2ARXInterrupt(void)
    { char ch;

    IFS1bits.U2ARXIF = 0; // Reset the RX interrupt flag.

    ch = U2ARXREG;

    Char_in = ch;

    Char_cap = 1; // Flag to indicate a character has been received.
    // 0x0A is a line feed. Some terms attach linefeeds so must discard them.

    if (ch != 0x0D && ch != 0x0A) { // If the rx'd char is not 'enter' or lf

    Rx_buff [Rx_index] = ch; // load the rx buffer with the char and

    Rx_index++; // increment the index.

    if (Rx_index >= RX_BUF_LEN)

    Rx_index = 0;
    }

    if (ch == 13) { // When the 'enter' char is received

    Rx_buff[Rx_index] = 0; // put a null char in the string.

    Rx_index = 0; // and reset the index.

    Com_flag = 1; // Com flag should be reset after the
    } // buffer has been read.
    // string is processed.

    }


    // interrput code for the timer 1

    void __ISR( _TIMER_1_VECTOR, ipl2) _T1Interrupt( void)
    {
    int i;

    asm("ei"); //To enable interrupts
    // clear interrupt flag and exit

    IFS0bits.T1IF = 0;

    sampleBuffer[sampleIndex].re = read_ext_adc1(5) - 25485; // read the ADC into the real part of the samplebuffer

    // increment the sampleIndex
    if (sampleIndex == (N-1))
    {
    sampleIndex = 0;
    }
    else
    {
    sampleIndex++;
    }




    } // T3 Interrupt


    void __ISR( _TIMER_3_VECTOR, ipl1) _T3Interrupt( void)
    { asm("ei");

    IFS0bits.T3IF = 0;

    //do something

    }


    Thanks
     
    #1
  2. rjenkins

    rjenkins AAC Fanatic!

    Joined:
    Nov 6, 2005
    1,015
    67
    Try to avoid doing any complex processing within an interrupt, keep it short so you do not have to re-enable interrupts while one is active.

    Another speed-up is to make buffers power-of-two lengths and simply do
    rx_index++;
    rx_index &= 0x1f; to limit the index to 0-31 or whatever.

    I usually poll any i/o within a timer routine, cycling fast enough to ensure no overruns.

    I'd generally run it at about 10KHz, but I have used in excess of 250KHz on PIC16.

    Examples, comments added for info:
    Code ( (Unknown Language)):
    1.  
    2. // Storage declarations
    3. int     cd_tbuf[32]; // The data buffer
    4. int     cd_tbufi; // Buffer Input pointer
    5. int     cd_tbufo; // Buffer Output pointer
    6. int     cd_tbufc; // Buffer Count
    7.  
    8. // Initialisation
    9. void rs_clear(void) {
    10.     rs_tbufi = 0;
    11.     rs_tbufo = 0;
    12.     rs_tbufc = 0;
    13. }            
    14.  
    15. // Routine to buffer TX characters
    16. void rs_tput(int i) {
    17.     rs_tbuf[rs_tbufi++] = i; // Store data, inc pointer
    18.     rs_tbufc++; // Inc buffer count
    19.     rs_tbufi &= 0x1f;  // Pointer roll-over to zero.
    20. }
    21.  
    22. // TX poll routine called from within RTC interrupt
    23. void rs_send(void) {
    24. // If nothing to send, quit.
    25.     if(rs_tbufi == rs_tbufo) {
    26.         rs_tbufc = 0;
    27.         return;
    28.     }
    29.  
    30. // Otherwise, if UART is not busy,
    31.     if(rs_tx_rdy())    {                
    32.         putchar(rs_tbuf[rs_tbufo++]); // Send character & inc pointe
    33.         rs_tbufo &= 0x1f; // Roll-over
    34.         rs_tbufc--; // Dec buffer count
    35.      }    
    36. }
    37.  
    38.  
    (Note - naming - That's pulled out of a program that has multiple comms routines named with different prefixes, that particular one just happened to be rs_... ).
     
    #2
  3. BMorse

    BMorse Senior Member

    Joined:
    Sep 26, 2009
    2,673
    233
    Do you have Multi vector Interrupts Enabled??

    here is a code snippet I used with the Pic32 interrupts.....
    at the bottom of the code, you can see my Interrupt initialization routine where I enable the Multi vector interrupts..... and as RJenkins had said, try not to do too much in an interrupt routine, You could very well miss a different interrupt....
    Code ( (Unknown Language)):
    1. /*
    2. // Interrupts
    3. */
    4. //****************************************************************
    5. #ifndef _bINT_HEADER_FILE
    6. #define _bINT_HEADER_FILE
    7.  
    8. //****************************************************************
    9. void __ISR( _RTCC_VECTOR,ipl1) RTCCInterrupt( void)
    10. {
    11.     MODE_CHANGED=1;
    12.     RtccAlarmDisable();
    13.     SYS_MODE++;                //Increment SYS_MODE to reflect current state of system
    14.     mRTCCClearIntFlag();    //Clear Interrupt Flag
    15.    
    16. }//RTCC Interrupt
    17.  
    18. void __ISR(_UART1_VECTOR,ipl2) IntUart1Handler(void)
    19. {
    20.     //is this an RX interrupt??
    21.     if (mU1RXGetIntFlag())
    22.     {//clear the RX interrupt flag
    23.         mU1RXClearIntFlag();
    24.         //putcUART2(ReadUART1();
    25.     }//RX Interrupt
    26.     if (mU1TXGetIntFlag())
    27.     {//we dont care for it so just clear it
    28.         mU1TXClearIntFlag();
    29.     }//End TX Interrupt
    30. }
    31.  
    32. void __ISR( _EXTERNAL_2_VECTOR,ipl3) INT2InterruptHandler(void)    //PIR Sensor Interrupt
    33. {
    34.     //mPORTDToggleBits(BIT_0);
    35.     asm ("ei");
    36.         Motion=1;            //Set Flag
    37.         Vanity_On=1;        //Set Flag
    38.         mSSR1_ON();            //Turn On Vanity Light
    39.         LOD=0;                //Reset Light On Delay
    40.         mINT2ClearIntFlag();
    41. }//End INT2
    42.  
    43. void __ISR( _EXTERNAL_1_VECTOR,ipl5) INT1InterruptHandler(void)    //MPR084Q Interrupt Source,
    44.                                                                 //Not used right now, using polling method instead
    45. {
    46.     asm ("ei");
    47.     mINT1ClearIntFlag();
    48. }//End INT1
    49.  
    50. //****************************************************************
    51. #endif
    52.  
    53. Init_Interrupts()
    54. {
    55.     mRTCCSetIntPriority(1);                //Set Real Time Clock And Calendar Priority Level
    56.     mRTCCClearIntFlag();                //Clear RTCC Interrupt Flag
    57.     mINT2SetIntPriority(3);                //Set Interrupt Priority for External Int Source 0    
    58.     mINT1SetIntPriority(5);                //Set Interrupt Priority for External Int Source 1
    59.     INTEnableSystemMultiVectoredInt();        //Enable Multi vectored Interrupts
    60.     mINT2IntEnable(1);                //Enable External Interrupt 0
    61.     mINT1IntEnable(1);                //Enable External Interrupt 1
    62. }//End Init Interrupts
    63.  
    64.  
    P.S.
    I also noticed when I was working with the Pic32, that you have to start with the lowest priority first..... if you notice in my code ipl1 is the first routine, all the way down to ipl5....

    B. Morse
     
    Last edited: Apr 22, 2010
    #3
  4. kasula4

    kasula4 Thread Starter New Member

    Joined:
    Apr 9, 2010
    4
    0
    Thanks for the replies. I have a question for BMORSE. I think IPL7 is the highest priority so I think asm(ei) should be used in lower priorities IPL(0) etc.., were you able to run the same code successfully.
     
    #4
  5. BMorse

    BMorse Senior Member

    Joined:
    Sep 26, 2009
    2,673
    233

    You are right ipl7 is the highest priority level, I used the asm (ei), just to make sure other interrupts are still enabled when entering that ISR.....

    And yes, the way I have the ISR's set up, seems to work very well for me....

    B. Morse
     
    #5
Loading...