From 165c14dc606a9996bd79af328bce09b34b99ae74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Thu, 7 Oct 2021 12:05:04 +0200 Subject: [PATCH] drivers: pwm_nrfx: Fix handling of zero length periods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the driver was called to set the period length for a channel to 0, it set the COUNTERTOP register in the PWM peripheral to 0, what resulted in an undefined behavior of the peripheral (and lack of the STOPPED event sometimes). The PWM API does not precise how should a zero length period be handled; some drivers return the -EINVAL error in such case, some do not. This patch fixes the pwm_nrfx driver so that it does not change the previously used COUNTERTOP register value when the period length is set to 0, and because the pulse cycles are always limited by the driver to period cycles (so 0 in this case), in result the relevant channel is simply deactivated. This allows users to switch off a channel by requesting the pulse width to be set to 0 without providing a non-zero period in such call. Signed-off-by: Andrzej Głąbek --- drivers/pwm/pwm_nrfx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index 2aa29ca0ad5..d2a5f7a333c 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -169,10 +169,13 @@ static int pwm_nrfx_pin_set(const struct device *dev, uint32_t pwm, pulse_cycles /= 2; } - /* Check if period_cycle is either matching currently used, or + /* Check if period_cycles is either matching currently used, or * possible to use with our prescaler options. + * Don't do anything if the period length happens to be zero. + * In such case, pulse cycles will be right below limited to 0 + * and this will result in making the channel inactive. */ - if (period_cycles != data->period_cycles) { + if (period_cycles != 0 && period_cycles != data->period_cycles) { int ret = pwm_period_check_and_set(config, data, channel, period_cycles); if (ret) {