Skip to main content
robertj.stuart9
Associate
July 27, 2016
Question

STM32F334 Burst DMA

  • July 27, 2016
  • 2 replies
  • 940 views
Posted on July 27, 2016 at 02:33

I have been trying to get the burst DMA working across Timers on the STM32F334 without success.

The reference manual has;

The burst DMA mode is permanently enabled (there is no enable bit). A burst DMA

operation is started by the first write access into the HRTIM_BDMADR register.

It is only necessary to have the DMA controller pointing to the HRTIM_BDMADR register as

the destination, in the memory, to the peripheral configuration with the peripheral increment

mode disabled (the HRTIM handles internally the data re-routing to the final destination

register).

I have put together the following code for the DMA

DMA_InitTypeDef     DMA_InitStruct;

// Enable DMA1 clock

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

// setup dma to point to HRTIM_BDMADR, using TIMERA dma channel

DMA_DeInit(DMA1_Channel3);

DMA_InitStruct.DMA_PeripheralBaseAddr    =  (uint32_t)&HRTIM1_COMMON->BDMADR;

DMA_InitStruct.DMA_MemoryBaseAddr        = (uint32_t)u32a_burst_dma_buf;

DMA_InitStruct.DMA_DIR                    = DMA_DIR_PeripheralDST;

DMA_InitStruct.DMA_BufferSize            = BURST_DMA_SIZE;

DMA_InitStruct.DMA_PeripheralInc        = DMA_PeripheralInc_Disable;

DMA_InitStruct.DMA_MemoryInc            = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_Word;

DMA_InitStruct.DMA_MemoryDataSize        = DMA_MemoryDataSize_Word;

DMA_InitStruct.DMA_Mode                    = DMA_Mode_Normal;

DMA_InitStruct.DMA_Priority                = DMA_Priority_Low;

DMA_InitStruct.DMA_M2M                    = DMA_M2M_Disable;

DMA_Init(DMA1_Channel3, &DMA_InitStruct);

// DMA1 Channel3 enable

DMA_Cmd(DMA1_Channel3, ENABLE);

// not sure about this....

HRTIM_DMACmd(HRTIM1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_TIM_DMA_RST, ENABLE);

// registers to be updated in burst-dma mode

HRTIM_BurstDMAConfig(HRTIM1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_BURSTDMA_CMP1 | HRTIM_BURSTDMA_CMP2 | HRTIM_BURSTDMA_CMP3 | HRTIM_BURSTDMA_CMP4);

HRTIM_BurstDMAConfig(HRTIM1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_BURSTDMA_CMP1 | HRTIM_BURSTDMA_CMP2);

At runtime

u32a_burst_dma_buf[0]        = 100;

u32a_burst_dma_buf[1]        = 200;

u32a_burst_dma_buf[2]        = 300;

u32a_burst_dma_buf[3]        = 400;

u32a_burst_dma_buf[4]        = 500;

u32a_burst_dma_buf[5]        = 600;

// disable DMA

DMA_Cmd(DMA1_Channel3, DISABLE);

// set the number of bytes to transmit

DMA_SetCurrDataCounter(DMA1_Channel3, BURST_DMA_SIZE);

// enable DMA

DMA_Cmd(DMA1_Channel3, ENABLE);

// not sure about this

HRTIM1_COMMON->BDMADR=0xFFFF;

I the outputs work fine when I update the registers from an interrupt, but it would be better to go thru the DMA. I have not been able to find an examples within STM32CubeMX, so any suggestions would be appreciated.

    This topic has been closed for replies.

    2 replies

    robertj.stuart9
    Associate
    August 1, 2016
    Posted on August 01, 2016 at 07:58

    Here is a solution

    static void     fv_htim_brust_dma_setup(void)

    {

        DMA_InitTypeDef         DMA_InitStruct;

        NVIC_InitTypeDef        NVIC_InitStruct;

        // Enable DMA1 clock

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

        // DMA1 Channel3 enable

        DMA_Cmd(DMA1_Channel3, ENABLE);

        // setup dma to point to HRTIM_BDMADR, using TIMERA dma channel

        DMA_DeInit(DMA1_Channel3);

        DMA_InitStruct.DMA_PeripheralBaseAddr    = (uint32_t)&HRTIM1_COMMON->BDMADR;

        DMA_InitStruct.DMA_MemoryBaseAddr        = (uint32_t)u32a_burst_dma_buf;

        DMA_InitStruct.DMA_DIR                    = DMA_DIR_PeripheralDST;

        DMA_InitStruct.DMA_BufferSize            = BURST_DMA_SIZE;

        DMA_InitStruct.DMA_PeripheralInc        = DMA_PeripheralInc_Disable;

        DMA_InitStruct.DMA_MemoryInc            = DMA_MemoryInc_Enable;

        DMA_InitStruct.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_Word;

        DMA_InitStruct.DMA_MemoryDataSize        = DMA_MemoryDataSize_Word;

        DMA_InitStruct.DMA_Mode                    = DMA_Mode_Normal;

        DMA_InitStruct.DMA_Priority                = DMA_Priority_Low;

        DMA_InitStruct.DMA_M2M                    = DMA_M2M_Disable;

        DMA_Init(DMA1_Channel3, &DMA_InitStruct);

        // registers to be updated in burst-dma mode

        HRTIM_BurstDMAConfig(HRTIM1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_BURSTDMA_CMP1 | HRTIM_BURSTDMA_CMP2 | HRTIM_BURSTDMA_CMP3 | HRTIM_BURSTDMA_CMP4);

        HRTIM_BurstDMAConfig(HRTIM1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_BURSTDMA_CMP1 | HRTIM_BURSTDMA_CMP2);

        // Enable DMA1 channel1 IRQ Channel

        NVIC_InitStruct.NVIC_IRQChannel                     = DMA1_Channel3_IRQn;

        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority     = 0;

        NVIC_InitStruct.NVIC_IRQChannelSubPriority             = 0;

        NVIC_InitStruct.NVIC_IRQChannelCmd                     = ENABLE;

        NVIC_Init(&NVIC_InitStruct);

    }

    In your control-loop

        // diable burst dma mode before updating registers

        NVIC_DisableIRQ(HRTIM1_TIMA_IRQn);

        // update the registers into the dma array

        u32a_burst_dma_buf[0]        = u16_S12_lo_FET_Ton;

        u32a_burst_dma_buf[1]        = u16_S12_lo_FET_Toff;

        u32a_burst_dma_buf[2]        = u16_ADC_trigger;

        u32a_burst_dma_buf[3]        = u16_ZDC1_blanking;

        u32a_burst_dma_buf[4]        = u16_S12_hi_FET_Ton;

        u32a_burst_dma_buf[5]        = u16_S12_hi_FET_Toff;

        // enable burst dma mode to update all registers at once

        NVIC_EnableIRQ(HRTIM1_TIMA_IRQn);

    J L
    Associate
    November 4, 2017
    Posted on November 04, 2017 at 08:00

    Hi S.r ,

    Do you have a full sample HRTIM code with DMA? I stuck on HRTIM register updated by DMA.

    Thanks,

    J.L