cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 DMA multiple streams

Francois Alexandre
Associate II
Posted on November 06, 2017 at 17:03

Hello,

In my custom design am using a STM32F767BITx. Am using an output compare at 5Mghz to trigger the DMA2 and get data from a gpio Port, in circular mode.

Am using the DMA_Stream2 and channel 7, DMA_PERIPH_TO_MEMORY, for this particular stream.

This works fine, i get correct datas.

However, i would like to use another in the same time to use another timer, channel and stream to send data to another GPIO using DMA2 at about 8Mghz

I read through the documentations and it's not clear for me if I can use another stream of DMA2 while the DMA2 if this one is use by another channel in circular mode.

So my question is simple can we use several stream of the same dma if one of them is in circular mode if the frequency of filling datas is less 10Mghz?

thanks for any advice

3 REPLIES 3
Posted on November 06, 2017 at 17:14

Each stream is independent so multiple can run concurrently until you run out of bandwidth.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Francois Alexandre
Associate II
Posted on November 10, 2017 at 16:32

Ok thanks you for your reply,

However it doesn't seem to work with my application. I think, I missed something, but I don't know what...

I have 2 streams for DMAs running in the same with the same frequency, they are both in circular mode

I have TIM8 triggering the DMA2 in to read data at 5mghz onto two GPIO port  GPIOG &  GPIOF

1: DMA2_Stream2, DMA_CHANNEL_7 for GPIOG

1: DMA2_Stream3, DMA_CHANNEL_7 for GPIOF

PROBLEM:

If i start 2 streams the transfer last twice the time compare to the time if just one stream is enable.

Here is my code TIMER 8 configuration:

    /* Compute the prescaler value to have TIMx counter clock equal to 100 MHz */

    uwPrescalerValue = ((SystemCoreClock) / (100000000)) - 1;

  

    htim8.Instance             = TIM8;

    htim8.Init.Period            = 20+1;// 5MghZ

    htim8.Init.Prescaler        = uwPrescalerValue;

    htim8.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;

    htim8.Init.CounterMode       = TIM_COUNTERMODE_UP;

    htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    if(HAL_TIM_OC_Init(&htim8) != HAL_OK)    {

        /* Initialization Error */

        Error_Handler();

    }

    TIM_OC_InitTypeDef sConfig;

    /*##-2- Configure the Output Compare channels #########################################*/

    /* Common configuration for all channels */

    sConfig.OCMode             = TIM_OCMODE_PWM1;

    sConfig.OCPolarity         = TIM_OCPOLARITY_HIGH;

    sConfig.OCNPolarity     = TIM_OCNPOLARITY_LOW;

    sConfig.OCFastMode         = TIM_OCFAST_ENABLE;

    sConfig.OCNIdleState     = TIM_OCNIDLESTATE_RESET;

    sConfig.OCIdleState      = TIM_OCIDLESTATE_RESET;

    sConfig.Pulse            = htim8.Init.Period /2;

    if(HAL_TIM_OC_ConfigChannel(&htim8, &sConfig, TIM_CHANNEL_1) != HAL_OK)    {//Stream 2 channel 0

        Error_Handler();

    }

    sConfig.OCMode             = TIM_OCMODE_TIMING;

    if(HAL_TIM_OC_ConfigChannel(&htim8, &sConfig, TIM_CHANNEL_2) != HAL_OK)    {//Stream 3 channel 7

              Error_Handler();

    }

Here is the DMA2 configuration

    __HAL_RCC_DMA2_CLK_ENABLE();

    hdma_adc1.Instance             = DMA2_Stream2;

    hdma_adc1.Init.Channel             = DMA_CHANNEL_7;

    hdma_adc1.Init.Direction         = DMA_PERIPH_TO_MEMORY;

    hdma_adc1.Init.PeriphInc         = DMA_PINC_DISABLE;

    hdma_adc1.Init.MemInc             = DMA_MINC_ENABLE;

    hdma_adc1.Init.PeriphDataAlignment     = DMA_PDATAALIGN_HALFWORD;

    hdma_adc1.Init.MemDataAlignment     = DMA_MDATAALIGN_HALFWORD;

    hdma_adc1.Init.Mode             = DMA_CIRCULAR;

    hdma_adc1.Init.Priority         = DMA_PRIORITY_HIGH;

    hdma_adc1.Init.FIFOMode         = DMA_FIFOMODE_ENABLE;

    hdma_adc1.Init.FIFOThreshold        = DMA_FIFO_THRESHOLD_FULL;

    hdma_adc1.Init.MemBurst         = DMA_MBURST_SINGLE;

    hdma_adc1.Init.PeriphBurst         = DMA_PBURST_SINGLE;

