Пример #1
0
static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev)
{
    uint16_t val = stm32_getreg16(dev, STM32_BTIM_CR1_OFFSET);
    val |= ATIM_CR1_CEN;
    stm32_tim_reload_counter(dev);
    stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);
}
Пример #2
0
static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode)
{
  uint16_t val = ATIM_CR1_CEN | ATIM_CR1_ARPE;

  DEBUGASSERT(dev != NULL);

  /* This function is not supported on basic timers. To enable or
   * disable it, simply set its clock to valid frequency or zero.
   */

  if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE || \
      ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE)
    {
      return -EINVAL;
    }

  /* Decode operational modes */

  switch (mode & STM32_TIM_MODE_MASK)
    {
      case STM32_TIM_MODE_DISABLED:
        val = 0;
        break;

      case STM32_TIM_MODE_DOWN:
        val |= ATIM_CR1_DIR;

      case STM32_TIM_MODE_UP:
        break;

      case STM32_TIM_MODE_UPDOWN:
        val |= ATIM_CR1_CENTER1;
        // Our default: Interrupts are generated on compare, when counting down
        break;

      case STM32_TIM_MODE_PULSE:
        val |= ATIM_CR1_OPM;
        break;

      default:
        return -EINVAL;
    }

  stm32_tim_reload_counter(dev);
  stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);

  /* Advanced registers require Main Output Enable */

    if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE ||
        ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE)
      {
        stm32_modifyreg16(dev, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE);
      }

  return OK;
}
Пример #3
0
static void stm32_cap_ackflags(FAR struct stm32_cap_dev_s *dev, int flags)
{
  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
  uint16_t mask = 0;

  if (flags & STM32_CAP_FLAG_IRQ_COUNTER)
    {
      mask |= ATIM_SR_UIF;
    }

  if (flags & STM32_CAP_FLAG_IRQ_CH_1)
    {
      mask |= ATIM_SR_CC1IF;
    }

  if (flags & STM32_CAP_FLAG_IRQ_CH_2)
    {
      mask |= ATIM_SR_CC2IF;
    }

  if (flags & STM32_CAP_FLAG_IRQ_CH_3)
    {
      mask |= ATIM_SR_CC3IF;
    }

  if (flags & STM32_CAP_FLAG_IRQ_CH_4)
    {
      mask |= ATIM_SR_CC4IF;
    }

  if (flags & STM32_CAP_FLAG_OF_CH_1)
    {
      mask |= ATIM_SR_CC1OF;
    }

  if (flags & STM32_CAP_FLAG_OF_CH_2)
    {
      mask |= ATIM_SR_CC2OF;
    }

  if (flags & STM32_CAP_FLAG_OF_CH_3)
    {
      mask |= ATIM_SR_CC3OF;
    }

  if (flags & STM32_CAP_FLAG_OF_CH_4)
    {
      mask |= ATIM_SR_CC4OF;
    }

  stm32_putreg16(priv, STM32_BTIM_SR_OFFSET, ~mask);
}
Пример #4
0
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq)
{
    int prescaler;

    ASSERT(dev);

    /* Disable Timer? */

    if (freq == 0)
    {
        stm32_tim_disable(dev);
        return 0;
    }

#if STM32_NATIM > 0
    if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE ||
            ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE)
    {
        prescaler = STM32_TIM18_FREQUENCY / freq;
    }
    else
