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.

EDMA channel triggered but memory not moved

Other Parts Discussed in Thread: OMAP3530

Hello, I have found a very weird behaviour of my edma channel. This is the configuration that I am using:

 

 edmaRegs->PARAMSET[59].OPT=0x0C38000 ;   
 edmaRegs->PARAMSET[59].SRC=(Uint32)&Variable1;
 edmaRegs->PARAMSET[59].A_B_CNT=0xFFFF0004 ;
 edmaRegs->PARAMSET[59].DST=(Uint32)&Variable2 ;
 edmaRegs->PARAMSET[59].SRC_DST_BIDX= 0;
 edmaRegs->PARAMSET[59].LINK_BCNTRLD= Param70;
 edmaRegs->PARAMSET[59].SRC_DST_CIDX= 0;
 edmaRegs->PARAMSET[59].CCNT= 0x01;

 

This channel is triggered from another EDMA channel. Basically what I want to do is move the content of variable1 to variable2, as you can see. In the code I have a line like this:

 

while (Variable1 != Variable2) {}; //wait condition until EDMA move variable1 to variable2.  And my code keep stuck in that line. You could think that the EDMA channel has not being triggered, but if I look dmaRegs->PARAMSET[59].A_B_CNT it has changed from 0xFFFF0004 to 0xFFFE0004, so it really has been triggered. Again, I look variable2 memory position, and its value has not being replaced with variable1 value.

I have declared variable1 and variable2 like int in main.c, and I configure EDMA in initEDMA.c where I declared both as extern int. So, what is wrong here???

 

Thank you in advance

 

PS: more facts that proves that EDMA channel has been really triggered: as you can see from this channel in the OPT field, I am triggering another chanel (0x38=56) and this channel have changed too its A_B_CNT from 0xFFFF to 0xFFFE, so it has been triggered after the intemediate completion of channel 59, which proves that 59 has been triggered. But no changes in memory... weird....

  • Caching could be the reason why you don't see the variable change via your program.

    Have you tried looking at the uncached memory location in CCS ?!

  • Actually,  I saw memory position of this variable in CCS and after some time, yeah I seems like has changed to the correct value. But the code still is stuck in this line, like no changes have being done.

     

    How can I see the "uncached" memory location... anyway, what could I do to solve the problem?

     

    Thank you very much for your answer

  • If you're using CCS 3.3 you can do View -> Memory and there are check-boxes for L1D, L1P, L2.  If something is cached it should be highlighted in the color corresponding to the check-box.  You can uncheck the box to see what's in the physical memory vs the cache.

  •  

             So I guess if it is a cache problem if I define the variables like "volatile" I would avoid this problem? I tried this before, but did not work well, I will try again this monday. Thanks

  • If variable1 and variable2 are located in the internal memory (L1D or L2 SRAM) then you will not have a coherence issue as the cache coherence is handled by the hardware for data stored in internal memory.

    There could potentially be two issues.  Since the variable would be changing outside the scope of the compiler it's hard to say how the compiler is handling it.  You should be using volatile in that case (or if an ISR in some other file was changing the value).  However, volatile will not solve all your issues.  At the end of the day, volatile just makes sure that the compiler creates the proper read instructions.  The compiler does not know anything about your memory placement or cache configuration or if a DMA is writing to a variable creating a cache coherence issue!

    Instead of polling the variable I recommend that you enable intermediate and final transfer completion.  Then you can either take an interrupt to indicate that the transfer is complete, or if you like polling you can leave the corresponding interrupt disabled in EDMA3.IER and poll EDMA3.IPR for the corresponding bit (TCC).  Furthermore, if your variables are in external memory then you would need to perform a block writeback of variable 1 BEFORE the transfer and you would need to perform a block invalidate of variable 2 AFTER the transfer.  In your current setup where you poll variable2 you would actually need to perform a block invalidate before every read!  Ugly...  To re-emphasize an earlier statement, that is only necessary in the case that the variable is in external memory.

    Brad

  •  

            Thank you very much for your help Brad, I really like your approach and I think it will work without problems. I will use polling of EMDA.IPR as I prefer to use poll for that part of the code. I will test it this monday.

     

    Thank you again

  • Well, I think I need some advice again. What Brad told me worked perfectly, but I am having same issue (cache coherence problem) in other part of my code.

     

    I have programed the McBSP to be served by EDMA, I have a BufferOutput, where I writte the message that I want to transmit, and after I enable the EDMA channel to drop words from this buffer and writte in DXR. In the program that I wrote by myself it works well, but when I tried to integrate in the third application that I am using I have a coherence problem:

     

    as you told me I have checked the memory location of BufferOutput and is highlighted in green which means L2 cache... and I have the problem that the the same message is transmitted two times, because it seems the cache is not refreshed with the new message. For example, I do:

     

    BufferOutput="hello"

    Enable EDMA channel that serves McBSP DXR register

     

    BufferOutput="goodbye"

    Enable EDMA channel that serves McBSP DXR register

     

    And I obtain something like "hello, hello, goodbye"... and of course that is not good for my application. advices????

     

    Thank you in advance

  • Delimiting my problem: the first "hello" that I want to transmit does not work. I have found that if I see the memory position, is highlighted in green (L2), with "hello" well written. But if I uncheck L2 checkbox, this positions appear with FFFFFF... , and of course I only transmitting FFFFF... instead of hello...

     

    so, what could you told me to solve this?

     

    Thank you very much

  • Ok, I have seen the light, I recommend this thread to who has the same problems:

    http://e2e.ti.com/forums/p/1355/4508.aspx#4508

  • Hello,

    I have the same problem of not seeing memory updated by EDMA transfering
    on OMAP3530 EVM.  Following are a description of my seetings.  I want to
    move data from an initialized buffer (srcBuff) to an empty buffer (dstBuff).

    After the transaction, I see IPR.b12 is set, but there're no data in dstBuff. 
    Both data buffers are in DSP's L2 memory (starting from 0x00800000), therefore
    I assume it's not a cache coherence problem. Actually, I don't quite understand
    what cache coherence problem is.  If I look into paramSet[12].A_B_CNT it
    changed from 0x00020004 to 0x00010004 after the first trigger, and so on.
    All of the contents of paramSet will be cleared when transfer has completed.


    Hope someone can help me with this. Thanks is advance.

    Juliann


    -------
    #define DATATX_COUNT   8
    Uint8  srcBuff[DATATX_COUNT];
    Uint8  dstBuff[DATATX_COUNT];


    for (i = 0, j = 1; i < DATATX_COUNT;i++,j++)
    {
       srcBuff[i] = j;
       dstBuff[i] = 0;
    }  

    TPCC_EMCR  = 0xFFFFFFFF;
    TPCC_EMCRH = 0xFFFFFFFF;
    TPCC_CCERRCLR = 0x00010003;
    TPCC_QUEPRI  = 0x00000010;
    TPCC_QWMTHR = (16<<8u)|(16&0xFF);        


    paramSet[12].OPT=0x0010C200;   
    paramSet[12].SRC=(Uint32)srcBuff;
    paramSet[12].A_B_CNT=0x00020004;
    paramSet[12].DST=(Uint32)dstBuff;
    paramSet[12].SRC_DST_BIDX= 0x00040000;
    paramSet[12].LINK_BCNTRLD= 0x0001FFFF;
    paramSet[12].SRC_DST_CIDX= 0;
    paramSet[12].CCNT= 0x1;


    TPCC_DCHMAP(12) = 0x00000180;
    TPCC_DMAQNUM(1) = 0x00010000;

    TPCC_IESR = (1<<12);

    numTX = 2;
     for (i=0; i<numTX; i++)
     {
         TPCC_ESR = (1<<12);
     }
     
     /* wait */
     while (!CSL_CHKbit(*(Uint32 *)(CSL_EDMA3CC_0_REGS + TPCC_IPR), EDMA3CC_IPR_I12));

     /* Transfer has completed, clear the status register. */
     REG_ACCESS(CSL_EDMA3CC_0_REGS, TPCC_ICR) = (1<<12);
    -------

  • Are you using BIOS?  I ask mainly to understand whether you have a linker command file generated by BIOS or if you wrote your own.  There are 2 separate address ranges that the 64x+ DSP core can use to address the internal L2 memory:

    • 0x007F8000 - visible only to 64x+ DSP core
    • 0x107F8000 - visible to both 64x+ core and EDMA

    You should make sure your linker command file defines the L2 memory to exist at the second address shown above rather than the first.  That way srcBuff will correspond to an address in the 0x107F8000 range.

    Brad

     

  • Hi Brad,

    First of all, you are right about the address setting for EDMA.  Below is
    the story how I solved the issue and some further questions.
        
      
    I'm not using BIOS, I wrote the linker command file on my own.  The run-time
    support library (rts64plus.lib) seems cannot be put into 0x107F8000, because
    _c_int00 mislayed when program is loaded into CCSv3.3.  Then I put rts library
    in 0x00800000 (or 0x007F8000), other programs in 0x107F8000 section, so _c_int00
    found its place but I got the following message and can't step through my programs.

       Loader: One or more sections of your program falls into a memory region
       that is not writable.  These regions will not actually be written to the
       target.  Check your linker configuration and/or memory map.
      
    This error message still appears after I modified the GEL file to tell Blackhawk
    JTAG emulator how to map address (see below, The last two lines were added).
    I even tried DSP/BIOS, it did nothing better on this issue, same error message.

       sdomap35xx_c64plus.gel:
       hotmenu setup_memory_map()
       {
          GEL_MapOn();
          GEL_MapReset();

          GEL_MapAddStr(0x007E0000, 0, 0x00004000, "R|W|AS4", 0);  /* L2 ROM */
          GEL_MapAddStr(0x007F8000, 0, 0x00008000, "R|W|AS4", 0);  /* L2 RAM */
          GEL_MapAddStr(0x00800000, 0, 0x00010000, "R|W|AS4", 0);  /* L2 RAM(Cache) */
       
          ....
          GEL_MapAddStr(0x107F8000, 0, 0x00008000, "R|W|AS4", 0);  /* aliasing L2 RAM */
          GEL_MapAddStr(0x10800000, 0, 0x00010000, "R|W|AS4", 0);  /* aliasing L2 RAM (cache) */

       }
      

    So I started to surf the internet and lucky I was to find a clue in this link:
    http://www.dsprelated.com/groups/c6x/show/10251.php  

    In CCS's 'options->memory map', I disabled memory mapping and everything works well
    except I had to set paramSet[12].SRC_DST_BIDX= 0x00040004 to get the srcBuff changing
    index.  


    Here are my questions:   
    1. Is GEL file necessary for JTAG emulator to know both ARM and DSP's memory mapping?   
    2. Is DSP/BIOS a must installed package for accessing DSP's memory starting from
       0x11000000 (a much lager memory section)?  Can I modify the linker command file
       generated by DSP/BIOS? I think I'll need to go with DSP/BIO in the near future.
      

    Juliann

     

  • JuliannH said:
    This error message still appears after I modified the GEL file to tell Blackhawk
    JTAG emulator how to map address (see below, The last two lines were added).

    Did you reload the gel file after you modified it?  If not, those changes never would have taken effect.  FYI, BIOS defines only the 0x10xxxxxx range of memory addresses so I know for certain that it is not required to have both sets. 

    JuliannH said:
    In CCS's 'options->memory map', I disabled memory mapping and everything works well
    except I had to set paramSet[12].SRC_DST_BIDX= 0x00040004 to get the srcBuff changing
    index. 

    This change is in line with my guess that perhaps you didn't reload the gel.

    JuliannH said:
    1. Is GEL file necessary for JTAG emulator to know both ARM and DSP's memory mapping?   

    If you have linked code into external memory then something needs to configure the DDR interface.  If the ARM is actually booted and running you may not need to worry about it.  However, on many of our single core devices the gel file will setup the PLLs and the DDR interface for you when you connect to the device such that CCS can load code/data into DDR.

    The memory mapping features that you are discussing are not required, but in general they improve the stability of the debug environment by preventing CCS from accidentally accessing reserved memory locations (e.g. as you scroll through a memory window, etc.).

    JuliannH said:
    2. Is DSP/BIOS a must installed package for accessing DSP's memory starting from
       0x11000000 (a much lager memory section)?  Can I modify the linker command file
       generated by DSP/BIOS? I think I'll need to go with DSP/BIO in the near future.
      

    No, BIOS is not required to access addresses over 0x11000000.  This is strictly a hardware thing.  Any addresses beginning with 0x11000000 are outside of the OMAP3530's DSP/IVA subsystem.   Note that not all of these addresses are RAM that you can use!  The only RAM available would be the DDR which begins at physical address 0x80000000.  Note, however, that you want to make sure you don't trample on the ARM's memory since it uses that same DDR.  Also, DSP accesses are going through an MMU (separate/different than ARM MMU).  By default the MMU is off and accesses just pass straight through.

  • Hi Brad,

    I don't remember whether I reloaded the GEL file after it was changed. I thought
    CCS will know the modification spontaneously, I probably didn't remove GEL file
    then reload it; in other case, I might reloaded it just for safe.  Today, I
    reviewed the project and found things are different to my previous summary.

    1. _c_int00 can be in 0x107F8000 (currently it's placed at 107FB800 for my project).
    2. 'option->memory map' of CCSv3.3 does not need to be disabled for accessing the
       0x107F8000 memory section. The modification I made to GEL file is sufficient, I
       don't remember what I did or didn't caused disable CCS's memory mapping is required.
       Sorry about my poor note.  One thing I noticed is the CCS's memory map dosen't
       exactly consist with GEL file.  Do I have to modify CCS's memory map to ensure
       consistence?
      
    I use u-Boot to boot OPAP3530, GEL files are only used for memory mapping and for ARM
    to release DSP from reset state. It is of this procedure because I previously had
    problems of merely using GEL file to power-up L4-Per power domain to get McBSP2's
    registers to be seen by JTAG and CCS. With u-Boot and trimmed GEL, problem is solved.

    Thanks for the information on DSP/BIOS.  I think I had wrong knowledge that DSP's memory
    address starting from 0x1100 0000 can be accessed by configuring MAR bits through
    DSP/BIOS's APIs.  It seems now I actually have to use DSPLink to get MMU going for
    a start.  Other engineers who are working solely on ARM don't know their memory
    arrangement and anything about DSP, neither do I know ARM, this is why I'm trying
    to kick DSP running applications in its memory.  And, right now I can't access DDR
    from DSP side either...I guess the answer is also in DSPLink.   

    Juliann

     

  • After making changes to the gel file you need to right-click on it and select "reload" to make the changes immediately applicable.

    JuliannH said:
    It seems now I actually have to use DSPLink to get MMU going for
    a start.

    By default the MMU is disabled in hardware with all accesses simply passing straight through.  It's not required to use dsplink in order to access DDR.  I recommend using dsplink for many other reasons, but that's not one of them.  Are you already using dsplink?  If so, it will configure the MMU according to the memory ranges setup in the BIOS tcf.  In other words, dsplink will configure the DSP MMU to be able to access only those regions that "belong" to the DSP.  This will protect the system from having the DSP overwrite ARM code.

  • Hi Brad,

    Now I can run DSPlink on OMAP3530EVM.  However, take the "loop" project as an example,
    its dsp codes including bios codes are all put in DDR2 by dsplink's default configuration.
    Is it allowable to put these codes in DSP's memory starting from 0x107f8000 and/or 0x11000000,
    while the corrsponding "loop" codes at ARM side are still put in DDR2? How to reach this goal
    (i.e. running DSP codes in its memory)?  Does the 4G memory (the 0x11000000 segment) really
    exist on EVM?
         
    I've tried to modify *.tcf and dsplink-omap3530-base.tci files but still in vain.
    I need some quick hints.


    Juliann

  • It's a 32-bit processor hence there is a 4GB memory map.  Of that 4GB there are peripheral registers, internal RAM, and space for external memory.  Although there is 4GB of addresses there is NOT 4GB of RAM.  The TRM shows the memory map and the amount of DDR is dependent upon which DDR device is populated on the EVM.  So, no, you won't be anywhere close to 4GB of memory.

    It's been a few years since I've worked directly with dsplink as opposed to higher up with codec engine, but my recollection was that you must modify TWO files in order to change the memory map and they must be consistent.  One file was the tcf file for the DSP.  The other file was on the arm side and was called CFG_OMAP_3530.c (or something really close!).

    I'm teaching a workshop right now so this is as much help as I can give quickly.  Since this thread is diverging from the original topic you might start a brand new thread with a title that more closely resembles the current issue such that the dsplink experts will find it.

    Best regards,
    Brad