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