//    /* Link hdma_adc1 to hdma[CC1] */

    __HAL_LINKDMA (&htim8, hdma[TIM_DMA_ID_CC1], hdma_adc1);

    /* Initialize TIMx DMA handle */

    if (HAL_DMA_Init(htim8.hdma[TIM_DMA_ID_CC1]) != HAL_OK){

      _Error_Handler(__FILE__, __LINE__);

    }

    /* Select Callbacks functions called after Transfer complete and Transfer error */

    HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_CPLT_CB_ID, Adc1TransferComplete);

    HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_ERROR_CB_ID,    Adc1TransferError);

    HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_HALFCPLT_CB_ID, Adc1TransferHalfComplete);

    HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 3,1);

    HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);

    hdma_adc2.Instance             = DMA2_Stream3;

    hdma_adc2.Init.Channel             = DMA_CHANNEL_7;

    hdma_adc2.Init.Direction         = DMA_PERIPH_TO_MEMORY;

    hdma_adc2.Init.PeriphInc         = DMA_PINC_DISABLE;

    hdma_adc2.Init.MemInc             = DMA_MINC_ENABLE;

    hdma_adc2.Init.PeriphDataAlignment     = DMA_PDATAALIGN_HALFWORD;

    hdma_adc2.Init.MemDataAlignment     = DMA_MDATAALIGN_HALFWORD;

    hdma_adc2.Init.Mode             = DMA_CIRCULAR;

    hdma_adc2.Init.Priority         = DMA_PRIORITY_HIGH;

    hdma_adc2.Init.FIFOMode         = DMA_FIFOMODE_ENABLE;

    hdma_adc2.Init.FIFOThreshold        = DMA_FIFO_THRESHOLD_FULL;

    hdma_adc2.Init.MemBurst         = DMA_MBURST_SINGLE;

    hdma_adc2.Init.PeriphBurst         = DMA_PBURST_SINGLE;

    /* Link hdma_adc1 to hdma[CC2] */

    __HAL_LINKDMA (&htim8, hdma[TIM_DMA_ID_CC2], hdma_adc2);

    /* Initialize TIMx DMA handle */

    HAL_DMA_Init(htim8.hdma[TIM_DMA_ID_CC2]);

    /* Select Callbacks functions called after Transfer complete and Transfer error */

    HAL_DMA_RegisterCallback(&hdma_adc2, HAL_DMA_XFER_CPLT_CB_ID, Adc2TransferComplete);

    HAL_DMA_RegisterCallback(&hdma_adc2, HAL_DMA_XFER_ERROR_CB_ID,    Adc2TransferError);

    HAL_DMA_RegisterCallback(&hdma_adc2, HAL_DMA_XFER_HALFCPLT_CB_ID, Adc2TransferHalfComplete);

    HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 3,2);

    HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);

HERE IS WHERE I START DMAS

    if (HAL_DMA_Start_IT(htim8.hdma[TIM_DMA_ID_CC1], (uint32_t)&GPIOG->IDR, (uint32_t)&ADCBuffer1, 50000) != HAL_OK){

        Error_Handler();

    }

    __HAL_TIM_ENABLE_DMA(&htim8, TIM_DMA_CC1);

    if (HAL_DMA_Start_IT(htim8.hdma[TIM_DMA_ID_CC2], (uint32_t)&GPIOF->IDR, (uint32_t)&ADCBuffer3, 50000) != HAL_OK){

        Error_Handler();

    }

    __HAL_TIM_ENABLE_DMA(&htim8, TIM_DMA_CC2);

Duration is not ok, i don't understand.

Thanks for any input for this issue.

regards

Posted on November 15, 2017 at 08:18

My bad sorry, Code above is fine.