• AVR Freaks

AnsweredHot!Stuck with UART2 RX interrupt

Author
BHUSHAN
Starting Member
  • Total Posts : 62
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
2019/04/25 04:25:46 (permalink)
0

Stuck with UART2 RX interrupt

I am using PIC32MX795F512L for my project. In the project I am enabling UART2 module with RX interrupt. If I using polling method then I am able to receive data on my terminal but as soon as I enable RX interrupt problem starts. Program Counter is not reaching ISR at all. Even after going through many posts I am unable to solve the issue. I think I am messing up with isr declaration. I am using C32 compiler(v2.02) and MPLAB ide v8.88. I have attached my code  with this post.
 
Thanks
#1
dvvrcognizant
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2019/03/13 07:48:11
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/25 05:17:18 (permalink)
0
Did you enable Rx interrupt for UART2?
#2
BHUSHAN
Starting Member
  • Total Posts : 62
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/25 05:25:51 (permalink)
0
dvvrcognizant
Did you enable Rx interrupt for UART2?


In UART_init() I am enabling UART2 RX interrupt (line number 3 to 5 of the mentioned function). Am I doing something wrong?
#3
KTrenholm
Super Member
  • Total Posts : 710
  • Reward points : 0
  • Joined: 2012/08/08 14:04:23
  • Location: Connecticut, USA
  • Status: online
Re: Stuck with UART2 RX interrupt 2019/04/25 06:37:55 (permalink)
0
Your comment in the ISR says:

 
PORTB = 0xff;    //PORTB is not becoming HIGH thus confirming that this ISR has not been entered
 

I don't think that's doing what you think it's doing.  Read pins with PORTx.  Write an output using LATx.
If that's the only way you are determining if your ISR is being entered, you may be firing the ISR and not realizing.
post edited by KTrenholm - 2019/04/25 06:40:42
#4
dvvrcognizant
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2019/03/13 07:48:11
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/25 06:52:47 (permalink)
0
SYS_MODULE_OBJ DRV_USART0_Initialize(void)
{
uint32_t clockSource;
DRV_USART_OBJ *dObj = (DRV_USART_OBJ*)NULL;
dObj = &gDrvUSART0Obj;
/* Disable the USART module to configure it*/
PLIB_USART_Disable (USART_ID_1);
dObj->transmitCallback = NULL;
dObj->receiveCallback = NULL;
dObj->errorCallback = NULL;
/* Initialize the USART based on configuration settings */
PLIB_USART_InitializeModeGeneral(USART_ID_1,
false, /*Auto baud*/
false, /*LoopBack mode*/
false, /*Auto wakeup on start*/
false, /*IRDA mode*/
false); /*Stop In Idle mode*/
/* Set the line control mode */
PLIB_USART_LineControlModeSelect(USART_ID_1, DRV_USART_LINE_CONTROL_8NONE1);
/* We set the receive interrupt mode to receive an interrupt whenever FIFO
is not empty */
PLIB_USART_InitializeOperation(USART_ID_1,
USART_RECEIVE_FIFO_ONE_CHAR,
USART_TRANSMIT_FIFO_IDLE,
USART_ENABLE_TX_RX_USED);
/* Get the USART clock source value*/
clockSource = SYS_CLK_PeripheralFrequencyGet ( CLK_BUS_PERIPHERAL_1 );
/* Set the baud rate and enable the USART */
PLIB_USART_BaudSetAndEnable(USART_ID_1,
clockSource,
9600); /*Desired Baud rate value*/
/* Clear the interrupts to be on the safer side*/
SYS_INT_SourceStatusClear(INT_SOURCE_USART_1_TRANSMIT);
SYS_INT_SourceStatusClear(INT_SOURCE_USART_1_RECEIVE);
SYS_INT_SourceStatusClear(INT_SOURCE_USART_1_ERROR);
/* Enable the error interrupt source */
SYS_INT_SourceEnable(INT_SOURCE_USART_1_ERROR);
/* Enable the Receive interrupt source */
SYS_INT_SourceEnable(INT_SOURCE_USART_1_RECEIVE);
/* Return the driver instance value*/
return (SYS_MODULE_OBJ)DRV_USART_INDEX_0;
}
-------------------------------------------------------------------------------
Above code is partial UART Driver code that is generated by the Harmony framework. Taking it as reference you may please try to find out what is missing in your code.
#5
BHUSHAN
Starting Member
  • Total Posts : 62
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/25 09:57:04 (permalink)
0
KTrenholm
Your comment in the ISR says:

 
 
 
PORTB = 0xff;    //PORTB is not becoming HIGH thus confirming that this ISR has not been entered
 
 
No Sir ,it is not entering ISR as I have also tried LATB for making PORTB pins high.
 
 

