Hot!PIC32MX795F512H UART1 Multi vectored mode issue....

Author
Avana
New Member
  • Total Posts : 3
  • Reward points : 0
  • Joined: 2017/04/19 02:14:25
  • Location: 0
  • Status: offline
2018/10/26 00:34:24 (permalink)
0

PIC32MX795F512H UART1 Multi vectored mode issue....

I am using PIC32MX795F512H (64 pin) device with XC32 (V1.43)compiler  for my project, presently I have configured two timers TIMER1 and TIMER3 for different purposes and UART1 module ,and in configuration I have programmed it to run for different speeds, and talking about interrupts I have configured for multi vectored mode as mentioned below
INTCONbits.MVEC = 1;                                    //Interrupt controller configured for Multi-vector mode
__builtin_enable_interrupts();                     //Enable Interrupt Exceptions globally
 
Note: All initializations of UART, TIMERS that I am using are done prior to enabling of global interrupts (as I have read somewhere this information)
 
#PRAGMA part:
 
#pragma config FSRSSEL = PRIORITY_7                   // SRS Select (SRS Priority 7)
#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_2                              // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_20                         // PLL Multiplier (20x 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_1                          // System PLL Output Clock Divider (PLL Divide by 1)
// DEVCFG1
#pragma config FNOSC = FRCPLL                              // Oscillator Selection Bits (FRC Osc w. PLL)
#pragma config FSOSCEN = OFF                                // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF                                          // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = OFF                              // Primary Oscillator Configuration (OFF mode)
#pragma config OSCIOFNC = OFF                             // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_2                               // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/2) 40Mhz
#pragma config FCKSM = CSDCMD                          // Clock Switch and Mon Sel (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576                      // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF                                 // Watchdog Timer Disable (WDT Disabled (SWDTEN Bit Controls))
// DEVCFG0
#pragma config DEBUG = OFF                                    // Background Debugger Enable (Debugger is disabled)
#pragma config ICESEL = ICS_PGx1                           // 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)
 
Coming to initializations and priorities of timers and uart modules:
//----------------------------Timer1 initialization---------------------------//
    T1CONbits.TON = 0;                                    //stop timer 1
    T1CON = 0X00;                                              // Pre-Scale = 1:1 (T1Clk: 80MHz)
    PR1 = 3400;                                                                    //load period reg with 3400 for 85us
    TMR1 = 0;                                                                       //clear tmr 1
    IPC1bits.T1IP = 7;                                          //priority level 7
    IFS0bits.T1IF = 0;                                                           //clear interrupt flag
    IEC0bits.T1IE = 1;                                          //enable interrupt   
    T1CONbits.TON = 1;                                                   //start the timer peripheral
//--------------------------Timer3 initialization-----------------------------//   
    T3CONbits.TON = 0;                                                    //stop timer 1
    T3CON = 0X00;                                               // Pre-Scale = 1:1 (T1Clk: 80MHz) //
    PR3 = 40000;                                                                  //load period reg 1ms
    TMR3 = 0;                                                                       //clear tmr 1
    IPC3bits.T3IP = 7;                                         //priority level 7
    IFS0bits.T3IF = 0;                                          //clear interrupt flag
    IEC0bits.T3IE = 1;                                          //Enable interrupt 
    T3CONbits.TON = 1;                                                    // start the timer peripheral
//---------------------Cache and Pre fetch initialization---------------------//
BMXCONbits.BMXWSDRM = 0;                         //Data RAM access from CPU have zero wait states    CHECONbits.PFMWS = 2;                                   //PFM Access Time Defined in Terms of SYSLK Wait States
CHECONbits.PREFEN = 1;                                  //Enable predictive pre fetch only for cacheable regions
//---------------------UART1 initialization----------------------------------------//
    U1MODE = 0x8000;                                                     //Enable UART for 8-bit data
    U1STA = 0x5400;                                         //Refer data sheet
    IPC6bits.U1IP = 7;                                                        //priority level7
    IPC6bits.U1IS = 0;                                                        //sub priority level0
    IEC0bits.U1RXIE = 1;                                                    //RX Interrupt enable
    IEC0bits.U1TXIE = 1;                                                    //TX Interrupt enable
    IFS0bits.U1RXIF = 0;                                                    //clear RX interrupt flag
    IFS0bits.U1TXIF = 0;                                    //clear TX interrupt flag
 
Below shows the ISR’s that im using for TIMER1, TIMER3 and UART1 modules:
 
void __ISR (_TIMER_1_VECTOR, IPL7SRS) Timer1Handler (void)
{
//My Application code
  IFS0bits.T1IF = 0;
}
 
void __ISR (_TIMER_3_VECTOR, IPL7SRS) Timer3Handler (void)
{
//My Application code
   IFS0bits.T3IF = 0;
}
 
