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.

example app uartEcho_edma not working



I was trying the example uartEcho_edma (C:\Program Files\Texas Instruments\StarterWare_02_00_00_04\examples\beaglebone\uart_edma) on beaglebone. The first DMA transfer worked and printed out the first line ("StarterWare AM335X UART DMA application"). The second DMA transfer didn't work. The program didn't print the second line ("Please Enter 08 bytes from keyboard"). The program kept waiting for the completion of the second DMA transfer. If I re-initialized the UART after the first DMA transfer, then the second DMA transfer would work.

What's the correct way to configure UART and DMA for repeated DMA transfers? Thanks for your help!

  • Hello Yanli,

    Firstly, have you defined the macro UART_ENABLE_FIFO in the application file ? If so, then the application would not work and this has come to our notice during our regular software tests.

    I would like to briefly explain the issue so that you gain an insight into the same.

    There are two modes in which UART could be operated - non-FIFO mode and FIFO mode. The FIFO mode of operation is where a dedicated 64 byte FIFO for transmission and a similar one for reception are used by the UART during transmission and reception. Whereas in the non-FIFO mode of operation, the above mentioned FIFOs are not used during transmission and reception. We observed in the UART EDMA application that consecutive transmissions are not happening in FIFO mode of operation of UART (the first TX transaction happens but the immediate next one does not start) and that the same works well in non-FIFO mode.

    You would have observed the problem that you stated when FIFO mode of UART operation is used (UART_ENABLE_FIFO macro is defined). The application in its default form does not use FIFOs and therefore the application works as expected.

    An internal communication in TI regarding this issue is in progress. This issue when fixed shall be included in the future releases.

    Please revert back for any queries.

     

    Thanks and Regards.

    Gurudutt

  • Hello Gurudutt,

    Thanks for your reply. I didn't define UART_ENABLE_FIFO, but the second DMA transfer still didn't work. The release notes (ReleaseNotes_02_00_00_04.pdf) had this on page 3:

    "UART EDMA example not working consistently with AM335X EVM and Beagle Bone"

    If it is "not working consistently", do you know when it does work? Thanks!

    --Yanli

  • Hello Yanli,

    I suppose you are referring to StarterWare 02.00.00.04 release. I tested the ELF executable (.out) of UART EDMA application (found in the path - binary\armv7a\cgttms470_ccs\am335x\beaglebone\uart_edma) through CCS on a Revision A1 BeagleBone board and it works as expected. Both the strings get displayed and reception also works.

    As I had mentioned before, the default state of the file does not define the macro UART_ENABLE_FIFO. Since the non-FIFO mode is used, the application should work.

    Are you testing the ELF executable or the binary image of the application ?

    Could you test the pre-built executable of this release and post me about the results ?

    Thanks and Regards.

    Gurudutt

  • Hello Gurudutt,

    The pre-built executable worked for me too. The one I built through CCS (without any changes to the source codes) didn't work.

    Thanks,

    Yanli

  • Gurudutt,

    Can you confirm that you can rebuild the UART_DMA example and that the .out file runs correctly?

    Thanks,
    Charles

  • Hello Charles/Yanli,

    I tested the executable of UART EDMA application obtained through CCS build and Cygwin build on a Revision A1 Beaglebone board. The application worked successfully and desired results were obtained.

    I have attached a compressed file with this post containing the executable that I used for my tests.

     I would like to explain the method I followed to build the application, load the executable through CCS and test it on a Beaglebone board.

     CCS Build

     The CCS project for UART EDMA application is present in the following path:

    “<StarterWare_02_00_00_04 Installation path>\build\armv7a\cgttms470_ccs\am335x\beaglebone\uart_edma”

     Steps to import and build the CCS project:

    • Launch CCS and then navigate to CCS Edit perspective.
    • Open Project Explorer Menu. Right-click on the mouse and select ‘Import’.
    • Import the CCS project specified in the path above.
    • Right –click on the Project name and select Clean Project. After the project is cleaned, right-click again and select Build Project. The project gets built.

     The executable will be available in the following path:

    “<StarterWare_02_00_00_04 Installation path>\binary\armv7a\cgttms470_ccs\am335x\beaglebone\uart_edma”

     Steps to load the executable:

    •  Navigate to the Debug Perspective in CCS.
    • Open Target Configuration Menu and launch the target configuration file for Beaglebone.
    • After the launch happens, navigate to the Debug menu, right-click on “Texas Instruments XDS100v2 USB Emulator_0/CortexA8” and select “Connect Target”.  The target gets connected.
    • The serial communication port number (COM Port Number) for USB Serial Port should be checked in the Device Manager of your Windows machine. The serial communication application (Tera Term/ HyperTerminal ) should be configured to communicate with that specific port. I am using Tera Term.
    • Travel to Run -> Load -> Load Program and load the executable.
    • The results shall show up on the serial console.

     

    Cygwin Build

     Steps to build the GCC makefile through Cygwin:

    • Launch the Cygwin shell. Travel to “cygdrive\<StarterWare_02_00_00_04 Installation path>\build\armv7a\gcc\am335x\beaglebone\uart_edma”  to find the makefile.
    • Ensure that you have exported the path of the Code Sourcery Installation in your machine.
    • Give the command ‘make clean’ to clean and ‘make’ to build the application.

    The executable will be available in the following path:

    “<StarterWare_02_00_00_04 Installation path>\binary\armv7a\gcc\am335x\beaglebone\uart_edma”.

    Load and test the executable by following the procedure mentioned above.

     

    The information mentioned above shall be redundant to you if you are adept in using CCS.

    But I wanted to make sure that we are standing on a common ground before going ahead.

     

    Please revert back for any queries.

     

    Thanks and Regards.

    Gurudutt.

     

  • Hello Charles/Yanli,

    The attachment which I mentioned before is with this post.

    Thanks and Regards.

    Gurudutt.

    UART_EDMA executable.zip
  • Compiling with Optimization Level 0 (in TMS470 Compiler Basic Options) made the example work as expected. But if I modified the source codes in the example without changing configuration of UART or EDMA, it stopped working again...

  • Hello Yanli,

    I see that you have mentioned two observations in your email.

    - Compiling with Optimization Level 0 (in TMS470 Compiler Basic Options) made the example work as expected.

    • I see that you have imported the CCS Project of UART EDMA to your workspace and have built it.
    • The optimization level used by you is 0. When the obtained executable is tested, it is found to work as expected. The Debug build configuration shall use an Optimization level of 0 by default (Though the TMS470 Compiler Basic Options window keeps the Optimization level field blank for Debug build, I suppose it uses Optimization Level 0).
    • Does this mean that the executable obtained from Release Build configuration did not work for you ? The reason behind me asking this is that the Release build configuration uses an Optimization level of 2. Please clarify this to me.

    - But if I modified the source codes in the example without changing configuration of UART or EDMA, it stopped working again...

    • You have mentioned that you have modified the source code. Can you specifically tell what changes you made ?  A snippet of the code changes would help.
    • Could you elaborate on the results you see on the serial console ? Perhaps a text copy of the contents of the serial console on your next post would help. If you were debugging and the execution hanged at some point, you could elaborate on that too.

    Thanks and Regards.

    Gurudutt.

  • Gurudutt,

    I am working with Yanli on this project.

    According to the TMS470 compiler documentation, leaving the optimization setting blank does not assume level 0. Level 0 and no optimization are different as shown below.

    • --opt_level=0 or -O0
    – Performs control-flow-graph simplification
    – Allocates variables to registers
    – Performs loop rotation
    – Eliminates unused code
    – Simplifies expressions and statements
    – Expands calls to functions declared inline

    Although enabling various levels of optimization does sometimes make the code work, it is not a permanent fix.  There appears to be some problem, perhaps hardware related, that requires a full reset of the UART before a message can be transmitted using DMA.  We would like to get to the root cause of this in order to determine the best way to handle it without having to fly blind.

    Our applications rely heavily on multiple asynch serial communications and we must have confidence that they will function properly.

    Randy Ott

  • Hello Randy,

     I appreciate your effort in enlightening me about the fact that No Optimization and Optimization Level 0 are different.

    I am equally coherent with your proposal that a permanent solution should be arrived at regarding this issue. Experimenting with various Optimization Levels and making the application work shall truly be a temporary solution.

    As I have already mentioned, a discussion thread is underway in TI and people are investigating this issue. Currently, I do not have updated information about the progress they have made. I will certainly get back to you once I am abreast with the latest information. If situation demands, a person who is well versed with this problem will pitch in and give his opinion. If a fix has been arrived at for this problem, then it shall be incorporated as a part of the future releases.

     I will get back to you with the latest information as early as possible.

     Thanks and Regards.

    Gurudutt.

  • static void callback(unsigned int tccNum, unsigned int status)

     {

    /* Disabling DMA Mode of operation in UART. */

     UARTDMADisable(SOC_UART_0_REGS);

     /* Disabling DMA transfer on the specified channel. */

    EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, tccNum, EDMA3_TRIG_MODE_EVENT);

     clBackFlag = 1;

     }

    If you set a breakpoint at "UARTDMADisable(SOC_UART_0_REGS);",The program will TX  "StarterWare AM335X UART DMA application" only.

    Or, If you add same code at the front of the  "UARTDMADisable(SOC_UART_0_REGS);",The program will TX  "StarterWare AM335X UART DMA application" only.

    So I think the problem is :

    If the program can not disabling DMA Mode of operation in UART immediately after the EDMA3 Completion,the EDMA3 will not miss the uart request, but the uart will not send the request anymore. So if you reinitializes the UART0,the EDMA3 will receive the uart request again.

  • The EDMA3EnableTransfer is in the edma.c of the drivers.

    If I add "if( chNum==26 ) EDMA3SetEvt(baseAdd, chNum);" at the front of "EDMA3EnableDmaEvt(baseAdd, chNum);" at the EDMA3EnableTransfer.

    The problem is resolved.  But why?

    unsigned int EDMA3EnableTransfer(unsigned int baseAdd, unsigned int chNum, unsigned int trigMode)

     {

    unsigned int retVal = FALSE;

    switch (trigMode)

     { case EDMA3_TRIG_MODE_MANUAL :

    if (chNum < SOC_EDMA3_NUM_DMACH) { EDMA3SetEvt(baseAdd, chNum); retVal = TRUE; } break;

    case EDMA3_TRIG_MODE_QDMA :

    if (chNum < SOC_EDMA3_NUM_QDMACH)

    { EDMA3EnableQdmaEvt(baseAdd, chNum); retVal = TRUE; } break;

    case EDMA3_TRIG_MODE_EVENT :

    if (chNum < SOC_EDMA3_NUM_DMACH)

     {

    /*clear SECR & EMCR to clean any previous NULL request */

    EDMA3ClrMissEvt(baseAdd, chNum);

    if( chNum==26 ) EDMA3SetEvt(baseAdd, chNum);

    /* Set EESR to enable event */

    EDMA3EnableDmaEvt(baseAdd, chNum);

     retVal = TRUE;

    } break;

    default : retVal = FALSE; break;

     } return retVal;

    }

  • The EDMA3EnableTransfer is in the edma.c of the drivers.

    If I del "EDMA3ClrMissEvt(baseAdd, chNum);" at the EDMA3EnableTransfer.

    The problem is resolved, too. I think it better than add "if( chNum==26 ) EDMA3SetEvt(baseAdd, chNum);" at the front of "EDMA3EnableDmaEvt(baseAdd, chNum);" at the EDMA3EnableTransfer.

    unsigned int EDMA3EnableTransfer(unsigned int baseAdd, unsigned int chNum, unsigned int trigMode)

     {

    unsigned int retVal = FALSE;

    switch (trigMode)

     { case EDMA3_TRIG_MODE_MANUAL :

    if (chNum < SOC_EDMA3_NUM_DMACH) { EDMA3SetEvt(baseAdd, chNum); retVal = TRUE; } break;

    case EDMA3_TRIG_MODE_QDMA :

    if (chNum < SOC_EDMA3_NUM_QDMACH)

    { EDMA3EnableQdmaEvt(baseAdd, chNum); retVal = TRUE; } break;

    case EDMA3_TRIG_MODE_EVENT :

    if (chNum < SOC_EDMA3_NUM_DMACH)

     {

    /*clear SECR & EMCR to clean any previous NULL request */

    //EDMA3ClrMissEvt(baseAdd, chNum);

    /* Set EESR to enable event */

    EDMA3EnableDmaEvt(baseAdd, chNum);

     retVal = TRUE;

    } break;

    default : retVal = FALSE; break;

     } return retVal;

    }

  • Hi Zuobing,

    The issues with UART_edma example workiing inconsistently have been fixed in the latest Starterware Release 02.00.01.01. The latest StarterWare package can be found at  http://processors.wiki.ti.com/index.php/StarterWare

    Regarding, the issue of putting a breakpoint in the ISR callback function. It is recommended not to put breakpoints in the completion ISR. If it has to be applied then it canbe put after the code which disables the DMA mode of UART. The reason behind this observation is as below,

    When the control hits the breakpoint in the EDMA Completion ISR, all the data of the first transaction would not be transmitted by UART. If the length of the first string was greater than the TX Threshold, then the current FIFO level would be greater than the TX Threshold. However by the time the application is executed further after the breakpoint, the UART would have transmitted all the data in TX FIFO. The UART would have sent a TX DMA event to EDMA when the FIFO level would have reached the TX Threshold. On execution, the EDMA executes the Dummy PaRAM set in response to the received UART TX event. Since the UART would not receive any data from the EDMA’s dummy transfer, it keeps the DMA request active. Thus the application hangs.

    Regards

    Anant Pai