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.

problem with UART on EVM TMDXEVM6678L

Other Parts Discussed in Thread: TMS320C6678

Hi!

I have a problem with UART on TMS320C6678.

I wrote a program (source file attached) that test UART on EVM TMDXEVM6678L.
In test program initialize UART in FIFO mode and enable loopback mode.
First write in TX FIFO 15 bytes and then read 15 bytes from RX FIFO.
Second before write any byte of 15 bytes in TX FIFO, wait while TX FIFO empty and then read 15 bytes from RX FIFO.
In second read only last 2 bytes from 15 bytes.

Why I read only 2 last bytes from RX FIFO?

#include <ti/csl/csl_types.h>

#include <ti/csl/csl_gpio.h>

#include <ti/csl/cslr_device.h>
#include <ti/csl/csl_chipAux.h>

#include <ti/csl/cslr_uart.h>

#include <stdio.h>

#define hUartRegs    ((CSL_UartRegs*) CSL_UART_REGS)

/******************************************************************************
 *
 * Function:    UartInit
 *
 * Description: This function initializes the UART.
 *
 * Parameters:  void
 *
 * Return Value: void
 *
 ******************************************************************************/
void UartInit(void)
{
    //      Allows access to the divisor latches of the baud generator during a
    // read or write operation (DLL and DLH)
    CSL_FINS (hUartRegs->LCR, UART_LCR_DLAB, CSL_UART_LCR_DLAB_ENABLE);
    //      Break condition is disabled.
    CSL_FINS (hUartRegs->LCR, UART_LCR_BC,   CSL_UART_LCR_BC_DISABLE);
    //      Stick parity is disabled.
    CSL_FINS (hUartRegs->LCR, UART_LCR_SP,   CSL_UART_LCR_SP_DISABLE);
    //      Odd parity is selected
    CSL_FINS (hUartRegs->LCR, UART_LCR_EPS,  CSL_UART_LCR_EPS_ODD);
    //      No PARITY bit is transmitted or checked
    CSL_FINS (hUartRegs->LCR, UART_LCR_PEN,  CSL_UART_LCR_PEN_DISABLE);

    // Set the baudrate,for accessing LCR[7] should be enable
    hUartRegs->DLL  = 0x30;
    hUartRegs->DLH  = 0x00;

    // Allows access to the receiver buffer register (RBR),
    // the transmitter holding register (THR), and the
    // interrupt enable register (IER) selected.
    CSL_FINS (hUartRegs->LCR, UART_LCR_DLAB, CSL_UART_LCR_DLAB_DISABLE);
    // Even Parity is selected
    CSL_FINS (hUartRegs->LCR, UART_LCR_EPS, CSL_UART_LCR_EPS_EVEN);
    // Parity Enable
    CSL_FINS (hUartRegs->LCR, UART_LCR_PEN, CSL_UART_LCR_PEN_ENABLE);

    // Disable THR, RHR, Receiver line status interrupts
    CSL_FINS (hUartRegs->IER, UART_IER_ERBI,  CSL_UART_IER_ERBI_DISABLE);
    CSL_FINS (hUartRegs->IER, UART_IER_ETBEI, CSL_UART_IER_ETBEI_DISABLE);
    CSL_FINS (hUartRegs->IER, UART_IER_ELSI,  CSL_UART_IER_ELSI_DISABLE);
    CSL_FINS (hUartRegs->IER, UART_IER_EDSSI, CSL_UART_IER_EDSSI_DISABLE);

    /* If autoflow control is desired,
    * write appropriate values to the modem
    * control register (MCR). Note that all UARTs
    * do not support autoflow control, see
    * the device-specific data manual for supported features.
    *
    * MCR
    * ====================================================
    * Bit  Field   Value   Description
    * 5    AFE     0       Autoflow control is disabled
    * 4    LOOP    0       Loop back mode is disabled.
    * 1    RTS     0       RTS control (UARTn_RTS is disabled,
    *                      UARTn_CTS is only enabled.)
    * =====================================================
    */

    hUartRegs->MCR = (1<<4);

    /* Choose the desired response to
    * emulation suspend events by configuring
    * the FREE bit and enable the UART by setting
    * the UTRST and URRST bits in the power and
    * emulation management register (PWREMU_MGMT).
    *
    *
    * PWREMU_MGMT
    * =================================================
    * Bit  Field   Value   Description
    * 14   UTRST   1       Transmitter is enabled
    * 13   URRST   1       Receiver is enabled
    * 0    FREE    1       Free-running mode is enabled
    * ===================================================
    *
    */
    hUartRegs->PWREMU_MGMT = 0x6001;

    /* Cleanup previous data (rx trigger is also set to 0)*/
    /* Set FCR = 0x07;        */
    CSL_FINS (hUartRegs->FCR, UART_FCR_FIFOEN,   CSL_UART_FCR_FIFOEN_ENABLE);
    CSL_FINS (hUartRegs->FCR, UART_FCR_TXCLR,    CSL_UART_FCR_TXCLR_CLR);
    CSL_FINS (hUartRegs->FCR, UART_FCR_RXCLR,    CSL_UART_FCR_RXCLR_CLR);
    CSL_FINS (hUartRegs->FCR, UART_FCR_DMAMODE1, CSL_UART_FCR_DMAMODE1_DISABLE);
    CSL_FINS (hUartRegs->FCR, UART_FCR_RXFIFTL,  CSL_UART_FCR_RXFIFTL_CHAR14);

    return;
}

