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.

DM36x EDMA problem for linking mode

Hi all,

I am trying to do a funny EDMA transfer between two memory buffers as shown in the following figure (a):

The idea is to copy the entire buffer to another one but swapping the bytes. In order to achieve this I implemented a ABC transfers using chaining so I can do this by copying first all the even bytes and then the odd bytes as shown in the figure (b). My EDMA configuration for this copy task is as follows:

paramsets[paramsetid].opt = (9 << 20) | (tcc << 12) | (1 << 2);
paramsets[paramsetid].src = (int)inPhysBuf + 1;
paramsets[paramsetid].dst = (int)outPhysBuf;

paramsets[paramsetid].acnt_bcnt = (W/2 << 16) | 0x01;  // We transfer 1 byte W/2 times per line
paramsets[paramsetid].srcbidx_dstbidx = (0x02 << 16) | 0x02;  // We jump 2 bytes per A transfer
paramsets[paramsetid].link_bcntrld = 0xFFFF; /* Avoid to link */
paramsets[paramsetid].srccidx_dstcidx = (W << 16) | W;

paramsets[paramsetid].ccnt = H;

edma_registers[esr_reg] = edma_registers[esr_reg] | (1 << channel_bit);

/* Wait for completion */
while (!(edma_registers[ipr_reg] & (1 << tcc_bit))) {

}

This code works fine for me and it does copy one even-bytes (A1,B1,...) sequence so it is necessary to duplicate this code for the odd-bytes (A2,B2,...) sequence. Note I had to use a while loop to check for the copy completion, I am wondering if there is another way to do this with the EDMA Manager API that comes with Linuxutils.

In order to avoid to copy this code twice I decided to link the PaRAM so when it finishes to copy the odd-bytes sequence  automatically loads a new PaRAM set for the even-bytes sequence. So my new code is as follows:

// This is the PaRAM we are going to load (PaRAM 65)

paramsets[65].opt = (9 << 20) | (tcc << 12) | (1 << 2);
paramsets[65].src = (int)inPhysBuf;  // See now we are copying the even
paramsets[65].dst = (int)outPhysBuf + 1 ;

paramsets[65].acnt_bcnt = (W/2 << 16) | 0x01;  // We transfer 1 byte W/2 times per line
paramsets[65].srcbidx_dstbidx = (0x02 << 16) | 0x02;  // We jump 2 bytes per A transfer
paramsets[65].link_bcntrld = 0xFFFF; /* Avoid to link */
paramsets[65].srccidx_dstcidx = (W << 16) | W;

paramsets[65].ccnt = H;

// This is the initial PaRAM, we are linking to PaRAM 65 

paramsets[paramsetid].opt = (9 << 20) | (tcc << 12) | (1 << 2);
paramsets[paramsetid].src = (int)inPhysBuf + 1;
paramsets[paramsetid].dst = (int)outPhysBuf;

paramsets[paramsetid].acnt_bcnt = (W/2 << 16) | 0x01;  // We transfer 1 byte W/2 times per line
paramsets[paramsetid].srcbidx_dstbidx = (0x02 << 16) | 0x02;  // We jump 2 bytes per A transfer
paramsets[paramsetid].link_bcntrld = 0x4820; /* Avoid to link */
paramsets[paramsetid].srccidx_dstcidx = (W << 16) | W;

paramsets[paramsetid].ccnt = H;

edma_registers[esr_reg] = edma_registers[esr_reg] | (1 << channel_bit);

/* Wait for completion */
while (!(edma_registers[ipr_reg] & (1 << tcc_bit))) {

}

This code does not crash at all but it seems like only the first PaRAM is being executed since the second copy is not noticeable in the buffer.  As an example there is an output of the first 25 bytes on the buffers before and after the copy

  • Source buffer

80 10 7f 10 80 10 7f 10 7f 10 7f 10 7f 10 7f 10 7f 10 7f 10 7f 10 7f 10 7f

  • Target buffer before the EDMA copy

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

  • Target buffer after the EDMA copy

10 0 10 0 10 0 10 0 10 0 10 0 10 0 10 0 10 0 10 0 10 0 10 0 10

So the even bytes are not being copied.

Some of the examples in the EDMA User's Guide (sprufi0) uses this linking mode but they seems not to use the C dimension, is that possible to achieve? Am I missing something in the OPT register?

Thanks in advance,

Marco

  • Hi all,

    I found the error! After we were polling for the completion bit in the IPR register it is necessary to trigger the event again in the ESR register to start the new transfer with the new PaRAM set (obviously we need to clear the completion bit before start the new transfer). This works, however polling for the completion is not at all a good idea, I am using the EDMA Manager API from a user space application so I don't have direct access to the EDMA interruption, is there a way to wait for the completion in a more efficient way using this API?

    Best Regards,

    Marco

  • Hi,

    I am closing this issue since I found the fix, however I am going to open a new post regarding the completion notification.

    Best Regards,

    Marco