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 EDMA3 chaining

Other Parts Discussed in Thread: CCSTUDIO

Hello

I have problem with chaining in EDMA3; I'm working with DSP C4655 (EVM).

I have a first channel EDMA that works well (with linking to other Param); I have another channel EDMA chained with the first channel but this channel never starts. For the first channel TCC is ok (this number is the chained channel) and CSL_EDMA3_TCCH_EN.
For example, this is useful for transfer samples from DDR0 to ping/pong buffers (first channel EDMA) and after sorting these samples (second 'chained' channel EDMA). (It's possible sorting data with a single channel but I would understand why chained channel doesn't works...)

I read the example from TI (Edma_chain_example in csl_c6455/example/edma documentation) and my idea is that only channel0 is working, channel 8 (chained to 0) never starts (I disable in channel0 the field CSL_EDMA3_TCCH_DIS and the dstBuff2 in fully in same manner: channel0 works two times and channed 8 never!).

Can someone help me?

Thanks

 

[ed: Note that this is the same content as http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/112/p/74136/265223.aspx#265223.]

  •  I'd suggest taking a look at Section 2.8 of the C645x EDMA UG spru966

    In particular "Channel number n needs to be programmed into the TCC bit of channel m channel options parameter (OPT) set."  Default settings use it's own channel number, thus by default it will work for it's on channel number.

    There's an option for setting this within the EDMA CSL.

    Best Regards,

    Chad

  • Ok Chad, it's right.

    In this example (it isn't my project but TI example!) TCC is like you told me but chianing doesn't work:

    in Channel 0 (first channel): TCC = 8

    Channel 8 is chained channel

     

    [ed: Note that this is the same content as http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/112/p/74136/265223.aspx#265223.]

     

     

     

  • Can you tell me why you think Channel 8 doesn't work at all? 

    Let's do some debugging.

    Can you put a breakpoint after the initialization of data and before the trigger of channel 0

        /* Trigger Channel 0 */
        CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);

    Run to this breakpoint and cut and paste the PaRAM entries for channel 0 and channel 8 from the memory window?

    After this, put a breakpoint before the check transfer occurs. 

        /* Check transfer */
        if(Verify_Transfer(512, 1, 1, 0, 0, 0, 0, srcBuff1, dstBuff1,TRUE) == FALSE)
            passStatus = 0;
        if(Verify_Transfer(512, 1, 1, 0, 0, 0, 0, srcBuff2, dstBuff2,TRUE) == FALSE)
            passStatus = 0;

    Run to this breakpoint, open a memory windows w/ the source and address locations for both channels, copy and paste these.  Note it doesn't need to be the full buffer, just enough to see that the data is valid (let's say 10 words or so each)

     

    Back to what you're wanting to do. It sounds like you want this to be used as a Ping Pong buffer from the initial description, but that's not what the example does.

    The Channel 0 sets up the TCC as 8 so it triggers Channel 8, then Channel 8 has TCC set to 1, so it wouldn't retrigger anything.

    Also, the channels are not setup to reload their existing PaRAM settings.

    It would take a modification to the example code to do what you're wanting it to do.  There are multiple examples provided to help you understand setting up for the different basic types of transfers, but not one that does the linking and chaining combination you'd need to do what you're wanting.  Basically you need to do linking so that it's repopulating the PARAM settings (put the PARAM settings in a unused channel and link to them - have it link back to itself.)  You'll need to do this for both channel 0 and channel 8.  Then in channel 8 you need to setup the TCC value to be 0, current code example has it as 1, so it will trigger channel 0 again once it's completed.

    Best Regards,

    Chad

  • Chad

    I made this debug:

    1)For Channel 0 I changed CSL_EDMA3_TCCH_EN to CSL_EDMA3_TCCH_DIS: now chaining dont exist...

    I put a breakpoint, as you told me, at:

      CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);

    I run to this break point and, in order to confirm my thesis, I wrote 0 in Param 8 (but it is not necessary...).

    If you run the project, the result is.... OK! It's wrong because now dstBuff2 would be 0 (channel 8 never started)!

    For my opinion, channel 0 works two times because, for channel 0:

        myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,2);   

    but itsn't correct, for me it would be:

        myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,1);   

    2) Another debug is that:

    in the original project (with chaining) you can add a spare buffer between srcBuff1 and srcBuff2:

    Uint8       srcBuff1[512];
    Uint8        spare[4]; // you can initialize this buffer to every value you want....
    Uint8       srcBuff2[512];
    Uint8       dstBuff1[512];
    Uint8       dstBuff2[512];

    Run the project... FAILED!

    My opinion is that channel 0 works two times (2 in CSL_EDMA3_CNT_MAKE(512,2))

     

  • Please go back and provide the information I requested so I can see what the values are so I can help debug what's going on in your situation.

    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,2);

    Does NOT make the channel run twice.  It sets bCnt to 2, which the channel runs once for a total of aCnt*bCnt.  This an AB (two dimensional transfer - but still single event)


    As for the inserting the Uint8 spare[4], I'm guessing that the verification routine is expecting the data to be aligned on a double word boundary, an what you've done is affectively shited the srcBuff2, dstBuff1 and dstBuff2 to a non double word alignment.  If you change it to spare[8] it should work if my theory is correct.

    Best Regards,

    Chad

  • Chad Courtney said:

     If you change it to spare[8] it should work if my theory is correct.

    I tried... the test fails...

    Chad, my problem is to have a simple project where chaining working.. I'm not able to work (never) with chaining.

    This Ti'example is simple ad useful (for me) to understand how setting chaining (I'll investigate linking and chaining together after this...), but for me... this example is wrong...

     

     

  • Ok, I've pulled up the Example Code, and there does appear to be some issues w/ it, but I'm not seeing a reason that it should not be chaining.

    #1, the bCnt value should be 1 for both of these since the data size of the buffer is only 512 Bytes not 1024 Bytes.  This would mask any chaining issue, because channel 0 was writting a 1024 Bytes to the destination and the buffers being back to back it was in effect writting both src1 and src2 buffers to dst1 and dst2 in one shot.

    Looking at the channel controller registers I do see that there is an IPR generated for channel 8 and the SER get's set for channel 8 (triggered by completion of channel 0, w/ TCC = 8.)  I think it should have triggered the channel 8 transfer, but I'm working on an old version of the simulator and not HW at this point and I'm not seeing the channel 8 transfer actually executing.

    What are you using to test this on, HW or Simulator.  If simulator which version of CCS are you using.

    I'm going to see if I can locate a board and try it on the board.

    Best Regards,

    Chad

  • Chad Courtney said:

    the bCnt value should be 1 for both of these since the data size of the buffer is only 512 Bytes not 1024 Bytes.  This would mask any chaining issue, because channel 0 was writting a 1024 Bytes to the destination and the buffers being back to back it was in effect writting both src1 and src2 buffers to dst1 and dst2 in one shot.

    Ok, I agree with you: correct value of BCNT is 1.

    But if you change this value in project you can see that only dstBuff1 is full (and correct, like srcBuff1), dstBuff2 in empty (0), chained channel 8 didn't start.

    I'm workink on HW (DSK C6455)

    Chad, thank to your patience....

     

     

  • Stefano,

    Attached is a new Edma_chain_example folder (zip'd) with the errors in the example fixed and some of my enhancements. I only use the Global Region on the C6455, so I #if 0'd out the region 5 references to avoid that source of confusion and error. I also prefer a generalized 64-bit variable for the intr/intrh accesses and a generalized reference to a channel's PaRAM number.

    The example folder was build and tested in the same location as the original: C:\CCStudio_v3.3\csl_c6455\example\edma\edma_chain_example. You can change the relative paths in the pjt file or through the Build Options menu item. This was tested only on CCSv3.3, and was run successfully on a DSK6455 in little endian mode.

    BCNT is set to 1.

    Please post any comments and suggestions.

    Regards,
    RandyP

     

    If this answers your question, please click the  Verify Answer  button below. If not, please reply back with more information to continue the thread.

    edma_chain_example.zip
  • Randy,

    thanks for this example.

    I write so you can tell me if I understand well.

        do {
            /* Poll on interrupt bit 1 */
            CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
            ullTemp = _itoll( regionIntr.intrh, regionIntr.intr );
        } while (!(ullTemp & ((unsigned long long)1 << 1)));  // generalized poll technique for 64-bit register



    Here we waiting for interrupt 1 (this INT is setting for chained channel 8). ok?

    _itoll make a merge like: intrh|inth (32 bit + 32 bit = 64 bit)
    _loll extract only 32 bit LSB (from bit 32 to 0)
    _hill exract only 32 bit MSB (from bit 64 to 33)


    It's right?

    So, channel 0 starts, at the end of his transfer channel 8 works (this is chained channel) and at the end we have interrupt.
    I understand so... it's correct?

    If yes, I'm satisfied.

    Last question... I make changes from your source code to original source code (from TI) but doesn't works... the problem is in using  region_5?

     

     

  • Stefano,

    You do understand the flow and operation well. You have understood the correct or expected operation from the beginning, but you were trying to understand why our example did not work. Your knowledge and understanding of the concepts was correct; our code was wrong.

    Stefano said:
    Here we waiting for interrupt 1 (this INT is setting for chained channel 8). ok?

    Communicating about the EDMA3 is difficult at times. We have used confusing words in the EDMA3 documentation, and that leads to misunderstandings. I prefer to refer to this bit as the "completion bit" or the IPR bit1 rather than "interrupt 1", because to me an interrupt is a specific event that goes to the DSP and not a status bit in an EDMA3 register. But you are correct that we are waiting for IPR.bit1 because Channel 8's TCC was set to 1. This shows that there is no direct relationship between the TCC value and the Channel number.

    Your bit numbers are off by 1 or 2. The descriptions of the _itoll intrinsic and others are in the Optimizing C Compiler User's Guide.

    Stefano said:
    I make changes from your source code to original source code (from TI) but doesn't works... the problem is in using  region_5?

    I made changes to the original source code to make it work and we can call that my source code. Now you are trying to take my changes back to the original to get it to work, also. This effort by you shows a brilliant and inquisitive mind. If you make all of the changes exactly, then you will have a copy of my source code back-fitted to the original. If you do not make all of the changes exactly, then you have a new problem to debug, and I have no idea what the problem might be.

    REGION_5 can work. It is a pain, in my opinion, and has no value for the code, in my opinion. That is an oversimplification on my part, but the fact is that I never use regions with C6455 code. If you insist on figuring out why it fails, you can do what I do: go to the EDMA3 User's Guide, find the section on steps to initiate a transfer, follow through the CSL source code to see which registers are written, and find the missing or erroneous steps.

    Regards,
    RandyP

  • RandyP said:

     I prefer to refer to this bit as the "completion bit" or the IPR bit1 rather than "interrupt 1", because to me an interrupt is a specific event that goes to the DSP and not a status bit in an EDMA3 register.

    Very correct, it's important the difference between interrupt and completion bit.

    Ok, thanks a lot for all.

    I read the meaning of "Explanation of Levels" and I understand becuase your level is 'genius': it's TRUE!

    Thanks to Chad too.

    bye

    Stefano