I don't think that's doing what you think it's doing.  Read pins with PORTx.  Write an output using LATx.
If that's the only way you are determining if your ISR is being entered, you may be firing the ISR and not realizing.




#6
KTrenholm
Super Member
  • Total Posts : 710
  • Reward points : 0
  • Joined: 2012/08/08 14:04:23
  • Location: Connecticut, USA
  • Status: online
Re: Stuck with UART2 RX interrupt 2019/04/25 10:20:52 (permalink)
0
I think your ISR definition might be suspect?  I have a C32 project using a PIC32MX564F128H and my UART 2 ISR is written:

 
#include <sys/attribs.h>     /* For __ISR macro*/
 
void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void){
 
/*U2 ISR Stuff Goes Here*/
 
}
 

 It looks like __ISR is just a macro for:

 
__attribute__((vector(v), interrupt(__VA_ARGS__), nomips16))
 

so I think it's just different ways to do the same thing.
 
Looking at the device header file though, I noticed near where the macro I use (_UART_2_VECTOR) is defined, there's also one for _UART2_RX_IRQ. So should your ISR perhaps be written as:

 
void __attribute__ ((__interrupt__)) _UART2_RX_IRQ (void)
 

Note the leading underscore in _UART2_RX_IRQ, your code is missing that, probably putting your ISR not at the correct vector for U2RX?  I don't know if that definition is actually viable.  It doesn't set a priority or anything.
 
I'm not a huge C32 user (I mostly only touch it for the occasional legacy project) so someone more familiar could very well drop in and correct me if I'm wrong.
post edited by KTrenholm - 2019/04/25 10:37:07
#7
KTrenholm
Super Member
  • Total Posts : 710
  • Reward points : 0
  • Joined: 2012/08/08 14:04:23
  • Location: Connecticut, USA
  • Status: online
Re: Stuck with UART2 RX interrupt 2019/04/25 10:38:48 (permalink)
0
Oh, and I forgot an obvious one.  Do you have interrupts globally enabled?
 
If you're using the peripheral libraries (plib.h) it's as easy as:

INTEnableInterrupts();

 
You can also use some inline assembly:

asm volatile ("ei");                /* Enable interrupts. */


 
You may also need to set the interrupt vector mode.  I'm not sure this is NEEDED (I don't know how it comes up by default), but the PLIB macro is:

/*Configure Multivector Interrupt Mode.  Using Single Vector Mode
    is expensive from a timing perspective, so most applications
    should probably not use a Single Vector Mode*/
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);


post edited by KTrenholm - 2019/04/25 10:48:16
#8
dvvrcognizant
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2019/03/13 07:48:11
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/25 22:21:05 (permalink)
0
// *****************************************************************************
// *****************************************************************************
// Section: System Interrupt Vector Functions
// *****************************************************************************
// *****************************************************************************
void __ISR(_UART_1_VECTOR, ipl1AUTO) _IntHandlerDrvUsartInstance0(void)
{
DRV_USART_TasksTransmit(sysObj.drvUsart0);
DRV_USART_TasksError(sysObj.drvUsart0);
DRV_USART_TasksReceive(sysObj.drvUsart0);
}

void __ISR(_UART_2_VECTOR, ipl1AUTO) _IntHandlerDrvUsartInstance1(void)
{
DRV_USART_TasksTransmit(sysObj.drvUsart1);
DRV_USART_TasksError(sysObj.drvUsart1);
DRV_USART_TasksReceive(sysObj.drvUsart1);
}
------------------------------------------------------------------------------------------
Above is the UART1 & UART2 ISRs code generated by the Harmony as part of UART Driver
This may serve as reference...
#9
BHUSHAN
Starting Member
  • Total Posts : 62
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/25 23:14:35 (permalink)
0
KTrenholm
I think your ISR definition might be suspect?  I have a C32 project using a PIC32MX564F128H and my UART 2 ISR is written:

 
 
 
#include <sys/attribs.h>     /* For __ISR macro*/
 
 
 
void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void){
}
 
 
 

 It looks like __ISR is just a macro for:

 
 
 
__attribute__((vector(v), interrupt(__VA_ARGS__), nomips16))
 
 
 

so I think it's just different ways to do the same thing.
 
Looking at the device header file though, I noticed near where the macro I use (_UART_2_VECTOR) is defined, there's also one for _UART2_RX_IRQ. So should your ISR perhaps be written as:

 
 
 
void __attribute__ ((__interrupt__)) _UART2_RX_IRQ (void)
 
 
 

Note the leading underscore in _UART2_RX_IRQ, your code is missing that, probably putting your ISR not at the correct vector for U2RX?  I don't know if that definition is actually viable.  It doesn't set a priority or anything.
 