#endif
    {
        prescaler = STM32_TIM27_FREQUENCY / freq;
    }

    /* We need to decrement value for '1', but only, if we are allowed to
     * not to cause underflow. Check for overflow.
     */

    if (prescaler > 0)
    {
        prescaler--;
    }

    if (prescaler > 0xffff)
    {
        prescaler = 0xffff;
    }

    stm32_putreg16(dev, STM32_BTIM_PSC_OFFSET, prescaler);
    stm32_tim_enable(dev);

    return prescaler;
}
Пример #5
0
static int stm32_cap_setclock(FAR struct stm32_cap_dev_s *dev, stm32_cap_clk_t clk,
                              uint32_t prescaler,uint32_t max)
{
  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
  uint16_t regval = 0;

  if (prescaler == 0)
    {
      /* Disable Timer */

      stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0);
      return 0;
    }

  /* We need to decrement value for '1', but only, if we are allowed to
   * not to cause underflow. Check for overflow.
   */

  if (prescaler > 0)
    {
      prescaler--;
    }

  if (prescaler > 0xffff)
    {
      prescaler = 0xffff;
    }


  switch(clk)
    {
      case STM32_CAP_CLK_INT:
          regval = GTIM_SMCR_DISAB;
          break;

      case STM32_CAP_CLK_EXT:
          regval = GTIM_SMCR_EXTCLK1;
          break;

      /* TODO: Add other case */

      default:
        return ERROR;
    }

  stm32_modifyreg16(priv, STM32_BTIM_EGR_OFFSET, GTIM_SMCR_SMS_MASK, regval);

  /* Set Maximum */

  stm32_putreg32(priv, STM32_BTIM_ARR_OFFSET, max);

  /* Set prescaler */

  stm32_putreg16(priv, STM32_BTIM_PSC_OFFSET, prescaler);

  /* Reset counter timer */

  stm32_modifyreg16(priv, STM32_BTIM_EGR_OFFSET, 0, BTIM_EGR_UG);

  /* Enable timer */

  stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, 0, BTIM_CR1_CEN);

#ifdef USE_ADVENCED_TIM
  /* Advanced registers require Main Output Enable */

  if (priv->base == STM32_TIM1_BASE || priv->base == STM32_TIM8_BASE)
    {
      stm32_modifyreg16(priv, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE);
    }
#endif

  return prescaler;
}
Пример #6
0
static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel, stm32_tim_channel_t mode)
{
    uint16_t ccmr_val = 0;
    uint16_t ccer_val = stm32_getreg16(dev, STM32_GTIM_CCER_OFFSET);
    uint8_t  ccmr_offset = STM32_GTIM_CCMR1_OFFSET;

    ASSERT(dev);

    /* Further we use range as 0..3; if channel=0 it will also overflow here */

    if (--channel > 4) return ERROR;

    /* Assume that channel is disabled and polarity is active high */

    ccer_val &= ~(3 << (channel << 2));

    /* This function is not supported on basic timers. To enable or
     * disable it, simply set its clock to valid frequency or zero.
     */

#if STM32_NBTIM > 0
    if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE
#endif
#if STM32_NBTIM > 1
            || ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE
#endif
#if STM32_NBTIM > 0
       )
    {
        return ERROR;
    }
