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.

Compiler/TM4C1290NCZAD: UART Interrupt RAW and Masked

Part Number: TM4C1290NCZAD

Tool/software: TI C/C++ Compiler

Hi, 

my hardware operates continuouly with UART Interrupts (Recieve and Transmits). For some reasons I get frame, parity and break errors, which I have to ignore. I'm using TI's driver lib to read the masked interrupt register with uint32_t uInts = MAP_UARTIntStatus(MY_UART_BASE, true);   

I found, that after some hours, I very seldom see uInts=0, but an Interrupt has been thrown. I read the raw register, and see, the value of that register 0x380. How can this happen, that the raw status is different to the masked, only in very rare cases?

Regards

Micky

  • Hello Michael,

    My initial suspicion is that the uInts status got cleared somehow. You mention having put in code to read the read the raw register, so that sounds like a variable that is just storing the result of the unmasked interrupt status for debugging purposes. With that in mind, would it be possible to also add in an extra variable whose only purpose is to store the masked result as well? Then you can compare the results when the issue occurs and determine if uInts status got impacted by another part of software.

    Also to clarify, you are definitely getting an interrupt when the issue occurs, and when the interrupt occurs you are not getting a value out of uInts, but you are from the Raw register? I ask to clarify as if an interrupt event is not set, the raw interrupt status is still visible via the UART Raw Interrupt Status register but the interrupt status will not be available in the Masked Interrupt Status register..
  • Hi Ralph,

    Ralph Jacobi said:

    Also to clarify, you are definitely getting an interrupt when the issue occurs, and when the interrupt occurs you are not getting a value out of uInts, but you are from the Raw register? I ask to clarify as if an interrupt event is not set, the raw interrupt status is still visible via the UART Raw Interrupt Status register but the interrupt status will not be available in the Masked Interrupt Status register..

    This is definitely the case about very 4 hours... (but not really regualary), the programm runs into vfnInternalError(). I'm a bit unsure, why this happens.

    my code is like:

    void vfnUartIntHandler(void)
    {
        uint32_t uInts = MAP_UARTIntStatus(MY_UART_BASE, true);  
        MAP_UARTIntClear(MY_UART_BASE, uInts);
        if (uInts & (UART_INT_TX ))
        {
            // Ein Transmit Interrupt => nächstes Zeichen laden, falls vorhanden
            vfnUebertragung();
        }
        if (uInts & (UART_INT_RX | UART_INT_9BIT | UART_INT_FE | UART_INT_PE | UART_INT_BE  ))
        {
         ...
        }
       if (uInts & ( UART_DR_OE) )
        {
          ...
       } 
    // Should never happen....
        if ((uInts & (UART_INT_RX | UART_INT_9BIT | UART_INT_FE | UART_INT_PE | UART_INT_BE |  UART_DR_OE | UART_INT_TX  ))==0)
        {
                uint32_t uIntsRaw = MAP_UARTIntStatus(ELMOS_UART_BASE, false);
                uint32_t auData[2] = {uInts, uIntsRaw }; 
                   vfnInternalError(enUARTRecv,(uint8_t*) &auData,8);
         }
    
    }

    Regards

    Micky

  • Hello Micky,

    Thanks for sharing the code! I see the issue now.

    The UART_DR_OE flag you are using is for the UART_O_DR register but you are not reading from that register.

    You need to use UART_INT_OE or other flags from the uart.h header file which defines all INT flags that come from the interrupt status registers.
  • Hi Ralph,

    thanks for that hint. I corected it. Anyway, I stored both flags and stored it in my Log-Memory

    uint32_t uInts = MAP_UARTIntStatus(ELMOS_UART_BASE, true);
    uint32_t uIntsRaw = MAP_UARTIntStatus(ELMOS_UART_BASE, false);
    uint32_t auData[2] = {uInts, uIntsRaw }; 
    vfnInternalError(enUARTRecv,(uint8_t*) &auData,8);

    and my log is

    17:10:31 17-12-2018:
      Val:  0x00-0x00-0x00-0x00-0x80-0x03-0x00-0x00

    17:35:31 17-12-2018:
      Val:  0x00-0x00-0x00-0x00-0x80-0x03-0x00-0x00

    20:55:32 17-12-2018:
      Val:  0x00-0x00-0x00-0x00-0x80-0x03-0x00-0x00

    01:15:33 18-12-2018:
      Val:  0x00-0x00-0x00-0x00-0x80-0x03-0x00-0x00

    02:45:34 18-12-2018:
      Val:  0x00-0x00-0x00-0x00-0x80-0x03-0x00-0x00

    04:30:35 18-12-2018:
      Val:  0x00-0x00-0x00-0x00-0x80-0x03-0x00-0x00


  • Hello Michael,

    I've been looking over documentation and your code and really haven't come up with an explanation for this behavior yet. It's not something we've seen before. I did notice one other possible disparity in the code though. You check the UARTIntStatus and clear it with MY_UART_BASE but then your API to read the Raw Status Register uses ELMOS_UART_BASE. Are these equivalently defined?

    I think it would help at this point to look at your UART initialization setup as well, especially the UARTIntEnable function.
  • Hi Ralph,
    I checked my code and found something referring your comment:
    " I ask to clarify as if an interrupt event is not set, the raw interrupt status is still visible via the UART Raw Interrupt Status register"
    I do UART Transfer with TX Interrupt after each Byte with ROM_UARTCharPutNonBlocking() .
    At least I found a scenario where the TX Interrupt was not yet thrown for the next char, but from another function the next char was loaded into the register with ROM_UARTCharPutNonBlocking(). I cannot say, if this is exactly the reason for the problem, but at least, I do not see this behavior any longer.
    Regards
    Micky