drivers: pwm: nrfx: Add option to glitch free 100% duty cycle
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 <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
28cfb3fecd
commit
0261d7d96d
2 changed files with 15 additions and 14 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue