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.

MSP430FR6007: DMA usage in 20Bit address room fails

Part Number: MSP430FR6007

Hi There,

I hat this topic, unfortunately it was closed: MSP430FR6007: crc_table function - MSP low-power microcontroller forum - MSP low-power microcontrollers - TI E2E support forums 

 

I boiled it now down to the 20 bit address room, my dma feeder works when Im 64kb address room in relation with the CRC module,

Unfortunately when I get in to extended address room 0x10000 it kills the system:

Basic question: Does the MSP430FR6007 DMA module support the extended address room?

    DMA_initParam cfg = {
        DMA_CHANNEL_0,                 // channelSelect
        DMA_TRANSFER_BLOCK,            // transferModeSelect
        static_cast<uint16_t>(length), // transferSize
        DMA_TRIGGERSOURCE_0,           // triggerSourceSelect
        DMA_SIZE_SRCBYTE_DSTBYTE,      // transferUnitSelect
        DMA_TRIGGER_RISINGEDGE         // triggerTypeSelect
    };

    DMA_init(&cfg);

    // Use proper 20-bit address handling
    // Convert pointers to 32-bit first to avoid truncation
    uint32_t volatile src_addr = reinterpret_cast<uint32_t>(src);
    uint32_t volatile dst_addr = reinterpret_cast<uint32_t>(dst);

    // Set the Source Address (20-bit)
    __data20_write_long((uint32_t)&DMA0SA, src_addr & 0xFFFFF);

    // Reset bits before setting them
    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) &= ~(DMASRCINCR_3);
    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) |= DMA_DIRECTION_INCREMENT;

    // Set the Destination Address (20-bit)
    __data20_write_long((uint32_t)&DMA0DA, dst_addr & 0xFFFFF);

    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) &= ~(DMADSTINCR_3);
    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) |= (DMA_DIRECTION_UNCHANGED << 2);

    // Clear DMA interrupt flag and start transfer
    DMA0CTL &= ~DMAIFG;
    DMA_enableTransfers(DMA_CHANNEL_0);
    DMA_startTransfer(DMA_CHANNEL_0);

    // Poll for completion
    while (!(DMA0CTL & DMAIFG))
    {
      __no_operation();
    }

    DMA_disableTransfers(DMA_CHANNEL_0);

 

  • The DMA hardware supports 20 bit addresses. The question is does the compiler generate the appropriate instructions for __data20_write_long?

  • the disassembly of the __data20_write_long. looks not too bad

    0x0001373a    1e 41 0a 00       mov    10(r1), r14      ;@>0000a
    0x0001373e    1f 41 0c 00       mov    12(r1), r15      ;@>0000c
    0x00013742    3e f3             and    #-1, r14         ;r3 As==11
    0x00013744    3f f0 0f 00       and    #15, r15         ;#0x000f
    0x00013748    8d 00 12 05       mova   r13, 1298        ;0x0512
    0x0001374c    8d 4e 00 00       mov    r14, 0(r13)      ;
    0x00013750    8d 4f 02 00       mov    r15, 2(r13)      ;

  • Nope, that is wrong.

    I was thrown by the usage of r13 but it turns out that disassembly is incorrect. 0x008d is not a move from register to absolute but a load immediate. 

    So this loads a 20 bit address into r13 (only 16 is needed) then uses two 16 bit writes to DMA0SA. It doesn't matter what order those happen in, the upper 16 bits will be zero.

    With GCC I get better results using __data16_write_addr()

  • good spot, first tests with the __data16_write_addre() are promising. I will do some further insights. I will close this when my tests are finished. thanks for now. 

  • The GCC documentation of the intrinsic support functions is thin so I looked for more. slau132 doesn't provide much more but it does include examples of code generated.

    Showing that the data20 function is useless with the DMA address registers.

**Attention** This is a public forum