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.

use DAT_copy() on DM648 CCS3.3

I want to use DAT_copy() to copy DDR2 data to L2 on DM648 CCS3.3, when I use DAT_copy() and DAT_wait() 100 times, the program could run rightly, when I use DAT_copy() and DAT_wait() 100 times in a tsk loop, while the tsk loop run every one time, the DAT_copy() and DAT_wait() run 100 times, the tsk just could run a few times, and then the program stops in the DAT_wait() func.

The interfaces of DAT APIs DM648 use CSL2.x, the header added, #include <csl_dat.h>, and the implement of DAT APIs use EDMA3 Driver and Resource Manager Package (EDMA3LLD) in csl2_dat.c, and the related lib edma3_drv_bios.lib and edma3_rm_bios.lib added. If you just copy 10 or less, the program run rightly and the data of copied is also right, but if you use it in the tsk loop and run always, it will stop in DAT_wait(), even if you give enough time to wait in the tsk loop.

#include <tsk.h>
#include <csl_dat.h>

#define HEIGHT 120
#define WIDTH 2096

#pragma DATA_SECTION(TestSrcBuf, ".extheap")  //DDR2
#pragma DATA_ALIGN(TestSrcBuf, 64)
unsigned char TestSrcBuf[HEIGHT*WIDTH];

#pragma DATA_SECTION(TestDstBuf, ".inheap")   //L2
#pragma DATA_ALIGN(TestDstBuf, 64)
unsigned char TestDstBuf[HEIGHT*WIDTH];

#pragma CODE_SECTION(TskCommand, ".incode")
void TskCommand()
{
   int i,cnt=0;
   int id;
   while(1)
   {
       for(i=0;i<HEIGHT;i++)
       { 
           id = DAT_copy(TestSrcBuf+i*WIDTH,TestDstBuf+i*WIDTH,WIDTH);
           DAT_wait(id);
       }
 
       //wait 100ms
       EVMDM648_waitusec(100000); 
 
       //-------------------------------------
       // other image process func
       //-------------------------------------
   }
}


EDMA init did in main() func:
edma_init();
DAT_open(DAT_CHAANY, DAT_PRI_LOW, DAT_OPEN_2D);

The edma_init() is in C:\dvsdk_1_11_00_00_DM648\edma3_lld_1_05_00\examples\CSL2_DAT_DEMO\demo, and the EDMA init and DAT_open() are successful, because I can copy a few times and the datas are right, if you change while(1) to for(cnt=0;cnt<100;cnt++), the program will run rightly.

So, I want to ask why it heppens, and how to solve the problem. How to use DAT on DM648 CCS3.3? I doubt if the way I use the DAT is wrong.

Thank you!

