/** * @brief Deactivates the TIMCAP peripheral. * * @param[in] timcapp pointer to the @p TIMCAPDriver object * * @notapi */ void timcap_lld_stop(TIMCAPDriver *timcapp) { if (timcapp->state == TIMCAP_READY) { /* Clock deactivation.*/ timcapp->tim->CR1 = 0; /* Timer disabled. */ timcapp->tim->DIER = 0; /* All IRQs disabled. */ timcapp->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_TIMCAP_USE_TIM1 if (&TIMCAPD1 == timcapp) { nvicDisableVector(STM32_TIM1_UP_NUMBER); nvicDisableVector(STM32_TIM1_CC_NUMBER); rccDisableTIM1(FALSE); } #endif #if STM32_TIMCAP_USE_TIM2 if (&TIMCAPD2 == timcapp) { nvicDisableVector(STM32_TIM2_NUMBER); rccDisableTIM2(FALSE); } #endif #if STM32_TIMCAP_USE_TIM3 if (&TIMCAPD3 == timcapp) { nvicDisableVector(STM32_TIM3_NUMBER); rccDisableTIM3(FALSE); } #endif #if STM32_TIMCAP_USE_TIM4 if (&TIMCAPD4 == timcapp) { nvicDisableVector(STM32_TIM4_NUMBER); rccDisableTIM4(FALSE); } #endif #if STM32_TIMCAP_USE_TIM5 if (&TIMCAPD5 == timcapp) { nvicDisableVector(STM32_TIM5_NUMBER); rccDisableTIM5(FALSE); } #endif #if STM32_TIMCAP_USE_TIM8 if (&TIMCAPD8 == timcapp) { nvicDisableVector(STM32_TIM8_UP_NUMBER); nvicDisableVector(STM32_TIM8_CC_NUMBER); rccDisableTIM8(FALSE); } #endif #if STM32_TIMCAP_USE_TIM9 if (&TIMCAPD9 == timcapp) { nvicDisableVector(STM32_TIM9_NUMBER); rccDisableTIM9(FALSE); } #endif } }
/** * @brief Deactivates the ICU peripheral. * * @param[in] icup pointer to the @p ICUDriver object * * @notapi */ void icu_lld_stop(ICUDriver *icup) { if (icup->state == ICU_READY) { /* Clock deactivation.*/ icup->tim->CR1 = 0; /* Timer disabled. */ icup->tim->DIER = 0; /* All IRQs disabled. */ icup->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_ICU_USE_TIM1 if (&ICUD1 == icup) { nvicDisableVector(STM32_TIM1_UP_NUMBER); nvicDisableVector(STM32_TIM1_CC_NUMBER); rccDisableTIM1(FALSE); } #endif #if STM32_ICU_USE_TIM2 if (&ICUD2 == icup) { nvicDisableVector(STM32_TIM2_NUMBER); rccDisableTIM2(FALSE); } #endif #if STM32_ICU_USE_TIM3 if (&ICUD3 == icup) { nvicDisableVector(STM32_TIM3_NUMBER); rccDisableTIM3(FALSE); } #endif #if STM32_ICU_USE_TIM4 if (&ICUD4 == icup) { nvicDisableVector(STM32_TIM4_NUMBER); rccDisableTIM4(FALSE); } #endif #if STM32_ICU_USE_TIM5 if (&ICUD5 == icup) { nvicDisableVector(STM32_TIM5_NUMBER); rccDisableTIM5(FALSE); } #endif #if STM32_ICU_USE_TIM8 if (&ICUD8 == icup) { nvicDisableVector(STM32_TIM8_UP_NUMBER); nvicDisableVector(STM32_TIM8_CC_NUMBER); rccDisableTIM8(FALSE); } #endif #if STM32_ICU_USE_TIM9 if (&ICUD9 == icup) { nvicDisableVector(STM32_TIM9_NUMBER); rccDisableTIM9(FALSE); } #endif } }
/** * @brief Deactivates the GPT peripheral. * * @param[in] gptp pointer to the @p GPTDriver object * * @notapi */ void gpt_lld_stop(GPTDriver *gptp) { if (gptp->state == GPT_READY) { gptp->tim->CR1 = 0; /* Timer disabled. */ gptp->tim->DIER = 0; /* All IRQs disabled. */ gptp->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_GPT_USE_TIM1 if (&GPTD1 == gptp) { nvicDisableVector(STM32_TIM1_UP_NUMBER); rccDisableTIM1(FALSE); } #endif #if STM32_GPT_USE_TIM2 if (&GPTD2 == gptp) { nvicDisableVector(STM32_TIM2_NUMBER); rccDisableTIM2(FALSE); } #endif #if STM32_GPT_USE_TIM3 if (&GPTD3 == gptp) { nvicDisableVector(STM32_TIM3_NUMBER); rccDisableTIM3(FALSE); } #endif #if STM32_GPT_USE_TIM4 if (&GPTD4 == gptp) { nvicDisableVector(STM32_TIM4_NUMBER); rccDisableTIM4(FALSE); } #endif #if STM32_GPT_USE_TIM5 if (&GPTD5 == gptp) { nvicDisableVector(STM32_TIM5_NUMBER); rccDisableTIM5(FALSE); } #endif #if STM32_GPT_USE_TIM8 if (&GPTD8 == gptp) { nvicDisableVector(STM32_TIM8_UP_NUMBER); rccDisableTIM8(FALSE); } #endif } }
/** * @brief Deactivates the QEI peripheral. * * @param[in] qeip pointer to the @p QEIDriver object * * @notapi */ void qei_lld_stop(QEIDriver *qeip) { if (qeip->state == QEI_READY) { qeip->tim->CR1 = 0; /* Timer disabled. */ /* Clock deactivation.*/ #if STM32_QEI_USE_TIM1 if (&QEID1 == qeip) { rccDisableTIM1(FALSE); } #endif #if STM32_QEI_USE_TIM2 if (&QEID2 == qeip) { rccDisableTIM2(FALSE); } #endif #if STM32_QEI_USE_TIM3 if (&QEID3 == qeip) { rccDisableTIM3(FALSE); } #endif #if STM32_QEI_USE_TIM4 if (&QEID4 == qeip) { rccDisableTIM4(FALSE); } #endif #if STM32_QEI_USE_TIM5 if (&QEID5 == qeip) { rccDisableTIM5(FALSE); } #endif } #if STM32_QEI_USE_TIM8 if (&QEID8 == qeip) { rccDisableTIM8(FALSE); } #endif }
/** * @brief Configures and activates the PWM peripheral. * @note Starting a driver that is already in the @p PWM_READY state * disables all the active channels. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_start(PWMDriver *pwmp) { uint32_t psc; uint32_t ccer; uint32_t dier; if (pwmp->state == PWM_STOP) { /* Clock activation and timer reset.*/ #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { rccEnableTIM1(FALSE); rccResetTIM1(); nvicEnableVector(STM32_TIM1_UP_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM1_CC_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); #if defined(STM32_TIM1CLK) pwmp->clock = STM32_TIM1CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { rccEnableTIM2(FALSE); rccResetTIM2(); nvicEnableVector(STM32_TIM2_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { rccEnableTIM3(FALSE); rccResetTIM3(); nvicEnableVector(STM32_TIM3_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { rccEnableTIM4(FALSE); rccResetTIM4(); nvicEnableVector(STM32_TIM4_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { rccEnableTIM5(FALSE); rccResetTIM5(); nvicEnableVector(STM32_TIM5_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { rccEnableTIM8(FALSE); rccResetTIM8(); nvicEnableVector(STM32_TIM8_UP_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM8_CC_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); #if defined(STM32_TIM8CLK) pwmp->clock = STM32_TIM8CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_PWM_USE_TIM9 if (&PWMD9 == pwmp) { rccEnableTIM9(FALSE); rccResetTIM9(); nvicEnableVector(STM32_TIM9_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM9_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK2; } #endif /* All channels configured in PWM1 mode with preload enabled and will stay that way until the driver is stopped.*/ pwmp->tim->CCMR1 = STM32_TIM_CCMR1_OC1M(6) | STM32_TIM_CCMR1_OC1PE | STM32_TIM_CCMR1_OC2M(6) | STM32_TIM_CCMR1_OC2PE; pwmp->tim->CCMR2 = STM32_TIM_CCMR2_OC3M(6) | STM32_TIM_CCMR2_OC3PE | STM32_TIM_CCMR2_OC4M(6) | STM32_TIM_CCMR2_OC4PE; } else { /* Driver re-configuration scenario, it must be stopped first.*/ pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */ pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */ pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */ pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */ pwmp->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ psc = (pwmp->clock / pwmp->config->frequency) - 1; chDbgAssert((psc <= 0xFFFF) && ((psc + 1) * pwmp->config->frequency) == pwmp->clock, "pwm_lld_start(), #1", "invalid frequency"); pwmp->tim->PSC = (uint16_t)psc; pwmp->tim->ARR = (uint16_t)(pwmp->period - 1); pwmp->tim->CR2 = pwmp->config->cr2; /* Output enables and polarities setup.*/ ccer = 0; switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC1P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC1E; default: ; } switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC2P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC2E; default: ; } switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC3P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC3E; default: ; } switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC4P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC4E; default: ; } #if STM32_PWM_USE_ADVANCED #if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 if (&PWMD1 == pwmp) { #endif #if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { #endif #if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) { #endif switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC1NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC1NE; default: ; } switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC2NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC2NE; default: ; } switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC3NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC3NE; default: ; } } #endif /* STM32_PWM_USE_ADVANCED*/ pwmp->tim->CCER = ccer; pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ pwmp->tim->SR = 0; /* Clear pending IRQs. */ pwmp->tim->DIER = (pwmp->config->callback == NULL ? 0 : STM32_TIM_DIER_UIE) | (pwmp->config->dier & ~STM32_TIM_DIER_IRQ_MASK); #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 #if STM32_PWM_USE_ADVANCED pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE; #else pwmp->tim->BDTR = STM32_TIM_BDTR_MOE; #endif #endif /* Timer configured and started.*/ pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; } /** * @brief Deactivates the PWM peripheral. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_stop(PWMDriver *pwmp) { /* If in ready state then disables the PWM clock.*/ if (pwmp->state == PWM_READY) { pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->DIER = 0; /* All IRQs disabled. */ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 pwmp->tim->BDTR = 0; #endif #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { nvicDisableVector(STM32_TIM1_UP_NUMBER); nvicDisableVector(STM32_TIM1_CC_NUMBER); rccDisableTIM1(FALSE); } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { nvicDisableVector(STM32_TIM2_NUMBER); rccDisableTIM2(FALSE); } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { nvicDisableVector(STM32_TIM3_NUMBER); rccDisableTIM3(FALSE); } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { nvicDisableVector(STM32_TIM4_NUMBER); rccDisableTIM4(FALSE); } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { nvicDisableVector(STM32_TIM5_NUMBER); rccDisableTIM5(FALSE); } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { nvicDisableVector(STM32_TIM8_UP_NUMBER); nvicDisableVector(STM32_TIM8_CC_NUMBER); rccDisableTIM8(FALSE); } #endif #if STM32_PWM_USE_TIM9 if (&PWMD9 == pwmp) { nvicDisableVector(STM32_TIM9_NUMBER); rccDisableTIM9(FALSE); } #endif } } /** * @brief Enables a PWM channel. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is active using the specified configuration. * @note The function has effect at the next cycle start. * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) * @param[in] width PWM pulse width as clock pulses number * * @notapi */ void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width) { pwmp->tim->CCR[channel] = width; /* New duty cycle. */ /* If there is a callback defined for the channel then the associated interrupt must be enabled.*/ if (pwmp->config->channels[channel].callback != NULL) { uint32_t dier = pwmp->tim->DIER; /* If the IRQ is not already enabled care must be taken to clear it, it is probably already pending because the timer is running.*/ if ((dier & (2 << channel)) == 0) { pwmp->tim->DIER = dier | (2 << channel); pwmp->tim->SR = ~(2 << channel); } } } /** * @brief Disables a PWM channel. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is disabled and its output line returned to the * idle state. * @note The function has effect at the next cycle start. * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) * * @notapi */ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) { pwmp->tim->CCR[channel] = 0; pwmp->tim->DIER &= ~(2 << channel); }
/** * @brief Configures and activates the PWM peripheral. * @note Starting a driver that is already in the @p PWM_READY state * disables all the active channels. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_start(PWMDriver *pwmp) { uint32_t psc; uint32_t ccer; if (pwmp->state == PWM_STOP) { /* Clock activation and timer reset.*/ #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { rccEnableTIM1(FALSE); rccResetTIM1(); #if !defined(STM32_TIM1_SUPPRESS_ISR) nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY); nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY); #endif #if defined(STM32_TIM1CLK) pwmp->clock = STM32_TIM1CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { rccEnableTIM2(FALSE); rccResetTIM2(); #if !defined(STM32_TIM2_SUPPRESS_ISR) nvicEnableVector(STM32_TIM2_NUMBER, STM32_PWM_TIM2_IRQ_PRIORITY); #endif #if defined(STM32_TIM2CLK) pwmp->clock = STM32_TIM2CLK; #else pwmp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { rccEnableTIM3(FALSE); rccResetTIM3(); #if !defined(STM32_TIM3_SUPPRESS_ISR) nvicEnableVector(STM32_TIM3_NUMBER, STM32_PWM_TIM3_IRQ_PRIORITY); #endif #if defined(STM32_TIM3CLK) pwmp->clock = STM32_TIM3CLK; #else pwmp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { rccEnableTIM4(FALSE); rccResetTIM4(); #if !defined(STM32_TIM4_SUPPRESS_ISR) nvicEnableVector(STM32_TIM4_NUMBER, STM32_PWM_TIM4_IRQ_PRIORITY); #endif #if defined(STM32_TIM4CLK) pwmp->clock = STM32_TIM4CLK; #else pwmp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { rccEnableTIM5(FALSE); rccResetTIM5(); #if !defined(STM32_TIM5_SUPPRESS_ISR) nvicEnableVector(STM32_TIM5_NUMBER, STM32_PWM_TIM5_IRQ_PRIORITY); #endif #if defined(STM32_TIM5CLK) pwmp->clock = STM32_TIM5CLK; #else pwmp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { rccEnableTIM8(FALSE); rccResetTIM8(); #if !defined(STM32_TIM8_SUPPRESS_ISR) nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY); nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY); #endif #if defined(STM32_TIM8CLK) pwmp->clock = STM32_TIM8CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_PWM_USE_TIM9 if (&PWMD9 == pwmp) { rccEnableTIM9(FALSE); rccResetTIM9(); #if !defined(STM32_TIM9_SUPPRESS_ISR) nvicEnableVector(STM32_TIM9_NUMBER, STM32_PWM_TIM9_IRQ_PRIORITY); #endif #if defined(STM32_TIM9CLK) pwmp->clock = STM32_TIM9CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif /* All channels configured in PWM1 mode with preload enabled and will stay that way until the driver is stopped.*/ pwmp->tim->CCMR1 = STM32_TIM_CCMR1_OC1M(6) | STM32_TIM_CCMR1_OC1PE | STM32_TIM_CCMR1_OC2M(6) | STM32_TIM_CCMR1_OC2PE; pwmp->tim->CCMR2 = STM32_TIM_CCMR2_OC3M(6) | STM32_TIM_CCMR2_OC3PE | STM32_TIM_CCMR2_OC4M(6) | STM32_TIM_CCMR2_OC4PE; #if STM32_TIM_MAX_CHANNELS > 4 pwmp->tim->CCMR3 = STM32_TIM_CCMR3_OC5M(6) | STM32_TIM_CCMR3_OC5PE | STM32_TIM_CCMR3_OC6M(6) | STM32_TIM_CCMR3_OC6PE; #endif } else { /* Driver re-configuration scenario, it must be stopped first.*/ pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */ pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */ pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */ pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */ #if STM32_TIM_MAX_CHANNELS > 4 if (pwmp->channels > 4) { pwmp->tim->CCXR[0] = 0; /* Comparator 5 disabled. */ pwmp->tim->CCXR[1] = 0; /* Comparator 6 disabled. */ } #endif pwmp->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ psc = (pwmp->clock / pwmp->config->frequency) - 1; osalDbgAssert((psc <= 0xFFFF) && ((psc + 1) * pwmp->config->frequency) == pwmp->clock, "invalid frequency"); pwmp->tim->PSC = psc; pwmp->tim->ARR = pwmp->period - 1; pwmp->tim->CR2 = pwmp->config->cr2; /* Output enables and polarities setup.*/ ccer = 0; switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC1P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC1E; default: ; } switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC2P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC2E; default: ; } switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC3P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC3E; default: ; } switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC4P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC4E; default: ; } #if STM32_PWM_USE_ADVANCED #if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 if (&PWMD1 == pwmp) { #endif #if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { #endif #if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) { #endif switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC1NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC1NE; default: ; } switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC2NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC2NE; default: ; } switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC3NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC3NE; default: ; } } #endif /* STM32_PWM_USE_ADVANCED*/ pwmp->tim->CCER = ccer; pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ pwmp->tim->SR = 0; /* Clear pending IRQs. */ pwmp->tim->DIER = pwmp->config->dier & /* DMA-related DIER settings. */ ~STM32_TIM_DIER_IRQ_MASK; #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 #if STM32_PWM_USE_ADVANCED pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE; #else pwmp->tim->BDTR = STM32_TIM_BDTR_MOE; #endif #endif /* Timer configured and started.*/ pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN; } /** * @brief Deactivates the PWM peripheral. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_stop(PWMDriver *pwmp) { /* If in ready state then disables the PWM clock.*/ if (pwmp->state == PWM_READY) { pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->DIER = 0; /* All IRQs disabled. */ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 pwmp->tim->BDTR = 0; #endif #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { #if !defined(STM32_TIM1_SUPPRESS_ISR) nvicDisableVector(STM32_TIM1_UP_NUMBER); nvicDisableVector(STM32_TIM1_CC_NUMBER); #endif rccDisableTIM1(FALSE); } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { #if !defined(STM32_TIM2_SUPPRESS_ISR) nvicDisableVector(STM32_TIM2_NUMBER); #endif rccDisableTIM2(FALSE); } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { #if !defined(STM32_TIM3_SUPPRESS_ISR) nvicDisableVector(STM32_TIM3_NUMBER); #endif rccDisableTIM3(FALSE); } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { #if !defined(STM32_TIM4_SUPPRESS_ISR) nvicDisableVector(STM32_TIM4_NUMBER); #endif rccDisableTIM4(FALSE); } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { #if !defined(STM32_TIM5_SUPPRESS_ISR) nvicDisableVector(STM32_TIM5_NUMBER); #endif rccDisableTIM5(FALSE); } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { #if !defined(STM32_TIM8_SUPPRESS_ISR) nvicDisableVector(STM32_TIM8_UP_NUMBER); nvicDisableVector(STM32_TIM8_CC_NUMBER); #endif rccDisableTIM8(FALSE); } #endif #if STM32_PWM_USE_TIM9 if (&PWMD9 == pwmp) { #if !defined(STM32_TIM9_SUPPRESS_ISR) nvicDisableVector(STM32_TIM9_NUMBER); #endif rccDisableTIM9(FALSE); } #endif } } /** * @brief Enables a PWM channel. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is active using the specified configuration. * @note The function has effect at the next cycle start. * @note Channel notification is not enabled. * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...channels-1) * @param[in] width PWM pulse width as clock pulses number * * @notapi */ void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width) { /* Changing channel duty cycle on the fly.*/ #if STM32_TIM_MAX_CHANNELS <= 4 pwmp->tim->CCR[channel] = width; #else if (channel < 4) pwmp->tim->CCR[channel] = width; else pwmp->tim->CCXR[channel - 4] = width; #endif } /** * @brief Disables a PWM channel and its notification. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is disabled and its output line returned to the * idle state. * @note The function has effect at the next cycle start. * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...channels-1) * * @notapi */ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) { #if STM32_TIM_MAX_CHANNELS <= 4 pwmp->tim->CCR[channel] = 0; pwmp->tim->DIER &= ~(2 << channel); #else if (channel < 4) { pwmp->tim->CCR[channel] = 0; pwmp->tim->DIER &= ~(2 << channel); } else pwmp->tim->CCXR[channel - 4] = 0; #endif }
/** * @brief Deactivates the GPT peripheral. * * @param[in] gptp pointer to the @p GPTDriver object * * @notapi */ void gpt_lld_stop(GPTDriver *gptp) { if (gptp->state == GPT_READY) { gptp->tim->CR1 = 0; /* Timer disabled. */ gptp->tim->DIER = 0; /* All IRQs disabled. */ gptp->tim->SR = 0; /* Clear pending IRQs. */ #if STM32_GPT_USE_TIM1 if (&GPTD1 == gptp) { #if !defined(STM32_TIM1_SUPPRESS_ISR) nvicDisableVector(STM32_TIM1_UP_NUMBER); #endif rccDisableTIM1(FALSE); } #endif #if STM32_GPT_USE_TIM2 if (&GPTD2 == gptp) { #if !defined(STM32_TIM2_SUPPRESS_ISR) nvicDisableVector(STM32_TIM2_NUMBER); #endif rccDisableTIM2(FALSE); } #endif #if STM32_GPT_USE_TIM3 if (&GPTD3 == gptp) { #if !defined(STM32_TIM3_SUPPRESS_ISR) nvicDisableVector(STM32_TIM3_NUMBER); #endif rccDisableTIM3(FALSE); } #endif #if STM32_GPT_USE_TIM4 if (&GPTD4 == gptp) { #if !defined(STM32_TIM4_SUPPRESS_ISR) nvicDisableVector(STM32_TIM4_NUMBER); #endif rccDisableTIM4(FALSE); } #endif #if STM32_GPT_USE_TIM5 if (&GPTD5 == gptp) { #if !defined(STM32_TIM5_SUPPRESS_ISR) nvicDisableVector(STM32_TIM5_NUMBER); #endif rccDisableTIM5(FALSE); } #endif #if STM32_GPT_USE_TIM6 if (&GPTD6 == gptp) { #if !defined(STM32_TIM6_SUPPRESS_ISR) nvicDisableVector(STM32_TIM6_NUMBER); #endif rccDisableTIM6(FALSE); } #endif #if STM32_GPT_USE_TIM7 if (&GPTD7 == gptp) { #if !defined(STM32_TIM7_SUPPRESS_ISR) nvicDisableVector(STM32_TIM7_NUMBER); #endif rccDisableTIM7(FALSE); } #endif #if STM32_GPT_USE_TIM8 if (&GPTD8 == gptp) { #if !defined(STM32_TIM8_SUPPRESS_ISR) nvicDisableVector(STM32_TIM8_UP_NUMBER); #endif rccDisableTIM8(FALSE); } #endif #if STM32_GPT_USE_TIM9 if (&GPTD9 == gptp) { #if !defined(STM32_TIM9_SUPPRESS_ISR) nvicDisableVector(STM32_TIM9_NUMBER); #endif rccDisableTIM9(FALSE); } #endif #if STM32_GPT_USE_TIM11 if (&GPTD11 == gptp) { #if !defined(STM32_TIM11_SUPPRESS_ISR) nvicDisableVector(STM32_TIM11_NUMBER); #endif rccDisableTIM11(FALSE); } #endif #if STM32_GPT_USE_TIM12 if (&GPTD12 == gptp) { #if !defined(STM32_TIM12_SUPPRESS_ISR) nvicDisableVector(STM32_TIM12_NUMBER); #endif rccDisableTIM12(FALSE); } #endif #if STM32_GPT_USE_TIM14 if (&GPTD14 == gptp) { #if !defined(STM32_TIM14_SUPPRESS_ISR) nvicDisableVector(STM32_TIM14_NUMBER); #endif rccDisableTIM14(FALSE); } #endif } }
/** * @brief Deactivates the EICU peripheral. * * @param[in] eicup Pointer to the @p EICUDriver object * * @notapi */ void eicu_lld_stop(EICUDriver *eicup) { if (eicup->state == EICU_READY) { /* Clock deactivation.*/ eicup->tim->CR1 = 0; /* Timer disabled. */ eicup->tim->DIER = 0; /* All IRQs disabled. */ eicup->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_EICU_USE_TIM1 if (&EICUD1 == eicup) { nvicDisableVector(STM32_TIM1_UP_NUMBER); nvicDisableVector(STM32_TIM1_CC_NUMBER); rccDisableTIM1(FALSE); } #endif #if STM32_EICU_USE_TIM2 if (&EICUD2 == eicup) { nvicDisableVector(STM32_TIM2_NUMBER); rccDisableTIM2(FALSE); } #endif #if STM32_EICU_USE_TIM3 if (&EICUD3 == eicup) { nvicDisableVector(STM32_TIM3_NUMBER); rccDisableTIM3(FALSE); } #endif #if STM32_EICU_USE_TIM4 if (&EICUD4 == eicup) { nvicDisableVector(STM32_TIM4_NUMBER); rccDisableTIM4(FALSE); } #endif #if STM32_EICU_USE_TIM5 if (&EICUD5 == eicup) { nvicDisableVector(STM32_TIM5_NUMBER); rccDisableTIM5(FALSE); } #endif #if STM32_EICU_USE_TIM8 if (&EICUD8 == eicup) { nvicDisableVector(STM32_TIM8_UP_NUMBER); nvicDisableVector(STM32_TIM8_CC_NUMBER); rccDisableTIM8(FALSE); } #endif #if STM32_EICU_USE_TIM9 if (&EICUD9 == eicup) { nvicDisableVector(STM32_TIM9_NUMBER); rccDisableTIM9(FALSE); } #endif #if STM32_EICU_USE_TIM12 if (&EICUD12 == eicup) { nvicDisableVector(STM32_TIM12_NUMBER); rccDisableTIM12(FALSE); } #endif } #if STM32_EICU_USE_TIM10 if (&EICUD10 == eicup) { nvicDisableVector(STM32_TIM10_NUMBER); rccDisableTIM10(FALSE); } #endif #if STM32_EICU_USE_TIM11 if (&EICUD11 == eicup) { nvicDisableVector(STM32_TIM11_NUMBER); rccDisableTIM11(FALSE); } #endif #if STM32_EICU_USE_TIM13 if (&EICUD13 == eicup) { nvicDisableVector(STM32_TIM13_NUMBER); rccDisableTIM13(FALSE); } #endif #if STM32_EICU_USE_TIM14 if (&EICUD14 == eicup) { nvicDisableVector(STM32_TIM14_NUMBER); rccDisableTIM14(FALSE); } #endif }