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-TM4C1294XL] : Data loss while using UART to receive data

I'm facing an interesting problem. I want to interface my Connected Launchpad with TM4C1294 with an external gateway device, which sends different amount of data different time. I have connected device to UART5 and and tried to echo what I receive at UART5 to UART0 and vice versa. If I'm using a while loop inside my main function for that, I'm getting everything working. The code is like this.

int main( void ) {
  // configure board and peripherals
  // .......

  // infinite loop
  while (1) {
    while( UARTCharsAvail(UART0_BASE) ) {
      UARTCharPut( UART5_BASE, UARTCharGet( UART0_BASE ) );
    }
    while( UARTCharsAvail(UART5_BASE) ) {
      UARTCharPut( UART0_BASE, UARTCharGet( UART5_BASE ) );
    }
} // end of main

But If I write the same code with interrupts I'm experiencing data loss. Here is my full code :

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

uint32_t g_ui32SysClock;

#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

void UARTIntHandler_device(void)
{
  uint32_t ui32Status;
  uint8_t i = 0, j = 0;
  uint8_t recvBuffer[100];

  IntDisable( INT_UART0 );
  IntDisable( INT_UART5 );

  ui32Status = UARTIntStatus(UART5_BASE, true);
  UARTIntClear(UART5_BASE, ui32Status);

  while(UARTCharsAvail(UART5_BASE)) {
    if( i < 100 ) {
      recvBuffer[i] = UARTCharGet(UART5_BASE);
      i++;
    }
    // Blink the LED to show a character transfer is occuring.
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
    SysCtlDelay(g_ui32SysClock / (1000 * 3));		// Delay for 1ms.
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
  }

  // Send it to PC
  for( j = 0; j < i; j++ ) {
    UARTCharPut( UART0_BASE, recvBuffer[j] );
  }
  IntEnable( INT_UART0 );
  IntEnable( INT_UART5 );
}

void UARTIntHandler_PC( void ) {
  uint32_t ui32Status;
  char data = 0;

  IntMasterDisable();

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

  while( UARTCharsAvail(UART0_BASE) ) {
    data = UARTCharGetNonBlocking( UART0_BASE );
    // UARTCharPut( UART0_BASE, data );
    UARTCharPut( UART5_BASE, data );
  }
  IntMasterEnable();
}

int main(void)
{
  g_ui32SysClock = MAP_SysCtlClockFreqSet( ( SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480 ),
											   120000000 );

  // Set up LEDs
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
  GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
  
  // Setup UART0 for connection to PC
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  GPIOPinConfigure(GPIO_PA0_U0RX);
  GPIOPinConfigure(GPIO_PA1_U0TX);
  GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
  UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 57600,
                      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

  // Setup UART5 for connection to EnOcean Pi
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
  GPIOPinConfigure(GPIO_PC6_U5RX);
  GPIOPinConfigure(GPIO_PC7_U5TX);
  GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
  UARTConfigSetExpClk(UART5_BASE, g_ui32SysClock, 57600,
                      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
  
  IntMasterEnable();
  IntEnable(INT_UART0);	UARTIntEnable( UART0_BASE, UART_INT_RX | UART_INT_RT );
  IntEnable(INT_UART5);	UARTIntEnable( UART5_BASE, UART_INT_RX | UART_INT_RT );

  while(1) {
    // Loop for ever
  }
}

I'm connecting PC to UART0 and my device to UART5 and if send

55 00 01 00 05 70 03 09 // in hex

I'm supposed to get

55  00 21 00 02  26  00 02 07 01 00 02 04 02 01 00 84 23 CC 45 4F 01 03 47 41 54 45 57 41 59 43 54 52 4C 00 00 00 00 00 A3 // in hex

But I'm getting

55  00 21 00 02  26  00 02 07 01 00 02 04 02 01 00 84 23 45 54 54 00

If I'm filling my lost data with XX, this will look like

55  00 21 00 02  26  00 02 07 01 00 02 04 02 01 00 84 23 XX 45 XX XX XX XX XX 54 XX XX XX XX XX 54 XX XX XX XX XX 00 XX XX

As you can see, after receiving some bytes, I'm constantly losing 5bytes of data in between.

Can anybody please help me to solve this problem?

Thanks,

vish

  • Hello Vish

    Do not disable the Interrupts or Interrup master control inside the Interrupt Handler. If there are other bytes being received, they may lost since the interrupt will not be acknowledged by the NVIC

    Secondly in the interrupt handler for device, do the same thing that you are doing on the PC side,

    Regards

    Amit

  • Hi Amit,

    Even after modifying the code as you said, I'm getting same results :(

    void UARTIntHandler_device(void)
    {  
    uint32_t ui32Status;
        uint8_t data;
        
        ui32Status = UARTIntStatus(UART5_BASE, true);
        UARTIntClear(UART5_BASE, ui32Status);

        while(UARTCharsAvail(UART5_BASE)) {
            data = UARTCharGetNonBlocking( UART5_BASE );
            UARTCharPut( UART0_BASE, data  );
            // Blink the LED to show a character transfer is occuring.
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
            SysCtlDelay(g_ui32SysClock / (1000 * 3));        // Delay for 1ms.
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
        }
    } void UARTIntHandler_PC( void ) { uint32_t ui32Status; char data = 0; ui32Status = UARTIntStatus(UART0_BASE, true); UARTIntClear(UART0_BASE, ui32Status); while( UARTCharsAvail(UART0_BASE) ) { data = UARTCharGetNonBlocking( UART0_BASE ); UARTCharPut( UART5_BASE, data ); } }

  • Hello Vishnu,

    Had to closely look at the first thread. I still did not get how a small transmit to the U5 gets converted to long sequence on U0? If you can explain that it would be useful in the debug.

    Regards

    Amit

  • Hello Vishnu,

    I was able to run the configuration that you had sent by sending two files from one PC to another and it worked fine. Attached is the code I used (some modified from your code)

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    uint32_t g_ui32SysClock;
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    void UARTIntHandler_device(void)
    {
    	uint32_t ui32Status;
    	char data = 0;
    
    	ui32Status = UARTIntStatus(UART5_BASE, true);
    	UARTIntClear(UART5_BASE, ui32Status);
    	while( UARTCharsAvail(UART5_BASE) )
    	{
    		data = UARTCharGetNonBlocking( UART5_BASE );
    	    UARTCharPut(UART0_BASE, data);
    	}
    }
    
    void UARTIntHandler_PC( void ) {
      uint32_t ui32Status;
      char data = 0;
    
      ui32Status = UARTIntStatus(UART0_BASE, true);
      UARTIntClear(UART0_BASE, ui32Status);
      while( UARTCharsAvail(UART0_BASE) ) {
        data = UARTCharGetNonBlocking( UART0_BASE );
        UARTCharPut( UART5_BASE, data );
      }
    
    }
    
    int main(void)
    {
      g_ui32SysClock = MAP_SysCtlClockFreqSet( ( SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480 ),
                                                   120000000 );
      // Set up LEDs
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
      GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
    
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);
    
      GPIOPinConfigure(GPIO_PA0_U0RX);
      GPIOPinConfigure(GPIO_PA1_U0TX);
      GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
      GPIOPinConfigure(GPIO_PC6_U5RX);
      GPIOPinConfigure(GPIO_PC7_U5TX);
      GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    
      UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 57600,
                          (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
    
      UARTConfigSetExpClk(UART5_BASE, g_ui32SysClock, 57600,
                          (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
    
      UARTIntEnable( UART0_BASE, UART_INT_RX | UART_INT_RT );
      UARTIntEnable( UART5_BASE, UART_INT_RX | UART_INT_RT );
      IntEnable(INT_UART0);
      IntEnable(INT_UART5);
    
      IntMasterEnable();
    
      while(1) {
        // Loop for ever
      }
    }
    

    Regards

    Amit

  • Hi Amit,

    Thanks alot :)