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.

Using DMA to write to GPIO?

Is it possible to use the DMA controller to write GPIO pins?

When I set the number of DMA transfers = 1, the transfer to Pin 4 seems to work. However, whenever I set the number of transfers > 1, there is no effect on Pin 4.

Why is this, and what am I doing wrong? I am trying to utilize the DMA to output a sine wave lookup table to pin 4 as quickly as possible.

  • What's the DMA trigger? And is your code really so top-secret that you cannot show it?
  • Hi, Sorry about that. I actually fixed my problem, but have one more question if you have a sec. My code is shown below.

    I enabled the DMA to be triggered based off the timer interrupts. However, it only seems to be triggered ONE time...unless I uncomment the code shown in the dma_1_interrupt function. By resetting up the DMA transfer, it will run again on the next timer trigger.

    How can I change my DMA code to perform a DMA transfer on every timer trigger?

    void DMA_Init() {
    DMA_enableModule();
    DMA_setControlBase(controlTable);
    DMA_assignChannel(DMA_CH0_TIMERA0CCR0);
    DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_TIMERA0CCR0,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_128);
    DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_TIMERA0CCR0, UDMA_MODE_AUTO, DAC_TABLE, P4POINT, 128);
    DMA_enableChannel(0);
    DMA_assignInterrupt(DMA_INT1, 0);
    Interrupt_enableInterrupt(INT_DMA_INT1);
    }

    ...

    void dma_1_interrupt(void)
    {
    //DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_TIMERA0CCR0, UDMA_MODE_AUTO, DAC_TABLE, P4POINT, 128);
    ///DMA_enableChannel(0);
    }
  • Additionally, this is my Timer config code.


    const Timer_A_UpModeConfig upConfig =
    {
    TIMER_A_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
    TIMER_A_CLOCKSOURCE_DIVIDER_1, // SMCLK/1 = 3MHz
    5000, // 5000 tick period
    TIMER_A_TAIE_INTERRUPT_DISABLE, // Disable Timer interrupt
    TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE// ,
    };

    void TimerA_Init() {
    Timer_A_configureUpMode(TIMER_A0_MODULE, &upConfig);
    }
  • It would be helpful to note which MCU you're using.

    I don't know anything about the ARM µDMA (and the Reference Manual isn't exactly helping), but it might be possible you need not auto mode but basic mode.

  • the docs for DMA_enableChannel  ( driverlib/MSP432P4xx/dma.h) say:


    //! When a DMA transfer is completed, the channel is automatically disabled by
    //! the DMA controller. Therefore, this function should be called prior to
    //! starting up any new transfer.

**Attention** This is a public forum