static void stm32_cap_enableint(FAR struct stm32_cap_dev_s *dev, stm32_cap_flags_t src, bool on) { const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; uint16_t mask = 0; DEBUGASSERT(dev != NULL); if (src & STM32_CAP_FLAG_IRQ_COUNTER) { mask |= ATIM_DIER_UIE; } if (src & STM32_CAP_FLAG_IRQ_CH_1) { mask |= ATIM_DIER_CC1IE; } if (src & STM32_CAP_FLAG_IRQ_CH_2) { mask |= ATIM_DIER_CC2IE; } if (src & STM32_CAP_FLAG_IRQ_CH_3) { mask |= ATIM_DIER_CC3IE; } if (src & STM32_CAP_FLAG_IRQ_CH_4) { mask |= ATIM_DIER_CC4IE; } /* Not IRQ on channel overflow */ if (on) { stm32_modifyreg16(priv, STM32_BTIM_DIER_OFFSET, 0, mask); } else { stm32_modifyreg16(priv, STM32_BTIM_DIER_OFFSET, mask, 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; }
int stm32_cap_deinit(FAR struct stm32_cap_dev_s * dev) { const struct stm32_cap_priv_s *priv = (struct stm32_cap_priv_s *)dev; uint32_t gpio; DEBUGASSERT(dev != NULL); /* Disable timer while is not configured */ stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0); gpio = stm32_cap_gpio(priv, STM32_CAP_CHANNEL_COUNTER); if (gpio) { stm32_unconfiggpio(gpio); } stm32_cap_set_rcc(priv, false); return OK; }
FAR struct stm32_cap_dev_s *stm32_cap_init(int timer) { const struct stm32_cap_priv_s *priv = stm32_cap_get_priv(timer); uint32_t gpio; if (priv) { stm32_cap_set_rcc(priv, true); gpio = stm32_cap_gpio(priv, STM32_CAP_CHANNEL_COUNTER); if (gpio) { stm32_configgpio(gpio); } /* Disable timer while is not configured */ stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0); } return (struct stm32_cap_dev_s *)priv; }
static int stm32_cap_setchannel(FAR struct stm32_cap_dev_s *dev, uint8_t channel, stm32_cap_ch_cfg_t cfg) { const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; uint32_t gpio = 0; uint16_t mask; uint16_t regval; uint16_t ccer_en_bit; DEBUGASSERT(dev != NULL); gpio = stm32_cap_gpio(priv, channel); if (gpio == 0) { return ERROR; } if ((cfg & STM32_CAP_MAPPED_MASK) == 0) { return ERROR; /* MAPPED not selected */ } /* Change to zero base index */ channel--; /* Set ccer : * * GTIM_CCER_CCxE Is written latter to allow writing CCxS bits. * */ switch (cfg & STM32_CAP_EDGE_MASK) { case STM32_CAP_EDGE_DISABLED: regval = 0; ccer_en_bit = 0; break; case STM32_CAP_EDGE_RISING: ccer_en_bit = GTIM_CCER_CC1E; regval = 0; break; case STM32_CAP_EDGE_FALLING: ccer_en_bit = GTIM_CCER_CC1E; regval = GTIM_CCER_CC1P; break; case STM32_CAP_EDGE_BOTH: ccer_en_bit = GTIM_CCER_CC1E; regval = GTIM_CCER_CC1P | GTIM_CCER_CC1NP; break; default: return ERROR; } /* Shift all CCER bits to corresponding channel */ mask = (GTIM_CCER_CC1E | GTIM_CCER_CC1P | GTIM_CCER_CC1NP); mask <<= (channel << 2); regval <<= (channel << 2); ccer_en_bit <<= (channel << 2); stm32_modifyreg16(priv, STM32_GTIM_CCER_OFFSET, mask, regval); /* Set ccmr */ regval = cfg; mask = (GTIM_CCMR1_IC1F_MASK | GTIM_CCMR1_IC1PSC_MASK | GTIM_CCMR1_CC1S_MASK); regval &= mask; if (channel & 1) { regval <<= 8; mask <<= 8; } if (channel < 2) { stm32_modifyreg16(priv, STM32_GTIM_CCMR1_OFFSET, mask, regval); } else { stm32_modifyreg16(priv, STM32_GTIM_CCMR2_OFFSET, mask, regval); } /* Set GPIO */ if ((cfg & STM32_CAP_EDGE_MASK) == STM32_CAP_EDGE_DISABLED) { stm32_unconfiggpio(gpio); } else { stm32_configgpio(gpio); } /* Enable this channel timer */ stm32_modifyreg16(priv, STM32_GTIM_CCER_OFFSET, 0, ccer_en_bit); return OK; }
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; }
static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source) { ASSERT(dev); stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, ATIM_DIER_UIE, 0); }
static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source) { DEBUGASSERT(dev != NULL); stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UIE); }