I am working with the nRF54L15 to create a driver for a peripheral which is controlled by two PWM signals.
My driver relies on the Zephyr PWM driver which goes back to your implementation of it in pwm_nrfx.c. Everything works fine except one case, and I don't understand this limitation.
If I command one of the signals to pulse at 100% duty cycle and I leave the other one off, if I then try to set the off PWM signal to a non-static setting (1-99% duty cycle) then it results in the "Incompatible period." error. [SDK\zephyr\drivers\pwm\pwm_nrfx.c, function pwm_period_check_and_set()]
Both of my PWM channels are set to the same frequency (PWM_USEC(100)) so I don't understand what the problem is here. Is the driver optimizing the PWM period to something other than my setting when I command the one signal to 100% duty cycle? And so when I set the other signal, the PWM driver is actually running a different period than my setting? I could understand this for power savings, but I need to somehow deal with this limitation.
Relevant code:
struct tps923653_config
{
const struct pwm_dt_spec en_pwm; // EN/PWM pin (High=Always On, Low=Device Disabled, PWM=PWM Dimming)
const struct pwm_dt_spec adim_hd; // ADIM/HD pin (High=PWM Dimming, Low=Hybrid Dimming, PWM=Analog Dimming)
};
/* Startup state: */
(void)pwm_set_pulse_dt(&config->en_pwm, 0); // Set low
(void)pwm_set_pulse_dt(&config->adim_hd, config->adim_hd.period); // Set high (100% duty cycle)
/* Produces the error: */
err = pwm_set_pulse_dt(&config->en_pwm, config->en_pwm.period/2);
if (err)
{
LOG_ERR("Failed to set EN/PWM: %d", err);
return err;
}
Relevant devicetree overlay:
&pinctrl {
pwm21_default: pwm21_default {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 11)>,
<NRF_PSEL(PWM_OUT1, 1, 12)>;
};
};
};
&pwm21 {
status = "okay";
pinctrl-0 = <&pwm21_default>; /* Only default, no low power config */
pinctrl-names = "default";
};
/ {
ir_driver: tps923653 {
compatible = "indesign,tps923653";
status = "okay";
/* EN/PWM and ADIM/HD pwm configuration */
pwms = <&pwm21 0 PWM_USEC(100) PWM_POLARITY_NORMAL>,
<&pwm21 1 PWM_USEC(100) PWM_POLARITY_NORMAL>;
// pwm-names = "en-pwm", "adim-hd";
};
};
Let me know if I am just outside of the scope of expected use of the pwm_nrfx.c driver and need to make something custom for my application, but I feel like this is may be a bug.