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.

TM4C1294NCPDT: Receive timeout

Part Number: TM4C1294NCPDT

Hi Folks,

I have to use UART (UART7) in my application configured in 9 bit UART mode. I implemented the logic that the end of receiving will be signed by the RX timeout interrupt. The interrupt service routine is below:

void Interrupt() {
	uint32_t intState = MAP_UARTIntStatus(MODBUS_UART, true);
	if (intState & UART_INT_9BIT) {
		// first write must be the slave address
		_receivedPDU.Deserialize(static_cast<uint8_t>(MAP_UARTCharGet(MODBUS_UART)));
		MAP_UARTIntClear(MODBUS_UART, UART_INT_9BIT);
	}

	if (intState & UART_INT_RX) {
		while (MAP_UARTCharsAvail(MODBUS_UART)) {
			_receivedPDU.Deserialize(static_cast<uint8_t>(MAP_UARTCharGet(MODBUS_UART)));
		}
	}

	if (intState & UART_INT_RT) {
		xSemaphoreGiveFromISR(_receiveSemaphore, NULL);
		MAP_UARTIntClear(MODBUS_UART, UART_INT_RT);
	}
}

As you can see, there are three conditions:

  • check if we received address frame
  • check if we should read out data
  • check timeout: notify a FreeRTOS thread about receive complete

The FreeRTOS thread looks, like:

SetRS485DriverToTxDir();
Send9BitAddress()
SendByte();
while(UARTBusy());

SetRS485DriverToRTxDir();

// Wait for the semaphore for 50 ms
if (xSemaphoreTake(_receiveSemaphore, 50) == pdFALSE) {
	return false;
   }
}

But I experienced, that I get receive timeout interrupt, even there is nobody who send me data (no cable is connected to the board), so the semaphore will be acquired and not timed out. One more information: As I checked the periphery via debugger, I saw that the data register holds 0x500, which is:

  • Break error
  • Parity error
  • Empy data (data = 0x0)

Can anybody help me, what can cause this strange behavioral?

  • Not all RS485 Line Drivers/Receivers are "happy" when the differential communication cable is unconnected. (you state that "no cable is connected.) Might the insertion of that cable - and a "silent" remote transmitter - strengthen your initial testing?
  • Norbert,
    Some hints (none of them will directly answer you question...)
    - As a good practice, clearing the interrupt flag should be done as soon as possible inside the ISR (there is some sort of buffer in the hardware that could leave the bit set for a few cycles after you do it). Hence, don't clear the bit AFTER serving it, but rather clear RIGHT after intState = MAP_UARTIntStatus(MODBUS_UART, true);
    - There is no logic in making your clearing conditional - once you copied the int reason to intState, clear ALL the flags. With the above routine, if you code diverts into the ISR for any other reason, your MCU will endless loop there - for such other reason will never be cleared.
    - Typically, the service applied to _RX and _RT are the same: submit the newly arrived bytes to whatever consumes them. _RT is simply an additional interrupt engine to make sure that you service those last few bytes that have arrived, but which were not in enough quantity to break the FIFO threshold that triggers _RX.
    - Make sure that _receivedPDU.Deserialize() is a quick routine that does not call anything below it (I don't know the source of that) - just to avoid long processing inside the ISR.
    As for the mysterious interrupt, as cb1 says, it is not unusual that floating circuits generate eventual transitions... Either way, your software will need to treat invalid received bytes inside your message...
    Regards
    Bruno