void __ISR(_UART_1_VECTOR, IPL7SRS)  Uart1Handler(void)
{
    led_reg.onoff.R_led = C_ON;                                 //LED to indicate UART TX or RX interrupt
    if (IFS0bits.U1RXIF == 1)                                            //generated if RX buffer if full
    {
      //My Application code
        IFS0bits.U1RXIF = 0;                                            //Clear Receive Interrupt
    }
    if (IFS0bits.U1TXIF == 1)                                          // generated if TX buffer is empty
    {
        //My Application code
        IFS0bits.U1TXIF = 0;                                                  //Clear Transmit Interrupt
    }   
}
 
NOTE: IM using LCD and LEDS and SWITCHES for different purposes and I am using TIMERS for that purpose
 
Problem part:
  1. 1.       As I was able to run all three modules (i.e. TIMER1 (priority 7), TIMER3 (priority 7) and UART1 (did not mention any priority)) under single vectored interrupts I was able to make all the modules work perfectly (suggests the initialization part is correct) now the requirement is to implement multi vectored mode (I am forced to give priorities)and I am having some issues.
  2. 2.       I am able to run both timers perfectly (tried toggling some LED under timer ISR both worked as programmed) so my LCD, LED and Switches (multiplexed) are perfect.
  3. 3.       I am having issue with UART, as mentioned above I am using an LED to check if there is an interrupt or not, but I am unable to see LED toggling inside the UART ISR.
  4. 4.       If I put the RX and TX interrupt monitoring part under the timer3 ISR I am able to communicate my device with UART priority 0 but if I change the priority to any level entire (LDC,LEDs ) thing keep resetting periodically.
  5. 5.       I tried changing priorities for timers (timer1 priority 6 and timer3 priority 7 as such) the timer stops working (LEDs stop working).
Questions:
  1. 1.       What is the priority I have to set for each module so that everything works fine (I didn’t have any issues in single vectored mode for priorities).
  2. 2.       Do the priorities depend on the speeds of the timers or any modules I am using?
  3. 3.       If the priorities of all three modules are set to level 7 (sub priorities are 0)both timers works fine but not UART (how actually timers works on same priority and what happens with UART to reset module )
  4. 4.       Is the function written for UART ISR has any mistakes so I am unable to get the interrupt inside that function.
  5. 5.       Is there any issue with FSRSSEL = PRIORITY_7 under pragma part (I read in some website saying it matters for priorities, which I didn’t find any difference when I tried to change).
  6. 6.       Do I need much knowledge about priorities and handling, suggest any links…
#1

