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: UART port reads junk after certain period of time

Part Number: EK-TM4C123GXL

Hi,

Recently I had an issue that the UART interrupt was not reading the whole message from the sensor correctly but now that is fixed. However, at the time all processing was kept inside the ISR which is not good practice and I want to move that part out of the ISR into main loop by flicking the flag. Unfortunately, I seem to have an issue that the UART port starts reading junk (the data that is read, is always the same byte values). I suspected maybe memory leak, but all variables are cleared and memory for the pointers freed after every cycle, therefore I ran out of ideas what could be an issue. Note that in the code below UART0 will be used for reading initial message from the host but it is not being used atm. The variables z and l are just used to check how many loops have been made, this is where I get the number of 58 successful reads but after the 59th, it will always be junk data. The data from sensor comes in correct form all the time (checked by oscilloscope), thus the code for Tiva has to be an issue. I have TM4C123GXL.

This is the main loop:

int main(void)
{
    ROM_FPUEnable();
    ROM_FPULazyStackingEnable();


    r_v.received_from_master = 0;

    reserve_memory_master();

    clock_init();

    gpio_init();
    setting_up();
    y = SysCtlClockGet()/1000;

    while(1)
    {
        reserve_memory(4);
        eeprom_write();
        r_v.transmitCounter_sensor = 0;
        delayMs(16); //15ms delay at 50MHz
        request_config_data();

        r_v.transmitCounter_sensor = 0;


        if(k==1)
        {
            master_transmit();
            free(r_v.receiveUART_sensor);
            free(r_v.transmit_receiveUART_sensor);
          //  free(r_v.receiveUART_master);

            k=0;
            z++;
            if(r_v.measure_array[0]!=0x40)
            {
                z=0;
            }
            memset(r_v.arr, 0, sizeof(r_v.arr));
            memset(r_v.measure_array, 0, sizeof(r_v.measure_array));
            ROM_UARTIntEnable(UART2_BASE, UART_INT_RX);
        }
        //delayMs(1);
    }
}

This is the interrupt:

void UART2IntHandler(void)
{
    uint32_t ui32Status;

    // Get the interrrupt status.
    //
    ui32Status = ROM_UARTIntStatus(UART2_BASE, true);

    //
    // Clear the asserted interrupts.
    //
    ROM_UARTIntClear(UART2_BASE, ui32Status);

    //
    // Loop while there are characters in the receive FIFO.
    //
    if(ui32Status & UART_INT_RX)
    {
        while(ROM_UARTCharsAvail(UART2_BASE))
          {
              if(r_v.read_eeprom)
              {
                 sensor_read();
                 r_v.read_eeprom = false;
              }
              else
              {
                 measurements();
              }
          }
              if(r_v.receiveCounter_sensor==r_v.sensor_receive_length)
              {
                  r_v.receiveCounter_sensor=0;
                  k=1;
                  l++;
                  ROM_UARTIntDisable(UART2_BASE, UART_INT_RX);
              }

    }
}

Below are the images for read values. First one has correct value on loop counter 58 (the correct data does come correct at every loop prior this):

The second image is incorrect data read at 59th loop (all other readings after this point will have exact same value):

  • I agree, your issue is likely in the code. You did not include the code that actually reads the FIFO and stores the characters. You need to debug this further. Can you detect the error condition and drop into a infinite loop where you have set a breakpoint and then check your buffer pointers?
  • Thanks for your reply.

    Sorry, I may have forgotten to add that part of the code. I actually disable FIFO as in that case I get incomplete messages. Below are parts of the code responsible for configuring the ports/pins and for reading the data on the port.

    This is how I configure the port:

    void configure_uart_port(uint32_t gpioPortBase, uint32_t uartPortBase, uint32_t intUartPort, uint32_t uartPortPinRx, uint32_t uartPortPinTx, uint8_t RXpin, uint8_t TXpin)
    {
        /* Example for setting uart port/pins and interrupt for corresponding uart
        // Set GPIO D6 and D7 as UART pins.
        //
        GPIOPinConfigure(GPIO_PD6_U2RX);
        GPIOPinConfigure(GPIO_PD7_U2TX);
        ROM_GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);
        ROM_SysCtlDelay(10);
        //
        // Configure the UART for 115,200, 8-N-2 operation.
        //
        ROM_UARTConfigSetExpClk(UART2_BASE, ROM_SysCtlClockGet(), 115200,
                                (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_TWO |
                                 UART_CONFIG_PAR_NONE));
        ROM_SysCtlDelay(10);
        //
        // Enable the UART interrupt.
        //
        ROM_UARTFIFOEnable(UART2_BASE);
    
        ROM_SysCtlDelay(10);
        ROM_UARTIntEnable(UART2_BASE, UART_INT_RX);
        ROM_UARTIntDisable(UART2_BASE, UART_INT_TX);
        //Enable UART and interrupts and disable FIFO
        ROM_UARTEnable(UART2_BASE);
        ROM_UARTFIFODisable(UART2_BASE);
        ROM_IntEnable(INT_UART2);
        */
    
            //Setup GPIO and UART port/pins
            GPIOPinConfigure(uartPortPinRx);
            GPIOPinConfigure(uartPortPinTx);
            ROM_GPIOPinTypeUART(gpioPortBase, RXpin | TXpin);
            ROM_SysCtlDelay(10);
            //
            // Configure the UART for 115,200, 8-N-2 operation.
            //
            ROM_UARTConfigSetExpClk(uartPortBase, ROM_SysCtlClockGet(), 115200,
                                    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_TWO |
                                     UART_CONFIG_PAR_NONE));
            ROM_SysCtlDelay(10);
    
            ROM_UARTFIFOEnable(uartPortBase);
    
            ROM_SysCtlDelay(10);
            ROM_UARTIntEnable(uartPortBase, UART_INT_RX);
            ROM_UARTIntDisable(uartPortBase, UART_INT_TX);
    
            ROM_UARTEnable(uartPortBase);
            ROM_UARTFIFODisable(uartPortBase);
            ROM_IntEnable(intUartPort);
    }

    And this part is for reading the UART2(where the sensor data comes in):

    void measurements(void)
    {
        uart_receive(r_v.receiveUART_sensor, r_v.receiveCounter_sensor);
        r_v.measure_array[r_v.receiveCounter_sensor] = r_v.receiveUART_sensor[r_v.receiveCounter_sensor];
        r_v.receiveCounter_sensor++;
    }
    
    void uart_receive(uint8_t *buf, int pos)
    {
        buf[pos] = ROM_UARTCharGetNonBlocking(UART2_BASE);
    }

    I am not entirely sure on your question though, I am not getting error messages, I just check when the data starts get corrupted and it always is at loop 59.

  • I recommend that you not disable the receive FIFO and that you enable both the (UART_INT_RX | UART_INT_RT). This way you get the benefit of the FIFO if your system is slow to respond to an interrupt and the receive timeout interrupt prevents you from getting incomplete messages because an odd character was left in the FIFO.
  • Unfortunately, I previously had issues with FIFO and the RT interrupt that is why I removed them --- with them, the code goes into FaultISR after several cycles. I checked that if I use array instead of a pointer to read the data into(originally I was reading data to pointer and copying to array and freeing the pointer) I don't have an issue anymore. I would prefer using pointer to read initial data bytes rather than straight to array.
  • I have managed to solve the issue. The problem was that interrupt was not happening exactly in the spot I wanted it to happen which made the other part of the code run before the interrupt happens which was not intended. I added while loop just before transmitting the message to the PC and that solved my issue.