cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F769 PWM using DMA on two channels PA2 and PA3 issue

VMoca.1
Associate II

Hello,

I have an issue with using two channels of DMA to generate the PWM on PA2 and PA3 pins.

I configured using CubeMX TIM2 PWM Generation CH3 and CH4.

I have added the DMA memory to peripheral for PA2 DMA1Stream1 and for PA3 DMA1Stream6.

The issue I have is that only the DMA1_Stream1_IRQHandler is called and only the PA2 PWM generation is done. DMA1_Stream6_IRQHandler is never called.

This is what I use to test PA3 pin.

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)

{

 GPIO_InitTypeDef  GPIO_InitStruct1;

 GPIO_InitTypeDef  GPIO_InitStruct2;

 static DMA_HandleTypeDef hdma_tim1;

 static DMA_HandleTypeDef hdma_tim2;

 /*##-1- Enable peripherals and GPIO Clocks #################################*/

 /* TIMx clock enable */

 TIMx_CLK_ENABLE();

 /* Enable GPIO Channel3/3N Clocks */

 TIMx_CHANNEL3_GPIO_CLK_ENABLE(); /* PA2 and PA3 */

 /* Enable DMA clock */

 DMAx_CLK_ENABLE();

   /* Configure TIM2_Channel3 in output, push-pull & alternate function mode */

   GPIO_InitStruct1.Pin = GPIO_PIN_CHANNEL4; /*  PA3 */

   GPIO_InitStruct1.Mode = GPIO_MODE_AF_PP;

   GPIO_InitStruct1.Pull = GPIO_PULLUP;

   GPIO_InitStruct1.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

   GPIO_InitStruct1.Alternate = GPIO_AF1_TIM2;

   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct1);

   /* Set the parameters to be configured */

   hdma_tim1.Init.Channel = DMA_CHANNEL_4; /* PA3 TIM2_CH4 */

   hdma_tim1.Init.Direction = DMA_MEMORY_TO_PERIPH;

   hdma_tim1.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_tim1.Init.MemInc = DMA_MINC_ENABLE;

   hdma_tim1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD ;

   hdma_tim1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD ;

   hdma_tim1.Init.Mode = DMA_CIRCULAR;

   hdma_tim1.Init.Priority = DMA_PRIORITY_HIGH;

   hdma_tim1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

   hdma_tim1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

   hdma_tim1.Init.MemBurst = DMA_MBURST_SINGLE;

   hdma_tim1.Init.PeriphBurst = DMA_PBURST_SINGLE;

   /* Set hdma_tim instance */

   hdma_tim1.Instance = DMA1_Stream6;

   /* Link hdma_tim to hdma[TIM_DMA_ID_CC4] (channel4) */

   __HAL_LINKDMA(htim, hdma[TIM_DMA_ID_CC4], hdma_tim1);

   /* Initialize TIMx DMA handle */

   HAL_DMA_Init(htim->hdma[TIM_DMA_ID_CC4]);

   /* ##-2- Configure the NVIC for DMA ######################################### */

   /* NVIC configuration for DMA transfer complete interrupt */

   HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);

}

This is the function to set-up the values to send on PWM in the main() with parameter 20000u corresponding to 20KHz.

void DMA_Config2(uint32_t DmaFreq)

{

   uint8_t idx = 0U;

    /* Load buffer for DMA */

    for (idx = 0; idx < DMA_PWM_MAX_BUF; idx++)

    {

       /* Compute CCR1 value to generate a duty cycle [%] */

       aCCValue_Buffer_right[idx] = (uint32_t)(((uint32_t) (100-idx) * (uwTimerPeriod - 1)) / 100);

    }

   /*##-1- Initialise Timer settings ##########################################*/

   TimHandle2.Instance = TIM2;

   TimHandle2.Init.Period           = uwTimerPeriod;

   TimHandle2.Init.RepetitionCounter = 1;

   TimHandle2.Init.Prescaler        = 0;

   TimHandle2.Init.ClockDivision    = 0;

   TimHandle2.Init.CounterMode      = TIM_COUNTERMODE_UP;

   TimHandle2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

   if (HAL_TIM_PWM_Init(&TimHandle2) != HAL_OK)

   {

    /* Initialization Error */

    Error_Handler();

   }

   /*##-2- Configure the PWM channel 3 ########################################*/

   sConfig2.OCMode      = TIM_OCMODE_PWM1;

   sConfig2.OCPolarity  = TIM_OCPOLARITY_HIGH;

   sConfig2.Pulse       = aCCValue_Buffer_right[0];

   sConfig2.OCNPolarity = TIM_OCNPOLARITY_HIGH;

   sConfig2.OCFastMode  = TIM_OCFAST_DISABLE;

   sConfig2.OCIdleState = TIM_OCIDLESTATE_RESET;

   sConfig2.OCNIdleState = TIM_OCNIDLESTATE_RESET;

   if (HAL_TIM_PWM_ConfigChannel(&TimHandle2, &sConfig2, TIM_CHANNEL_4) != HAL_OK) /* PA3 */

   {

    /* Configuration Error */

    Error_Handler();

   }

   /*##-3- Start PWM signal generation in DMA mode ##############################*/

   if (HAL_TIM_PWM_Start_DMA(&TimHandle2, TIM_CHANNEL_4, aCCValue_Buffer_right, DMA_PWM_MAX_BUF) != HAL_OK) /* PA3 */

   {

    /* Starting Error */

    Error_Handler();

   }

}