6 Replies Related Threads

    ROSS
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/04/08 07:14:15
    • Location: 0
    • Status: offline
    Re: PIC32MX795F512H UART1 Multi vectored mode issue.... 2018/10/26 01:35:25 (permalink)
    0
    hi
    make sure your ISR are as short as possible. your ISR priorities are all the same so this will do the basic ordering. I would set the uart the highest priority and the timers lower (as long as they are not critical). Another useful tip is to just clear the interrupt and set flag, then in the main routine read flags and process data , so making the ISR short. I have seen programs that disable the interrupts whilst dealing with another interrupt. I would set the interrupt to generate on each byte in the uart and use the uart fifo as extra time if dealing with the timers.
    I am working the same device, all interrupt driven and it works after a long debug. I have 5 uarts (3 x 115200 and 2 x 9600) with a timer to read values from an ADC using SPI on a program and a I2C device. It was impossible hard to use harmony so wrote it all in XC32. also data was unbound on the uarts so I couldn't use DMA.
    If your data is fixed length, I would use DMA, as it will gain you time as the uart interrupt will not be required. 
    You don't mention the speed of you processor clock, run it as fast as possible, also the clock division for this PIC does not give true baud rates (% error) make sure you can deal with the error or pick a clock that give exact baud. do you use an osc or an osc and 32khz xtal?  
    Have you simulated the design or run a debugger on it? I found that running the debugger really helpful as everything is in real time. 
    there is sections in the Xc32 that explain the priority interrupts, I know I have read them.
    regards
    Ross
     
     
    #2
    ROSS
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/04/08 07:14:15
    • Location: 0
    • Status: offline
    Re: PIC32MX795F512H UART1 Multi vectored mode issue.... 2018/10/26 02:02:56 (permalink)
    0
    hi
    did you include
    #include <sys/attribs.h> //necessary for Interrupt declarations
    regards
    Ross
    #3
    ROSS
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/04/08 07:14:15
    • Location: 0
    • Status: offline
    Re: PIC32MX795F512H UART1 Multi vectored mode issue.... 2018/10/26 02:15:30 (permalink)
    0
    hi
    just looked at my code the all 5 uarts are on interrupt 5,0 and my timers is on 2,3 (PWM) and 2,0 for adc. I have two timers one to produce pwm pulses for a fan and the other for ADC reads. If the uart interrupts it clears int flag and set a flag for the main program to reads data (round robin). Setting the uarts all at the same priority means then cannot interrupt each other and hence rely on round robin.
    another thing is the read all the data out of the uart fifo and check its empty, maybe you not doing this?
    regards
    Ross
    #4
    jg_ee
    Super Member
    • Total Posts : 142
    • Reward points : 0
    • Joined: 2015/04/30 10:54:52
    • Location: Colorado
    • Status: offline
    Re: PIC32MX795F512H UART1 Multi vectored mode issue.... 2018/10/26 08:47:12 (permalink)
    0
    EDIT: Mistook ROSS as OP so thought his interrupts didn't match, the below is probably not the issue.
     
    Make sure your IPLNSRS in the function names match the actual priority you have the peripherals set to. Quoted from the XC32 manual chapter 14:
     
    "
    Application code is responsible for applying the correct IPL specifier value
    to each ISR. The interrupt source’s priority level must match the ISR’s IPL
    value (e.g., IPLnSRS) or the interrupt will not be handled correctly. Mismatching priority levels may result in critical runtime problems such as a
    stack overflow that overwrites data memory. This can include corruption of
    memory reserved for use by the Debug Executive, causing the debug tool
    to behave erratically.
    "
     
    Otherwise, make a simple example with only timers, and if you still have problems include the entirety of the code and someone can help you out better.
    post edited by jg_ee - 2018/10/26 09:01:09
    #5
    Avana
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2017/04/19 02:14:25
    • Location: 0
    • Status: offline
    Re: PIC32MX795F512H UART1 Multi vectored mode issue.... 2018/11/26 01:58:35 (permalink)
    0
    Thank you for your response.

    Topic: FSRSSEL is used to select priority level that uses the shadow register.
    Response: As we were discussing about FSRSSEL, I did not know exactly the concept of shadow register, later after studying on that came to conclusion that SRS register set will not be a part of our project. Instead decided to use SOFT priority (IPL1SOFT for 2 timers and IPL6SOFT UART interrupt) also made sure same interrupt is been assigned during initializations also.
    As per your suggestion I tried making UART higher priority and timers lower priority but still problem exists i.e. unable to get UART interrupt.

    Topic: May I know what does the UART do? Both Transmit and Receive? Does TXIF asserted manually in the code?
    What does the ISR for Timer 1 and Timer 3 do? Could you try to use priority 6 for both timers and priority 7 for the UART?
    Response: UART uses both TX and RX interrupt for transmission and reception respectively
    Also TXIF is not modified in the code, just waiting for its interrupt and cleared whenever there is an interrupt.
    ISR for timer 1 is used to handle keys scanning and for other timing references (85us).
    ISR for timer 3 is used to collect data samples of ADC at 1ms each.
    Yes I did try making UART priority 7 and timers at priority 6 but still UART is not generating any interrupt.

    Question: Presently I have changed the pragma part like this #pragma config FSRSSEL = PRIORITY_4
    It means to say it follows shadow register set 4 for interrupts and initialized priorities as follows
    • Timer 1 - IPL1SOFT
    • Timer 3 - IPL1SOFT
    • UART - IPL6SOFT
    Once in while I changed SRS to SOFT, now I am able to RUN timers at different interrupt priorities. Why?
    I Guess I have given UART higher priority and both timers lower priority and since I have chosen SOFT interrupt it has to do nothing with the PRAGMA part I believe.
    Correct me if I am wrong…

    I would like to present my problem :( visualizing things on oscilloscope)
    • If two timers are made to run with (or with same priority) different priorities everything runs fine (with UART TXIE and RXIE disabled).
    • Once I set UART TXIE and RXIE, even timer interrupts will not work (not even UART inturrupt).

    Thank you
    #6
    Cino
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2010/08/24 06:49:26
    • Location: Sofia,BG
    • Status: offline
    Re: PIC32MX795F512H UART1 Multi vectored mode issue.... 2018/11/26 02:48:42 (permalink)
    0
    It is not enough to clear TX int flag when exit interrupt, it needs also to remove reason for it, because on this chip RX and Tx interrupts are asserted. So while TX buffer is empty, controller will enter TX interrupt continuously.

    Also you can add another condition to RX and TX check inside int routine, since the vector is shared, and you can enter in it for RX but to execute also TX condition (possible mismatch if you use RX,TX ring buffers)

    if ( (IFS0bits.U1TXIF == 1) && (IEC0bits.U1TXIE == 1) )
    #7
    Jump to:
    © 2019 APG vNext Commercial Version 4.5