I'm not a huge C32 user (I mostly only touch it for the occasional legacy project) so someone more familiar could very well drop in and correct me if I'm wrong.




 
Thanks for your time Sir. I am declaring ISR as void  __attribute__(( __interrupt__ )) _UART2_RX_IRQ (void)
{
  ISR Stuff Goes Here*/
}
 
but my compiler is giving an error:- main.c:46:40: error: expected identifier or '(' before numeric constant
Even I found your suggested "_UART2_RX_IRQ" in my controller header file but this error is popped up by compiler. When I change ISR declaration as void  __attribute__(( __interrupt__ )) _UART_2_RX_IRQ (void) then there is no error.
Given below is my changes made to my code(attached to my first post). Project is buiding correctly but still ISR is not  executing.
 
  void  __attribute__(( __interrupt__ )) _UART_2_RX_IRQ (void)
{
 char x;
 LATB = 0xff; //PORTB is not becoming HIGH thus confirming that this ISR has not been entered
 x = U2RXREG;
 IFS1bits.U2RXIF=0;
}

void main(){
unsigned char i=0; ;
 AD1PCFG = 0xFFFF;
TRISB = 0;
LATB = 0x0f;
InitI2C();
delay();
asm volatile("di");// Disable all interrupts
asm volatile("ehb");// Disable all interrupts
UART_init();//initialize UART
asm volatile ("ei"); //enable all interrupts
IFS1bits.U2RXIF = 0;//clear interrupt flag
IEC1bits.U2RXIE = 1;//Enable UART2 RX interrupt
Uart_Tx('j');//I am receiving transmitted character in my terminal
while(1);//wait forever for UARTRX interrupt
}



#10
KTrenholm
Super Member
  • Total Posts : 710
  • Reward points : 0
  • Joined: 2012/08/08 14:04:23
  • Location: Connecticut, USA
  • Status: online
Re: Stuck with UART2 RX interrupt 2019/04/26 06:45:52 (permalink) ☄ Helpfulby BHUSHAN 2019/04/28 21:43:50
0
Have you tried using the __ISR(vector,ipl) macro?  This is what basically all the examples use.
Doing so will rule out a problem with the definition of your ISR function.  I still don't trust what you have written as being valid for the UART 2 Interrupt Vector.
 

/*Remember to have the same IPL here as is set in the IPL register*/

void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void){

/*Do Stuff*/

}


 
Note that UART2 only has one vector, rather than seperate ones for RX and TX.  You'll have to determine the interrupt source via looking at the interrupt flag for U2RX and U2TX.
 

/*Remember to have the same IPL here as is set in the IPL register*/

void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void){

    if (IFS1bits.U2RXIF){

        /*Do UART 2 Receive Stuff*/

        /*Ensure RX buffer is clear before clearing IF*/

        while (U2STAbits.URXDA){
            c_in = U2RXREG;
        }

        IFS1bits.U2RXIF = 0;

    }

 

    if (IFS1bits.U2TXIF){

        /*Do UART 2 TX stuff (if using interrupts for TX)*/

        IFS1bits.U2TXIF = 0;

        }

}


#11
BHUSHAN
Starting Member
  • Total Posts : 62
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/26 23:06:49 (permalink)
0
KTrenholm
Have you tried using the __ISR(vector,ipl) macro?  This is what basically all the examples use.
Doing so will rule out a problem with the definition of your ISR function.  I still don't trust what you have written as being valid for the UART 2 Interrupt Vector.
 

 
 
 
/*Remember to have the same IPL here as is set in the IPL register*/
 
 
 

void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void){
 
 
 

/*Do Stuff*/
 
 
 

}
 
 
 


 Note that UART2 only has one vector, rather than seperate ones for RX and TX.  You'll have to determine the interrupt source via looking at the interrupt flag for U2RX and U2TX. 

 
 
 
/*Remember to have the same IPL here as is set in the IPL register*/
 
 
 