Yonghao

  • Yonghao,

    How much of your L2 is being used as cache?

    If I understand correctly, you can do 120 DAT_copy's in the inner for-loop with no problem. Is that correct?

    But if you go through the outer loop too many times, you will get stuck in DAT_wait. Is that also correct?

    Since while(1) fails but for(cnt=0;cnt<100;cnt++) passes, try increasing this outer loop count to see if you can get it to fail at some certain number.

    Why did you set the buffers to be aligned to 64 bytes? The line width is not a multiple of 64 so the lines will not start at 64 byte boundaries, except for the first one and every fourth one.

    No good answers from me, yet, but your answers to these questions may help to clarify some things.

    Regards,
    RandyP

  • RandyP,
    The size of L2 is 64KB. While the .inheap is in ISRAM, the size of ISRAM is 512KB, I am sorry, the previous sign is wrong.

    .inheap :> ISRAM .extheap :> DDR2   ISRAM base=0x00a00000 len=0x00080000  DDR2 base=0xe0000000 len=0x08000000

    If I understand correctly, you can do 120 DAT_copy's in the inner for-loop with no problem. Is that correct?
    --yes, you are right.

    But if you go through the outer loop too many times, you will get stuck in DAT_wait. Is that also correct?
    --yes, it is right.

    Since while(1) fails but for(cnt=0;cnt<100;cnt++) passes, try increasing this outer loop count to see if you can get it to fail at some certain number.
    --I have try many times,10,50,100,200 times,but the at a certain number 200,sometimes it could run rightly,while sometimes it could run wrongly and stop in DAT_wait().

    Why did you set the buffers to be aligned to 64 bytes? The line width is not a multiple of 64 so the lines will not start at 64 byte boundaries, except for the first one and every fourth one.
    --I set the buffers to be aligned to 64 bytes,because this program is used on DM642 originally, now I need migrate it to DM648, so I don't change the align. You mean there is problem?

    Thank you for your replay in time

    Regards,
    Yonghao

     

  • Yonghao,

    What is the L2CFG setting for L2 cache. Is that what you mean to say is 64KB?

    There is no particular problem with the alignment, but it could have indicated the WIDTH setting was a typo since it does not retain the alignment for each row.

    The failure at 200 is a strong indicator. I recommend you look for a stack overflow or heap overflow condition. I also still am curious about the cache setting.

    Where is your .stack section placed?

    Regards,
    RandyP

  • RandyP,

    The cache setting of program is below:
    void config_cache(void)
    {
       CSL_CacheRegsOvly cacheRegs = (CSL_CacheRegsOvly)CSL_CACHE_0_REGS;
       volatile unsigned int stall;   
       // The below writes to the CFG registers are followed by a dummy read. Mode
       // switches require that a read is performed immediately after the write.  The
       // read stalls the cpu to ensure the mode change completes. 
       // Set L1P size to 32K
       CSL_FINST(cacheRegs->L1PCFG,CACHE_L1PCFG_MODE,32K);
       stall = cacheRegs->L1PCFG; 
       // Set L1D size to 32K
       CSL_FINST(cacheRegs->L1DCFG,CACHE_L1DCFG_MODE,32K);
       stall = cacheRegs->L1DCFG;
       // Set L2 size to 64k and normal opperation
       cacheRegs->L2CFG = CSL_FMKT(CACHE_L2CFG_MODE,64K) | CSL_FMKT(CACHE_L2CFG_L2CC,NORMAL);
       stall = cacheRegs->L2CFG;
       // The MAR registers set the cachability of memory spaces external tothe
       // megamodule.  Below is an example of turning on cachability for tworanges.
       // Reference spru187 for a complete list the MAR ranges.
       // Set MAR[16] range 0x10000000-0x10FFFFFF as cacheable
       CSL_FINST(cacheRegs->MAR[16],CACHE_MAR_PC,CACHEABLE);
       // Set MAR[17] range 0x11000000-0x11FFFFFF as cacheable
       CSL_FINST(cacheRegs->MAR[17],CACHE_MAR_PC,CACHEABLE);
    }

    .stack section is placed in DDR2.

    I have try it on C:\dvsdk_1_11_00_00_DM648\edma3_lld_1_05_00\examples\CSL2_DAT_DEMO\demo\dat_demo_dm648.prj. I just change the DAT_main() func in main.c, add while(1){ DAT_copy(..); DAT_wait(..); } to DAT_open(){..}, and define the src_buf[] and dst_buf[],  it runs about a minute, then it also stops.

    Regards,
    Yonghao

  • Yonghao,

    There is nothing in your code that I can see to cause an error. But your linker command file is wrong where it sets the ISRAM len=0x00080000; this needs to be reduced by the 64K that is used by the cache, so it should be len=0x00070000. If you are using more than 0x70000 in ISRAM, then you will easily be corrupting the cache memory.

    The last two active lines of your function, above, are setting MAR for reserved areas and will have no effect. I assume you meant to enable cache to the DDR memory, in which case you need to set several MAR bits according to the regions of DDR that you want to be cacheable.

    With the CSL2_DAT_DEMO\dat_demo_dm648 project, does it work if you do not make any modifications?

    Regards,
    RandyP

  • Regards,


    Nowadays I find the problem about the setting of ISRAM size, and I change the len=0x00060000. And the problem is same.


    Yes,the MAR setting will have no effect,I don't change because I can't find the spru187 decoment about MAR setting, but it should not matter, can I delete the last two active lines about setting MAR?


    With the CSL2_DAT_DEMO\dat_demo_dm648 project, if I don't change anything it can work, but it just DAT_copy() 4 times in the program runtime, and if I just copy 1 time in the tsk loop in my project, it can work too.


    Yesterday, I just open one channel, it originally open 10 channel, copying 100 times in the tsk loop, the loop can run 20000 times, but it stops in the DAT_wait() finally, the waitID is 6 then I view the EDMA reg IPR, the corresponding bit is 0, it means the copy has completed, while the corresponding bit of the global variable 'TransferCompleteL' is 1, the 'TransferCompleteL' is changed in a lookback func _SetupTransferOptions(), the reg changes to 0 but the variable in the program doesn't change to 0, so it can't go out of DAT_wait(). And I change the the corresponding bit of the global variable 'TransferCompleteL' to 0 manually, it can run out of DAT_wait(), while the next time after the DAT_copy(), it stops in DAT_copy()...


    And in normal copying, the program run to DAT_copy(),the IPR reg bit 6 and TransferCompleteL varibale bit 6 are 0, after DAT_copy() and before DAT_copy() the IPR reg bit 6 and TransferCompleteL varibale bit 6 are 1, after DAT_wait() the IPR reg bit 6 and TransferCompleteL varibale bit 6 are 0, I only open channel 6. So I doubt if there is a problem in the lookback func, it can't change the TransferCompleteL varibale in program in time.

    Regards,
    Yonghao

  • Yonghao,

    yonghao zhu said:
    Yes,the MAR setting will have no effect,I don't change because I can't find the spru187 decoment about MAR setting, but it should not matter, can I delete the last two active lines about setting MAR?

    SPRU187 is the Compiler User's Guide and it does not have any relationship with the MAR bits, which are hardware features. Please look for the Megamodule Reference Guide and the Cache User's Guide, both of which are referenced in the datasheet on page 9. And on page 12 of the datasheet, it shows the regions affected by the ranges of MAR bits; the Megamodule Reference Guide has a better table, and it also shows the register field and values.

    Instead of deleting the two active lines, just comment them out so you can come back later if you decide you want to make DDR cacheable.

    yonghao zhu said:
    Yesterday, I just open one channel, it originally open 10 channel, copying 100 times in the tsk loop, the loop can run 20000 times, but it stops in the DAT_wait() finally, the waitID is 6 then I view the EDMA reg IPR, the corresponding bit is 0, it means the copy has completed, while the corresponding bit of the global variable 'TransferCompleteL' is 1, the 'TransferCompleteL' is changed in a lookback func _SetupTransferOptions(), the reg changes to 0 but the variable in the program doesn't change to 0, so it can't go out of DAT_wait(). And I change the the corresponding bit of the global variable 'TransferCompleteL' to 0 manually, it can run out of DAT_wait(), while the next time after the DAT_copy(), it stops in DAT_copy()...

    This is not clear to me:

    1. "the loop can run 20000 times, but it stops in the DAT_wait() finally," Can it run 20000 times or does it stop in DAT_wait()?
    2. "the waitID is 6 then I view the EDMA reg IPR, the corresponding bit is 0, it means the copy has completed, while the corresponding bit of the global variable 'TransferCompleteL' is 1" IPR.bit6=0 does not mean the copy has completed; IPR.bit6=1 means the copy has completed, at least until the program code clears that bit. The DAT_copy function in the csl2_dat.c file that I have from edma3_lld_02_11_05_02\examples shows that DAT_copy sets TransferCompleteL when the transfer is started, so that bit6=1 means the transfer has not completed, either. 
    3. "the 'TransferCompleteL' is changed in a lookback func _SetupTransferOptions(), the reg changes to 0 but the variable in the program doesn't change to 0" _SetupTransferOptions() is not a loopback function. _transferComplete is a callback function that should be called by an interrupt when the IPR bit is set. Are you getting this interrupt being called? At least this is the way the older version of the code looks. I am also confused over versions of the CSL code, not knowing which you are using.
    4. "And I change the the corresponding bit of the global variable 'TransferCompleteL' to 0 manually, it can run out of DAT_wait(), while the next time after the DAT_copy(), it stops in DAT_copy().." Changing the bit manually is not good, because it is a sign that something has failed, and you need to find out what that is, first. Do you really mean "it stops in DAT_copy()"? Where?

    You will have to do some debugging to figure out what makes it fail and what will make it work. This CSL code has been in use for a long time, so you should assume it is correct and your use of it is causing the problem. Even though we do not see what is wrong with what you are doing, that is still the safest assumption for you to find a solution.

    Try making each DAT_copy use a shorter count than WIDTH to see if the size of the copy makes a difference.
    Put a dummy for-loop delay between the DAT_copy and the DAT_wait.
    Write your own while-loop that samples either TransferCompleteL or IPR, depending on whether you have an interrupt running or are polling.

    Regards,
    RandyP

  •  

    RandyP,


    I have sent my project to your mailbox, you can see it and debug it. Can you give a whole project using DAT APIs on DM648 on CCS3.3 including header files and all lib files.
    Thank you!


    Regards,
    Yonghao

  • Yonghao,

    I do not know what you mean by "mailbox". Unfortunately, in any case I am not in a position to debug your program for you.

    After you have tried my recommendations above, please reply back with your results. Those may suggest the next steps to take as you work through this process.

    As is often the case on the forum, we both get deeply involved in answering a specific question, such as why can you not do the DAT_copy/DAT_wait an infinite number of times successfully. But if we back up and look at the application, a more successful question to ask is "what are you trying to do?" Copying an image or array can be done with a single QDMA command, and perhaps with the DAT_copy2d, depending on the nature of the data (is it contiguous on a line).

    You can also create more complex copy operations using DMA channels instead of QDMA channels. This may require you to study the EDMA3 User's Guide in more detail to understand the use of the EDMA3 module instead of using the DAT_* APIs. If that is not the direction you plan to go, that will be understandable, but I wanted to make the suggestion.

    Regards,
    RandyP

  •  I come to the same point as you, it seemed DAT_copy in DM648 dvsdk 1.11 can't work good with other tasks and interrupts?????? DAT_copy will dead at DAT_wait randomly.

    If TI can give some response about this "maybe-bug"???