drivers: pwm: mcux_ftm: configure pwm in ticks, not frequency/percent
Configure the PWM period and pulse width in timer ticks instead of calculating the frequency and duty cycle for use in the higher level MCUX API. This improves the resolution of the PWM output signal considerably. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
80a0d9d16b
commit
2703d4cd20
1 changed files with 17 additions and 37 deletions
|
@ -30,7 +30,7 @@ struct mcux_ftm_config {
|
|||
struct mcux_ftm_data {
|
||||
u32_t clock_freq;
|
||||
u32_t period_cycles;
|
||||
ftm_chnl_pwm_signal_param_t channel[MAX_CHANNELS];
|
||||
ftm_chnl_pwm_config_param_t channel[MAX_CHANNELS];
|
||||
};
|
||||
|
||||
static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
||||
|
@ -39,7 +39,7 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
{
|
||||
const struct mcux_ftm_config *config = dev->config->config_info;
|
||||
struct mcux_ftm_data *data = dev->driver_data;
|
||||
u8_t duty_cycle;
|
||||
status_t status;
|
||||
|
||||
if ((period_cycles == 0U) || (pulse_cycles > period_cycles)) {
|
||||
LOG_ERR("Invalid combination: period_cycles=%d, "
|
||||
|
@ -52,8 +52,7 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
duty_cycle = pulse_cycles * 100U / period_cycles;
|
||||
data->channel[pwm].dutyCyclePercent = duty_cycle;
|
||||
data->channel[pwm].dutyValue = pulse_cycles;
|
||||
|
||||
if ((flags & PWM_POLARITY_INVERTED) == 0) {
|
||||
data->channel[pwm].level = kFTM_HighTrue;
|
||||
|
@ -61,13 +60,10 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
data->channel[pwm].level = kFTM_LowTrue;
|
||||
}
|
||||
|
||||
LOG_DBG("pulse_cycles=%d, period_cycles=%d, duty_cycle=%d, flags=%d",
|
||||
pulse_cycles, period_cycles, duty_cycle, flags);
|
||||
LOG_DBG("pulse_cycles=%d, period_cycles=%d, flags=%d",
|
||||
pulse_cycles, period_cycles, flags);
|
||||
|
||||
if (period_cycles != data->period_cycles) {
|
||||
u32_t pwm_freq;
|
||||
status_t status;
|
||||
|
||||
if (data->period_cycles != 0) {
|
||||
/* Only warn when not changing from zero */
|
||||
LOG_WRN("Changing period cycles from %d to %d"
|
||||
|
@ -78,38 +74,22 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
|
||||
data->period_cycles = period_cycles;
|
||||
|
||||
pwm_freq = (data->clock_freq >> config->prescale) /
|
||||
period_cycles;
|
||||
|
||||
LOG_DBG("pwm_freq=%d, clock_freq=%d", pwm_freq,
|
||||
data->clock_freq);
|
||||
|
||||
if (pwm_freq == 0U) {
|
||||
LOG_ERR("Could not set up pwm_freq=%d", pwm_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
FTM_StopTimer(config->base);
|
||||
FTM_SetTimerPeriod(config->base, period_cycles);
|
||||
|
||||
status = FTM_SetupPwm(config->base, data->channel,
|
||||
config->channel_count, config->mode,
|
||||
pwm_freq, data->clock_freq);
|
||||
|
||||
if (status != kStatus_Success) {
|
||||
LOG_ERR("Could not set up pwm");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
FTM_SetSoftwareTrigger(config->base, true);
|
||||
FTM_StartTimer(config->base, config->ftm_clock_source);
|
||||
|
||||
} else {
|
||||
FTM_UpdatePwmDutycycle(config->base, pwm, config->mode,
|
||||
duty_cycle);
|
||||
FTM_UpdateChnlEdgeLevelSelect(config->base, pwm,
|
||||
data->channel[pwm].level);
|
||||
FTM_SetSoftwareTrigger(config->base, true);
|
||||
}
|
||||
|
||||
status = FTM_SetupPwmMode(config->base, data->channel,
|
||||
config->channel_count, config->mode);
|
||||
if (status != kStatus_Success) {
|
||||
LOG_ERR("Could not set up pwm");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
FTM_SetSoftwareTrigger(config->base, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -128,7 +108,7 @@ static int mcux_ftm_init(struct device *dev)
|
|||
{
|
||||
const struct mcux_ftm_config *config = dev->config->config_info;
|
||||
struct mcux_ftm_data *data = dev->driver_data;
|
||||
ftm_chnl_pwm_signal_param_t *channel = data->channel;
|
||||
ftm_chnl_pwm_config_param_t *channel = data->channel;
|
||||
struct device *clock_dev;
|
||||
ftm_config_t ftm_config;
|
||||
int i;
|
||||
|
@ -153,8 +133,8 @@ static int mcux_ftm_init(struct device *dev)
|
|||
for (i = 0; i < config->channel_count; i++) {
|
||||
channel->chnlNumber = i;
|
||||
channel->level = kFTM_NoPwmSignal;
|
||||
channel->dutyCyclePercent = 0;
|
||||
channel->firstEdgeDelayPercent = 0;
|
||||
channel->dutyValue = 0;
|
||||
channel->firstEdgeValue = 0;
|
||||
channel++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue