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.

[LM4F120H5QR] Repeated UART interrupt.

Hello,

I wrote some code that provides me possibility to communicate with PC. But my MCU response seems to be weird. Because if command is less than 8 characters everything is good. Problems appears when command is longer than 8 characters, and interrupt is called twice or more with the same value in FIFO i supposed. Result of this is i have doubled or tripled MCU response of command.

Here is my UART configuration and interrupt handler ( port A is configured in another part of code ):

 

void InitUART()
{
	// running clock for uart module
	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

	// pin configurations
	GPIOPinConfigure(GPIO_PA0_U0RX);
	GPIOPinConfigure(GPIO_PA1_U0TX);
	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

	// configuring uart to 9660 baud rate and 8n1 mode
	UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);

	// running uart interrupts
	IntEnable(INT_UART0);
	UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
}
void UARTIntHandler()
{
	unsigned charNum = 0;
	int flag;

	// clearing interupt flags
	UARTIntClear(UART0_BASE, UARTIntStatus(UART0_BASE, true));

	clearBuffer();

	for ( charNum = 0; UARTCharsAvail(UART0_BASE); ++charNum )
	{
		reciveBuffer[charNum] = UARTCharGetNonBlocking(UART0_BASE);
	}

	flag = CmdLineProcess(reciveBuffer);

	if (flag == CMDLINE_BAD_CMD)
	{
		UARTSend("Bad command.\n");
	}
	else if ( flag == CMDLINE_TOO_MANY_ARGS )
	{
		UARTSend("Too many arguments.\n");
	}
	else if ( flag == CMDLINE_TOO_FEW_ARGS )
	{
		UARTSend("Too few arguments.\n");
	}
	else if ( flag == CMDLINE_INVALID_ARG )
	{
		UARTSend("Invalid arguments.\n");
	}
}

  • Hi Mateusz,

    Could you check what does UARTIntStatus(UART0_BASE, true) return? 

    Also, you have a interrupt for the RX FIFO but you don't set the level you want it to interrupt. Use UARTFIFOLevelSet(). You can see in 14.3.9 Interrupts that you need that (although there is a default value).

  • You have enabled two possible interrupt sources for your UART interrupt, RX and RT(receive timeout), you need to check which source triggered the interrupt.

    Also keep in mind that when you configure the UART, it will enable the RX(and TX) fifo to halve by default, which is 8 bytes long, thus what's happening is that you get the timeout interrupt as long you've less than 8 characters in the buffer, but a second when you've 8 characters(once for the timeout and once for the RX buffer).

    Oeps, too late...

  • Hello Mateusz,

    I would agree with marc on the manner the interrupt handler is being used.

    UARTIntClear(UART0_BASE, UARTIntStatus(UART0_BASE, true));

    There are 2 interrupt bits being unmasked. Receive and Receive Timeout. Instead of just clearing the same, read the status and then take an action based on if it is Receive or Receive Timeout.

    Secondly, the FIFO can only read the data once. If the FIFO is empty then you would always be getting the last data if you read it over and over again.

    Regards

    Amit