cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F334 Burst DMA

robertj.stuart9
Associate
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.

2 REPLIES 2
robertj.stuart9
Associate
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 II
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