/******************************************************************************
 *
 * Function:    UartSetBaudRate
 *
 * Description: This function sets the UART baudrate.
 *
 * Parameters:  UINT16 uiBaudRate - baudrate to set
 *
 * Return Value: void
 *
 ******************************************************************************/
void UartSetBaudRate(uint16_t uiBaudRate)
{
    uint8_t uiDLLVal = 0;
    uint8_t uiDLHVal = 0;

    hUartRegs->MDR = 1;

    hUartRegs->LCR = 0x80;
    uiDLLVal = (uint8_t )(0x00FF & uiBaudRate);
    uiDLHVal = (uint8_t )(0x00FF & (uiBaudRate  >> 8));

    // Set the baudrate,for accessing LCR[7] should be enable
    hUartRegs->DLL  = uiDLLVal;
    hUartRegs->DLH  = uiDLHVal;
    hUartRegs->LCR = 0x03;
}

/******************************************************************************
 *
 * Function:    UartReadData
 *
 * Description: This function reads a byte of data from I2C UART device
 *
 * Return Value: uint8_t - 8-bit value read from the RBR register
 ******************************************************************************/
uint8_t UartReadData(void)
{
    uint8_t uRcvChar = 0;

    uRcvChar = CSL_FEXT(hUartRegs->RBR, UART_RBR_DATA);

    return uRcvChar;
}

/******************************************************************************
 *
 * Function:    UartWriteData
 *
 * Description: This function writes a byte of data to UART device
 *
 * Parameters:  uint8_t uchAddress - Address of 8-bit register
 *                              uint8_t uchByte -  8-bit data to write to THR
 *
 * Return Value: none
 ******************************************************************************/
void UartWriteData(uint8_t uchByte)
{
    CSL_FINS(hUartRegs->THR, UART_THR_DATA, uchByte);
    return;
}

/******************************************************************************
 *
 * Function:    UartIsDataReady
 *
 * Description: This function gets the status of DR bit
 *
 * Parameters:  none
 *
 * Return Value: Status of DR bit
 *
 ******************************************************************************/
Bool UartIsDataReady(void)
{
    Bool DR_val = FALSE;

    if (CSL_UART_LSR_DR_READY == (CSL_FEXT(hUartRegs->LSR, UART_LSR_DR))) {
        DR_val  = TRUE;
    }

    return (DR_val);
}

/******************************************************************************
 *
 * Function:    UartIsFifoEmpty
 *
 * Description: This function gets the status of THRE bit
 *
 * Parameters:  none
 *
 * Return Value: Status of DR bit
 *
 ******************************************************************************/
