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.

How to do a EDMA transfer 1D to circular buffer

the purpose is to move 20 * bit32 from a FPGA FIFO to a internal circular buffer.(count = 32).

The C6711D get the external int 7 as the event and trigger an EDMA interrupt for each fame. After the EDMA param is exhausted, it will reload the param via a link.

Please help check the code and find what is the error.

void InitDMAExtint7()
{
    UINT32 i;
    volatile UINT32 *edma_ptr;
   
    /*set event selector, default extint7 using channel 7*/
       
    /*clear pending flag*/
    EDMA_CIPR = 0xffffu;  
    /*enable channel interrupt*/
    //EDMA_CIER = 0x1u << 7;
    /*no chain for channel 7*/
    EDMA_CCER = 0;
    /*disable event 7*/
    EDMA_EER &= ~(1 << 7);
   
    /*clear EDMA channel 7 param*/
    edma_ptr = (UINT32*)&EDMA_7;
   
    for(i = 0; i < 6; i ++) {
        *edma_ptr ++ = 0x00000000;
    }

    EDMA_ECR = 0x1u << 7;
   
}

void SetDMA7()
{
    //UINT32 index ;
    volatile EDMA_PaRAM *pEDMA = (volatile EDMA_PaRAM *)&EDMA_7;
    volatile EDMA_PaRAM *pEDMA_Link = (volatile EDMA_PaRAM *)&EDMA_8;
    /*disable event 7*/
    EDMA_EER &= ~(1 << 7);
   
    //index = (DatasDMA.IndiceEntree + 1) & (ET_C_SIZE_ELTS_FILES - 1);
   
    /*OPT: PRI=2 ESIZE=0 2DS =0 SUM=11 2DD =0 DUM=1 TCINT=1 TCC=7 LINK=1 FS=1*/
    pEDMA->opt = 0x43370003;
    /*RSC = FPGA FIFO*/
    pEDMA->src = ET_C_MAC_BASE;
    /*CNT: FRMCNT =1 ELECNT = count of 32bit in a frame*/
    pEDMA->cnt = ((ET_C_SIZE_ELTS_FILES-1) << 16)|ET_C_SIZE_FRAME;
    /*DST: DATADMA point */ /*write to next buffer,inc index after transfer*/
    pEDMA->dst = (UINT32)DatasDMA.FileCirculaire;
    /*IDX: 0*/
    pEDMA->idx = 0x00000004;
    /*RLD: 0 */
    pEDMA->div = (EDMA_PaRAM_EVT8 & 0xffff);
   
    pEDMA_Link->opt = pEDMA->opt;
    pEDMA_Link->src = pEDMA->src;
    pEDMA_Link->cnt = pEDMA->cnt;
    pEDMA_Link->dst = pEDMA->dst;
    pEDMA_Link->idx = pEDMA->idx;
    pEDMA_Link->div = pEDMA->div;


/*enable event 7*/
    EDMA_EER |= 0x1u << 7;   
}

  • It seems only working when when the frame count =0, do anyone know why?

    I keep the rest parameter unchange, when frame count =0, it can works. when frame count > 0, it can not trigger EDMA INT.

  • jun wu,

    jun wu79673 said:
    Please help check the code and find what is the error.

    What are we looking for? What is the problem that you need fixed? How is it behaving now and why is that wrong?

    jun wu79673 said:
    the purpose is to move 20 * bit32 from a FPGA FIFO to a internal circular buffer.(count = 32).

    This is unusual, and I do not believe there is a simple way to do this.

    1. Can you read 16 * bit32 from the FIFO each time? That would make the circular buffer effect much easier to implement.

    2. Can you change the buffer size to 40 instead of 32? That might prevent using the circular addressing instruction mode, but adding an if-statement to change the address might not hurt performance much for such a small buffer size.

    3. The complex way that might work would be to use 8 Link Param Sets with each of the 8 start addresses. The first set writes 20 words starting at offset = 0*4; the second set writes 12 words starting at offset = 20*4 then 8 words back at offset = 0*4; the third set writes 20 words starting at offset = 8*4; the fourth set writes 4 words starting at offset = 28*4 then 16 words back at offset = 0*4; and so on. The two-step transfers like the second and fourth ones will require chaining to another channel and link sets for that chained channel to implement the second phase that starts "back at offset = 0*4". If this idea makes sense and you are very experienced with the EDMA linking and chaining, then it might work. If this idea does not make sense, then please ignore it; I have not tested this, but it could work if you have a lot of experience with debugging EDMA operations, and it might not work even if you are an expert because my logic might be wrong.

    jun wu79673 said:
    when frame count > 0, it can not trigger EDMA INT.

    It will not trigger EDMA INT until all frames have been sent. For a 1D transfer with FS=1, it will require FrameCnt Int7 events before the completion interrupt will be signalled.

    Regards,
    RandyP

  • Sorry for the confusion because I write not clear in the previous. Actually it the FPGA FIFO is 20*bit32 and must be read in increment address. And the target circular is int32 buffer[32][20], so it is not 20->32 buffer, but 20->32*20. But what you said is already very useful to me. Previously I thought I will get a EDMA INT from every TR when frame cnt >0.

    In the code I designed a indexed reading from the source and increment wrting to target, when 32 frames has been transfered, it will reload the param from PARAM8. Could you check if my design is reasonable? If my opt is correct? If the FRMIDX shall be zero? what value shall ELEIDX be ?

    /*OPT: PRI=2 ESIZE=0 2DS =0 SUM=11 2DD =0 DUM=1 TCINT=1 TCC=7 LINK=1 FS=1*/
        pEDMA->opt = 0x43370003;
        /*RSC = FPGA FIFO*/
        pEDMA->src = ET_C_MAC_BASE;
        /*CNT: FRMCNT =1 ELECNT = count of 32bit in a frame*/
        pEDMA->cnt = ((ET_C_SIZE_ELTS_FILES-1) << 16)|ET_CE__SIZFRAME;
        /*DST: DATADMA point */ /*write to next buffer,inc index after transfer*/
        pEDMA->dst = (UINT32)DatasDMA.FileCirculaire;
        /*IDX: FRMIDX=0 ELEIDX =4 */
        pEDMA->idx = 0x00000004;

        /*RLD: 0 */
        pEDMA->div = (EDMA_PaRAM_EVT8 & 0xffff);


    I am not a experienced EDMA user, but what you have said really helps me. Thanks. If you have any suggestion to how to monitor the DMA working condition and how to solve racing conditions. In my allplication, the C6711D is a subcomponent of the system ,so it can not be seprately debugged, And when working actually it has 3 DMA channels working parallely. The crystal is 18.432M and the sysclk1 is set at 165M.

    1. Host CPU will read 60*32 bit data by HPI interface twice per second.

    2.It shall read the FIFO 20*bit32 every 25us( The DMA transfer will cost 3us more than a internal ram -> internal ram transfer ). The DMA trasfer is started by a event7, 6711 shall write 0 to the first byte to tell the FPGA that the reading is complete in EDMA ISR.This DMA using the Q2

    3. Every 595us the M0BSP shall send 32*16bit in 2M frequency in DMA Q1, which means 32 TR submitted every 8us.

    I found the DMA will fail to receive data about 1 minute after reset . So far I have not got the reason. Do you think it may be a DMA racing  problem ?

     

     

  • As you know now, you can ignore the three options I listed above. I assumed I understood what (count=32) meant, but I was wrong.

    You are trying to copy 32 frames of data to a frame buffer and then start over. This is a "Frame Synchronized 1D Transfer (FS = 1)" and is described in the EDMA Reference Guide in section 1.4.1.2. You must implement the ELEIDX and FRMIDX as shown in the Figure in that section.

    You will get an interrupt at the end when all 32 frames have been copied from the FPGA FIFO.

    jun wu79673 said:

    I found the DMA will fail to receive data about 1 minute after reset . So far I have not got the reason. Do you think it may be a DMA racing  problem ?

    It is not clear to me what the first sentence means exactly. I see no reason to suspect a race condition, but I do not know your system as well as you do. Why do you suspect a race condition?

    Regards,
    RandyP

  • RandyP said:

    It is not clear to me what the first sentence means exactly. I see no reason to suspect a race condition, but I do not know your system as well as you do. Why do you suspect a race condition?

    Regards,
    RandyP

      means the EDMA interrupt will not be triggered one minute later.

    I suspected the EDMA racing for if I changed the sending via M0BSP by polling the XRST of SPCR instead of DMA sending, it can keep working normally.

  • jun wu79673 said:
    means the EDMA interrupt will not be triggered one minute later.

    You will miss just one EDMA interrupt, or there will not be any EDMA interrupts after 1 minute?

    What are the states of the relevant signals at this point?
    Can you be sure that GPIO 7 toggled?
    Is its bit set in ER?
    In EER?
    Can you tell if the transfer occurred, or is that impossible because the data is always different?
    Is the CIPR bit set?
    Is the CIER bit set?
    Is the IFR bit set for the EDMAINT?

    Does the McBSP0 continue working even when the FIFO read has ended?

    Does the failure always occur after the exact same number of transfers, or at the exact same address of the internal buffer?

    Are there any clues in the similarity of the PARAM registers when the failure occurs?

    Regards,
    RandyP

  • The hand -shake between dsp and fpga is that 

    1 .FPGA  -> extint 7 Dsp

    2. Dsp read data from FPGA FIFO

    3.Dsp write 0 to FPGA FIFO

    One communication end. Then it repeat.

    If the dsp failed to reply the FPGA FIFO with 0, the communication will stop.

    So I added count both in extint7 and edmaint and found that the extint7_count is exactly one more than the count of edma interrupt.  And I will check the regiester value and reply you later. thanks.

  • I check the extint7 signal and found that there could be multi consecutive request within a short time. I suspect that if I use the event 7 to trigger the edma transfer, the dsp may lost several request before the previous transfer complete and the emda channel parameter is reloaded. So when the next event arrives and the channel parameter set is exhausted, the event will be discarded.

    So I modify the design as the following.

    1. extint 7 ISR start  cup-triggered  edma transfer.

    2.setup up two channel to service the same event. Add a count in the extint7 ISR to decide which channel shall be used.

    3.If multi request received before current transfer ended, a response to the FPGA will cause it resend a signal if it has unread data in the FIFO.

     

    Test shows that the desing can work at most workload of the system.

     

    Thanks Randyp to give me advice how to detect the problem. And I learn a lot of dma knowledge in the discussion.