cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to generate complementary pwm signal with DMA.

Ravi1
Associate II

I'm trying to program stm32h750vb to run ws2812b RGB LED. My RGB LED is connected to TIM1CH2N. I'm unable to generate desired PWM signal with my DMA settings. I have tested PWM signal without DMA it is working fine. So, as per my knowledge my timer settings are working well and fine, only issue might causing is DMA settings. If you're able to figure out loop holes from configuration, it would be helpful.

Timer & clock configuration :

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Supply configuration update enable

 */

 HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

 /** Configure the main internal regulator output voltage

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 /** Initializes the RCC Oscillators according to the specified parameters

 * in the RCC_OscInitTypeDef structure.

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

 RCC_OscInitStruct.HSEState = RCC_HSE_ON;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

 RCC_OscInitStruct.PLL.PLLM = 1;

 RCC_OscInitStruct.PLL.PLLN = 12;

 RCC_OscInitStruct.PLL.PLLP = 2;

 RCC_OscInitStruct.PLL.PLLQ = 2;

 RCC_OscInitStruct.PLL.PLLR = 2;

 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;

 RCC_OscInitStruct.PLL.PLLFRACN = 4096;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB buses clocks

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

               |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;

 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

 {

  Error_Handler();

 }

}

/**

 * @brief TIM1 Initialization Function

 * @param None

 * @retval None

 */

static void MX_TIM1_Init(void)

{

 /* USER CODE BEGIN TIM1_Init 0 */

 /* USER CODE END TIM1_Init 0 */

 TIM_ClockConfigTypeDef sClockSourceConfig = {0};

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 TIM_OC_InitTypeDef sConfigOC = {0};

 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 /* USER CODE BEGIN TIM1_Init 1 */

 /* USER CODE END TIM1_Init 1 */

 htim1.Instance = TIM1;

 htim1.Init.Prescaler = 0;

 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim1.Init.Period = 250;

 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim1.Init.RepetitionCounter = 0;

 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

 {

  Error_Handler();

 }

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

 sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 125;

 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

 {

  Error_Handler();

 }

 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

 sBreakDeadTimeConfig.DeadTime = 0;

 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

 sBreakDeadTimeConfig.BreakFilter = 0;

 sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;

 sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;

 sBreakDeadTimeConfig.Break2Filter = 0;

 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM1_Init 2 */

 /* USER CODE END TIM1_Init 2 */

 HAL_TIM_MspPostInit(&htim1);

}

DMA Configurations :

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)

{

 if(htim_base->Instance==TIM1)

 {

 /* USER CODE BEGIN TIM1_MspInit 0 */

 /* USER CODE END TIM1_MspInit 0 */

  /* Peripheral clock enable */

  __HAL_RCC_TIM1_CLK_ENABLE();

  /* TIM1 DMA Init */

  /* TIM1_COM Init */

  hdma_tim1_com.Instance = DMA1_Stream0;

  hdma_tim1_com.Init.Request = DMA_REQUEST_TIM1_COM;

  hdma_tim1_com.Init.Direction = DMA_MEMORY_TO_PERIPH;

  hdma_tim1_com.Init.PeriphInc = DMA_PINC_DISABLE;

  hdma_tim1_com.Init.MemInc = DMA_MINC_ENABLE;

  hdma_tim1_com.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

  hdma_tim1_com.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

  hdma_tim1_com.Init.Mode = DMA_CIRCULAR;

  hdma_tim1_com.Init.Priority = DMA_PRIORITY_HIGH;

  hdma_tim1_com.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

  if (HAL_DMA_Init(&hdma_tim1_com) != HAL_OK)

  {

   Error_Handler();

  }

  __HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_COMMUTATION],hdma_tim1_com);

 /* USER CODE BEGIN TIM1_MspInit 1 */

 /* USER CODE END TIM1_MspInit 1 */

 }

}

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 if(htim->Instance==TIM1)

 {

 /* USER CODE BEGIN TIM1_MspPostInit 0 */

 /* USER CODE END TIM1_MspPostInit 0 */

  __HAL_RCC_GPIOB_CLK_ENABLE();

  /**TIM1 GPIO Configuration

  PB14   ------> TIM1_CH2N

  */

  GPIO_InitStruct.Pin = GPIO_PIN_14;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /* USER CODE BEGIN TIM1_MspPostInit 1 */

 /* USER CODE END TIM1_MspPostInit 1 */

 }

}

/**

* @brief TIM_Base MSP De-Initialization

* This function freeze the hardware resources used in this example

* @param htim_base: TIM_Base handle pointer

* @retval None

*/

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)

{

 if(htim_base->Instance==TIM1)

 {

 /* USER CODE BEGIN TIM1_MspDeInit 0 */

 /* USER CODE END TIM1_MspDeInit 0 */

  /* Peripheral clock disable */

  __HAL_RCC_TIM1_CLK_DISABLE();

  /* TIM1 DMA DeInit */

  HAL_DMA_DeInit(htim_base->hdma[TIM_DMA_ID_COMMUTATION]);

 /* USER CODE BEGIN TIM1_MspDeInit 1 */

 /* USER CODE END TIM1_MspDeInit 1 */

 }

}

5 REPLIES 5

https://community.st.com/s/question/0D53W00000FPbd8SAD/how-to-use-timers-complementary-output-is-for-regular-peripherals-programming

Read out and check/compare the GPIO and TIM register content between working and non-working cases.

How do you observe the output signal?

JW

> __HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_COMMUTATION],hdma_tim1_com);

Don't use the Commutation event unless you exactly know what are you doing. Use Update instead.

JW

I tap the output pin and observe signal using Logic Analyzer.

Still I'm not able to generate any signal. That solution did not helped me.

HAL_TIMEx_PWMN_Start_DMA(&htim1, TIM_CHANNEL_2, (uint32_t *) LEDbuffer, LED_BUFFER_SIZE);

This is the function I call to generate PWM signal.

   /* Enable the DMA stream */

   if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK)

   {

    return HAL_ERROR;

   }

:::: This is where I have encountered an Error