Ejemplo n.º 1
0
/**
  * @brief  This function will set the PWM to the required value
  * @param  port : the gpio port to use
  * @param  pin : the gpio pin to use
  * @param  clock_freq : frequency of the tim clock
  * @param  period : period of the tim counter
  * @param  value : the value to push on the PWM output
  * @param  do_init : if set to 1 the initialization of the PWM is done
  * @retval None
  */
void pwm_start(PinName pin, uint32_t clock_freq,
                uint32_t period, uint32_t value, uint8_t do_init)
{
  TIM_HandleTypeDef timHandle = {};
  TIM_OC_InitTypeDef timConfig = {};
  uint32_t timChannel;

  /* Compute the prescaler value to have TIM counter clock equal to clock_freq Hz */
  timHandle.Instance               = pinmap_peripheral(pin, PinMap_PWM);
  if (timHandle.Instance == NP) return;
  timHandle.Init.Prescaler         = (uint32_t)(getTimerClkFreq(timHandle.Instance) / clock_freq) - 1;
  timHandle.Init.Period            = period -1;
  timHandle.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
  timHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
#if !defined(STM32L0xx) && !defined(STM32L1xx)
  timHandle.Init.RepetitionCounter = 0;
#endif
  timHandle.State= HAL_TIM_STATE_RESET;
  // TBC: is timHandle.State field should be saved ?

  if (do_init == 1) {
    g_current_pin = pin;
    if (HAL_TIM_PWM_Init(&timHandle) != HAL_OK) {
      return;
    }
  }
  timChannel = get_pwm_channel(pin);
  if (!IS_TIM_CHANNELS(timChannel)) return;
  //HAL_TIM_PWM_Stop(&timHandle, timChannel);

  /*##-2- Configure the PWM channels #########################################*/
  /* Common configuration for all channels */
  timConfig.OCMode       = TIM_OCMODE_PWM1;
  timConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
  timConfig.OCFastMode   = TIM_OCFAST_DISABLE;
#if !defined(STM32L0xx) && !defined(STM32L1xx)
  timConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
  timConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  timConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;
#endif
  timConfig.Pulse = value;

  if (HAL_TIM_PWM_ConfigChannel(&timHandle, &timConfig, timChannel) != HAL_OK)
  {
    /*##-2- Configure the PWM channels #########################################*/
    return;
  }

#if !defined(STM32L0xx) && !defined(STM32L1xx)
  if(STM_PIN_INVERTED(pinmap_function(pin, PinMap_PWM))) {
    HAL_TIMEx_PWMN_Start(&timHandle, timChannel);
  } else
#endif
  {
    HAL_TIM_PWM_Start(&timHandle, timChannel);
  }
}
Ejemplo n.º 2
0
/**
  * @brief  This function will disable the PWM
  * @param  port : the gpio port to use
  * @param  pin : the gpio pin to use
  * @retval None
  */
void pwm_stop(PinName pin)
{
  TIM_HandleTypeDef timHandle;
  uint32_t timChannel;

  timHandle.Instance = pinmap_peripheral(pin, PinMap_PWM);
  if (timHandle.Instance == NP) return;
  timChannel = get_pwm_channel(pin);
  if (!IS_TIM_CHANNELS(timChannel)) return;

#if !defined(STM32L0xx) && !defined(STM32L1xx)
  if (STM_PIN_INVERTED(pinmap_function(pin, PinMap_PWM))) {
    HAL_TIMEx_PWMN_Stop(&timHandle, timChannel);
  } else
#endif
  {
    HAL_TIM_PWM_Stop(&timHandle, timChannel);
  }

  HAL_TIM_PWM_DeInit(&timHandle);
}
Ejemplo n.º 3
0
/*
 * Set the period and pulse width for a PWM pin.
 *
 * Parameters
 * dev: Pointer to PWM device structure
 * pwm: PWM channel to set
 * period_cycles: Period (in timer count)
 * pulse_cycles: Pulse width (in timer count).
 *
 * return 0, or negative errno code
 */
static int pwm_stm32_pin_set(struct device *dev, u32_t pwm,
			     u32_t period_cycles, u32_t pulse_cycles)
{
	struct pwm_stm32_data *data = DEV_DATA(dev);
	TIM_HandleTypeDef *TimerHandle = &data->hpwm;
	TIM_OC_InitTypeDef sConfig;
	u32_t channel;
	bool counter_32b;

	if (period_cycles == 0 || pulse_cycles > period_cycles) {
		return -EINVAL;
	}

	/* configure channel */
	channel = (pwm - 1)*CHANNEL_LENGTH;

	if (!IS_TIM_INSTANCE(PWM_STRUCT(dev)) ||
		!IS_TIM_CHANNELS(channel)) {
		return -ENOTSUP;
	}

#ifdef CONFIG_SOC_SERIES_STM32F1X
	/* FIXME: IS_TIM_32B_COUNTER_INSTANCE not available on
	 * SMT32F1 Cube HAL since all timer counters are 16 bits
	 */
	counter_32b = 0;
#else
	counter_32b = IS_TIM_32B_COUNTER_INSTANCE(PWM_STRUCT(dev));
#endif

	/*
	 * The timer counts from 0 up to the value in the ARR register (16-bit).
	 * Thus period_cycles cannot be greater than UINT16_MAX + 1.
	 */
	if (!counter_32b && (period_cycles > 0x10000)) {
		/* 16 bits counter does not support requested period
		 * You might want to adapt PWM output clock to adjust
		 * cycle durations to fit requested period into 16 bits
		 * counter
		 */
		return -ENOTSUP;
	}

	/* Configure Timer IP */
	TimerHandle->Instance = PWM_STRUCT(dev);
	TimerHandle->Init.Prescaler = data->pwm_prescaler;
	TimerHandle->Init.ClockDivision = 0;
	TimerHandle->Init.CounterMode = TIM_COUNTERMODE_UP;
	TimerHandle->Init.RepetitionCounter = 0;

	/* Set period value */
	TimerHandle->Init.Period = period_cycles - 1;

	HAL_TIM_PWM_Init(TimerHandle);

	/* Configure PWM channel */
	sConfig.OCMode       = TIM_OCMODE_PWM1;
	sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
	sConfig.OCFastMode   = TIM_OCFAST_DISABLE;
	sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
	sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
	sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;

	/* Set the pulse value */
	sConfig.Pulse = pulse_cycles;

	HAL_TIM_PWM_ConfigChannel(TimerHandle, &sConfig, channel);

	return HAL_TIM_PWM_Start(TimerHandle, channel);
}