Bool UartIsFifoEmpty(void)
{
    Bool THRE_val = FALSE;

    if (CSL_UART_LSR_THRE_EMPTY == (CSL_FEXT(hUartRegs->LSR, UART_LSR_THRE))) {
        THRE_val  = TRUE;
    }

    return (THRE_val);
}


// uart clock = sysclk7 = coreclk/6

#define PLATFORM_UART_INPUT_CLOCK_RATE  ((1000000000)/(6))

void main(void)
{
  //CSL_chipWriteTSCL(0);

  char msg[] ="simple message";
  uint8_t data;

  /* Initialize UART in FIFO mode & enable loopback mode */
  UartInit();
  UartSetBaudRate((PLATFORM_UART_INPUT_CLOCK_RATE/(921600 * 16)));

  int cnt=10;
  while (cnt--)
  {
    unsigned i;

    /** ------ 1. write TX FIFO and read from RX FIFO ------ **/

    printf("write TX FIFO and read from RX FIFO\n");
    /* write data to TX FIFO */
    for (i=0; i< sizeof(msg); i++)
    {
      UartWriteData(msg[i]);
    }

    /* read data form RX FIFO */
    for (i=0; i< sizeof(msg); i++)
    {
      while (!UartIsDataReady());
      data=UartReadData();
      printf("%c",data);
    }

    printf("\n");

    /** ------ 2. wait while TX FIFO empty write TX FIFO and read from RX FIFO ------ **/

    printf("wait while TX FIFO empty write TX FIFO and read from RX FIFO\n");

    /* wait while TX FIFO empty and write data to TX FIFO  */
    for (i=0; i< sizeof(msg); i++)
    {
      /* wait while TX FIFO empty */
      while (!UartIsFifoEmpty());
      UartWriteData(msg[i]);
    }

    /* read data form RX FIFO */
    /* error!!! read  */
    for (i=0; i< sizeof(msg); i++)
    {
      /* error!!! here read only two last bytes -
       * msg[sizeof(msg)-2], msg[sizeof(msg)-1] */
      while (!UartIsDataReady());
      data=UartReadData();
      printf("%c",data);
    }

    printf("\n");
  }

}


With regard, Aleksey Shupletsov!

  • Hi,lexa

    The FIFO have two different mode(poll and interrupt),you used FIFO poll mode.

    I coded a uart driver(FIFO interrupt mode).It`s Ok.

    But i never use the loopback.you can chang your mode.

    And then you can count occured interrupt times.

    With regard,

    Li

  • In FIFO mode, the THRE bit is set when the transmitter FIFO is empty, and it is cleared when at least one byte is loaded into the FIFO.

    If you are checking this bit before every bit you are going to transmit, it is equal to use the UART TX in non-FIFO mode, since you transmit the next data only when the FIFO is entirely empty.

    There is huge delay between the CPU starts to transmit the data and CPU starts to receive the data if the THRE is being checked for every byte of data in the loopback mode. The receiver side may run into time-out status. And it could not recover correctly in the loopback mode.

    May I ask if  you have seen the issue in normal operation (two-UART connection) with this polling method please?

  • Hi, Steven

    Yes, I've seen this problem in normal operation (two-UART connection).

     I understand that checking this bit before every transmit, it is equal to use the UART TX in non-FIFO. This is a test program to search for the causes of the loss of the received data.

    Could you explain why "The receiver side may run into time-out status. And it could not recover correctly in the loopback mode."?

    On my opinion, the following occurs:

    when TX fifo transmit last byte, then RX fifo cleared (i don't know why) and that's why I received only two last byte that were in TX and RX shift register.

    Sincerely,

    Aleksey

  • Hi,

    I found a bug in UART code from PDK: UartWriteData() use a macro (CSL_FINS) that first read the register (in this case the THR that when reading becames the RBR), modify it and then write it back.

    Since, at every UartWriteData() You could remove a char from the RX FIFO.