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); }
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; }
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); }
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; }
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 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; }
static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source) { stm32_putreg16(dev, STM32_BTIM_SR_OFFSET, ~ATIM_SR_UIF); }
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); }
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); }
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; }