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.

URGENT: DSK 6455 EDMA

Other Parts Discussed in Thread: CCSTUDIO

I've got a problem of configuring the EDMA in DSK6455.

I use channel 52 to chansfer data from L2 to extra memory by EMIF.

Channel 52 is triggered by GPIO 4 event, but now when GPIO4 event happened, it can't trigger the channnel 52 sometime.

I think maybe some register is not set correctly, but I couldn't find the problem.

I' m waiting for your answer! Thanks!

  • I would check DCHMAP52 to see which Parameter RAM entry it points to.  Then I would check the corresponding PaRAM to make sure it is still programmed correctly.

  • YES, I've wrote the DCHMAP52 = 0x0000 0000, then wrote the PaRAM0.

    but, now I've got a new problem. Now I use two channel work seperately, if the data size for transfer is more than 1024 byte, It will not work . If less than 1024 byte, it works well.

    I'm not sure wheter the problem came from the GPIO event did not respond or the completion interrupt didn't  come?

    could you give me your email address, I'd like you to read my code to give me some suggestions,

    Thanks a lot.

  • I'll try to help you on the forum, but you'll need a local FAE for anything more.

    Is something being corrupted if you go beyond 1024 bytes?  Since it's a 16-bit field  there doesn't appear to be anything significant from an EDMA perspective with crossing a 1KB boundary.

  • Jessie Cui said:

    YES, I've wrote the DCHMAP52 = 0x0000 0000, then wrote the PaRAM0.

    but, now I've got a new problem.

    Does this mean the first problem was solved by adding the DCHMAP52 update? If so, that is great news.

    Jessie Cui said:

    Now I use two channel work seperately, if the data size for transfer is more than 1024 byte, It will not work . If less than 1024 byte, it works well.

    I'd like you to read my code to give me some suggestions,

    As Brad asked, what does it mean when you say "it will not work"?

    You can easily embed some code snippets in a posting for forum review.

  • The problem of GPIO4 doesn't trigger the channel 52 is still not solved! I find that  the SERH.E52 is set when channel 52 doesn't triggered. The register means the event is currently stored in the event queue, event ariter will not priortize additional events. Is the problem associated with the event queue? I didn't make configuration of event queue. How can I make the SER not be set all the time?

    The problem of code size is solved. I make a new section in .cmd fiie and use the #pragma data_section().  

  • Most commonly, EMRH.E52 would also be set in a situation like this. This is the only case I have seen of SER being held set with no further transfer requests for that channel being queued.

    When the last successful transfer completed, the PaRAM LINK field determined how to reload the PaRAM. If LINK=0xFFFF, then the PaRAM will be cleared to 0's, otherwise LINK specifies the address of another PaRAM set that will be copied to the active PaRAM set.

    If the active PaRAM is cleared because of LINK=0xFFFF, that PaRAM must be programmed before the next event (GPIO4) occurs. If the PaRAM is all 0's, in particular if ACNT=BCNT=CNT=0, then this is considered a NULL PaRAM Set. This is considered to be an error condition; the EMR bit is set indicating that an event was missed and the SER bit is set indicating that an event was ready to be enqueued but has not been enqueued.

    The best procedure for clearing SER and EMR is the following:

    1. Write 1 to the corresponding bit in SECR or SECRH to clear the bit in SER or SERH.
    2. Read SER or SERH to see if it is cleared. If it is still set, repeat steps 1 and 2 until it is cleared. Another pending event could cause it to get set again after clearing it.
    3. Write 1 to the corresponding bit in EMCR or EMCRH to clear the bit in EMR or EMRH.
  • First, I reset the EMR. And then, before trigger the channel 52, I reset the SER to 0.

    I'm sure the SER and EMR are reset to 0 before event comes.

    But, when GPIO 4 event comes, the SERH.E52 set to 1, IPRH has no changes, there still no interrupt.

    I' eager for help. Is there any way to make the interrupt respond stably?[:'(]

  • Jessie Cui said:

    Is there any way to make the interrupt respond stably?

    Yes, absolutely, the GPIO4 event + EDMA + interrupt + DSP programming can be made to respond stably.

    I have these concerns, and believe I must be honest with you and hope you take my words as a serious intent to help your success:

    1. In your second posting to this thread, you said "I wrote the DCHMAP52 = 0x0000 0000". I infer from this that you are performing direct register writes to the EDMA registers rather than using the CSL_edma3 module or the EDMA3 LLD (Low Level Drivers) libraries. These libraries have been tested and examples are supplied with them to help you move easily through the process of programming and using the EDMA3. It will be much more difficult to help you if you are not using CSL or LLD.
    2. In my previous posting to this thread, I gave you a specific sequence of events to ensure that SER and EMR are cleared. Your response shows that you did not use that sequence but used another sequence that you believe is working. If you want your system to work stably, first follow my advice to get it working, and then back out the changes you do not want to use. If you do not try my advice, there is no point in my giving you any additional advice. This may not be directly affecting your current problem, but we cannot know that at this point.
    3. For your debug purposes, in one memory window, display the PARAM used for this channel and for any LINK sets and in one (or more) memory windows display all of the EDMA3 CC registers. Look at those registers after preparing everything for the first transfer before the first GPIO4 event, then look at those registers immediately after the GPIO4 event, then look at those registers after preparing everything for the second transfer before the second GPIO4 even, then after the second event. Any registers that change will be highlighted in red, making them easy to notice, and bit 52 will be the interesting bit to see set somewhere. This should help you to notice what is blocking the results you want to see.

    You may be able to attach your source file to you posting. When writing your reply, click on the Options tab and click the Attach File button. I have heard that you must change a filename from .c to .txt for it to post, but I am not certain that this is a requirement. If it is a large amount of code, it may not be practical, so please use your judgment.

  • Thank U very much!

    I use the CSL_EDMA3_module.  I found that some register doesn't have the right value when debugging in the evironment of the DSK6455. So I wite some sentens like *((volatile Uint32 *)DCHMAP52) = 0x0000 0000;

    I follow your step to clear SER and EMR, and I'm sure they are cleared before GPIO4 comes. But when GPIO4 comes, SERH.E52 = 1 and the IPR still has no change.  I've use the register window to see the changes of the key register.

    Below is a part of my code. I appreciate your advice.

    /* Imitate the example edma_interrupt in
       ..\CCStudio_v3.3\default_package\csl_c6455\example\edma
       GPIO rising edge trigger the EDMA
       McBSP congfigured as GPIO, NOT clkx as GPIO4 to DSP
    */

    /* Edma module setup */
    dmahwSetup.paramNum = 0;                 // Parameter set 0
    dmahwSetup.que      = CSL_EDMA3_QUE_0;   // queue 0
    hwSetup.dmaChaSetup = &dmahwSetup;
    hwSetup.qdmaChaSetup = NULL;
    status = CSL_edma3HwSetup(hModule,&hwSetup);

        
    *((volatile Uint32 *)DCHMAP52) = 0x00000000;    // DCHMAP52

    *((volatile Uint32 *)0x02A01008) = 0xffffffff;    // ECR
    *((volatile Uint32 *)0x02A0100C) = 0xffffffff;    // ECRH
      
    /* Setup the DRAE masks */
    regionAccess.region = CSL_EDMA3_REGION_1 ;
    regionAccess.drae =   0xffff ;  
    regionAccess.draeh =  0xff0000 ;
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess);
        

    /* Channel 52 open */
    chAttr.regionNum = CSL_EDMA3_REGION_1;
    chAttr.chaNum = 52; // GPIO4 event
    hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &status);  

        
        
    *((volatile Uint32 *)0x02A01030) = 0x00000000;     // EESR
    *((volatile Uint32 *)0x02A01034) = 0x00100000;     // EESRH


    /* Get the parameter handle */
    hParamBasic = CSL_edma3GetParamHandle(hChannel,0,&status);
        

    /* Edma parameter entry Setup */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                      CSL_EDMA3_TCCH_DIS, \
                                      CSL_EDMA3_ITCINT_DIS, \
                                      CSL_EDMA3_TCINT_EN,\
                                      52,\
                                      CSL_EDMA3_TCC_NORMAL,\
                                      CSL_EDMA3_FIFOWIDTH_NONE, \
                                      CSL_EDMA3_STATIC_DIS, \
                                      CSL_EDMA3_SYNC_A, \
                                      CSL_EDMA3_ADDRMODE_INCR, \
                                      CSL_EDMA3_ADDRMODE_INCR); 
    myParamSetup.srcAddr = (Uint32)Data_Rand;                                                 // source address
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(32768,1);                 // Acnt Bcnt 
    myParamSetup.dstAddr = 0xc0000000;                                                              // destination address
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);                      // B src and dst index
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL, 
                                                   0);                                                                                // link and Bcnt reload
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);                   // C src and dst index
    myParamSetup.cCnt = 1;                                                                                     // C cnt
    status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);


    /* Association of an EDMA event handler with the INTC routine */
    EventRecord.handler = &eventEdmaHandler;
    EventRecord.arg = (void*)(hModule);
    CSL_intcPlugEventHandler(hIntcEdma,&EventRecord);

    /* Enabling event edma  */
    CSL_intcHwControl(hIntcEdma,CSL_INTC_CMD_EVTENABLE,NULL);
        
    /* Hook up the EDMA event with an completion code function handler */
    EdmaEventHook(52, tcc1Fxn_read); 

    /* Enable interrupts */
    regionIntr.region = CSL_EDMA3_REGION_1 ;                     // 设置IER
    regionIntr.intr =  0x0;    
    regionIntr.intrh = 0x100000 ;   // bit 52
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);   

    /* Follow your step to clear SER and EMR */
    while(*(volatile Uint32 *)0x02a0103C != 0)      // SERH
    {
         *((volatile Uint32 *)0x02A01044) = 0xffffffff;  // SECRH
    }

    *((volatile Uint32 *)0x02a00308) = 0xffffffff;  // EMCR
    *((volatile Uint32 *)0x02a0030c) = 0xffffffff;  // EMCRH


    /* GPIO4 come */
    *((volatile Uint32 *)McBSP_PCR0) = 0x00003200;    //display:0

    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");

    *((volatile Uint32 *)McBSP_PCR0) = 0x00003202;    //display:1 reset to FPGA 

    /.../
     

    Thank you very much!

     

  • Jessie Cui said:

    Thank U very much!

    I use the CSL_EDMA3_module.  I found that some register doesn't have the right value when debugging in the evironment of the DSK6455. So I wite some sentens like *((volatile Uint32 *)DCHMAP52) = 0x0000 0000;

    I follow your step to clear SER and EMR, and I'm sure they are cleared before GPIO4 comes. But when GPIO4 comes, SERH.E52 = 1 and the IPR still has no change.  I've use the register window to see the changes of the key register.

    Below is a part of my code. I appreciate your advice.

    /* Imitate the example edma_interrupt in
       ..\CCStudio_v3.3\default_package\csl_c6455\example\edma
       GPIO rising edge trigger the EDMA
       McBSP congfigured as GPIO, NOT clkx as GPIO4 to DSP
    */

    /* Edma module setup */
    dmahwSetup.paramNum = 0;                 // Parameter set 0
    dmahwSetup.que      = CSL_EDMA3_QUE_0;   // queue 0
    hwSetup.dmaChaSetup = &dmahwSetup;
    hwSetup.qdmaChaSetup = NULL;
    status = CSL_edma3HwSetup(hModule,&hwSetup);

        
    *((volatile Uint32 *)DCHMAP52) = 0x00000000;    // DCHMAP52

    *((volatile Uint32 *)0x02A01008) = 0xffffffff;    // ECR
    *((volatile Uint32 *)0x02A0100C) = 0xffffffff;    // ECRH
      
    /* Setup the DRAE masks */
    regionAccess.region = CSL_EDMA3_REGION_1 ;
    regionAccess.drae =   0xffff ;  
    regionAccess.draeh =  0xff0000 ;
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess);

    /* Channel 52 open */
    chAttr.regionNum = CSL_EDMA3_REGION_1;
    chAttr.chaNum = 52; // GPIO4 event
    hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &status);  

        
        
    *((volatile Uint32 *)0x02A01030) = 0x00000000;     // EESR
    *((volatile Uint32 *)0x02A01034) = 0x00100000;     // EESRH


    /* Get the parameter handle */
    hParamBasic = CSL_edma3GetParamHandle(hChannel,0,&status);

    /* Edma parameter entry Setup */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                      CSL_EDMA3_TCCH_DIS, \
                                      CSL_EDMA3_ITCINT_DIS, \
                                      CSL_EDMA3_TCINT_EN,\
                                      52,\
                                      CSL_EDMA3_TCC_NORMAL,\
                                      CSL_EDMA3_FIFOWIDTH_NONE, \
                                      CSL_EDMA3_STATIC_DIS, \
                                      CSL_EDMA3_SYNC_A, \
                                      CSL_EDMA3_ADDRMODE_INCR, \
                                      CSL_EDMA3_ADDRMODE_INCR); 
    myParamSetup.srcAddr = (Uint32)Data_Rand;                                                 // source address
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(32768,1);                 // Acnt Bcnt 
    myParamSetup.dstAddr = 0xc0000000;                                                              // destination address
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);                      // B src and dst index
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL, 
                                                   0);                                                                                // link and Bcnt reload
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);                   // C src and dst index
    myParamSetup.cCnt = 1;                                                                                     // C cnt
    status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);


    /* Association of an EDMA event handler with the INTC routine */
    EventRecord.handler = &eventEdmaHandler;
    EventRecord.arg = (void*)(hModule);
    CSL_intcPlugEventHandler(hIntcEdma,&EventRecord);

    /* Enabling event edma  */
    CSL_intcHwControl(hIntcEdma,CSL_INTC_CMD_EVTENABLE,NULL);
        
    /* Hook up the EDMA event with an completion code function handler */
    EdmaEventHook(52, tcc1Fxn_read); 

    /* Enable interrupts */
    regionIntr.region = CSL_EDMA3_REGION_1 ;                     // 设置IER
    regionIntr.intr =  0x0;    
    regionIntr.intrh = 0x100000 ;   // bit 52
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);   

    /* Follow your step to clear SER and EMR */
    while(*(volatile Uint32 *)0x02a0103C != 0)      // SERH
    {
         *((volatile Uint32 *)0x02A01044) = 0xffffffff;  // SECRH
    }

    *((volatile Uint32 *)0x02a00308) = 0xffffffff;  // EMCR
    *((volatile Uint32 *)0x02a0030c) = 0xffffffff;  // EMCRH


    /* GPIO4 come */
    *((volatile Uint32 *)McBSP_PCR0) = 0x00003200;    //display:0

    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");
    asm(" NOP ");

    *((volatile Uint32 *)McBSP_PCR0) = 0x00003202;    //display:1 reset to FPGA 

    /.../

    Thank you very much!

     

    It looks like you've enabled the event prior to configuring the associated Parameter RAM.  The behavior you're seeing would occur if an event came in at this time.  I think you just need to enable the event AFTER you have configured all the Parameter RAM, interrupt handlers, etc.

  • Thanks a lot!

    I've follow the Setting Up a Transfer in EDMA UG appendix B. In the step 1.d. It said to set EER. Then Parameter set up is in step 2.

    I'll try your suggestion right now! Thank you for your advice.

  • I've tried your suggestion, but it stil can't work!

    The situation is still that, before the event comes, SER and EMR are 0, and PaRAM set correctly. but when the event comes, the SER set to 1, no IPR set. 

    Would you give me another advice? Thank you!

  • Debugging EDMA can be a lot like debugging assembly programs - you have several registers to look at. For your debug purposes, in one memory window, display the PARAM used for this channel and for any LINK sets and in one (or more) memory windows display all of the EDMA3 CC registers. Look at those registers after preparing everything for the first transfer before the first GPIO4 event, then look at those registers immediately after the GPIO4 event, then look at those registers after preparing everything for the second transfer before the second GPIO4 even, then after the second event. Any registers that change will be highlighted in red, making them easy to notice, and bit 52 will be the interesting bit to see set somewhere. This should help you to notice what is blocking the results you want to see.

    Another way to look at the registers is in the watch window, using the hModule handle and clicking down to regs and the actual registers. The biggest problem with this is getting it all displayed in hex rather than useless decimal. That is one reason the memory window works well, but it is not very helpful in terms of labels. Maybe doing both will make it easier - the memory window to quickly see what changes, then the watch window to dig down to which registers are changing.

    Something is happening that is not possible to figure out without more debug, so you will need to get this broader information on registers. But please do not just post a list from the memory window, please discover which registers are changing. And that may lead you to your answer.

    It may make it easier to figure out by manually triggering Channel 52 using ESRH rather than depending on the GPIO4 external event happening. In other words, do not enable the event, then after setting everything up, manually trigger the channel, observe the transfer results and all the PARAM and registers, then trigger another transfer manually to see if you get the same bad results as when using GPIO4.

  • I read the EDMA3 UG Appendix B Setting Up a Transfer again, I found that I havn't setup the queue.

    So I use the DMAQNUM to set channel 52 in queue 0. It works well.

    But I have a question. If I want use channel 52 and channel 0 work alternately.

    How could I set the QUEUE? Channel 0 and channel 52 are all set in queue0. Is there priority? would I set the size of the queue?

    Thank you!

  • You have shown tremendous patience and determination and great skill to have reached this point with your program. The example program that you started with was not correct in the way it initialized the EDMA registers, and it unnecessarily complicated your program by using the REGION_1.

    Would you please attempt to attach your source .c file to your reply. I would like to make several edits and that may be easier for both of us than me sending you a different example that you would still need to change again.

    When you reply, there will be three tabs at the top, Compose / Options / Preview. Click on Options, and there should be a button under File Attachment that says Add/Update. Click on that and browse to your source file. One comment I have heard is that you might have to change the filename from MySource.c to MySource.txt, for example, in other words the extension may have to change to .txt, but I do not know this for certain.

    Jessie Cui said:

    But I have a question. If I want use channel 52 and channel 0 work alternately.

    How could I set the QUEUE? Channel 0 and channel 52 are all set in queue0. Is there priority? would I set the size of the queue?

    The simple answer to your question is that the queue should be assigned at the first stages of the EDMA3 module setup. It is acceptable for both channel 0 and 52 to use the same queue. They will be able to execute alternately quite well this way.

  • In this code, I use region 0, as your step to clear SER and EMR, use DMAQNUM to put channel 52 and 0 in the queue 0.

    They work well untiil now!

    Please don't hesitate to give me suggestion!

    Thank you!

  • Jessie Cui said:

    In this code, I use region 0, as your step to clear SER and EMR, use DMAQNUM to put channel 52 and 0 in the queue 0.

    They work well untiil now!

    Please don't hesitate to give me suggestion!

    Thank you!

    I've debug the code in the DSK6455 again.

    I found that the Interrupt can respond correctly, but the transfer time is too long,

    This code must be has wrong!

    Is the PaRAM link to itself has problem?

    I'm very puzzled!

  • Since you have been debugging the code, if you have an updated file, please post it so I can work from the latest.

    Jessie Cui said:

    I found that the Interrupt can respond correctly, but the transfer time is too long,

    Please explain what this means. Do you get the interrupt several times, once for each transfer completion? How long is the transfer time and what did you expect it to be?

    Jessie Cui said:

    Is the PaRAM link to itself has problem?

    Yes, the PaRAM link to itself is a problem. If you look at the PaRAM in a memory window, you will see that it does not have good values after the first transfer has completed.

    Please explain what you would like this part of the application to do. I saw McBSP and GPIO references.

    Do you require the use of Region 0 or of Region 1? There are some advanced tricks that you can do to get extra interrupts, but it will be much easier if you only use the Global Region. That will be my recommendation unless you have a specific need that is addressed by the use of the region logic.

  • RandyP said:

    Since you have been debugging the code, if you have an updated file, please post it so I can work from the latest.

    The last one is the latest code. As you see I put the EDMA configuring out of the while(). It means to save the time of the while(). In the earlier code I put the EDMA

    configuring in the while(). This is the code enclosed.

    RandyP said:

    I found that the Interrupt can respond correctly, but the transfer time is too long,

     

    Please explain what this means. Do you get the interrupt several times, once for each transfer completion? How long is the transfer time and what did you expect it to be?

     

    [/quote]

    I use the Agilent Logic Analysis System to see the loop time. The loop time of the code in this letter is much shorter than the last one. The difference between the two

    code is PaRAM link method and wether the EDMA configering is in the while() or not.


    RandyP said:

    Please explain what you would like this part of the application to do. I saw McBSP and GPIO references.

    Do you require the use of Region 0 or of Region 1? There are some advanced tricks that you can do to get extra interrupts, but it will be much easier if you only use the

    Global Region. That will be my recommendation unless you have a specific need that is addressed by the use of the region logic.

     You can see the McBSP as the GPIO4's input, FPGA make this signal reversed, then give it to GPIO4.

    There is no require to use the shadow region, I will have a try to use the global region. Thank you for the advice!


    RandyP said:

    Yes, the PaRAM link to itself is a problem. If you look at the PaRAM in a memory window, you will see that it does not have good values after the first transfer has

    completed.

    But I use the register window to see the change of the PaRAM, I found that there is no change after transfer completed when using link to itself. Do you mean that the

    PaRAM has a responding time to link to itself? And is the time longer than the time of configering the channel again?  

  • For some reason, I did not receive an email notice of your latest posting with the updated code. So my work was based on your previous version. All this means is that there may be some additional updates from your new code that you would need to apply to my example.

    I have attached C6455_Edma.zip which contains the "complete" project files for a manual-only EDMA project with interrupts. Since I did not have your hardware, I was only able to trigger channel 52 using the manual triggering. This project may be unzipped into C:\CCStudio_v3.3\MyProjects to form the new folder C6455_Edma with these project files. You may need to update the .pjt file for your paths to the 3 libraries and to the CSL include folders. Otherwise, the Debug Build Configuration should work fine for building and loading and running the example.

    I will try to list the changes that I made to the code. I changed the order of some of the CSL calls because I wanted them to match the way I had them in another example from which I copied code to build this from example. The new example uses the Global Region exclusively. Here is a summary list of code changes in my main.c and my reasons:

    1. For my build using CodeGen tools v6.1.11, I needed string.h to be included in order to find memset.
    2. Only one EDMA interrupt is used for all of the interrupts that will be serviced from the EDMA. The eventEdmaHandler function acts as a handler to call a different function for each TCC that gets thrown to the EDMA's IPR. So I did not use the second interrupt objects but did add a second "ISR" for Channel 0 like you did.
    3. I prefer to use a variable for the channel number and TCC rather than hard-coding this value in several places. It makes it easier to change for a different application. The only point that might be confusing is that I used tccGpio4 for the TCC number and the DMA channel number. These will commonly be the same, but not always. In these examples, it works okay this way using just one variable for both. I also declared tccCh0. I would have used the names from your latest code if I knew about it; sorry.
    4. The CSL objects and handles often need to be global, but most of the other CSL-related variables can be local to the function that uses them.
    5. There must be a separate chObj for each of the DMA channels you want to open. I added chObj1 for the Channel 0 object.
    6. Line 77: One of the most important changes was for the dmahwSetup and qdmahwSetup variables. Both of these must be arrays and the supplied default values will have most of the correct information. When you use these, you will assign Param 0-63 to the DMA channels 0-63, then assign Param 64-67 to the QDMA channels 0-3. These are good defaults that can be changed as shown in the file.
    7. I put a #if 0 around your McBSP and GPIO init code since I was not using those. And for my visual pleasure, I init'd the Data_Rand array with the incrementing values to make it easier to see that the copies were done correctly.
    8. The order of the INTC and EDMA CSL calls are in the order that I always use. In many of the commands, the order from your file would have been fine, I just did not want to figure out if that was an issue or not and made them all be in the order I have used successfully. The calls to CSL_intcGlobalNmiEnable (line 128) and CSL_intcGlobalEnable (line 131) should really be placed later in the code after all interrupt and event handler code has been completed.
    9. Line 135: This uses the Global interrupt from the EDMA now. I commented or used #if 0 to remove all of the Region setup code.
    10. Line 155 and later: I commented out all of the direct register writes. In spite of the earlier discussion about SER and EMR, these are not generally needed unless you run into problems.
    11. Line 166: This now does a correct HwSetup for all of the DMA and QDMA channels. You can see in the code lines above it that you can set param numbers and queue numbers here. The defaults from the declaration are key, as well as using arrays instead of single structs. This was the first thing I saw from the example you originally copied that prompted me to go through this effort to get you a better example.
    12. Line 185: This is the right way to get another EDMA ISR to run, or technically another EDMA call-back from the EDMA ISR handler.
    13. Line 210: Since I do not like hard-coded numbers, and since the repaired HwSetup assigns a Param for every channel, I prefer to pull out the assigned Param number from the channel and then use that variable (paramNum in this case) to get the handle in line 217. This is also done later for Channel 0.
    14. Line 248: To avoid having to hard-code the intr/intrh assignments, I use this Uint64 or long long construct to make the assignments a little more robust.
    15. Line 295 and above: Since you are using BCNT=CCNT=1 and ASYNC, is it conceivable that doing the 'link to itself' will work, but it is not safe, in my opinion. Because of the single event transfer that you want to do and to then repeat, the correct choice would be to change the STATIC_DIS to STATIC_EN and make the Param static. This means that it will not get updated or linked or changed in any way after a transfer is done. This only works for single-event transfers and is commonly used for QDMA channels. This would allow you to pull this code completely out of the while() loop. Because I did not try this, I cannot guarantee it, but I am confident you will figure it out and get it working that way.
    16. In edmaIntDispatcher.c, there was also a region reference. That had to be changed to REGION_GLOBAL to match everything else.

    For testing this, I set breakpoints on the two CHANNEL_SET lines and clicked Run to go back-and-forth between them.

    I have at least lightly touched on some of your latest questions. Please send more if some clarification is needed.

    C6455_Edma.zip
  • Thank you very much!

    Your suggestion is very helpful!

    I'll try your code on hardware and then send you a message.

    Thank you a lot!

  • I've tried your code, and it works well when using the manual trigger.

    But there should set the EER when using the event trigger. And clear EMR and SER.

    As your suggestion, I use the STATIC_EN in PaRAM set, and put the PaRAM set out of the while().

    But, this is incorrect. The IPR.E0 and IPRH.E52 are all set when the second loop comes , so the interrupt handler will hook both the functions.

    How can I solve this problem?

  • Jessie Cui said:

    But there should set the EER when using the event trigger. And clear EMR and SER.

    Yes, you need to set the EER for your application. You were already doing that in your application code. You also must remove the manual triggers since they are no longer needed.

    Clearing EMR and SER are not generally needed, unless you run into problems. It will never hurt, unless you clear SER at the exact time that a new GPIO4 event is coming in.

    Are you still seeing EMR and/or SER set?

    Jessie Cui said:

    The IPR.E0 and IPRH.E52 are all set when the second loop comes , so the interrupt handler will hook both the functions.

    If you are using the eventEdmaHandler() in the file from my project, it clears all set IPR/H bits on line 81. Are you reaching the two ISRs in your application? If your application variable is getting set, then you must be. Are you using the old eventEdmaHandler or the one in the edmaIntDispatcher.c that I supplied? Set a breakpoint to see if you are getting there, and check Properties on the filename in the Project window to confirm what folder it is coming from, or change the filename for one of them.

  • RandyP said:

    Are you still seeing EMR and/or SER set?

    I think it's much safe to clear them before event comes.

    RandyP said:

    If you are using the eventEdmaHandler() in the file from my project, it clears all set IPR/H bits on line 81. Are you reaching the two ISRs in your application? If your application variable is getting set, then you must be. Are you using the old eventEdmaHandler or the one in the edmaIntDispatcher.c that I supplied? Set a breakpoint to see if you are getting there, and check Properties on the filename in the Project window to confirm what folder it is coming from, or change the filename for one of them.

    I use your ISR handler. Today I make three counter in ISR, tccGpio4Fxn, tccCh0Fxn seperately, I run the code for a while, then I find the counter is correct. But when I set breakpoint in ISR and then debug by step, the IPR.E0 and IPRH.E52 are all set. The position of the breakpoint is below. I wonder is my debug method is incorrect?

        ... ...

        count++;
        /* Read the IPR */
    [*au]    regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
        CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND, &regionIntr);
       
        while (regionIntr.intr || regionIntr.intrh) {
            intr    = regionIntr.intr;
            intrh = regionIntr.intrh;
            tcc   = 0;
           
            while (intr) {
                maskVal = 1 << tcc;
                if (intr & maskVal) {
    [*au]                InvokeHandle(tcc);
                    intr &= ~maskVal;
                }
                tcc++;     
            }      
           
            tcc = 0;
            while (intrh) {
                maskVal = 1 << tcc;
                if (intrh & maskVal) {
    [*au]                InvokeHandle((tcc+32));
                    intrh &= ~maskVal;
                }      
                tcc++;
            }
           
            CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR,&regionIntr);      
            CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);        
        }            

    ... ...

     

    void tccGpio4Fxn(void)
    {

        intFlag_r = 1;
     count_r ++;
    }
    void tccCh0Fxn(void)
    {

        intFlag_w = 1;
     count_w ++;
    }

  • It can be misleading to set a breakpoint inside an ISR. The issue in your case is that you are debugging a real-time system but only stopping one part of it, the DSP core.

    The EDMA continues working as long as it is programmed correctly. And your FPGA continues running as well as the rest of the system.

    What is triggering the EDMA events that result in setting the IPR/H bits?

    Do those events continue running when you stop the DSP?

    If the EDMA responds to those events, will it set the IPR/H bits "again"?

    Can this occur while you are single-stepping in the ISR?

    More importantly, since the routine is working while you are letting it run without the breakpoints, what are you trying to figure out by using the breakpoints?

    For this type of issue, the best you might get from the breakpoints in the ISR is simply confirmation that the ISR is being reached, rather than being able to determine how it will be interacting within the system that continues to run. And you have successfully shown that the ISR is being reached and that your counters are counting correctly. Good job!

  • A colleague pointed out to me that there was a severe weakness in the edmaIntDispatcher.c file's eventEdmaHandler function. The problem was that the IPR/H value needed to be qualified by IER/H or else invalid ISR branches could occur due to bits being set in IPR/H that were not intended to cause DSP interrupts.

    This has been fixed and the zip file replaced. The change was to add

        regionIntr.intr &= hModule->regs->IER;
        regionIntr.intrh &= hModule->regs->IERH;

    in two places after the GetHwStatus calls to get the IPR/H values.

    This fix was already in a version of this file that is used in the TI Technical Training Organization's IW6455 class.

    Please update to the new version of this file or make the appropriate edits to your version.

  • Thank you!

    I've follow your advice, the routine works well.

    Would you please recommend me some training? I think I need some training about 6455.

  • The absolute best training that we have available are the Technical Training Workshops. These are offered world-wide and are presented by live in-person instructors who can address your questions during the course of the class. For the value received, the cost is well worth it even if you have to travel to the class. The only downside is finding the class you want right now when you need it.

    We also have a lot of online training material. To look through the list of on-demand choices:

    Go to www.ti.com and click on Training & Events in the middle of the page.
    Select Topic = DSP and Subtopic=C6000 Fixed-point DSPs (or try one of the more specific choices)
    Then Type=On-demand.
    Click Search.

    From Training & Events, you can also find the list of live classroom training events.

    From the Product Folder of the C6455, under Technical Documents is a list of Application Notes that can be very helpful. And the User's Guide are where the complete facts are detailed. At your knowledge level, the Technical Documents may be the best place to go for getting a better understanding of any specific parts of the C6455.

    There is a new Online Training for the C6474 that is not exactly relevant, but it is like 3 C6455s put together, but a different set of external peripherals. Half or more of the class is relevant to the C6455 since they have the same C64x+ DSP core (or 3 of them). I have a bit of trouble getting to the full course from various searches, but you are supposed to be able to reach it by clicking on http://e2e.ti.com/media/p/36682.aspx .