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: RS485 communication : UART Speed Issue in two TM4c1294ncpdt controller communication

Part Number: TM4C1294NCPDT

/**************************************************************** UART INIT ******************************************************************************************/

void ConfigureModubusUART6(void)
{
// Enable the GPIO Peripheral used by the UART.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);

// Enable UART6.
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);

// Configure GPIO Pins for UART mode.
GPIOPinConfigure(GPIO_PP0_U6RX);
GPIOPinConfigure(GPIO_PP1_U6TX);
GPIOPinTypeUART(GPIO_PORTP_BASE, GPIO_PIN_0 | GPIO_PIN_1);

// TODO: Previous Buad rate: 115200
// Initialize the UART for console I/O.
UARTConfigSetExpClk(UART6_BASE, SYSTEMCLOCK, 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
}

/**************************************************************************************************************************************************************/

I have set up UART as per above init function. I have set the baud rate to 115200. Theoretically at a baud rate of this, time needed to transmit 8 bits can be around (8/115200 =)  69usec. Hence to transfer 600 bytes this time can be around 42msec. But in my case it is taking 128 to 200 msec to transmit 600 bytes. We are using modbus-RS485 communication, hence we have to toggle the direction pin whenever we transmit or receive. 

We are measuring this time between S-RX-1 and S-RX-2 in the below code

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_3, GPIO_PIN_3);

UART0print("S-RX-1\r\n");

/* Slave data Request from master: LED ON */
GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_1 , GPIO_PIN_1);

FPGAincomingData[1] = slaveCommandRxBuf[1];

// TODO: SysCtlDelay(SYSTEMCLOCK/100);
softDelay(3);// MUST Delay larger then master send data and also give delay to receive


/* Sent to mBus-UART */
UART6print((const char *)FPGAincomingData);

/* Sent to Debug-UART */
UART0print("S-TX-2 > "); UART0print((const char*)FPGAincomingData); UART0print("\n");
UART0print("S-TX-3 > \r\n");

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Regards,

sagar

  • Hello Sagar,

    The theoretical output is exactly that, theoretical. That's if you are spending 100% of your time driving the UART bus constantly. You should monitor the UART line and see how much time is spent driving the bus versus how much time the bus is idle as the overhead from the MCU comes into play. Reading data too & from buffers, each API call needed to send UART data etc. could all become potential bottlenecks depending how optimized routines are. Looking at the capture, you should be able to identify areas where delays in transmission are occurring.

    Also it looks like the method you are using is not using the DMA. You may be able to speed up the process by using the DMA to streamline the data transfer to the UART peripheral.

    Best Regards,

    Ralph Jacobi

  • I am using this API UART6print(const char* text)   for transferring 600 bytes data.
    In this function base API is UARTCharPut(uint32_t ui32Base, unsigned char ucData)
    provided by TI SDK, I don't want to use UART DMA, so any other way to achieve speed.

    void UART6print(const char* text)
    {
    const char* p;

    // Iterate over each character of `text`,
    // until we reach the NUL terminator
    for (p = text; *p != '\0'; p++)
    {
    // Pass each character to some function
    UARTCharPut(UART6_BASE, *p);
    }
    }

    /******************* uart.c - Driver for the UART **************************/
    //*****************************************************************************
    //
    //! Waits to send a character from the specified port.
    //!
    //! \param ui32Base is the base address of the UART port.
    //! \param ucData is the character to be transmitted.
    //!
    //! This function sends the character \e ucData to the transmit FIFO for the
    //! specified port. If there is no space available in the transmit FIFO, this
    //! function waits until there is space available before returning.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    UARTCharPut(uint32_t ui32Base, unsigned char ucData)
    {
    //
    // Check the arguments.
    //
    ASSERT(_UARTBaseValid(ui32Base));

    //
    // Wait until space is available.
    //
    while(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF)
    {
    }

    //
    // Send the char.
    //
    HWREG(ui32Base + UART_O_DR) = ucData;
    }

  • Hi,

    Don't forget, each byte also has at least a start and stop bit so it 10 bits, not 8. Your 42ms is really about 50ms.

    The UART has a 16 byte FIFO, so it should be able to transmit bytes virtually end to end - unless the FIFO is getting empty at some point. Perhaps you can get a scope on the output and see where the gaps are - between each character, or between groups of several characters.

  • Hello Sagar,

    Jim offers good guidance here - at this point we really need to understand where the gaps in the transmission are to provide further advise here about where bottlenecks may be.

    Best Regards,

    Ralph Jacobi