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.

About the useage of EDMA in DM8127



hi all,

      I want to add my DSP algorithm in alg_link using IPNC_RDK3.0,I want to move a few lines of frame from DDR3 to L2_ram to process.then return the data back to ddr3, I tried memcpy() API,but it costs so much time.

Fortunately I find 8127 EDMA API in the dir...\ipnc_rdk\ipnc_mcfw\mcfw\src_bios6 \links_c6xdsp\va\valink_alg.c. In Func VaLink_algCopyFrames() it called the EDMA api, The code has showed below:

/* copy the frame */   

edmaWidth  = pObj->inQueInfo.chInfo[0].width;    

edmaHeight = pObj->inQueInfo.chInfo[0].height;           

  /* copy Y plane */    

DM81XX_EDMA3_setParams(VA_LINK_EDMA3_CH_ID,    // chId                                   

                                                  VA_LINK_EDMA3_QUEUE_ID,    // dmaQueue                                  

                                                  (UInt32)pFullFrame->addr[0][0],  // srcAddr                                  

                                                  (UInt32)pEmptyFrame->addr[0][0], // dstAddr                                  

                                                    edmaWidth,              // edmaWidth                                  

                                                   edmaHeight,             // edmaHeight                                  

                                                   edmaWidth,              // srcLineOffset                                  

                                                   edmaWidth);             // dstLineOffset

/* Trigger the edma transfer */    

DM81XX_EDMA3_triggerTransfer(VA_LINK_EDMA3_CH_ID);        

pEmptyFrame->timeStamp = pFullFrame->timeStamp;

 

 

 

Then I add the code to the the Alglink_priv.c:

Int32 AlgLink_algProcessData(AlgLink_Obj * pObj)

{

    extern unsigned char *frame_buffer; //frame_buffer大小为2048*1280;开辟在在DDR 的SR2上

    unsigned char * current_frame;

     unsigned char * temp;

     int edmaWidth = 2048;

     int edmaHeight = 1280;

     UInt32 frameId, status;   

     System_LinkInQueParams *pInQueParams;   

     FVID2_Frame *pFrame;

    FVID2_FrameList frameList;

     pInQueParams = &pObj->createArgs.inQueParams;  

    System_getLinksFullFrames(pInQueParams->prevLinkId,                            

    pInQueParams->prevLinkQueId, &frameList);

    if (frameList.numFrames)  

     {      

  /* SCD should be done first as it requires to operate on raw YUV */   

     if (pObj->createArgs.enableSCDAlg)      {           

             status =   AlgLink_ScdalgProcessData(&pObj->scdAlg, &frameList, &pObj->outObj[0].bufOutQue);

            if (status == FVID2_SOK)             {              

                 /* Send-out the output bitbuffer */               

               System_sendLinkCmd(pObj->createArgs.outQueParams.nextLink,                                  

                SYSTEM_CMD_NEW_DATA); 

        }

     }

        for(frameId=0; frameId<frameList.numFrames; frameId++)         {           

        pFrame = frameList.frames[frameId];

            if(pFrame->channelNum >= pObj->inQueInfo.numCh)               

             continue;

//*************************************add my alg ****************************//

/* copy the frame */   

edmaWidth  = pObj->inQueInfo.chInfo[0].width;   

edmaHeight = pObj->inQueInfo.chInfo[0].height;          

  /* copy Y plane */   

DM81XX_EDMA3_setParams(VA_LINK_EDMA3_CH_ID,    // chId                                   

                                                  VA_LINK_EDMA3_QUEUE_ID,    // dmaQueue                                 

                                                  (UInt32)pFrame->addr[0][0],  // srcAddr                                 

                                                  (UInt32)(frame_buffer), // dstAddr                                 

                                                    edmaWidth,              // edmaWidth                                  

                                                   edmaHeight,             // edmaHeight                                 

                                                   edmaWidth,              // srcLineOffset                                 

                                                   edmaWidth);             // dstLineOffset

/* Trigger the edma transfer */   

DM81XX_EDMA3_triggerTransfer(VA_LINK_EDMA3_CH_ID);       

pEmptyFrame->timeStamp = pFullFrame->timeStamp;

//Determine  data movement  error or not

  current_frame = (unsigned char *)pFrame->addr[0][0];

   temp = frame_buffer;

  for(i=0;i<2048*1280;i++){

   if(*temp !=*current_frame)

    Vps_printf("wrong!!!!!!!");

   current_frame++;

  temp++;

}

//********************************************************************************//

            // do SW OSD           

if (pObj->createArgs.enableOSDAlg)             {   

            AlgLink_OsdalgProcessFrame(&pObj->osdAlg, pFrame);           

              }       

          }       

     System_putLinksEmptyFrames(pInQueParams->prevLinkId,                                  

      pInQueParams->prevLinkQueId, &frameList);  

  }

       return FVID2_SOK;

}

 

