Lines Matching +full:one +full:- +full:timer +full:- +full:only
6 * SPDX-License-Identifier: Apache-2.0
24 #include <zephyr/dt-bindings/pwm/stm32_pwm.h>
31 /* L0 series MCUs only have 16-bit timers and don't have below macro defined */
39 * @brief Capture state when in 4-channel support mode
65 /* only used when four_channel_capture_support */
71 * This is not the case when using four-channel-support.
79 /** Timer clock (Hz). */
90 TIM_TypeDef *timer; member
101 /** Maximum number of timer channels : some stm32 soc have 6 else only 4 */
131 /** Maximum number of complemented timer channels is ARRAY_SIZE(ch2ll_n)*/
199 * @brief Check if LL counter mode is center-aligned.
203 * @return `true` when center-aligned, otherwise `false`.
213 * Obtain timer clock speed.
215 * @param pclken Timer clock control subsystem.
216 * @param tim_clk Where computed timer clock will be stored.
235 if (pclken->bus == STM32_CLOCK_BUS_APB1) { in get_tim_clk()
241 if (pclken->bus == STM32_CLOCK_BUS_APB1) { in get_tim_clk()
243 apb_psc = (uint32_t)(READ_BIT(RCC->APB1DIVR, RCC_APB1DIVR_APB1DIV)); in get_tim_clk()
252 apb_psc = (uint32_t)(READ_BIT(RCC->APB2DIVR, RCC_APB2DIVR_APB2DIV)); in get_tim_clk()
267 * Up to a certain threshold value of APB{1,2} prescaler, timer clock in get_tim_clk()
269 * (2 if TIMPRE=0, 4 if TIMPRE=1). Above threshold, timer clock is set in get_tim_clk()
297 * If the APB prescaler equals 1, the timer clock frequencies in get_tim_clk()
316 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_set_cycles()
324 return -EINVAL; in pwm_stm32_set_cycles()
328 * Non 32-bit timers count from 0 up to the value in the ARR register in pwm_stm32_set_cycles()
329 * (16-bit). Thus period_cycles cannot be greater than UINT16_MAX + 1. in pwm_stm32_set_cycles()
331 if (!IS_TIM_32B_COUNTER_INSTANCE(cfg->timer) && in pwm_stm32_set_cycles()
333 LOG_ERR("Cannot set PWM output, value exceeds 16-bit timer limit."); in pwm_stm32_set_cycles()
334 return -ENOTSUP; in pwm_stm32_set_cycles()
338 if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || LL_TIM_IsEnabledIT_CC2(cfg->timer) || in pwm_stm32_set_cycles()
339 LL_TIM_IsEnabledIT_CC3(cfg->timer) || LL_TIM_IsEnabledIT_CC4(cfg->timer)) { in pwm_stm32_set_cycles()
341 return -EBUSY; in pwm_stm32_set_cycles()
345 ll_channel = ch2ll[channel - 1u]; in pwm_stm32_set_cycles()
348 negative_ll_channel = ch2ll_n[channel - 1u]; in pwm_stm32_set_cycles()
354 * the channel param could be the complementary one in pwm_stm32_set_cycles()
360 return -EINVAL; in pwm_stm32_set_cycles()
368 LL_TIM_CC_DisableChannel(cfg->timer, current_ll_channel); in pwm_stm32_set_cycles()
372 if (cfg->countermode == LL_TIM_COUNTERMODE_UP) { in pwm_stm32_set_cycles()
374 period_cycles -= 1U; in pwm_stm32_set_cycles()
375 } else if (cfg->countermode == LL_TIM_COUNTERMODE_DOWN) { in pwm_stm32_set_cycles()
377 pulse_cycles -= 1U; in pwm_stm32_set_cycles()
379 period_cycles -= 1U; in pwm_stm32_set_cycles()
380 } else if (is_center_aligned(cfg->countermode)) { in pwm_stm32_set_cycles()
384 return -ENOTSUP; in pwm_stm32_set_cycles()
387 if (!LL_TIM_CC_IsEnabledChannel(cfg->timer, current_ll_channel)) { in pwm_stm32_set_cycles()
401 oc_init.OCState = LL_TIM_CC_IsEnabledChannel(cfg->timer, ll_channel) in pwm_stm32_set_cycles()
404 oc_init.OCPolarity = LL_TIM_OC_GetPolarity(cfg->timer, ll_channel); in pwm_stm32_set_cycles()
412 LL_TIM_CC_IsEnabledChannel(cfg->timer, negative_ll_channel) in pwm_stm32_set_cycles()
416 LL_TIM_OC_GetPolarity(cfg->timer, negative_ll_channel); in pwm_stm32_set_cycles()
427 if (IS_TIM_SLAVE_INSTANCE(cfg->timer)) { in pwm_stm32_set_cycles()
428 LL_TIM_SetSlaveMode(cfg->timer, in pwm_stm32_set_cycles()
430 LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_ITR0); in pwm_stm32_set_cycles()
431 LL_TIM_DisableMasterSlaveMode(cfg->timer); in pwm_stm32_set_cycles()
435 /* in LL_TIM_OC_Init, the channel is always the non-complementary */ in pwm_stm32_set_cycles()
436 if (LL_TIM_OC_Init(cfg->timer, ll_channel, &oc_init) != SUCCESS) { in pwm_stm32_set_cycles()
437 LOG_ERR("Could not initialize timer channel output"); in pwm_stm32_set_cycles()
438 return -EIO; in pwm_stm32_set_cycles()
441 LL_TIM_EnableARRPreload(cfg->timer); in pwm_stm32_set_cycles()
442 /* in LL_TIM_OC_EnablePreload, the channel is always the non-complementary */ in pwm_stm32_set_cycles()
443 LL_TIM_OC_EnablePreload(cfg->timer, ll_channel); in pwm_stm32_set_cycles()
444 LL_TIM_SetAutoReload(cfg->timer, period_cycles); in pwm_stm32_set_cycles()
445 LL_TIM_GenerateEvent_UPDATE(cfg->timer); in pwm_stm32_set_cycles()
447 /* in LL_TIM_OC_SetPolarity, the channel could be the complementary one */ in pwm_stm32_set_cycles()
448 LL_TIM_OC_SetPolarity(cfg->timer, current_ll_channel, get_polarity(flags)); in pwm_stm32_set_cycles()
449 set_timer_compare[channel - 1u](cfg->timer, pulse_cycles); in pwm_stm32_set_cycles()
450 LL_TIM_SetAutoReload(cfg->timer, period_cycles); in pwm_stm32_set_cycles()
460 const struct pwm_stm32_config *cfg = dev->config; in init_capture_channels()
472 if (LL_TIM_IC_Init(cfg->timer, ch2ll[channel - 1], &ic) != SUCCESS) { in init_capture_channels()
474 return -EIO; in init_capture_channels()
481 if (LL_TIM_IC_Init(cfg->timer, ch2ll[complimentary_channel[channel] - 1], &ic) != SUCCESS) { in init_capture_channels()
483 return -EIO; in init_capture_channels()
496 * four-channel-capture-support setting in the node. in pwm_stm32_configure_capture()
497 * - Two Channel Support: in pwm_stm32_configure_capture()
498 * Only two channels (1 and 2) are available for capture. It uses in pwm_stm32_configure_capture()
500 * - Four Channel Support: in pwm_stm32_configure_capture()
507 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_configure_capture()
508 struct pwm_stm32_data *data = dev->data; in pwm_stm32_configure_capture()
509 struct pwm_stm32_capture_data *cpt = &data->capture; in pwm_stm32_configure_capture()
512 if (!cfg->four_channel_capture_support) { in pwm_stm32_configure_capture()
514 LOG_ERR("PWM capture only supported on first two channels"); in pwm_stm32_configure_capture()
515 return -ENOTSUP; in pwm_stm32_configure_capture()
519 LOG_ERR("PWM capture only exists on channels 1, 2, 3 and 4."); in pwm_stm32_configure_capture()
520 return -ENOTSUP; in pwm_stm32_configure_capture()
524 if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || LL_TIM_IsEnabledIT_CC2(cfg->timer) || in pwm_stm32_configure_capture()
525 LL_TIM_IsEnabledIT_CC3(cfg->timer) || LL_TIM_IsEnabledIT_CC4(cfg->timer)) { in pwm_stm32_configure_capture()
527 return -EBUSY; in pwm_stm32_configure_capture()
532 return -EINVAL; in pwm_stm32_configure_capture()
535 if (!cfg->four_channel_capture_support && !IS_TIM_SLAVE_INSTANCE(cfg->timer)) { in pwm_stm32_configure_capture()
536 /* slave mode is only used when not in four channel mode */ in pwm_stm32_configure_capture()
537 LOG_ERR("Timer does not support slave mode for PWM capture"); in pwm_stm32_configure_capture()
538 return -ENOTSUP; in pwm_stm32_configure_capture()
541 cpt->callback = cb; /* even if the cb is reset, this is not an error */ in pwm_stm32_configure_capture()
542 cpt->user_data = user_data; in pwm_stm32_configure_capture()
543 cpt->capture_period = (flags & PWM_CAPTURE_TYPE_PERIOD) ? true : false; in pwm_stm32_configure_capture()
544 cpt->capture_pulse = (flags & PWM_CAPTURE_TYPE_PULSE) ? true : false; in pwm_stm32_configure_capture()
545 cpt->continuous = (flags & PWM_CAPTURE_MODE_CONTINUOUS) ? true : false; in pwm_stm32_configure_capture()
548 LL_TIM_SetSlaveMode(cfg->timer, LL_TIM_SLAVEMODE_DISABLED); in pwm_stm32_configure_capture()
555 if (!cfg->four_channel_capture_support) { in pwm_stm32_configure_capture()
557 LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_TI1FP1); in pwm_stm32_configure_capture()
559 LL_TIM_SetTriggerInput(cfg->timer, LL_TIM_TS_TI2FP2); in pwm_stm32_configure_capture()
561 LL_TIM_SetSlaveMode(cfg->timer, LL_TIM_SLAVEMODE_RESET); in pwm_stm32_configure_capture()
564 LL_TIM_EnableARRPreload(cfg->timer); in pwm_stm32_configure_capture()
565 if (!IS_TIM_32B_COUNTER_INSTANCE(cfg->timer)) { in pwm_stm32_configure_capture()
566 LL_TIM_SetAutoReload(cfg->timer, 0xffffu); in pwm_stm32_configure_capture()
568 LL_TIM_SetAutoReload(cfg->timer, 0xffffffffu); in pwm_stm32_configure_capture()
570 LL_TIM_EnableUpdateEvent(cfg->timer); in pwm_stm32_configure_capture()
577 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_enable_capture()
578 struct pwm_stm32_data *data = dev->data; in pwm_stm32_enable_capture()
579 struct pwm_stm32_capture_data *cpt = &data->capture; in pwm_stm32_enable_capture()
581 if (!cfg->four_channel_capture_support) { in pwm_stm32_enable_capture()
583 LOG_ERR("PWM capture only supported on first two channels"); in pwm_stm32_enable_capture()
584 return -ENOTSUP; in pwm_stm32_enable_capture()
588 LOG_ERR("PWM capture only exists on channels 1, 2, 3 and 4."); in pwm_stm32_enable_capture()
589 return -ENOTSUP; in pwm_stm32_enable_capture()
593 if (LL_TIM_IsEnabledIT_CC1(cfg->timer) || LL_TIM_IsEnabledIT_CC2(cfg->timer) || in pwm_stm32_enable_capture()
594 LL_TIM_IsEnabledIT_CC3(cfg->timer) || LL_TIM_IsEnabledIT_CC4(cfg->timer)) { in pwm_stm32_enable_capture()
596 return -EBUSY; in pwm_stm32_enable_capture()
599 if (!data->capture.callback) { in pwm_stm32_enable_capture()
601 return -EINVAL; in pwm_stm32_enable_capture()
604 cpt->channel = channel; in pwm_stm32_enable_capture()
605 cpt->state = CAPTURE_STATE_WAIT_FOR_PULSE_START; in pwm_stm32_enable_capture()
606 data->capture.skip_irq = cfg->four_channel_capture_support ? 0 : SKIPPED_PWM_CAPTURES; in pwm_stm32_enable_capture()
607 data->capture.overflows = 0u; in pwm_stm32_enable_capture()
609 clear_capture_interrupt[channel - 1](cfg->timer); in pwm_stm32_enable_capture()
610 LL_TIM_ClearFlag_UPDATE(cfg->timer); in pwm_stm32_enable_capture()
612 LL_TIM_SetUpdateSource(cfg->timer, LL_TIM_UPDATESOURCE_COUNTER); in pwm_stm32_enable_capture()
614 enable_capture_interrupt[channel - 1](cfg->timer); in pwm_stm32_enable_capture()
616 LL_TIM_CC_EnableChannel(cfg->timer, ch2ll[channel - 1]); in pwm_stm32_enable_capture()
617 LL_TIM_CC_EnableChannel(cfg->timer, ch2ll[complimentary_channel[channel] - 1]); in pwm_stm32_enable_capture()
618 LL_TIM_EnableIT_UPDATE(cfg->timer); in pwm_stm32_enable_capture()
619 LL_TIM_GenerateEvent_UPDATE(cfg->timer); in pwm_stm32_enable_capture()
626 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_disable_capture()
628 if (!cfg->four_channel_capture_support) { in pwm_stm32_disable_capture()
630 LOG_ERR("PWM capture only supported on first two channels"); in pwm_stm32_disable_capture()
631 return -ENOTSUP; in pwm_stm32_disable_capture()
635 LOG_ERR("PWM capture only exists on channels 1, 2, 3 and 4."); in pwm_stm32_disable_capture()
636 return -ENOTSUP; in pwm_stm32_disable_capture()
640 LL_TIM_SetUpdateSource(cfg->timer, LL_TIM_UPDATESOURCE_REGULAR); in pwm_stm32_disable_capture()
642 disable_capture_interrupt[channel - 1](cfg->timer); in pwm_stm32_disable_capture()
644 LL_TIM_DisableIT_UPDATE(cfg->timer); in pwm_stm32_disable_capture()
645 LL_TIM_CC_DisableChannel(cfg->timer, ch2ll[channel - 1]); in pwm_stm32_disable_capture()
646 LL_TIM_CC_DisableChannel(cfg->timer, ch2ll[complimentary_channel[channel] - 1]); in pwm_stm32_disable_capture()
653 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_isr()
654 struct pwm_stm32_data *data = dev->data; in pwm_stm32_isr()
655 struct pwm_stm32_capture_data *cpt = &data->capture; in pwm_stm32_isr()
658 if (cpt->skip_irq != 0u) { in pwm_stm32_isr()
659 if (LL_TIM_IsActiveFlag_UPDATE(cfg->timer)) { in pwm_stm32_isr()
660 LL_TIM_ClearFlag_UPDATE(cfg->timer); in pwm_stm32_isr()
663 if (LL_TIM_IsActiveFlag_CC1(cfg->timer) in pwm_stm32_isr()
664 || LL_TIM_IsActiveFlag_CC2(cfg->timer) in pwm_stm32_isr()
665 || LL_TIM_IsActiveFlag_CC3(cfg->timer) in pwm_stm32_isr()
666 || LL_TIM_IsActiveFlag_CC4(cfg->timer)) { in pwm_stm32_isr()
667 LL_TIM_ClearFlag_CC1(cfg->timer); in pwm_stm32_isr()
668 LL_TIM_ClearFlag_CC2(cfg->timer); in pwm_stm32_isr()
669 LL_TIM_ClearFlag_CC3(cfg->timer); in pwm_stm32_isr()
670 LL_TIM_ClearFlag_CC4(cfg->timer); in pwm_stm32_isr()
671 cpt->skip_irq--; in pwm_stm32_isr()
677 if (LL_TIM_IsActiveFlag_UPDATE(cfg->timer)) { in pwm_stm32_isr()
678 LL_TIM_ClearFlag_UPDATE(cfg->timer); in pwm_stm32_isr()
679 if (cfg->four_channel_capture_support && in pwm_stm32_isr()
680 cpt->state == CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT) { in pwm_stm32_isr()
682 cpt->state = CAPTURE_STATE_WAIT_FOR_PERIOD_END; in pwm_stm32_isr()
684 cpt->overflows++; in pwm_stm32_isr()
688 if (!cfg->four_channel_capture_support) { in pwm_stm32_isr()
689 if (is_capture_active[cpt->channel - 1](cfg->timer) || in pwm_stm32_isr()
690 is_capture_active[complimentary_channel[cpt->channel] - 1](cfg->timer)) { in pwm_stm32_isr()
691 clear_capture_interrupt[cpt->channel - 1](cfg->timer); in pwm_stm32_isr()
693 [complimentary_channel[cpt->channel] - 1](cfg->timer); in pwm_stm32_isr()
695 cpt->period = get_channel_capture[cpt->channel - 1](cfg->timer); in pwm_stm32_isr()
696 cpt->pulse = get_channel_capture in pwm_stm32_isr()
697 [complimentary_channel[cpt->channel] - 1](cfg->timer); in pwm_stm32_isr()
700 if (cpt->state == CAPTURE_STATE_WAIT_FOR_PULSE_START && in pwm_stm32_isr()
701 is_capture_active[cpt->channel - 1](cfg->timer)) { in pwm_stm32_isr()
703 * This sets the pulse-start at 0 and makes the pulse-end in pwm_stm32_isr()
711 cpt->state = CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT; in pwm_stm32_isr()
712 LL_TIM_GenerateEvent_UPDATE(cfg->timer); in pwm_stm32_isr()
714 } else if ((cpt->state == CAPTURE_STATE_WAIT_FOR_UPDATE_EVENT || in pwm_stm32_isr()
715 cpt->state == CAPTURE_STATE_WAIT_FOR_PERIOD_END) && in pwm_stm32_isr()
716 is_capture_active[cpt->channel - 1](cfg->timer)) { in pwm_stm32_isr()
717 cpt->state = CAPTURE_STATE_IDLE; in pwm_stm32_isr()
719 * the timer value when the pulse and period ended respectively. in pwm_stm32_isr()
721 cpt->pulse = get_channel_capture[complimentary_channel[cpt->channel] - 1] in pwm_stm32_isr()
722 (cfg->timer); in pwm_stm32_isr()
723 cpt->period = get_channel_capture[cpt->channel - 1](cfg->timer); in pwm_stm32_isr()
726 clear_capture_interrupt[cpt->channel - 1](cfg->timer); in pwm_stm32_isr()
728 if (cpt->state != CAPTURE_STATE_IDLE) { in pwm_stm32_isr()
734 if (cpt->overflows) { in pwm_stm32_isr()
735 status = -ERANGE; in pwm_stm32_isr()
738 if (!cpt->continuous) { in pwm_stm32_isr()
739 pwm_stm32_disable_capture(dev, cpt->channel); in pwm_stm32_isr()
741 cpt->overflows = 0u; in pwm_stm32_isr()
742 cpt->state = CAPTURE_STATE_WAIT_FOR_PULSE_START; in pwm_stm32_isr()
745 if (cpt->callback != NULL) { in pwm_stm32_isr()
746 cpt->callback(dev, cpt->channel, cpt->capture_period ? cpt->period : 0u, in pwm_stm32_isr()
747 cpt->capture_pulse ? cpt->pulse : 0u, status, cpt->user_data); in pwm_stm32_isr()
756 struct pwm_stm32_data *data = dev->data; in pwm_stm32_get_cycles_per_sec()
757 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_get_cycles_per_sec()
759 *cycles = (uint64_t)(data->tim_clk / (cfg->prescaler + 1)); in pwm_stm32_get_cycles_per_sec()
776 struct pwm_stm32_data *data = dev->data; in pwm_stm32_init()
777 const struct pwm_stm32_config *cfg = dev->config; in pwm_stm32_init()
788 return -ENODEV; in pwm_stm32_init()
791 r = clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken); in pwm_stm32_init()
797 r = get_tim_clk(&cfg->pclken, &data->tim_clk); in pwm_stm32_init()
799 LOG_ERR("Could not obtain timer clock (%d)", r); in pwm_stm32_init()
803 /* Reset timer to default state using RCC */ in pwm_stm32_init()
804 (void)reset_line_toggle_dt(&data->reset); in pwm_stm32_init()
807 r = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); in pwm_stm32_init()
813 /* initialize timer */ in pwm_stm32_init()
816 init.Prescaler = cfg->prescaler; in pwm_stm32_init()
817 init.CounterMode = cfg->countermode; in pwm_stm32_init()
821 if (LL_TIM_Init(cfg->timer, &init) != SUCCESS) { in pwm_stm32_init()
822 LOG_ERR("Could not initialize timer"); in pwm_stm32_init()
823 return -EIO; in pwm_stm32_init()
828 if (IS_TIM_BREAK_INSTANCE(cfg->timer)) { in pwm_stm32_init()
829 LL_TIM_EnableAllOutputs(cfg->timer); in pwm_stm32_init()
833 LL_TIM_EnableCounter(cfg->timer); in pwm_stm32_init()
836 cfg->irq_config_func(dev); in pwm_stm32_init()
894 .timer = (TIM_TypeDef *)DT_REG_ADDR(PWM(index)), \
897 .pclken = DT_INST_CLK(index, timer), \