DMA Offset

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hello,

   

I have a doubt about configuring a DMA with two TDs. For example, the first TD (TD[0]) goes from position 0 to 63 of an array, when it finishes, it switches to TD[1], where it goes from 64 to 128 of that same array. The first part is done correctly, however, the second part, the DMA is not transferring correctly the array's data.

   

I have set up the configuration as below:

   

-------------------------------------------------------------------------------------------------------------------------------------

   

CyDmaTdSetConfiguration(dmaDescriptor[0],

   

        TEXT_MESSAGE_LENGTH*2, dmaDescriptor[1],

   

        (TD_INC_SRC_ADR | DMA_1__TD_TERMOUT_EN));

   

    

   

    CyDmaTdSetConfiguration(dmaDescriptor[1],

   

        TEXT_MESSAGE_LENGTH*2, dmaDescriptor[0],

   

        (TD_INC_SRC_ADR | DMA_1__TD_TERMOUT_EN));

   

 

   

    CyDmaTdSetAddress(dmaDescriptor[0],

   

        LO16((uint32)textMessage), LO16((uint32)UART_1_TXDATA_PTR));

   

    CyDmaTdSetAddress(dmaDescriptor[1],

   

 

   

        LO16((textMessage[TEXT_MESSAGE_LENGTH])), LO16((uint32)UART_1_TXDATA_PTR));

   

-------------------------------------------------------------------------------------------------------------------------------------

   

I think that the problem is that I didn't set up the offset correctly (I have tried using pointers also).

   

Thank you in advance

   

Chang

0 Likes
4 Replies
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

When I read your code right, each TD transfers TEXT_MESSAGE_LENGTH*2 bytes. But you set the address of the second TD with an offset of just TEXT_MESSAGE_LENGTH to the beginning of the textMessage array. This means the two TDs overlap by TEXT_MESSAGE_LENGTH bytes.

0 Likes
Anonymous
Not applicable

I have changed the length of the TD, but  I am also I am getting strange output for the second half of the array.

0 Likes
Anonymous
Not applicable

 I was able to figure it out. The reason was that the source address (in this case) is a memory address, so to give the address of that position we should put '&':

   

------------------------------------------------------------------------------------------------------------------------------------------------------------

   

CyDmaTdSetAddress(dmaDescriptor[0],

   

        LO16((uint32)textMessage), LO16((uint32)UART_1_TXDATA_PTR));

   

CyDmaTdSetAddress(dmaDescriptor[1],

   

 

   

        LO16((uint32)(&textMessage[TEXT_MESSAGE_LENGTH])), LO16((uint32)UART_1_TXDATA_PTR));

   

------------------------------------------------------------------------------------------------------------------------------------------------------------

   

 

   

Chang

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Ah, the wonders of C pointer handling 🙂

0 Likes