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.

PROCESSOR-SDK-AM335X: UART looback issue

Part Number: PROCESSOR-SDK-AM335X

Hi,

I am using SKAM335x board and TI SDK RTOS on windows host PC.

I have enabled uart0 looback for testing. I am sending data and same data I am receiving. When I do step in while debugging it is receiving a data properly but if I run the program without any breakpoint or step in then uart0 is not receiving data correctly. 

I gave delay also between transmit and uart but then also it is not working.

Another thing is that, if I have enabled the loopback then why it is printing data on terminal whatever I am transmitting. This problem is coming while running the code completely not in step in.

Please suggest any solution to this problem.

Regards,

Gaurav

  • Hi Guarav,

    Are you using a UART example provided with PRSDK?

    What version of PRSDK are you using?

    Have you made modifications to the code?

    I assume this is an internal loopback (configured w/ switch below), not an external loopback?

    uint32_t loopback;
    /**< flag to indicate in loopback mode */

    Regards,
    Frank

  • Hi Frank,

    I am using TI SDK RTOS 6.01.00.08.

    I configured uart with the help of driver functions. Yes, this is an internal loopback.

    Please suggest any solution to rectify this problem. 

    Please find attached .c file.

    uart_module.c
    /*-----------------------------------------------------------------------------------------
    FUNCTION NAME: UART0_Init
    DESCRIPTION  : To initialize UART0
    PARAMETERS   : None
    RETURN       : Void
    -------------------------------------------------------------------------------------------*/
    void UART0_Init(void)
    {
            /* Configuring the system clocks for UART0 instance. */
             UART0ModuleClkConfig();
    
             // Performing the Pin Multiplexing for UART0 instance.
             UARTPinMuxSetup(0);
    
             // Performing a module reset.
             UARTModuleReset(SOC_UART_0_REGS);
    
             //Performing FIFO configurations.
             UartFIFOConfigure(SOC_UART_0_REGS);
    
             UartConfigure(SOC_UART_0_REGS,BAUD_RATE_115200, (UART_FRAME_WORD_LENGTH_8 |
                                                   UART_FRAME_NUM_STB_1 |
                                                   UART_PARITY_NONE));
    }
    /*-----------------------------------------------------------------------------------------
    FUNCTION NAME: UartFIFOConfigure
    DESCRIPTION  : To configure UART FIFO
    PARAMETERS   : none
    RETURN       : Void
    -------------------------------------------------------------------------------------------*/
    void UartFIFOConfigure(uint32_t baseaddress)
    {
        unsigned int fifoConfig = 0;
    
        /*
        ** - Transmit Trigger Level Granularity is 4
        ** - Receiver Trigger Level Granularity is 1
        ** - Transmit FIFO Space Setting is 56. Hence TX Trigger level
        **   is 8 (64 - 56). The TX FIFO size is 64 bytes.
        ** - The Receiver Trigger Level is 1.
        ** - Clear the Transmit FIFO.
        ** - Clear the Receiver FIFO.
        ** - DMA Mode enabling shall happen through SCR register.
        ** - DMA Mode 0 is enabled. DMA Mode 0 corresponds to No
        **   DMA Mode. Effectively DMA Mode is disabled.
        */
        fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_4,
                                      UART_TRIG_LVL_GRANULARITY_1,
                                      UART_FCR_TX_TRIG_LVL_56,
                                      1,
                                      1,
                                      1,
                                      UART_DMA_EN_PATH_SCR,
                                      UART_DMA_MODE_0_ENABLE);
    
        /* Configuring the FIFO settings. */
        UARTFIFOConfig(baseaddress, fifoConfig);
    }
    /*-----------------------------------------------------------------------------------------
    FUNCTION NAME: UartBaudRateSet
    DESCRIPTION  : To configure UART baudrate
    PARAMETERS   : uint32_t baudRate
    RETURN       : Void
    -------------------------------------------------------------------------------------------*/
    void UartBaudRateSet(uint32_t baseaddress,uint32_t baudRate)
    {
        unsigned int divisorValue = 0;
    
        /* Computing the Divisor Value. */
        divisorValue = UARTDivisorValCompute(UART_MODULE_INPUT_CLK,
                                             baudRate,
                                             UART16x_OPER_MODE,
                                             UART_MIR_OVERSAMPLING_RATE_42);
    
        /* Programming the Divisor Latches. */
        UARTDivisorLatchWrite(baseaddress, divisorValue);
    }
    /*-----------------------------------------------------------------------------------------
    FUNCTION NAME: UartLineCharacSet
    DESCRIPTION  : To configure UART Character length
    PARAMETERS   : uint32_t lineCharConfig
    RETURN       : Void
    -------------------------------------------------------------------------------------------*/
    void UartLineCharacSet(uint32_t baseaddress,uint32_t lineCharConfig)
    {
        unsigned int wLenStbFlag = 0;
        unsigned int parityFlag = 0;
    
        wLenStbFlag = (lineCharConfig & (UART_LCR_NB_STOP | UART_LCR_CHAR_LENGTH));
        parityFlag = (lineCharConfig & (UART_LCR_PARITY_TYPE2 |
                                        UART_LCR_PARITY_TYPE1 |
                                        UART_LCR_PARITY_EN));
    
        UARTLineCharacConfig(baseaddress, wLenStbFlag, parityFlag);
    }
    /*-----------------------------------------------------------------------------------------
    FUNCTION NAME: UartConfigure
    DESCRIPTION  : To configure UART
    PARAMETERS   : uint32_t baseaddress,uint32_t baudRate, uint32_t lineCharConfig
    RETURN       : Void
    -------------------------------------------------------------------------------------------*/
    void UartConfigure(uint32_t baseaddress,uint32_t baudRate, uint32_t lineCharConfig)
    {
        UartBaudRateSet(baseaddress,baudRate);
    
        /* Switching to Configuration Mode B. */
        UARTRegConfigModeEnable(baseaddress, UART_REG_CONFIG_MODE_B);
    
        UartLineCharacSet(baseaddress,lineCharConfig);
    
        /* Disabling write access to Divisor Latches. */
        UARTDivisorLatchDisable(baseaddress);
    
        /* Disabling Break Control. */
        UARTBreakCtl(baseaddress, UART_BREAK_COND_DISABLE);
    
        /* Switching to UART16x operating mode. */
        UARTOperatingModeSelect(baseaddress, UART16x_OPER_MODE);
    }
    
    void RS422_Test(void)
    {
    
        uint8_t txByte = 0;
    
        uint8_t rxByte = 0;
    
    
        ConsoleUtilsPrintf("\tRS-422 Test.\n\n\r");
    
        ConsoleUtilsPrintf("\tRS-422 CH1 loopback Test is performing......\n\n\r");
    
        UARTLoopbackModeControl(SOC_UART_0_REGS,0x10);//UART_LOOPBACK_MODE_ENABLE
    
        txByte ='a';
    
    
        UARTFIFOCharPut(SOC_UART_0_REGS, txByte);
    
        //DU_Delay(1);
    
        rxByte = UARTFIFOCharGet(SOC_UART_0_REGS);
    
        UARTLoopbackModeControl(SOC_UART_0_REGS,0);
    
        if(txByte == rxByte)
        {
            ConsoleUtilsPrintf("\t   RS-422 CH1 Loopback Test is PASS\n\r");
        }
    
        else
        {
            ConsoleUtilsPrintf("\t  RS-422 CH1 Loopback Test is FAIL\n\r");
        }
    
            ConsoleUtilsPrintf("\t  RS-422 CH2 Loopback Test is performing......\n\n\r");
    
    
        UARTLoopbackModeControl(SOC_UART_1_REGS,0x10);//UART_LOOPBACK_MODE_ENABLE
    
        txByte ='C';
    
        UARTFIFOCharPut(SOC_UART_1_REGS, txByte);
    
        //DU_Delay(1);
    
        rxByte = UARTFIFOCharGet(SOC_UART_1_REGS);
    
        if(txByte == rxByte)
        {
            ConsoleUtilsPrintf("\t RS-422 CH2 Loopback Test is PASS\n\r");
        }
    
        else
        {
            ConsoleUtilsPrintf("\t RS-422 CH2 Loopback Test is FAIL\n\r");
        }
        UARTLoopbackModeControl(SOC_UART_1_REGS,0);
    
    
    }
    uart.c
    /**
     * \file   uart.c
     *
     * \brief  This file contains functions which does the platform specific
     *         configurations for UART.
     */
    
    /*
    * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
    */
    /*
    *  Redistribution and use in source and binary forms, with or without
    *  modification, are permitted provided that the following conditions
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */
    
    
    #include "hw_control_AM335x.h"
    #include "soc_AM335x.h"
    #include "hw_cm_wkup.h"
    #include "hw_cm_per.h"
    #include "evmskAM335x.h"
    #include "hw_types.h"
    
    /**
     * \brief   This function selects the UART pins for use. The UART pins
     *          are multiplexed with pins of other peripherals in the SoC
     *          
     * \param   instanceNum    The instance number of the UART to be used.
     *
     * \return  None
     *
     * \note    This pin multiplexing depends on the profile in which the EVM
     *          is configured.
     */
    
    
    void UARTPinMuxSetup(unsigned int instanceNum)
    {
        switch(instanceNum)
        {
            case 0:
            {
                /* RXD */
                HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_RXD(0)) =
                    ( CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUTYPESEL |//CONTROL_CONF_UART0_RXD_CONF_UART0_RXD_PUDEN
                     CONTROL_CONF_UART0_RXD_CONF_UART0_RXD_RXACTIVE);
    
                /* TXD */
                HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_TXD(0)) =
                    CONTROL_CONF_UART0_TXD_CONF_UART0_TXD_PUTYPESEL;
            }
            break;
    
            case 1:
            {
                 //RXD
               /* HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_RXD(1)) =
                    (CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUDEN |
                     CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_RXACTIVE);
    
                 //TXD
                HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_TXD(1)) = CONTROL_CONF_UART1_TXD_CONF_UART1_TXD_PUDEN;*/
                HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_RXD(1)) =
                            (CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUTYPESEL |
                             CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_RXACTIVE);
    
                       // TXD
                       HWREG(SOC_CONTROL_REGS + CONTROL_CONF_UART_TXD(1)) =
                               CONTROL_CONF_UART1_TXD_CONF_UART1_TXD_PUTYPESEL;
    
            }
            break;
    
            default:
            break;
        }
    }
    
    /*
    ** This function enables the module clock for UART0 instance.
    */
    
    void UART0ModuleClkConfig(void)
    {
    
        /* Writing to MODULEMODE field of CM_WKUP_UART0_CLKCTRL register. */
        HWREG(SOC_CM_WKUP_REGS + CM_WKUP_UART0_CLKCTRL) |=
              CM_WKUP_UART0_CLKCTRL_MODULEMODE_ENABLE;
    
        /* Waiting for MODULEMODE field to reflect the written value. */
        while(CM_WKUP_UART0_CLKCTRL_MODULEMODE_ENABLE !=
              (HWREG(SOC_CM_WKUP_REGS + CM_WKUP_UART0_CLKCTRL) &
               CM_WKUP_UART0_CLKCTRL_MODULEMODE));
    
        /*
        ** Waiting for CLKACTIVITY_UART0_GFCLK field in CM_WKUP_CLKSTCTRL
        ** register to attain desired value.
        */
        while(CM_WKUP_CLKSTCTRL_CLKACTIVITY_UART0_GFCLK !=
              (HWREG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &
               CM_WKUP_CLKSTCTRL_CLKACTIVITY_UART0_GFCLK));
    
        /*
        ** Waiting for IDLEST field in CM_WKUP_UART0_CLKCTRL register to attain
        ** desired value.
        */
        while((CM_WKUP_UART0_CLKCTRL_IDLEST_FUNC <<
               CM_WKUP_UART0_CLKCTRL_IDLEST_SHIFT) !=
              (HWREG(SOC_CM_WKUP_REGS + CM_WKUP_UART0_CLKCTRL) &
               CM_WKUP_UART0_CLKCTRL_IDLEST));
    }
    
    void UART1ModuleClkConfig(void)
    {
        /* Writing to MODULEMODE field of CM_PER_UART1_CLKCTRL register. */
            HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) |=
                  CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE;
    
            /* Waiting for MODULEMODE field to reflect the written value. */
            while(CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE !=
                  (HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) &
                   CM_PER_UART1_CLKCTRL_MODULEMODE));
    
            /*
            ** Waiting for CLKACTIVITY_UART1_GFCLK field in CM_L4LS_CLKSTCTRL
            ** register to attain desired value.
            */
            while(CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_UART_GFCLK !=
                  (HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) &
                          CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_UART_GFCLK));
    
            /*
            ** Waiting for IDLEST field in CM_PER_UART1_CLKCTRL register to attain
            ** desired value.
            */
            while((CM_PER_UART1_CLKCTRL_IDLEST_FUNC <<
                   CM_PER_UART1_CLKCTRL_IDLEST_SHIFT) !=
                  (HWREG(SOC_CM_PER_REGS + CM_PER_UART1_CLKCTRL) &
                   CM_PER_UART1_CLKCTRL_IDLEST));
    }
    
    /****************************** End of file *********************************/
    
    uart_irda_cir.c

    Regards,

    Gaurav

  • Gaurav,

    I surmise your test function is RS422_Test(). I notice you're using these CSL API functions:

        UARTFIFOCharPut(SOC_UART_0_REGS, txByte);

        rxByte = UARTFIFOCharGet(SOC_UART_0_REGS);

    Please see the descriptions of these CSL API functions in <PDK>\packages\ti\csl\src\ip\uart\V1\uart.h:

    /**
     * \brief   This API writes a byte to the Transmitter FIFO without checking for
     *          the emptiness of the Transmitter FIFO or the Transmitter Shift
     *          Register(TSR).
     *
     * \param   baseAddr     Memory address of the UART instance being used.
     * \param   byteTx      The byte to be transmitted by the UART.
     *
     *
     * \return  None
     *
     * \note    Unlike the APIs UARTCharPut() or UARTCharPutNonBlocking(), this
     *          API does not check for the emptiness of the TX FIFO or TSR. This
     *          API is ideal for use in FIFO mode of operation where the 64-byte
     *          TX FIFO has to be written with successive bytes. If transmit
     *          interrupt is enabled, it provides a mechanism to control the
     *          writes to the TX FIFO.
     */
    extern void UARTFIFOCharPut(uint32_t baseAddr, uint8_t byteTx);

    Note: "without checking for the emptiness

    /**
     * \brief   This API reads the data present at the top of the RX FIFO, that
     *          is, the data in the Receive Holding Register(RHR). However
     *          before reading the data from RHR, it does not check whether
     *          RHR has fresh data or not.
     *
     * \param   baseAddr     Memory address of the UART instance being used.
     *
     *
     * \return  The data read from the RHR.
     *
     * \note    1) Since this API does not check whether RX FIFO(RHR) has fresh
     *             data before reading the same, the application should ensure
     *             that RX FIFO has data before calling this API. The API
     *             UARTCharsAvail() can be used to check if the RX FIFO has
     *             atleast one byte of data.\n
     *          2) If the RX FIFO did not have any fresh data and this API is
     *             called, this API would return an unknown value.\n
     */
    extern int8_t UARTFIFOCharGet(uint32_t baseAddr);

    Note: "It doesn't not check whether RHR has fresh data or not" 

    Have you tried inserting larger delays?

    I suggest you experiment with these API functions instead:

    extern void UARTCharPut(uint32_t baseAddr, uint8_t byteTx);

    extern int8_t UARTCharGet(uint32_t baseAddr);

    extern uint8_t UARTCharGetTimeout(uint32_t baseAddr, uint32_t timeOutVal);

     

    Regards,
    Frank

  • Frank,

    Yes, I tried with 50 ms delay but same problem.

    Thanks for your answer.

    I checked with your suggested APIs and UART but same problem is coming.

    I configured uart in one .c file and transmitting and receiving in another .c file then this problem is coming.

    But if I configure and do transmission in same .c file then this problem is not working. Why is it so?

    Mistakenly, I clicked on resolved. It is not resolved. 

    Regards,

    Gaurav

  • Frank,

    Yes, I tried with 50 ms delay but same problem.

    Thanks for your answer.

    I checked with your suggested APIs and UART but same problem is coming.

    I configured uart in one .c file and transmitting and receiving in another .c file then this problem is coming.

    But if I configure and do transmission in same .c file then this problem is not working. Why is it so?

    Mistakenly, I clicked on resolved. It is not resolved. 

    Regards,

    Gaurav

  • Gaurav,

    >> But if I configure and do transmission in same .c file then this problem is not working

    I don't understand. Are you saying the problem doesn't occur when you have all the code (configuration, transmit, receive) in the same C file, but the failure occurs when the same code split into two separate C files?

    Regards,
    Frank

  • Frank,

    Yes your are right. 

    Why is it so? 

    Regards,

    Gaurav

  • Gaurav,

    Is there something different about how the single or split files are compiled (e.g. pre-defined symbols, optimization options, etc.)?

    Is there something different about how the code is linked for the two cases (check the .map file)?

    Regards,
    Frank

  • Frank,

    I didn't change any compilation configuration or any configuration related to mapping too in both cases. 

    Let me check .map files then I'll let you know.

    Regards,

    Gaurav

  • Hi Gaurav,

    I haven't heard back from you in ~1 week, so I'm assuming this issue has been resolved and I'm closing the thread. Please reopen the thread if you're still having an issue.

    Regards,
    Frank

  • Hi Frank,

    Sorry for not reply. I was busy with some other work. Still same issue is coming. I am checking this UART issue. If you have any further idea please let me know.

    Regards,

    Gaurav