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.

TM4C123GH6PM: uDMAChannelTransferSet sets unaligned end address

Part Number: TM4C123GH6PM


Hi,

according to the manual uDMA source/destination end pointers are inclusive I understand that it should point to last address in buffer. 

In Tiva C driver sources those addresses are calculated as following:

pvSrcAddr = (void *)((uint32_t)pvSrcAddr + ui32BufferBytes - 1);

...

pvDstAddr = (void *)((uint32_t)pvDstAddr + ui32BufferBytes - 1);

That is correct for byte transfers but in case half-word or word transfers resulting address will be unaligned. Is that important to set address end pointers in channel control structure aligned according to address increment?

thanks,

Dmitri

  • Hi,

    Is that important to set address end pointers in channel control structure aligned according to address increment?

    Yes, The addresses should be aligned to the item size. Please see below description.

  • So uDMAChannelTransferSet calculates wrong address which is not aligned to the item size in case of half-word or word transfers.

  • Please look at how ui32BufferBytes is calculated. ui32BufferBytes is based on ui32TransferSize adjusted for the item size. Let's say the item size is half-word. This means ui32Inc will be 0x1. Refer to the datasheet description. If you are going to transfer only item then ui32BufferBytes will be 1 << 1 which becomes 2. If you are going to transfer 5 items then ui32BufferBytes will be 5 << 1 which is 10. As you can see ui32BufferBytes value will be aligned to the half-word, whether ui32BufferBytes is 2 or 10. If the item size is a word then ui32Inc will be 0x2 and there will be left shift by 2 to perform. Transfer size of 1 item will give ui32BufferBytes equal to 4 and 5 items will result ui32BufferBytes equal to 20 and either 4 or 20 and therefore the final pvSrcAddr will be aligned to word address. 

    if(ui32Inc != UDMA_SRC_INC_NONE)
    {
    ui32Inc = ui32Inc >> 26;
    ui32BufferBytes = ui32TransferSize << ui32Inc;
    pvSrcAddr = (void *)((uint32_t)pvSrcAddr + ui32BufferBytes - 1);
    }

  • Thanks but what I still do not understand that is "-1" for address calculation. Suppose we have to transfer 5 half words and pvSrcAddr  becomes (5 <<1) - 1 = 9 but the address of the last half word is 8. So the question what would be correct end address 8 or 9 for that case?

  • I think the line of code is merely to program the end address to the uDMA control table. Let's suppose the beginning of the source address is 0x20000000 and you are trying to transfer 5 items of 32-bit word. What is the end address? The end address is 0x20000000 + (5 << 2) - 1 which 0x20000013. Take for another example with 16 items of 16-bit half word transfers. The end address is 0x20000000 + ( 16 << 1) - 1 which is 0x2000001F. It is the beginning of the source or destination address that needs to align with its size, not the ending address for which to be programmed to the control table. See below. As the transfer is on going the end address pointer is used for comparison if the transfer has reached the end. 

  • Ok. My confusion was that I looked at last address used during transfer that is not equal to end address.

    For 5 words transfer addresses on internal bus will be:

    0x20000000

    0x20000004

    0x20000008

    0x2000000c

    0x20000010 <- last word transferred but end address is 0x20000013

    For 16 half words:

    0x20000000

    0x20000002

    0x20000004

    ....

    0x2000001E <- last half word but end address is 0x2000001F