#endif

    /* Decode configuration */

    switch (mode & STM32_TIM_CH_MODE_MASK)
    {
    case STM32_TIM_CH_DISABLED:
        break;

    case STM32_TIM_CH_OUTPWM:
        ccmr_val  =  (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) + ATIM_CCMR1_OC1PE;
        ccer_val |= ATIM_CCER_CC1E << (channel << 2);
        break;

    default:
        return ERROR;
    }

    /* Set polarity */

    if (mode & STM32_TIM_CH_POLARITY_NEG)
    {
        ccer_val |= ATIM_CCER_CC1P << (channel << 2);
    }

    /* Define its position (shift) and get register offset */

    if (channel & 1)
    {
        ccmr_val <<= 8;
    }

    if (channel > 1)
    {
        ccmr_offset = STM32_GTIM_CCMR2_OFFSET;
    }

    stm32_putreg16(dev, ccmr_offset, ccmr_val);
    stm32_putreg16(dev, STM32_GTIM_CCER_OFFSET, ccer_val);

    /* set GPIO */

    switch (((struct stm32_tim_priv_s *)dev)->base)
    {
#if CONFIG_STM32_TIM2
    case STM32_TIM2_BASE:
        switch (channel)
        {
#if defined(GPIO_TIM2_CH1OUT)
        case 0:
            stm32_tim_gpioconfig(GPIO_TIM2_CH1OUT, mode);
            break;
#endif
#if defined(GPIO_TIM2_CH2OUT)
        case 1:
            stm32_tim_gpioconfig(GPIO_TIM2_CH2OUT, mode);
            break;
#endif
#if defined(GPIO_TIM2_CH3OUT)
        case 2:
            stm32_tim_gpioconfig(GPIO_TIM2_CH3OUT, mode);
            break;
#endif
#if defined(GPIO_TIM2_CH4OUT)
        case 3:
            stm32_tim_gpioconfig(GPIO_TIM2_CH4OUT, mode);
            break;
#endif
        default:
            return ERROR;
        }
        break;
#endif
#if CONFIG_STM32_TIM3
    case STM32_TIM3_BASE:
        switch (channel)
        {
#if defined(GPIO_TIM3_CH1OUT)
        case 0:
            stm32_tim_gpioconfig(GPIO_TIM3_CH1OUT, mode);
            break;
#endif
#if defined(GPIO_TIM3_CH2OUT)
        case 1:
            stm32_tim_gpioconfig(GPIO_TIM3_CH2OUT, mode);
            break;
#endif
#if defined(GPIO_TIM3_CH3OUT)
        case 2:
            stm32_tim_gpioconfig(GPIO_TIM3_CH3OUT, mode);
            break;
#endif
#if defined(GPIO_TIM3_CH4OUT)
        case 3:
            stm32_tim_gpioconfig(GPIO_TIM3_CH4OUT, mode);
            break;
#endif
        default:
            return ERROR;
        }
        break;
#endif
#if CONFIG_STM32_TIM4
    case STM32_TIM4_BASE:
        switch (channel)
        {
#if defined(GPIO_TIM4_CH1OUT)
        case 0:
            stm32_tim_gpioconfig(GPIO_TIM4_CH1OUT, mode);
            break;
#endif
#if defined(GPIO_TIM4_CH2OUT)
        case 1:
            stm32_tim_gpioconfig(GPIO_TIM4_CH2OUT, mode);
            break;
#endif
#if defined(GPIO_TIM4_CH3OUT)
        case 2:
            stm32_tim_gpioconfig(GPIO_TIM4_CH3OUT, mode);
            break;
#endif
#if defined(GPIO_TIM4_CH4OUT)
        case 3:
            stm32_tim_gpioconfig(GPIO_TIM4_CH4OUT, mode);
            break;
#endif
        default:
            return ERROR;
        }
        break;
#endif
#if CONFIG_STM32_TIM5
    case STM32_TIM5_BASE:
        switch (channel)
        {
#if defined(GPIO_TIM5_CH1OUT)
        case 0:
            stm32_tim_gpioconfig(GPIO_TIM5_CH1OUT, mode);
            break;
#endif
#if defined(GPIO_TIM5_CH2OUT)
        case 1:
            stm32_tim_gpioconfig(GPIO_TIM5_CH2OUT, mode);
            break;
#endif
#if defined(GPIO_TIM5_CH3OUT)
        case 2:
            stm32_tim_gpioconfig(GPIO_TIM5_CH3OUT, mode);
            break;
#endif
#if defined(GPIO_TIM5_CH4OUT)
        case 3:
            stm32_tim_gpioconfig(GPIO_TIM5_CH4OUT, mode);
            break;
#endif
        default:
            return ERROR;
        }
        break;
#endif

#if STM32_NATIM > 0
#if CONFIG_STM32_TIM1
    case STM32_TIM1_BASE:
        switch (channel)
        {
#if defined(GPIO_TIM1_CH1OUT)
        case 0:
            stm32_tim_gpioconfig(GPIO_TIM1_CH1OUT, mode);
            break;
#endif
#if defined(GPIO_TIM1_CH2OUT)
        case 1:
            stm32_tim_gpioconfig(GPIO_TIM1_CH2OUT, mode);
            break;
#endif
#if defined(GPIO_TIM1_CH3OUT)
        case 2:
            stm32_tim_gpioconfig(GPIO_TIM1_CH3OUT, mode);
            break;
#endif
#if defined(GPIO_TIM1_CH4OUT)
        case 3:
            stm32_tim_gpioconfig(GPIO_TIM1_CH4OUT, mode);
            break;
#endif
        default:
            return ERROR;
        }
        break;
#endif
#if CONFIG_STM32_TIM8
    case STM32_TIM8_BASE:
        switch (channel)
        {
#if defined(GPIO_TIM8_CH1OUT)
        case 0:
            stm32_tim_gpioconfig(GPIO_TIM8_CH1OUT, mode);
            break;
#endif
#if defined(GPIO_TIM8_CH2OUT)
        case 1:
            stm32_tim_gpioconfig(GPIO_TIM8_CH2OUT, mode);
            break;
#endif
#if defined(GPIO_TIM8_CH3OUT)
        case 2:
            stm32_tim_gpioconfig(GPIO_TIM8_CH3OUT, mode);
            break;
#endif
#if defined(GPIO_TIM8_CH4OUT)
        case 3:
            stm32_tim_gpioconfig(GPIO_TIM8_CH4OUT, mode);
            break;
#endif
        default:
            return ERROR;
        }
        break;
#endif
#endif
    default:
        return ERROR;
    }

    return OK;
}
Пример #7
0
static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source)
{
    stm32_putreg16(dev, STM32_BTIM_SR_OFFSET, ~ATIM_SR_UIF);
}
Пример #8
0
static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev)
{
    uint16_t val = stm32_getreg16(dev, STM32_BTIM_CR1_OFFSET);
    val &= ~ATIM_CR1_CEN;
    stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val);
}
Пример #9
0
static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev)
{
    uint16_t val = stm32_getreg16(dev, STM32_BTIM_EGR_OFFSET);
    val |= ATIM_EGR_UG;
    stm32_putreg16(dev, STM32_BTIM_EGR_OFFSET, val);
}
Пример #10
0
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq)
{
  uint32_t freqin;
  int prescaler;

  DEBUGASSERT(dev != NULL);

  /* Disable Timer? */

  if (freq == 0)
    {
      stm32_tim_disable(dev);
      return 0;
    }

  /* Get the input clock frequency for this timer.  These vary with
   * different timer clock sources, MCU-specific timer configuration, and
   * board-specific clock configuration.  The correct input clock frequency
   * must be defined in the board.h header file.
   */

  switch (((struct stm32_tim_priv_s *)dev)->base)
    {
#ifdef CONFIG_STM32F7_TIM1
      case STM32_TIM1_BASE:
        freqin = STM32_APB2_TIM1_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM2
      case STM32_TIM2_BASE:
        freqin = STM32_APB1_TIM2_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM3
      case STM32_TIM3_BASE:
        freqin = STM32_APB1_TIM3_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM4
      case STM32_TIM4_BASE:
        freqin = STM32_APB1_TIM4_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM5
      case STM32_TIM5_BASE:
        freqin = STM32_APB1_TIM5_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM6
      case STM32_TIM6_BASE:
        freqin = STM32_APB1_TIM6_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM7
      case STM32_TIM7_BASE:
        freqin = STM32_APB1_TIM7_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM8
      case STM32_TIM8_BASE:
        freqin = STM32_APB2_TIM8_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM9
      case STM32_TIM9_BASE:
        freqin = STM32_APB2_TIM9_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM10
      case STM32_TIM10_BASE:
        freqin = STM32_APB2_TIM10_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM11
      case STM32_TIM11_BASE:
        freqin = STM32_APB2_TIM11_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM12
      case STM32_TIM12_BASE:
        freqin = STM32_APB1_TIM12_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM13
      case STM32_TIM13_BASE:
        freqin = STM32_APB1_TIM13_CLKIN;
        break;
#endif
#ifdef CONFIG_STM32F7_TIM14
      case STM32_TIM14_BASE:
        freqin = STM32_APB1_TIM14_CLKIN;
        break;
#endif
      default:
        return -EINVAL;
    }

  /* Select a pre-scaler value for this timer using the input clock
   * frequency.
   */

  prescaler = freqin / freq;

  /* We need to decrement value for '1', but only, if that will not to
   * cause underflow.
   */

  if (prescaler > 0)
    {
      prescaler--;
    }

  /* Check for overflow as well. */

  if (prescaler > 0xffff)
    {
      prescaler = 0xffff;
    }

  stm32_putreg16(dev, STM32_BTIM_PSC_OFFSET, prescaler);
  stm32_tim_enable(dev);

  return prescaler;
}