void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void){
 
 
 

    if (IFS1bits.U2RXIF){
 
 
 

        /*Do UART 2 Receive Stuff*/
 
 
 

        /*Ensure RX buffer is clear before clearing IF*/
 
 
 

        while (U2STAbits.URXDA){
            c_in = U2RXREG;
        }
 
 
 

        IFS1bits.U2RXIF = 0;
 
 
 

    }
 
 
 

 
 
 
 

    if (IFS1bits.U2TXIF){
 
 
 

        /*Do UART 2 TX stuff (if using interrupts for TX)*/
 
 
 

        IFS1bits.U2TXIF = 0;
 
 
 

        }
 
 
 

}
 
 
 






 
Thanks a lot SIR. The ISR routine provided by you void __ISR(_UART_2_VECTOR,IPL7) uart2_isr(void) is working fine. Now I have some queries for you:-
(1) As you said that in the ISR we have to track the interrupt flag of RX or of TX whichever has raised the flag. However if I enable only UART2 RX interrupt ( IEC1bits.U2RXIE = 1;//Enable UART2 RX interrupt) and not the UART2 TX interrupt( IEC1bits.U2TXIE = 0;//Disable UART2 TX interrupt) then I don't think that ISR will be entered on TX interrupt.
(2) What is the difference between your ISR decalaration "void __ISR(_UART_2_VECTOR,IPL5) uart2_isr(void)"  and  this decalaration "void __ISR(_UART_2_VECTOR, IPL5SRS) _UART_2_RX_IRQ(void)"   as both are working fine except in one condition ?
(3) My last concern is that how you found the correct declaration of ISR ? I searched many sites and posts but was unable to find correct one. Also your declaration works only when "#include <sys/attribs.h>"  isincluded. Can't we have an alternative where no extra header file is included( as it consumes memory). In other PIC microcontrollers there was no need to insert any extra header file for ISR routine to be recognised by the compiler.
                     Thanks again.
 
 
    
post edited by BHUSHAN - 2019/04/26 23:08:17
#12
cvm
Super Member
  • Total Posts : 292
  • Reward points : 0
  • Joined: 2011/09/16 05:16:15
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/27 20:15:26 (permalink) ☼ Best Answerby BHUSHAN 2019/04/28 21:44:00
4 (1)
You can simply use the attributes without the use of a macro, if wanted. You can also let the compiler create a default context save where it will figure out the requested priority level and if shadow registers are used. When you let the compiler figure it out (in its generated isr code), you only have to set the irq priority and assign shadow registers in the irq setup code. Doing this eliminates the 'coordination' required when changing priority levels and shadow sets.
 
You do get a few extra instructions in the isr, along with additional register saving (that may end up being skipped if shadow registers are in use for the irq level). I think its a very small price to pay for simplicity, and eliminates the problem of forgetting to change the isr priority/shadow set use to match the irq setup (which can cause strange problems that are hard to figure out).
 
__attribute__(( vector(_UART_2_VECTOR), interrupt, nomips16 ))
void uart2_isr()
{
}
 
the vector attribute places dispatch code at the vector location specified (jump to function)
the interrupt attribute (without arguments) tells the compiler to produce a default interrupt context save/restore
the nomips16 may or may not be required for your MX, doesn't hurt (I think you have to jump through some hoops to get to a point where it matters- at that point you would know what it is all about)


#13
BHUSHAN
Starting Member
  • Total Posts : 62
  • Reward points : 0
  • Joined: 2019/02/04 23:17:18
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/28 21:49:33 (permalink)
0
cvm
You can simply use the attributes without the use of a macro, if wanted. You can also let the compiler create a default context save where it will figure out the requested priority level and if shadow registers are used. When you let the compiler figure it out (in its generated isr code), you only have to set the irq priority and assign shadow registers in the irq setup code. Doing this eliminates the 'coordination' required when changing priority levels and shadow sets.

You do get a few extra instructions in the isr, along with additional register saving (that may end up being skipped if shadow registers are in use for the irq level). I think its a very small price to pay for simplicity, and eliminates the problem of forgetting to change the isr priority/shadow set use to match the irq setup (which can cause strange problems that are hard to figure out).

__attribute__(( vector(_UART_2_VECTOR), interrupt, nomips16 ))
void uart2_isr()
{
}

the vector attribute places dispatch code at the vector location specified (jump to function)
the interrupt attribute (without arguments) tells the compiler to produce a default interrupt context save/restore
the nomips16 may or may not be required for your MX, doesn't hurt (I think you have to jump through some hoops to get to a point where it matters- at that point you would know what it is all about)






 
Thanks Sir for your help. Your ISR declaration is working with no need of #include <sys/attribs.h>   and nomips16. Till now I didn't find any issue with this ISR declaration. DO me a last favour, suggest me books or links where I can find a complete comprehensive material for Interrupts. How exactly you got this ISR declaration ? 
#14
cvm
Super Member
  • Total Posts : 292
  • Reward points : 0
  • Joined: 2011/09/16 05:16:15
  • Location: 0
  • Status: offline
Re: Stuck with UART2 RX interrupt 2019/04/28 22:43:23 (permalink) ☄ Helpfulby BHUSHAN 2019/05/01 21:24:10
4 (1)
The sys/atrribs.h is doing nothing more than putting a pretty wrapper on things. If you read it you can figure out what they are doing with their macros and simply do it yourself.
 
I think the xc32 users guide (pdf file in docs folder) cover interrupts pretty well. Along with the attrib header, you can piece things together where you can understand what the various function attributes actually do. I cannot suggest any books or links as I just read the docs, headers, my compiled code (using objdump), trial and error, using debugger, etc.
 
#15
Jump to:
© 2019 APG vNext Commercial Version 4.5