This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C123GXL: Why the random interrupt is coming after the expected interrupt?

Part Number: EK-TM4C123GXL

I'm working on the EK-TM4C123GXL eval board. I'm trying to send 3 bytes via UART terminal using interrupt example: $2#.

So i made a loop as following,

                    do{
                            input[i] = UARTCharGetNonBlocking(UART0_BASE);
                            c = input[i];
                            UARTprintf("Data in c: %c\n",c);
                            i++;
                      }while(c!='#' && UARTCharsAvail(UART0_BASE));
                
                        UARTprintf("Data is received\n");    


in which once user entered "#"  control will come out of the loop and will print data received. But, in my case after entering  "#" control is coming out of the loop but, again because of interrupt, the control goes to the handler and its printing some garbage value.(below is the screenshot)

Which is not expected. What will be the reason behind this? Why even if nothing is sent via terminal still I'm getting interrupt?
Here I'm attaching my code below. Any help or hint will be really appreciated.
Thank You.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "driverlib/sysctl.h"
#include "inc/hw_uart.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "utils/uartstdio.h"
#include "driverlib/uart.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"

unsigned char c;

void UART0_Handler(void)
{
  uint32_t ui32Status;
	unsigned char input[3];
	int i=0;
    //
    // Get the interrrupt status.
    //
    ui32Status = UARTIntStatus(UART0_BASE, true);

    //
    // Clear the asserted interrupts.
    //
    UARTIntClear(UART0_BASE, ui32Status);

    //
    // Loop while there are characters in the receive FIFO.
    //

					do{
							input[i] = UARTCharGetNonBlocking(UART0_BASE);
							c = input[i];
							UARTprintf("Data in c: %c\n",c);
							i++;
					  }while(c!='#' && UARTCharsAvail(UART0_BASE));
				
						UARTprintf("Data is received\n");			
}



void InitConsole(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioConfig(0, 115200, 16000000);
	    //
    // Enable processor interrupts.
    //
    IntMasterEnable();    //
    // Enable the UART interrupt.
    //
    IntEnable(INT_UART0_TM4C123);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
}



int main()
{

	InitConsole();

	while(1)
	{
		
	}

}

                   

  • Hello Omkar,

    I tried testing your application code but it is hitting FaultISR for me at times so I am not sure what is going on exactly but a few comments:

    1) You have UARTIntClear early in your ISR and the interrupt flag is likely being set again.

    2) Using a do while in an ISR is very very poor code design, you should shift that to main and use the ISR to read data into a global buffer and then flag to main data is received and then run your loop that way.

    3) The UART terminal on your PC may be sending a CR or LF which is being registered after the #.

  • Hello Ralph

    Again thank you so much for the reply I will definitely going to apply your suggestions. As I'm still in a learning phase I would really like to learn the best possible way or tips to write an ISR for any application. Would you like to suggest any article ,book or something which will help me to improve myself in this area?

    Regards

    Omkar

  • Hello Omkar,

    General practice is that an ISR should contain as minimal processing as possible. Using an ISR to receive data and then send it out with loops is not considered to be very efficient. What ends up happening is while you are in the loop in an ISR, the program cannot execute anything else that may be equally important. For a simple system with only one ISR it isn't a big deal but as you get into more complex systems, you'll find that the latency of ISR's are very important so best to learn those practices early on.

    I don't have any resources handy but I think you would be able to read up on details by researching topics like 'how to make a good interrupt service routine' or 'how to write interrupt handlers'.

  • Okay I will keep practicing more. Again thank you so much for the detailed explanation for why not to use while loop in the ISR. I really appreciate your help.

    Regards

    Omkar