After compile and run I found the mistake about DMA transfer. The data in src addr and dest addr is different.

I am sure the frame size is 2048*1280,and I run the fullfeature mode ,valink is not running;this DMA channel would

be unused.So what's wrong with it?Is sth wrong about my EDMA configuration?Have you used EDMA transfer  in

8127before? If you have,please tell me how to do it.Thank you very much!!

regards

                                                                                                            Chase Yan

  • Hi,

    Can you print the edmaWidth and edmaHeight just before DM81XX_EDMA3_setParams() API call?

    regards,

    Anand

  • Anand,

       Thanks for your reply.I have printed  edmaWidth and edmaHeifght:

    edmaWidth  = pObj->inQueInfo.chInfo[0].width;  (1920)   

    edmaHeight = pObj->inQueInfo.chInfo[0].height;  (1080)

    but when running AlgLink_algProcessData(),I printed the pFrame->addr[0][0],  It's print four address periotically

    so I guess There  must be a buffer which stores  four frames  each time. and  the interval of adjacent address is

    0x180000; I found the format of frame is YUV420,so I compute The framesize is 2048*1080. I tried both

     edmaWidth = 2048, edmaHeight = 1280 and edmaWidth = 1920,edmaHeight =1080; But the data transfer is still

    incorrect,I'm so confused what's wrong about it .can you give me some advise?Thanks!

      regards

                                                                                                                                  chase yan

  • Hi,

    Do you still have the following code marked in RED?

     

    /* copy the frame */   

    edmaWidth  = pObj->inQueInfo.chInfo[0].width;   

    edmaHeight = pObj->inQueInfo.chInfo[0].height;          

      /* copy Y plane */   

    DM81XX_EDMA3_setParams(VA_LINK_EDMA3_CH_ID,    // chId                                   

                                                      VA_LINK_EDMA3_QUEUE_ID,    // dmaQueue                                 

                                                      (UInt32)pFrame->addr[0][0],  // srcAddr                                 

                                                      (UInt32)(frame_buffer), // dstAddr                                 

                                                        edmaWidth,              // edmaWidth                                  

                                                       edmaHeight,             // edmaHeight                                 

                                                       edmaWidth,              // srcLineOffset                                 

                                                       edmaWidth);             // dstLineOffset

    /* Trigger the edma transfer */   

    DM81XX_EDMA3_triggerTransfer(VA_LINK_EDMA3_CH_ID);       

    regards,

    Anand

  • Anand,

           I shielded this two lines and directly use variable assignment just like

         edmaWidth = 2048;

         edmaHeight = 1280;

        memcpy() can be called correctly.but it costs so much time.

        I thik there are two aspects that may cause this EDMA problems 

       1. frame size is incorrent;

        2. Va_Link_EDMA3_CH(channel 8)  might have been used.

        but I have make many experiments to change edmaWidth and Height, and also EDMA channel ID,the problem

        still exists. I am so confused about it...any suggestion?

           regards

                                                                            chase yan

                        

                                                        

  • Hi,

    The destnation memory may be cached.

    Can you print the address of 'frame_buffer' and also send me your '../ipnc_rdk/ipnc_mcfw/mcfw/src_bios6/cfg/ti814x/FC_RMAN_IRES_c6xdsp.cfg' file?

    Pl. do cache write back after EDMA transfer using the following call:

    Cache_wb(frame_buffer,(2048 * 1280),Cache_Type_ALL,TRUE);

    regards,

    Anand

  • Anand,

         The address of frame_buffer is 0xbc779500, The four addresses  of pFrame->addr[0][0] is

    0xbb879500 ,  0xbbc39500 ,   0xbbff9500,   0xbc3b9500;Here is my config file:

     7028.FC_RMAN_IRES_c6xdsp.cfg

    as you have said,I made the frame_buffer cachable in my codes. so I add two lines in my codes: 

    Cache_wb(pFrame->addr[0][0], 2048*1280, Cache_Type_ALL,  TRUE);    

     Cache_inv(frame_buffer, 2048*1280, Cache_Type_ALL, TRUE);

    It works!!I The problem is caused by cache coherency ,Thank you  Anand!! 

    regards

                                                                                    chase yan