Skip to content

Commit 886a99e

Browse files
PetervdPerk-NXPkartben
authored andcommitted
kinetis-tpm: Implement pulse_cycles directly instead of duty cycle
When using low PWM frequency i.e 50Hz the resolution of pulse_cycles got lost from converting pulse_cycles to duty cycle % and then back to pulse_cycles again. Furthermore TPM_UpdateChnlEdgeLevelSelect call would restart the pwm constantly on a mcux_tpm_set_cycles call now only call TPM_UpdateChnlEdgeLevelSelect when changing the polarity Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
1 parent d2d0e85 commit 886a99e

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

drivers/pwm/pwm_mcux_tpm.c

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,22 @@ static int mcux_tpm_set_cycles(const struct device *dev, uint32_t channel,
5555
{
5656
const struct mcux_tpm_config *config = dev->config;
5757
struct mcux_tpm_data *data = dev->data;
58-
uint8_t duty_cycle;
59-
60-
if (period_cycles == 0U) {
61-
LOG_ERR("Channel can not be set to inactive level");
62-
return -ENOTSUP;
63-
}
6458

6559
if (channel >= config->channel_count) {
6660
LOG_ERR("Invalid channel");
6761
return -ENOTSUP;
6862
}
6963

70-
duty_cycle = pulse_cycles * 100U / period_cycles;
71-
data->channel[channel].dutyCyclePercent = duty_cycle;
64+
if (period_cycles == 0 || period_cycles == TPM_MAX_COUNTER_VALUE(base)) {
65+
return -ENOTSUP;
66+
}
7267

73-
if ((flags & PWM_POLARITY_INVERTED) == 0) {
74-
data->channel[channel].level = kTPM_HighTrue;
75-
} else {
76-
data->channel[channel].level = kTPM_LowTrue;
68+
if ((TPM_MAX_COUNTER_VALUE(base) == 0xFFFFU) &&
69+
(pulse_cycles > TPM_MAX_COUNTER_VALUE(base))) {
70+
return -ENOTSUP;
7771
}
7872

79-
LOG_DBG("pulse_cycles=%d, period_cycles=%d, duty_cycle=%d, flags=%d",
80-
pulse_cycles, period_cycles, duty_cycle, flags);
73+
LOG_DBG("pulse_cycles=%d, period_cycles=%d, flags=%d", pulse_cycles, period_cycles, flags);
8174

8275
if (period_cycles != data->period_cycles) {
8376
uint32_t pwm_freq;
@@ -106,6 +99,9 @@ static int mcux_tpm_set_cycles(const struct device *dev, uint32_t channel,
10699

107100
TPM_StopTimer(config->base);
108101

102+
/* Set counter back to zero */
103+
config->base->CNT = 0;
104+
109105
status = TPM_SetupPwm(config->base, data->channel,
110106
config->channel_count, config->mode,
111107
pwm_freq, data->clock_freq);
@@ -115,13 +111,24 @@ static int mcux_tpm_set_cycles(const struct device *dev, uint32_t channel,
115111
return -ENOTSUP;
116112
}
117113
TPM_StartTimer(config->base, config->tpm_clock_source);
118-
} else {
119-
TPM_UpdateChnlEdgeLevelSelect(config->base, channel,
120-
data->channel[channel].level);
121-
TPM_UpdatePwmDutycycle(config->base, channel, config->mode,
122-
duty_cycle);
123114
}
124115

116+
if ((flags & PWM_POLARITY_INVERTED) == 0 &&
117+
data->channel[channel].level != kTPM_HighTrue) {
118+
data->channel[channel].level = kTPM_HighTrue;
119+
TPM_UpdateChnlEdgeLevelSelect(config->base, channel, kTPM_HighTrue);
120+
} else if ((flags & PWM_POLARITY_INVERTED) != 0 &&
121+
data->channel[channel].level != kTPM_LowTrue) {
122+
data->channel[channel].level = kTPM_LowTrue;
123+
TPM_UpdateChnlEdgeLevelSelect(config->base, channel, kTPM_LowTrue);
124+
}
125+
126+
if (pulse_cycles == period_cycles) {
127+
pulse_cycles = period_cycles + 1U;
128+
}
129+
130+
config->base->CONTROLS[channel].CnV = pulse_cycles;
131+
125132
return 0;
126133
}
127134

0 commit comments

Comments
 (0)