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.

AM3517 External DMA not working

I am progamming a design based on the AM3517EVM, and I am having trouble with an external DMA request. I can do a Software-Triggered (Nonsynchronized) DMA Transfer, however, when I try and change it to a Hardware-Synchronized DMA Transfer, using sys_ndmareq1 pin, it does not work. The DMA controller behaves as if it is stalled/ "not seeing" the sys_ndmareq1 input. I followed all of the steps outlined below (doc: SPRUGR0C – October 2009 – Revised November 2013, pp.820). Any ideas would be greatly appreciated. Thanks! Kerry

7.5.3 Hardware-Synchronized Transfer
To monitor a hardware synchronized DMA transfer, initialize the SDMA.DMA4_CDACi register before the
software enable.
To configure an LCh to synchronize by element, packet, frame, or block, the frame synchronization
SDMA.DMA4_CCRi[5] FS bit and the block synchronization SDMA.DMA4_CCRi[18] BS bit register must
be programmed. For all the following synchronized transfers (element, packet, frame or block
synchronized transfers) User must set first : SDMA.DMA4_CCRi[24] SEL_SRC_DST_SYNC to 1 when the
source triggers on the DMA request and SDMA.DMA4_CCRi[24] SEL_SRC_DST_SYNC to 0 when the
Destination triggers on the DMA request. Note: User must take care when setting the
SDMA.DMA4_CCRi[23] PREFETCH bit it is in conjunction with SDMA.DMA4_CCRi[24]
SEL_SRC_DST_SYNC bit .
• To configure an LCh to transfer one element per DMA request:
1. Set the number of DMA request associated to the current LCH in the SDMA.DMA4_CCRi[20:19]
SYNCHRO_CONTROL_UPPER and SDMA.DMA4_CCRi[4:0] SYNCHRO bit field.
2. Set the data type, also referenced as element size (ES), in the SDMA.DMA4_CSDPi[1:0] DATA_TYPE
bit field.
3. Set the Read Port access type (single or burst access) in the SDMA.DMA4_CSDPi[8:7]
SRC_BURST_EN bit field.
4. Set the Write Port access type (single or burst access) in the SDMA.DMA4_CSDPi[15:14]
DST_BURST_EN bit field.
5. Set the Read Port addressing mode in the SDMA.DMA4_CCRi[13:12] SRC_AMODE bit field.
6. Set the Write Port addressing mode in the SDMA.DMA4_CCRi[15:14] DST_AMODE bit field.
7. Set the Read start address in the SDMA.DMA4_CSSAi[31:0] SRC_START_ADRS bit field.
8. Set the Write start address in the SDMA.DMA4_CDSAi[31:0] DST_START_ADRS bit field.
9. Set both FS and BS to 0 in SDMA.DMA4_CCRi[5] FS and SDMA.DMA4_CCRi[18] BS.
10. Set to 1 the channel enable bit SDMA.DMA4_CCRi[7] EN bit.

  • Have you checked that the pin muxing is configured correctly to select that function? Is the INPUTENABLE set for the pin mux register?
  • Brad,

    I have checked the pin configuration and Mode 1 (SYS_NDMAREQ1 input) is properly selected. 

    Register Name: CONTROL_PADCONF_GPMC_NCS3[31:16];  Physical Address: 0x480020B4 (+2);  Mode 0: gpmc_ncs4;  Mode 1: SYS_NDMAREQ1;  Mode 2: ---------------------;   Mode 3: gpt9_pwm_evt;  Mode 4: gpio_55.

    Is there something I should check next???


    Thanks!

    Kerry

  • Please report back the value of that register, i.e.. the full 32 bits from 0x4800 02B4.
  • The full 32 bits from 0x4800 20B4 is 0x0101 0118. For GPIO 55 (bits[31:16]), this should be: input enabled, no PU/PD and mode 1 (NDMAREQ1).
  • Looks good! What is the 32-bit value of CONTROL_DEVCONF0 at address 0x4800 2274?

    How did you program the channel's DMA4_CCRi register?
  • Here are my settings for synchronous DMA transfer on channel10:

    // set for synch transfer
    CONTROL_DEVCONF0 |= 0x3; //edge sensitive
    asm("nop");
    DMA4_CCR_CH10 |= 0x00000002; //0x2 = DMAREQ1
    asm("nop");
    DMA4_CCR_CH10 |= (1 << 24); //sync on source
    asm("nop");
    DMA4_CCR_CH10 |= (1 << 25); //buffering disable
    asm("nop");

    // set to zero for monitoring DMA
    DMA4_CDAC_CH10 = 0x00000000;
    asm("nop");
  • Is this through Linux or some kind of RTOS? Can you please read back the value of DMA4_CCR_CH10 at run-time to see the final value that ends up there? If I did my math correctly I believe the address is 0x48056440.

    Are you positive that nothing else has previously used the register for anything? Your code looks a bit dangerous, i.e. it seems to implicitly assume the value of the register is zero. It seems overkill to perform a bunch of read-modify-writes on the register itself. In my opinion you would be better off to do something like:

    reg_val = 0;
    reg_val |= 0x00000002; //0x2 = DMAREQ1
    reg_val |= (1 << 24); //sync on source
    reg_val |= (1 << 25); //buffering disable
    DMA4_CCR_CH10 = reg_val;
  • Some good news, my colleague was able to get the synchronous DMA working on his prototype board. I will run his code and mine and hopefully identify the root cause of the problem. I will post to this thread as soon as I have results. Thanks for your help! Kerry
  • Brad,

    I was able to trace my issue to the programming of the DMA4_CCRi register.
    To enable the S_DMA_1 request, for example, SDMA.DMA4_CCRi[4:0] SYNCHRO_CONTROL must be set to 0x2
    DMA request number + 1.

    For my application:
    DMA Source = SYS_DMA_REQ1
    DMA Request Line = S_DMA_2
    DMA Request Number = 2
    SDMA.DMA4_CCRi[4:0] SYNCHRO_CONTROL = 0x03 (DMA Request Number + 1)
    ( <-- I had mistakenly set the SDMA.DMA4_CCRi[4:0] to 0x02)

    Thanks for your help!
    Kerry

    Information from doc: SPRUGR0C – October 2009 – Revised November 2013
    ================================================================
    Table 7-3. SDMA Request Mapping
    DMA Request Number - DMA Request Line - DMA Source - Description
    1 - S_DMA_1 - SYS_DMA_REQ0 - External DMA request 0 (system expansion)
    2 - S_DMA_2 - SYS_DMA_REQ1 - External DMA request 1 (system expansion)

    NOTE: DMA Request Line
    A DMA request line must not be shared between concurrently enabled DMA channels.
    However, a DMA request line can be shared between several chained logical channels.
    The channel synchronization control registers are 1-based. For example, to enable the
    S_DMA_1 request, SDMA.DMA4_CCRi[4:0] SYNCHRO_CONTROL must be set to 0x2
    (DMA request number + 1).