Lines Matching +full:pwm +full:- +full:mode

6  * SPDX-License-Identifier: Apache-2.0
16 #include <zephyr/drivers/pwm.h>
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
69 /* When PWM capture is done by resetting the counter with UIF then the
71 * This is not the case when using four-channel-support.
77 /** PWM data. */
88 /** PWM configuration. */
183 * Obtain LL polarity from PWM flags.
185 * @param flags PWM flags.
199 * @brief Check if LL counter mode is center-aligned.
201 * @param ll_countermode LL counter mode.
203 * @return `true` when center-aligned, otherwise `false`.
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()
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()
340 LOG_ERR("Cannot set PWM output, capture in progress"); 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()
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()
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()
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()
473 LOG_ERR("Could not initialize main channel for PWM capture"); 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()
482 LOG_ERR("Could not initialize complimentary channel for PWM capture"); 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()
499 * the slave mode controller to reset the counter on each edge. in pwm_stm32_configure_capture()
500 * - Four Channel Support: in pwm_stm32_configure_capture()
502 * slave mode controller it uses the ISR to reset the counter. 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()
526 LOG_ERR("PWM capture already in progress"); in pwm_stm32_configure_capture()
527 return -EBUSY; in pwm_stm32_configure_capture()
531 LOG_ERR("No PWM capture type specified"); 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()
595 LOG_ERR("PWM capture already active"); in pwm_stm32_enable_capture()
596 return -EBUSY; in pwm_stm32_enable_capture()
599 if (!data->capture.callback) { in pwm_stm32_enable_capture()
600 LOG_ERR("PWM capture not configured"); 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()
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()
764 static DEVICE_API(pwm, pwm_stm32_driver_api) = {
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()
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()
809 LOG_ERR("PWM pinctrl setup failed (%d)", r); 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()
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()
842 #define PWM(index) DT_INST_PARENT(index) macro
847 IRQ_CONNECT(DT_IRQ_BY_NAME(PWM(index), name, irq), \
848 DT_IRQ_BY_NAME(PWM(index), name, priority), \
850 irq_enable(DT_IRQ_BY_NAME(PWM(index), name, irq)); \
855 IRQ_CONNECT(DT_IRQN(PWM(index)), \
856 DT_IRQ(PWM(index), priority), \
858 irq_enable(DT_IRQN(PWM(index))); \
864 COND_CODE_1(DT_IRQ_HAS_NAME(PWM(index), cc), \
879 .bus = DT_CLOCKS_CELL(PWM(index), bus), \
880 .enr = DT_CLOCKS_CELL(PWM(index), bits) \
886 .reset = RESET_DT_SPEC_GET(PWM(index)), \
894 .timer = (TIM_TypeDef *)DT_REG_ADDR(PWM(index)), \
895 .prescaler = DT_PROP(PWM(index), st_prescaler), \
896 .countermode = DT_PROP(PWM(index), st_countermode), \