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.

AM335X DMA transfer questions

Hi:

I got an AM335X EVM,and now I'm trying to use DMA to transfer data between memory and  a 16bit FIFO(word-expansion).The FIFO chip is IDT7205L20J and it's data bus DQ[0-15] connect to GPMC AD[0-15].Since the FIFO could not generates DMA transfer request, I plan to use the GPMC+DMA method.My questions are:

1.Is it possible to achieve my goal?The TRM says the GPMC could generate one DMA event.

2.If possible,how should I confiure the GPMC? device type NAND or NOR?burst support?multiple access support?read/write type Asynchronous or Synchronous?

3.Does GPMC has a specific DMA channel?e.g. channel 52.Or shall I allocate one for it?

4.I'm trying to use AB-Synchronized Transfer type defined by the EDMA3(section 11.3.2.2 in TRM).To genrate transfer completion interrupt, CCNT(number of frames) events are needed to completely service a PaRAM set.Does that mean CCNT transfer requests must be summitted to the EDMA?If so, are the transfer requests generated by the attached device?that is,the FIFO,or the GPMC servicing the FIFO?

Confusing about this and need suggestions...

  • Following is my experiment using DMA transfer from memory to memory.It's primary purpose is to copy 1K bytes data from source buffer to dest buffer.

    unsigned char *dest_buf;

    unsigned char *src_buf;

    // alloc 1K bytes memory for both  dest_buf and src_buf

    dest_addr = dma_map_single(&(pdev->dev), dest_buf, BUF_SIZE, DMA_FROM_DEVICE);

    src_addr = dma_map_single(&(pdev->dev), src_buf, BUF_SIZE, DMA_TO_DEVICE);

    /* allocate edma channel */
    channel = edma_alloc_channel(AM33XX_DMA_GPM, fifo_dma_cb, &dma_completion, EVENTQ_2);
    if (channel < 0)
    {
        printk("DMA request failed!\n");
        return -1;
    }

    /* dma transfer completion interrupt enable*/
    edma_read_slot(channel, &p_ram);
    p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(channel) );
    edma_write_slot(channel,&p_ram);

    ...

    dma_sync_single_for_device(&(pdev->dev), src_addr, BUF_SIZE, DMA_TO_DEVICE);

    /* set destination paRAM */

    edma_set_dest(channel, dest_addr, INCR, W16BIT);
    edma_set_dest_index(channel, 2, 1024);

    /* set source paRAM */

    edma_set_src(channel, src_addr, INCR, W16BIT);
    edma_set_src_index(channel, 2, 1024);

    /*acnt=2,bcnt=512,ccnt=1,transfer type = AB-Synchronized*/
    edma_set_transfer_params(channel, 2, 512, 1, 1, ABSYNC);

    edma_start(channel);

     wait_for_completion(&dma_completion);

    dma_sync_single_for_cpu(&(pdev->dev),dest_addr, BUF_SIZE, DMA_FROM_DEVICE);


    It works well.Transfer completion was detected and the callback function executed.But if I change the tansfer paramters as follow:

    edma_set_transfer_params(channel, 2, 32, 16, 1, ABSYNC);

    then no transfer completion detected;the callback function didn't work.It appears only the first 64 bytes data were correctly transfered.What's wrong?


  • Hi,

    It looks like the problem you are having is related to setting CCNT>1. This is a 3D transfer, and requires that the transfer needs to get re-triggerred at the end of each 'frame'. That's why you are seeing the first frame getting transfered and without any subsequent triggers what you see is what is expected.

    You can accomplish what you are trying to do with a single 'start' by setting the OPT word's ITTCHEN bit, which will cause intermediate transfers that count down the CCNT to self-trigger and do  the full 3D transfer. Also make sure the STATIC bit of OPT word is set to OFF.

    Murat

  • raormanrat,

    many thanks!

    I've set the OPT word's ITCCHEN bit and cleared the STATIC bit.The 3D transfer then acts exactly what I expected.Problem resovled.

  • Great, thanks for reporting that your problem got solved and this can be marked 'resolved'.