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.

C6747: MCASP can't receive data with EDMA3

I'm successful in sending and receiving data with MCASP0 no EDMA3. Then I want use EDMA3 to serivice for MCASP data transfer.
MCASP is working in Burst Transfer Mode, and data is transfered from AXR0[0] to AXR0[1]. I want to transfer 10*Uint32 from the 'xmt' to 'rcv' with MCASP0 that is serviced by EDMA3. There is No interrupt in MCASP and EDMA3.
In MCASP0, the code settings that support EDMA3 as follows,
 mcasp0Regs->RFMT = (Uint32) 0x000000F0;
 mcasp0Regs->REVTCTL = CSL_MCASP_REVTCTL_RDATDMA_ENABLE;
        mcasp0Regs->XFMT = (Uint32) 0x000000F0;
 mcasp0Regs->XEVTCTL = CSL_MCASP_XEVTCTL_XDATDMA_ENABLE;

And EDMA3 settings are:
1.EDMA3 data sending
edma3ccRegs->EESR |= (Uint32) 0x0002;
edma3ccRegs->DMAQNUM[0] = (CSL_EDMA3CC_DMAQNUM_E1_Q0 << CSL_EDMA3CC_DMAQNUM_E1_SHIFT);
edma3ccRegs->PARAMSET[1].OPT = (CSL_EDMA3CC_OPT_TCINTEN_ENABLE << CSL_EDMA3CC_OPT_TCINTEN_SHIFT)|\
          (0x01 << CSL_EDMA3CC_OPT_TCC_SHIFT)|\
          (CSL_EDMA3CC_OPT_SYNCDIM_ABSYNC << CSL_EDMA3CC_OPT_SYNCDIM_SHIFT);
edma3ccRegs->PARAMSET[1].SRC = (Uint32) &xmt;
edma3ccRegs->PARAMSET[1].A_B_CNT = (Uint32) 0x000A0004;
edma3ccRegs->PARAMSET[1].DST = 0x01D00200;
edma3ccRegs->PARAMSET[1].SRC_DST_BIDX = (0x0000 << CSL_EDMA3CC_SRC_DST_BIDX_DSTBIDX_SHIFT)|\
     (0x0001 << CSL_EDMA3CC_SRC_DST_BIDX_SRCBIDX_SHIFT);
edma3ccRegs->PARAMSET[1].LINK_BCNTRLD = 0x000A4020;
edma3ccRegs->PARAMSET[1].SRC_DST_CIDX = (Uint32)0x00;
edma3ccRegs->PARAMSET[1].CCNT = (Uint32)0x01;
edma3ccRegs->IESR =0x00;

2.EDMA3 data receiving
edma3ccRegs->EESR |= (Uint32) 0x0001;
edma3ccRegs->DMAQNUM[0] = (CSL_EDMA3CC_DMAQNUM_E0_Q0 << CSL_EDMA3CC_DMAQNUM_E0_SHIFT);
edma3ccRegs->PARAMSET[0].OPT = (CSL_EDMA3CC_OPT_TCINTEN_ENABLE << CSL_EDMA3CC_OPT_TCINTEN_SHIFT)|\
          (0x00 << CSL_EDMA3CC_OPT_TCC_SHIFT)|\
          (CSL_EDMA3CC_OPT_SYNCDIM_ABSYNC << CSL_EDMA3CC_OPT_SYNCDIM_SHIFT);
edma3ccRegs->PARAMSET[0].SRC = 0x01D00200;
edma3ccRegs->PARAMSET[0].A_B_CNT = (Uint32) 0x000A0004;
edma3ccRegs->PARAMSET[0].DST = (Uint32) &rcv;
edma3ccRegs->PARAMSET[0].SRC_DST_BIDX = (0x0001 << CSL_EDMA3CC_SRC_DST_BIDX_DSTBIDX_SHIFT)|\
     (0x0000 << CSL_EDMA3CC_SRC_DST_BIDX_SRCBIDX_SHIFT);
edma3ccRegs->PARAMSET[0].LINK_BCNTRLD = 0x000A4000;
edma3ccRegs->PARAMSET[0].SRC_DST_CIDX = (Uint32)0x00;
edma3ccRegs->PARAMSET[0].CCNT = (Uint32)0x01;

