Arm Mbed and Pelion Device Management support forum

STM32F769 PWM using DMA on two channels PA2 and PA3 issue

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();
}
}