diff --git a/drivers/pwm/pwm_mcux_sctimer.c b/drivers/pwm/pwm_mcux_sctimer.c index fe5eda5d3d0341..611d78191aef5d 100644 --- a/drivers/pwm/pwm_mcux_sctimer.c +++ b/drivers/pwm/pwm_mcux_sctimer.c @@ -31,6 +31,53 @@ struct pwm_mcux_sctimer_data { sctimer_pwm_signal_param_t channel[CHANNEL_COUNT]; }; + + +static int mcux_sctimer_pwm_get_cycles_per_sec(const struct device *dev, + uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + + *cycles = CLOCK_GetFreq(kCLOCK_BusClk) / config->prescale; + + return 0; +} + +static int mcux_sctimer_pwm_init(const struct device *dev) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + sctimer_config_t pwm_config; + status_t status; + int i; + int err; + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + SCTIMER_GetDefaultConfig(&pwm_config); + /* Divide the SCT clock by 8 */ + pwm_config.prescale_l = config->prescale - 1; + + status = SCTIMER_Init(config->base, &pwm_config); + if (status != kStatus_Success) { + LOG_ERR("Unable to init PWM"); + return -EIO; + } + + for (i = 0; i < CHANNEL_COUNT; i++) { + data->channel[i].output = i; + data->channel[i].level = kSCTIMER_HighTrue; + data->channel[i].dutyCyclePercent = 0; + data->period_cycles[i] = 0; + } + + return 0; +} + static int mcux_sctimer_pwm_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags) @@ -58,17 +105,9 @@ static int mcux_sctimer_pwm_set_cycles(const struct device *dev, duty_cycle = 100 * pulse_cycles / period_cycles; if (duty_cycle == 0) { - SCT_Type *base = config->base; - - SCTIMER_StopTimer(config->base, kSCTIMER_Counter_U); - - /* Set the output to inactive State */ - if (data->channel[channel].level == kSCTIMER_HighTrue) { - base->OUTPUT &= ~(1UL << channel); - } else { - base->OUTPUT |= (1UL << channel); - } - + // Workaround fix to make it work for WMS V2 + LOG_DBG("Stop SCTimer Workaround: Re-Init SCTimer to reset all events"); + mcux_sctimer_pwm_init(dev); return 0; } @@ -104,6 +143,7 @@ static int mcux_sctimer_pwm_set_cycles(const struct device *dev, SCTIMER_StartTimer(config->base, kSCTIMER_Counter_U); } else { + LOG_DBG("UPDATE dutycycle to %u\n", duty_cycle); data->period_cycles[channel] = period_cycles; SCTIMER_UpdatePwmDutycycle(config->base, channel, duty_cycle, data->event_number[channel]); @@ -112,51 +152,6 @@ static int mcux_sctimer_pwm_set_cycles(const struct device *dev, return 0; } -static int mcux_sctimer_pwm_get_cycles_per_sec(const struct device *dev, - uint32_t channel, - uint64_t *cycles) -{ - const struct pwm_mcux_sctimer_config *config = dev->config; - - *cycles = CLOCK_GetFreq(kCLOCK_BusClk) / config->prescale; - - return 0; -} - -static int mcux_sctimer_pwm_init(const struct device *dev) -{ - const struct pwm_mcux_sctimer_config *config = dev->config; - struct pwm_mcux_sctimer_data *data = dev->data; - sctimer_config_t pwm_config; - status_t status; - int i; - int err; - - err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (err) { - return err; - } - - SCTIMER_GetDefaultConfig(&pwm_config); - /* Divide the SCT clock by 8 */ - pwm_config.prescale_l = config->prescale - 1; - - status = SCTIMER_Init(config->base, &pwm_config); - if (status != kStatus_Success) { - LOG_ERR("Unable to init PWM"); - return -EIO; - } - - for (i = 0; i < CHANNEL_COUNT; i++) { - data->channel[i].output = i; - data->channel[i].level = kSCTIMER_HighTrue; - data->channel[i].dutyCyclePercent = 0; - data->period_cycles[i] = 0; - } - - return 0; -} - static const struct pwm_driver_api pwm_mcux_sctimer_driver_api = { .set_cycles = mcux_sctimer_pwm_set_cycles, .get_cycles_per_sec = mcux_sctimer_pwm_get_cycles_per_sec,