Then in main code, CPU is polling for the complete of sending and receiving.
   while (!(edma3ccRegs->IPR & 0x0002));
   while (!(edma3ccRegs->IPR & 0x0001));

After running the code, I saw:
IPR =2; XSTAT=0x00000124; RSTAT=0x00000104; 
and the data in rcv is all 0. That means no data is received.
 Is there any error in my settings?

  • This is the same issue as your other thread, right?  The problem is solved now that you've fixed your linker command file, correct?

  • Thanks for your reply.

    Yes, the same issue, I solved the prior problem for the purpose of this one. it's because I can't let the EDMA3 service the MCASP correctly that I decided first to operate the EDMA3 correctly. 

    And I've fixed my linker command file correctly :L2:      o = 11800000h   l = 00040000h.

    But the data didn't transfer.

    and XSTAT= 0x00000124; That's means the AXEVT0 has been triggered.

  • Please post the raw contents of Parameter Set 1 (from the Memory View) before any transfers occur and after.

  • PARAM 1before transfer occur:

    PARAM 1 after transfer:
  • A couple of things I notice:

    1. You are using AB-sync transfers, I think you mean to use A-sync transfers.  With AB-sync transfers you are telling the EDMA to transfer BCNT arrays of ACNT bytes on each transfer request.  So the EDMA will end up transferring 10x4 bytes on the first McASP transfer request.  

    2. Your LINK value doesn't look right.  Set it to PARAM * 0x20, where PARAM is the PARAM you want to reload from.  This should not be PARAM0-32 as these are used for channel synchronization and will be continuously updated on each transfer.

  • Lian,

    The BIDX field is supposed to be specified in bytes. Please check the value you use to see if it matches your intended value.

  • Thanks for your reply!

    Gus Martinez said:

    1. You are using AB-sync transfers, I think you mean to use A-sync transfers.  With AB-sync transfers you are telling the EDMA to transfer BCNT arrays of ACNT bytes on each transfer request.  So the EDMA will end up transferring 10x4 bytes on the first McASP transfer request.  

    About 1,  I have some uncertainty and  question about how the EDMA and MCASP work together.  I use the MCASP "Burst Transfer Mode".

    And the AXEVT and AREVT are triggered every slot. That means AXEVT and AREVT are triggered when every Uint32 data is sending and receiving. I want to transfer 10*Uint32 data from 'xmt' to 'rcv'. But for EDMA3, once the event is triggered, EDMA3 will transfer ACNT*BCNT*CCNT numbers of Bytes.
    So, for me, does that means I can only transfer 1*Uint32= 4*Bytes every AXEVT and AREVT? That means I should set ACNT=4,BCNT=1,CCNT=1. As a result, EDMA3 event should be triggered 10 times. And I must use the LINK another 9 times to complete the 10*Uint32 data transfer.
    Is it right? If it's wrong, how should I set the ACNT,BCNT and CCNT? How can I complete the 10*Uint32 data transfer in Burst Transfer Mode with EDMA3?
    I'm so confused. Wish your help.

  • On an A-sync transfer (OPT.SYNCDIM = 0), the EDMA will transfer ACNT bytes to the destination, so four bytes in your case, and decrement BCNT by one on each event.

    On an AB-sync transfer (OPT.SYNCDIM = 1), the EDMA will transfer BCNT x ACNT bytes to the destination, so 10 x 4 in your case, and decrement CCNT by one on each event.  

    Even though you want to transfer only 10 32-bit values to the McASP, you can't dump all that data in one shot.  The McASP will get overrun!  In burst transfer more, the McASP transmitter should keep generating events as soon as it is ready to send more data.  You only have to take the transmitter out of reset for it to generate the first event.

    In your case, set SYNCDIM = 0 (A-sync transfer), keep ACNT = 4, BCNT = 10, and CCNT = 1.  One more thing, if you want to terminate all EDMA transfers after 10 32-bit values have been transfered, set LINK = 0xFFFF in your PaRAM. 

  • Thanks for your help! I have changed my EDMA3 settings as you said.

    This is the Parameters Set 1 settings.

    This is the Parameters Set 0 Settings.

    But it didn't work. and the code is polling here all the time.

         while (!(edma3ccRegs->IPR & 0x0002));
      while (!(edma3ccRegs->IPR & 0x0001));

    And now the MCASP's register state is :

    The MCASP's transmitter and reciever are all out of reset. And the XEVT is triggered. But the EDMA3 sending didn't happen.

    Can you give me any suggestions? Thanks a lot.

  • About MCASP, I have some confuse. Maybe this is  the Key to the question.

    Follow the C6747 MCASP  "2.4.1.2 Transmit/Receive Section Initialization" , I set the EDMA3 Parameters in step 6 a.  The original text is,

    【6. Setup data acquisition as required:
    a . If DMA is used to service the McASP, set up data acquisition as desired and start the DMA in this step, before the McASP is taken out of reset.】

    Question 1:  "start the DMA in this step", What does this mean? What should I do?

    Question 2: "2.4.1.2 Transmit/Receive Section Initialization"  Step 8 a is the other one that is related to EDMA3 when initialing MCASP.

    【a . If DMA is used to service the McASP, the DMA automatically services the McASP upon receiving AXEVT. Before proceeding in this step, you should verify that the XDATA bit in the XSTAT is cleared to 0, indicating that all transmit buffers are already serviced by the DMA.】

    In this step, what I need to do when I am programming?

  • Lian,

    The McASP User's Guide has the right steps for you to use. I covers many more scenarios than we can cover easily in this forum, so that you can understand how your system should work.

    Lian said:
    Question 1:  "start the DMA in this step", What does this mean? What should I do?

    For a DMA channel to respond to an event, the DMA channel must be configured, the PARAM must be initialized for the first transfer, and the Event Enable Register (EER) must be set to enable the McASP event to get through. This is what we mean by "start the DMA".

    Lian said:
    Question 2:..., you should verify that the XDATA bit in the XSTAT is cleared to 0, indicating that all transmit buffers are already serviced by the DMA.

    This step is not absolutely required, but is an error/status test to make sure you have everything configured correctly. Similar to testing the return status of functions that you know will return OK once you have the program working right, XDATA will always be 0 if you have the McASP and EDMA3 configured correctly. But right now, while you are debugging the system to get it running the first time, it would be a good idea to test XDATA at this point to make sure it is 0.

     

    I would like to recommend a training video for EDMA3. It was prepared for the C6474 multi-core DSP but the basics of the EDMA3 are the same from one device to another. In the Training section of TI.com, there is a training video set for the C6474. The EDMA3/QDMA/IDMA Module will apply to your current questions. You can find the complete video set at http://focus.ti.com/docs/training/catalog/events/event.jhtml?sku=OLT110002 .

    Regards,
    RandyP

  • Lian,

    Please explain a bit more what you are trying to do with the EDMA3? Or maybe you can explain what the non-EDMA3 version did with the data. It is not clear from your register settings or text exactly what you want the behavior to be.

    For example, how many serializers do you use?
    What do you mean by "I want to transfer 10*Uint32 from the 'xmt' to 'rcv'"?
    Do you always use the same buffer(s)?
    Is this supposed to be an internal loopback from McASP transmit to McASP receive, or perhaps an external loopback from McASP receive to McASP transmit?

     

    Some comments on your code:

    Lian said:
    edma3ccRegs->EESR |= (Uint32) 0x0002;

    This is a "set" register, so it will always read 0. You do not need to do the |= but simply = will do what you want.

    Lian said:
    (0x0001 << CSL_EDMA3CC_SRC_DST_BIDX_SRCBIDX_SHIFT)

    Unless you only want to keep one byte from each Uint32, this is the wrong index value. The training video may be the clearest way to explain indexing.

    Lian said:
    edma3ccRegs->IESR =0x00;

    This is also a "set" register, so writing 0 has no effect. If you intention is to clear the corresponding IER bit, use IECR = 0x0002 and 0x0001.

     

    To help more, we will need to understand more about how you wish to use the McASP.

    Regards,
    RandyP

  • Thanks for your reply! I will explain the non-EDMA3 version first.

    RandyP said:

    For example, how many serializers do you use?
    What do you mean by "I want to transfer 10*Uint32 from the 'xmt' to 'rcv'"?
    Do you always use the same buffer(s)?
    Is this supposed to be an internal loopback from McASP transmit to McASP receive, or perhaps an external loopback from McASP receive to McASP transmit?

    I use 2 serializers. AXR0[0] is output while AXR0[1] is input. They are connected externally. And I set ASYNC=0 in register ACLKXCTL. That means "transmit/receive operation Synchronous". Transmit clock and frame sync provides the source for both the transmit and receive sections. MCASP0 is working in Burst Transfer Mode. And 'xmt' and 'rcv' is defined in L2 RAM (L2:      o = 11800000h   l = 00040000h). Non-EDMA3, so I sent the xmt by writing into the XBUF0 in turn, and I receive the rcv by reading from the RBUF1 in turn till the 10*32bits are all received. Maybe the following picture is more clear to show what I mean.

  • MCASP with EDMA3 shows as follows.

    I want to use the EDMA3 to tranfer the xmt in turn to the XBUF0 instead of writing to XBUF0 directly by CPU.

    In future, I will use the MCASP-to-MCASP between 2 DSPs to tranfer data. Maybe, the number of the data is very large. I only need to trigger the XEVT and set the EDMA3 correctly, then the EDMA3 can transfer the data automaticlly. At the same time, I can use the CPU  to do other things.

  • RandyP said:

    This step is not absolutely required, but is an error/status test to make sure you have everything configured correctly. Similar to testing the return status of functions that you know will return OK once you have the program working right, XDATA will always be 0 if you have the McASP and EDMA3 configured correctly. But right now, while you are debugging the system to get it running the first time, it would be a good idea to test XDATA at this point to make sure it is 0.

     

    I test the XDATA at this point, and it is not 0. That means I haven't cofigured the EDMA3 and MCASP correctly. I will lean the training video first as you said.

    Thanks a lot.

  • Can you show the code you use for writing and reading the data in the non-EDMA version, please? I assume it is a set of small loops that use polling and sample counting.

  • Yes, you are right. 

    The code is,

      for (i=0; i<=N-1;i++) 

      {

        while (!(mcasp0Regs->XSTAT & 0x0020));                

        mcasp0Regs->XBUF0 = (Uint32) xmt[i];    

       while (!(mcasp0Regs->RSTAT & 0x0020));

        rcv[i] = mcasp0Regs->RBUF1;                  

      } 

     And I looked at the video "EDMA/QDMA/IDMA", and I changed the code as follows.

    DMA Channel 1:

    McASP0 Transmit: edma3ccRegs->PARAMSET[1].SRC_DST_BIDX = (0x0000 << CSL_EDMA3CC_SRC_DST_BIDX_DSTBIDX_SHIFT)|\

                                                                                                                                  (0x0004 << CSL_EDMA3CC_SRC_DST_BIDX_SRCBIDX_SHIFT);

    DMA Channel 0:

    McASP0 Receive edma3ccRegs->PARAMSET[0].SRC_DST_BIDX = (0x0004 << CSL_EDMA3CC_SRC_DST_BIDX_DSTBIDX_SHIFT)|\

                                                                                                                               (0x0000 << CSL_EDMA3CC_SRC_DST_BIDX_SRCBIDX_SHIFT);

  • So Gus had the right idea in his original post to you. You want to transmit 10 (N) words and receive 10 words and then stop.

    As Gus said, you want to use A-Sync instead of AB-Sync, so you will transfer exactly 1 word each time an A-EVT0 occurs.

    For debug purposes, do set the LINK field to 0xFFFF. This will make it so that the DMA transfers will stop after 10, and the PARAM will all get cleared to 0's so you can tell something happened. Unfortunately, there will quickly be an 11th AXEVT0 that will try to run this channel again, and when the PARAM is NULL'd to all 0's an error condition exists which means EMR and SER will be set and this channel will not work again until they are cleared. Even if you clear them or if you handle the event differently, it will need to be carefully handled with some cleverness in the PARAM and one or more LINK PARAM sets. But that will be for another day after you get this first set of 10 to work right.

    This may be all you need to get this going.

    Please let us know. And when it is working, continue the discussion with what you want to do next with the McASP.

    Regards,
    RandyP

  • A couple of comments:

    1. Burst mode is useful when you want to transfer data via the McASP "once in a while".  Although your immediate goal is to transfer only a few words, if your end goal is to have a continuous, never-stopping data stream, then you are better off with TDM mode.  The choice between burst mode and TDM mode can affect the way you program the EDMA.  

    2. Using one serializer vs. multiple serializers (that is more than one transmit serializer or more than one receive serializer) will also affect the way you program the EDMA.  If your end goal is to use only one serializer for transmit and one for receive then you are on the right path.

    As far as further debug goes, I think you are programming the EDMA correctly now.  This may fall back on the McASP programming or a software sequence.  One debug trick you can try is to manually trigger the EDMA transfer by writing to the EDMA ESR register.  This will force a transfer request which would normally be generated by the AXEVT DMA event.  If the BCNT in your PARAM decreases by one after every write to ESR then you know the EDMA is transferring data to the McASP. 

    If the transfer happens, then we need to figure out why the EDMA is not seeing a McASP event.  The value that you read from the McASP XSTAT register indicates that XCKFAIL and XDATA are set.  I think you can ignore XCKFAIL since this is used for some special transmitter clock checking which I doubt you are using.  XSTAT indicates that the McASP has requested data which would mean the McASP has generated AXEVT.  Since the EDMA is not transferring data, then perhaps the order in which you are enabling the EDMA and the McASP is the problem.  I think you've seen the init sequence outlined in the McASP user guide, but generally you want to make sure the EDMA is fully programmed before you take the McASP transmitter and receiver out of reset (XSMRST = 1 and RSMRST = 1).

    Finally please note that there are essentially two EDMAs in the device.  Each has its own set of registers and PARAMs.  Make sure you are using EDMA0 registers and PARAMs since this is the only EDMA which has access to McASP events.

    [correction] Added some clarification on what I meant by "multiple serializers".

  • O(∩_∩)O~. Thanks for your reply, and your reply gives me lots of help.

    My end goal is to have "once in a while" data transfer between 2 DSPs and use one serializer for transmit and one for receive. Maybe, every 8ms to transfer 1000*32bits data, and I have calculated that the time is enough. If the ACLKX is 20MHz ( up to 40MHz), then the transfer takes 1000*32/20M=1.6ms. Because the data number is large, so use the EDMA3.

    Gus Martinez said:

      As far as further debug goes, I think you are programming the EDMA correctly now.  This may fall back on the McASP programming or a software sequence.  One debug trick you can try is to manually trigger the EDMA transfer by writing to the EDMA ESR register.  This will force a transfer request which would normally be generated by the AXEVT DMA event.  If the BCNT in your PARAM decreases by one after every write to ESR then you know the EDMA is transferring data to the McASP. 

    Yes, you are right. The EDMA3 is correct. My test step is,

    1, Set ACNT=4,BCNT=1,CCNT=1.DSTBIDX=0,SRCBIDX=0. Running the code, the result is IPR=2, EMR=0;

    2,Set ACNT=4,BCNT=10,CCNT=1.DSTBIDX=0,SRCBIDX=4. Runing the code, the result is IPR=0,EMR=0;

    3,Set ACNT=4,BCNT=10,CCNT=1.DSTBIDX=0,SRCBIDX=4. Manually trigger the EDMA transfer 9 times, the result is IPR=2, EMR=0;

    4, Set ACNT=4,BCNT=10,CCNT=1.DSTBIDX=0,SRCBIDX=4. Manually trigger the EDMA transfer 10 times, the result is IPR=2,EMR=2.

    I think that means the first AXEVT is triggered by MCASP transmitter out of reset. But the problem is that the MCASP only triggers one AXEVT, so the EDMA only sent one 32bits to XBUF0 only one time, the second and other AXEVT are not triggered continously. I should check my MCASP carefully. Why is it only one AXEVT? Do you have any suggestion?

  • AXEVT should be generated each time XDATA is set.  XDATA is set each time a value is copied from the transmit register (XBUF) to the shift register, and after the transmitter is taken out of reset.  What is the value of XDATA before you take the transmitter out of reset and what is its value after you manually trigger the EDMA events?  Can you also make sure XEVTCTL.XDATDMA is set to 0 (default).  

  • Gus Martinez said:

    ..... The value that you read from the McASP XSTAT register indicates that XCKFAIL and XDATA are set.  I think you can ignore XCKFAIL since this is used for some special transmitter clock checking which I doubt you are using.  

    I set the XCLKCHK and RCLKCHK both RESETVAL (0x00). Is this related to the XCKFAIL?

    Gus Martinez said:

     Since the EDMA is not transferring data, then perhaps the order in which you are enabling the EDMA and the McASP is the problem.  I think you've seen the init sequence outlined in the McASP user guide, but generally you want to make sure the EDMA is fully programmed before you take the McASP transmitter and receiver out of reset (XSMRST = 1 and RSMRST = 1).

    I program my code just as the the init sequence "2.4.1.2 Transmit/Receive Section Initialization", 11 steps. What's more, I seperate Transmit and Receive Initialization. I doubt if I should first initialize the Receive first, then initialize the Transmitter. Because when the transmitter out of reset, the AXEVT is triggered, the EDMA channel 1 will sent the data instantly, so the receiver should prepare before the transmitter. Is that right?

    Gus Martinez said:

    Finally please note that there are essentially two EDMAs in the device.  Each has its own set of registers and PARAMs.  Make sure you are using EDMA0 registers and PARAMs since this is the only EDMA which has access to McASP events.

    I use 2 DMA channels, and set PARAM0 and PARAM1 separately. So I should use the EVENT0 and EVENT 1  as the following picture.

     

  • I set the XEVTCL,  "mcasp0Regs->XEVTCTL = CSL_MCASP_XEVTCTL_XDATDMA_ENABLE;" equals to XEVTCL=0x00;

    Before the serializers out of reset, the XDATA is 0 (XSTAT=0x0000010C). After the serializers out of reset,the XDATA is 1 (XSTAT=0x0000012C). After I manually trigger the EDMA events, XDATA is 1 (XSTAT=0x00000124).

     

  • I test my code further. I find that maybe the real reason why the MCASP only triggers one AXEVT is that, though the EDMA3 channel 1 responds to the first AXEVT (I saw the BCNT change from 10 to 9),in fact, EDMA3 channel I doesn't  sent the first Uint32 to XBUF0. So, the XDATA=1 always. So, the second and other AXEVT aren't triggered.

    My test step as follows,

    1. McASP transmits data  with EDMA3 while receive data without EDMA3.

    2. When the serializers out of reset, I saw BCNT decrease from 10 to 9, but the XBUF1 is empty (default ,0x00), and my code is polling here,   "while (!(mcasp0Regs->RSTAT & 0x0020)); ".

    If the transmitter send the data out, the receiver without EDMA3 should receive the data, and the RBUF1 should have the data. That means the transmitters with EDMA3 doesn't send the data to XBUF0, though EDMA3 responses to the first AXEVT.

    And I really set the DMA channel 1 DST to the XBUF0. " edma3ccRegs->PARAMSET[1].DST = 0x01D00200;"

    In order to verify this guess, I trigger the EDMA3 EVENT 1 manually  n times (n=1~9) by setting the ESR 0x0002 till IPR=2. However, the receiver without EDMA3 doesn't receive any data.

    So, why the EDMA3 doesn't send the 32bit data to the XBUF0 when it is triggered by the AXEVT?

    Hope you reply as soon as possible!  Thank a lot! O(∩_∩)O~

  • Thanks you all very much! The MCASP with EDMA3 sending and receiving are all successful.

    I didn't change the my code at all. The reason is that the first circuit board I used maybe has something wrong with its EDMA3 to XBUF0.  Today, I program another code that is using EDMA3 to service SPI. and that's successful.  And I thought the operating principle is the same. So I changed another curcuit board, and it's sucessful.

    I'm so unlucky to meet a C6747 with something wrong.  Maybe there is something wrong with my "Ren Pin"(in Chinese).

    I'm so sorry to trouble you for so long time.

    In a word. Thanks you all so much for your warm-hearted helping. O(∩_∩)O~

    Best wishes!