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 ec55bef6960..6a106c12841 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); diff --git a/dts/bindings/pwm/nordic,nrf-pwm.yaml b/dts/bindings/pwm/nordic,nrf-pwm.yaml index 8f481d8971c..e5adfc6ede9 100644 --- a/dts/bindings/pwm/nordic,nrf-pwm.yaml +++ b/dts/bindings/pwm/nordic,nrf-pwm.yaml @@ -18,6 +18,11 @@ properties: type: boolean description: Set this to use center-aligned (up and down) counter mode. + idleout-supported: + type: boolean + description: | + Indicates if the PWM instance has the IDLEOUT register. + "#pwm-cells": const: 3 diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 48d0d93b061..27c3bc7192f 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -656,6 +656,7 @@ clocks = <&hsfll120>; power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; #pwm-cells = <3>; + idleout-supported; }; spis120: spi@8e5000 { @@ -1008,6 +1009,7 @@ clocks = <&fll16m>; power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; #pwm-cells = <3>; + idleout-supported; }; i2c130: i2c@9a5000 { @@ -1141,6 +1143,7 @@ clocks = <&fll16m>; power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; #pwm-cells = <3>; + idleout-supported; }; i2c132: i2c@9b5000 { @@ -1274,6 +1277,7 @@ clocks = <&fll16m>; #pwm-cells = <3>; power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + idleout-supported; }; i2c134: i2c@9c5000 { @@ -1407,6 +1411,7 @@ clocks = <&fll16m>; #pwm-cells = <3>; power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + idleout-supported; }; i2c136: i2c@9d5000 { diff --git a/dts/vendor/nordic/nrf54l20.dtsi b/dts/vendor/nordic/nrf54l20.dtsi index f3b63d1ed44..bee70effa0e 100644 --- a/dts/vendor/nordic/nrf54l20.dtsi +++ b/dts/vendor/nordic/nrf54l20.dtsi @@ -489,6 +489,7 @@ reg = <0xd2000 0x1000>; interrupts = <210 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; pwm21: pwm@d3000 { @@ -497,6 +498,7 @@ reg = <0xd3000 0x1000>; interrupts = <211 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; pwm22: pwm@d4000 { @@ -505,6 +507,7 @@ reg = <0xd4000 0x1000>; interrupts = <212 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; adc: adc@d5000 { diff --git a/dts/vendor/nordic/nrf54l_05_10_15.dtsi b/dts/vendor/nordic/nrf54l_05_10_15.dtsi index be367ee81d8..c548c269973 100644 --- a/dts/vendor/nordic/nrf54l_05_10_15.dtsi +++ b/dts/vendor/nordic/nrf54l_05_10_15.dtsi @@ -479,6 +479,7 @@ reg = <0xd2000 0x1000>; interrupts = <210 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; pwm21: pwm@d3000 { @@ -487,6 +488,7 @@ reg = <0xd3000 0x1000>; interrupts = <211 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; pwm22: pwm@d4000 { @@ -495,6 +497,7 @@ reg = <0xd4000 0x1000>; interrupts = <212 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; adc: adc@d5000 { diff --git a/dts/vendor/nordic/nrf9280.dtsi b/dts/vendor/nordic/nrf9280.dtsi index 06e0a3a1514..fb27488e9dc 100644 --- a/dts/vendor/nordic/nrf9280.dtsi +++ b/dts/vendor/nordic/nrf9280.dtsi @@ -479,6 +479,7 @@ status = "disabled"; interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; spi120: spi@8e6000 { @@ -767,6 +768,7 @@ status = "disabled"; interrupts = <420 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; i2c130: i2c@9a5000 { @@ -881,6 +883,7 @@ status = "disabled"; interrupts = <436 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; i2c132: i2c@9b5000 { @@ -995,6 +998,7 @@ status = "disabled"; interrupts = <452 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; i2c134: i2c@9c5000 { @@ -1109,6 +1113,7 @@ status = "disabled"; interrupts = <468 NRF_DEFAULT_IRQ_PRIORITY>; #pwm-cells = <3>; + idleout-supported; }; i2c136: i2c@9d5000 {