cancel
Showing results for 
Search instead for 
Did you mean: 

Is there impossible to start PWM DMA on several channels of same timer in HAL?

Vthe
Associate II

I want to start PWM DMA on channels 2 and 3 of TIM2, but I've found that it is possible to start only one DMA per timer. My MCU is stm32f103 series and my code is:

HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_2, (uint32_t*)&send_buff_one , 16);
HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_3, (uint32_t*)&send_buff_two , 16);

HAL_TIM_PWM_Start_DMA() is impemented in HAL by this way:

HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
{
  uint32_t tmpsmcr;
 
  /* Check the parameters */
  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
 
  if (htim->State == HAL_TIM_STATE_BUSY)
  {
    return HAL_BUSY;
  }
  else if (htim->State == HAL_TIM_STATE_READY)
  {
    if ((pData == NULL) && (Length > 0U))
    {
      return HAL_ERROR;
    }
    else
    {
      htim->State = HAL_TIM_STATE_BUSY;
    }
  }

so, after first call of HAL_TIM_PWM_Start_DMA() htim2->State will HAL_TIM_STATE_BUSY and second call of HAL_TIM_PWM_Start_DMA() for htim2 will fail with HAL_BUSY result.

Is this implementaion reflects hardware limitation of MCU or is it just lack of HAL implementation?

2 REPLIES 2

> Is this implementaion reflects hardware limitation of MCU or is it just lack of HAL implementation?

In the particular case of 'F1, it's the latter (although I wouldn't call it lack/defficiency of HAL, but a design choice); in other STM32 families it's both.

Cube/HAL, as any similar library would do, implements inevitably just a limited subset of the almost infinite possible combinations of usage modes of the hardware, so the designers had to chose the "most usual modes of usage" to implement. If you want something else, go straight programming the hardware; this may influence other Cube/HAL-based parts of your program, there is no "gracious fallback".

Also, Hardware Abstraction is about finding a common mutual denominator in the hardware amongst all supported models. And while in 'F1 all timer channels can be used as a separate DMA channel trigger, this is not the case for many other STM32 families, where for most timers there is only a single DMA trigger shared by all channels (and other DMA sources) of a single timer.

In some cases, features of one particular family, which can't be supported by all the supported families, are supported in supplemental files, e.g. stm32f4xx_hal_tim_ex.c - check if CubeF1 has similar and if there are functions of interest in there.

I don't use Cube/HAL.

JW

SKuch
Associate

HAL_TIM_STATE_BUSY is cleared in the TIM_DMADelayPulseHalfCplt interrupt handler. I don't know what is the point here. You can wait for the half DMA transfer completion to reset timer state, or it may be safe to set htim->State = HAL_TIM_STATE_READY manually after first HAL_TIM_PWM_Start_DMA call. I guess second option will be mandatory if you run DMA with interrupts disabled.