From 0261d7d96d90e24e01a5125a3bdc9a19eff8d627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 29 May 2025 08:25:32 +0200 Subject: [PATCH] drivers: pwm: nrfx: Add option to glitch free 100% duty cycle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IDLEOUT presence in PWM means that there are 3 sources from which PWM pin can be driven: - GPIO setting when PWM peripheral is disabled. - IDLEOUT setting when PWM is enabled. - PWM Sequence when it is in use. IDLEOUT setting cannot be changed after enabling PWM so it is configured to the initial state of the pin. It means that if duty cycle is 100%, GPIO output is set to 1 but initial pin state was 0 (IDLEOUT setting) there will be a glitch between disabling a PWM sequence and disabling a PWM peripheral. By default, PWM driver tries to disable PWM peripheral if all channels are 0% or 100% duty cycle to safe power. When IDLEOUT feature is present there will be a short glitch on channels with 100% duty cycle. In order to avoid that CONFIG_PWM_NRFX_NO_GLITCH_DUTY_100 option is added (enabled by default). When option is enabled 100% duty cycle is achieved by PWM sequence and not by driving a GPIO pin. It will consume more power in cases where all channels are 0% or 100% with at least one channel set to 100% duty cycle. Signed-off-by: Krzysztof Chruściński --- drivers/pwm/Kconfig.nrfx | 10 ++++++++++ drivers/pwm/pwm_nrfx.c | 19 +++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/pwm/Kconfig.nrfx b/drivers/pwm/Kconfig.nrfx index 933fe7cb29c..d99b5aaf3ab 100644 --- a/drivers/pwm/Kconfig.nrfx +++ b/drivers/pwm/Kconfig.nrfx @@ -20,3 +20,13 @@ config PWM_NRFX select PINCTRL help Enable support for nrfx Hardware PWM driver for nRF52 MCU series. + +config PWM_NRFX_NO_GLITCH_DUTY_100 + bool "No glitches when using 100% duty" + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_NORDIC_NRF_PWM),idleout-supported,True) + default y + help + Due to how IDLEOUT feature in PWM works it is possible to see a glitch on a channel + with 100% duty cycle when all other channels switches to 0% or 100%. Enabling this + option ensures that there are no glitches but it also means that 100% duty cycle + on any channels requires PWM peripheral to be active. diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index bab8b0f003e..38ab71ba883 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -240,6 +240,9 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, /* Constantly active (duty 100%). */ /* This value is always greater than or equal to COUNTERTOP. */ compare_value = PWM_NRFX_CH_COMPARE_MASK; + needs_pwm = pwm_is_fast(config) || + (IS_ENABLED(NRF_PWM_HAS_IDLEOUT) && + IS_ENABLED(CONFIG_PWM_NRFX_NO_GLITCH_DUTY_100)); } else { /* PWM generation needed. Check if the requested period matches * the one that is currently set, or the PWM peripheral can be @@ -279,20 +282,8 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, if (inverted) { out_level ^= 1; } - /* Output of fast PWM instance is directly connected to GPIO pads, - * thus it cannot controlled by GPIO. Use regular 0%/100% duty cycle - * playback instead. - */ -#ifdef PWM_NRFX_FAST_PRESENT - if (pwm_is_fast(config)) { - nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1, - NRFX_PWM_FLAG_NO_EVT_FINISHED); - } else { -#else - { -#endif - nrf_gpio_pin_write(psel, out_level); - } + + nrf_gpio_pin_write(psel, out_level); } data->pwm_needed &= ~BIT(channel);