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.

MSP430FR5xxx: Using DMA with array in C

I'm trying to transfer blocks of data (stored in C arrays of type  static unsigned short, 16-bit) between memory and eUSCI using DMA on FR5xxx. I keep getting incorrect result. A debug run in Code Composer Studio shows that, the consecutive elements in arrays are stored in +2 memory locations, for example, array[0] is at 0x001CCC2, while array[1] is at 0x001CCC4 instead of 0x001CCC3, and so on... But according to the device user guide, in "block transfer" DMA moves data in +1 memory address. So I believe this is the problem. (However if I'm wrong, please correct me.)

So, what's the solution?

First it seems that DMA can't increment address by +2 in block transfer, so I need to arrange data in consecutive memory locations.

Does the way the array is stored have anything to do with compiler optimization setting? For example, if I increase compiler optimization setting, will the array elements be put consecutively in memory? (Both array "unsigned short" and memory are 16-bit, so it's possible?)

Or, should I change the array type to "static constant" or "unsigned 8-bit" or something else? (The actual data being transferred is only 8 bit)

Or, should I just write the data to a specified address in assembly line... However what's the correct format of specifying the starting address in assembly line? I can't find examples or specifications. For example if the starting address is 0x01CCC0, is the format            .ALIGN  0x01CCC0          followed by the data sequence?  And if I do this, is there any way to prevent C compiler from overwriting the data?

Thanks.

  • The DMA pointers increment by the sizes set with DMASRCBYTE and DMADSTBYTE.
  • OK so if I need to move the lower byte of data in memory to the lower byte of UCAxTXBUF, I should choose DMASRCBYTE and DMADSTBYTE to be both 1 right? However that's what I did, and it showed problem. Do you mean I should choose DMASRCBYTE and DMADSTBYTE to be both 0 in this case so DMA will increment in +2 address?
    And just to confirm... each memory address holds 16-bit data, right?
  • You can configure the DMA to transfer word- or bytewise. The UCAxTXBUF is an eight bit register that can only hold one byte. There is no high- or low-byte of that register. When using the DMA to transfer data to the TX buffer, then an address increment of +2 is the wrong way.
  • When you set DMASRCBYTE to 1 and DMADSTBYTE to 0, the DMA controller will read 16-bit words from the array, and then throw away the upper 8 bits of each entry when writing to TXBUF.
  • Zhongzhu Guo said:
    OK so if I need to move the lower byte of data in memory to the lower byte of UCAxTXBUF, I should choose DMASRCBYTE and DMADSTBYTE to be both 1 right? However that's what I did, and it showed problem. Do you mean I should choose DMASRCBYTE and DMADSTBYTE to be both 0 in this case so DMA will increment in +2 address?

    And just to confirm... each memory address holds 16-bit data, right?

    Based on your first post, you have 8-bit data values stored in the low byte of each 16-bit element of your source array. The appropriate configuration to write those values to TXBUF is (DMADSTBYTE | DMASRCINCR_3 | DMADSTINCR_0). That means 16-bit source data, increment source address (by 2 because the source is 16-bit), 8-bit destination (discard upper byte of source data) and leave destination unchanged.

    Unless you really need your source data in this form it would probably be better to change the source array to contain unsigned char rather than short. It'll take half as much memory that way.

    To answer your second question, each address holds 8-bit data. When accessing even addresses it's possible to read one byte from that address and one byte from the following odd address in a single 16-bit transfer.

  • Thank you very much, problem solved now.

**Attention** This is a public forum