18 REPLIES 18

​Hello,

I have managed to set-up the desired PA3 to use DMA but only with Steam7.

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)

{

GPIO_InitTypeDef GPIO_InitStruct;

static DMA_HandleTypeDef hdma_tim; 

/* Configure TIM2_Channel3 in output, push-pull & alternate function mode */

GPIO_InitStruct.Pin = GPIO_PIN_3; /* PA3 */

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* Set the parameters to be configured on DMA */

hdma_tim.Init.Channel = DMA_CHANNEL_3; /*PA2 and PA3 have the same channel*/

hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_tim.Init.MemInc = DMA_MINC_ENABLE;

hdma_tim.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD ;

hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD ;

hdma_tim.Init.Mode = DMA_CIRCULAR;

hdma_tim.Init.Priority = DMA_PRIORITY_HIGH;

hdma_tim.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

hdma_tim.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

hdma_tim.Init.MemBurst = DMA_MBURST_SINGLE;

hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;

/* Set hdma_tim instance */

hdma_tim.Instance = DMA1_Stream7; 

/* Link hdma_tim to hdma[TIM_DMA_ID_CC4] (channel3) */

__HAL_LINKDMA(htim, hdma[TIM_DMA_ID_CC4], hdma_tim);

/* Initialize TIMx DMA handle */

HAL_DMA_Init(htim->hdma[TIM_DMA_ID_CC4]); 

/*##-2- Configure the NVIC for DMA #########################################*/

/* NVIC configuration for DMA transfer complete interrupt */

HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);

}

and

void DMA_Config(uint32_t DmaFreq)

{

uint8_t idx = 0U;

/* Compute the value of ARR regiter to generate signal frequency at 20.00 Khz */

uwTimerPeriod = (uint32_t)(((SystemCoreClock/2) / DmaFreq) - 1);

/* Load buffer for DMA */

for (idx=0; idx < DMA_PWM_MAX_BUF; idx++)

{

/* Compute CCR1 value to generate a duty cycle [%] */

aCCValue_Buffer_left[idx] = (uint32_t)(((uint32_t) idx * (uwTimerPeriod - 1)) / 100);

}

/*##-1- Initialise Timer settings ##########################################*/

TimHandle.Instance = TIM2;

TimHandle.Init.Period = uwTimerPeriod;

TimHandle.Init.RepetitionCounter = 1;

TimHandle.Init.Prescaler = 0;

TimHandle.Init.ClockDivision = 0;

TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;

TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK)

{

/* Initialization Error */

Error_Handler();

}

/*##-2- Configure the PWM channel 3 ########################################*/

sConfig.OCMode = TIM_OCMODE_PWM1;

sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfig.Pulse = aCCValue_Buffer_left[0];

sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfig.OCFastMode = TIM_OCFAST_DISABLE;

sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_4) != HAL_OK) /* PA3 */

{

/* Configuration Error */

Error_Handler();

}

/*##-3- Start PWM signal generation in DMA mode ##############################*/

if (HAL_TIM_PWM_Start_DMA(&TimHandle, TIM_CHANNEL_4, aCCValue_Buffer_left, DMA_PWM_MAX_BUF) != HAL_OK) /* PA2 */

{

/* Starting Error */

Error_Handler();

}

}

VMoca.1
Associate II

​I will try to merge the PA2 and PA3 implementation next.

Thank you for your support

VMoca.1
Associate II

The CubeMX is blocking selecting both CH3 TIM2_CH3 (Stream1) and CH​4 TIM2_CH3(Stream7)...

> I have managed to set-up the desired PA3 to use DMA but only with Steam7.

Oh, that's an unexpected twist.

Do you use also CH2 on that timer for DMA?

JW

Imen GH
ST Employee

Hello,

I succeeded to generate PWM using DMA for both TIM2 channels on PA2 and PA3.

You find attached the compiled code I used.

0690X00000DAe2JQAT.png

Hello,

I cannot find the HAL_TIM_PWM_Init() and HAL_TIM_MspPostInit() functions content from your configuration.

Is it possible to send me this file two?

Thank you.

Hello,

Could you please send me the HAL_TIM_MspPostInit() and the HAL_TIM_PWM_MspInit() functions as well.

Thank you.

Imen GH
ST Employee

​Hello,

You will find attached my file STM32f7xx_hal_msp.c

The contents of this file was automatically generated ( I didn't add or change anything )

Regards

​Ok, thank you. It works now. I have used different variables in the code (initiated in tim.c with a name and used it in DMA_Config, another variable) and it was not the same addresses :D

Now it is working.