Hello,
I am using the nrf5340 on some custom hardware, and I am using 3 LEDʻs and running them with the PWM0 peripheral to fade and blink and indicate states for the firmware. The LEDʻs are driven as active-low, and I am using the PWM flag PWM_POLARITY_INVERTED in the device tree to make sure this works.
After initialization, the PWM peripheral works very well, and using the zephyr driver is very easy to use. However, I am finding that before initialization, there is a function called in the pwm_nrfx.c that will reset the LEDʻs pin states to 0. This, of course, turns the LEDʻs on, and I have to set the PWM peripheral to 0% duty cycle when I initialize in my own code in order to make sure they start in the OFF state.
This results in a brief flash of white at the start of the firmware, of which I found no way to control. I am trying to debug and step through to figure out why this is not working but what I am arriving at is the PWM_POLARITY_INVERTED is not actually taken into account when the pins get initialized. Is this correct? Is there a way I can configure this and make sure the pins initialize to digital 1 because they should be ACTIVE_LOW?
Here is my device tree file configuring PWM0:
/ { pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_INVERTED>; }; pwm_led1: pwm_led_1 { pwms = <&pwm0 1 PWM_MSEC(10) PWM_POLARITY_INVERTED>; }; pwm_led2: pwm_led_2 { pwms = <&pwm0 2 PWM_MSEC(10) PWM_POLARITY_INVERTED>; }; }; }; &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; pinctrl-1 = <&pwm0_sleep>; pinctrl-names = "default", "sleep"; }; pwm0_default: pwm0_default { group1 { psels = <NRF_PSEL(PWM_OUT0, 0, 28)>, <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>; }; };
Here is my code that initializes the PWM LEDs:
static const struct pwm_dt_spec _ledr = PWM_DT_SPEC_GET(DT_ALIAS(pwm_ledr)); static const struct pwm_dt_spec _ledg = PWM_DT_SPEC_GET(DT_ALIAS(pwm_ledg)); static const struct pwm_dt_spec _ledb = PWM_DT_SPEC_GET(DT_ALIAS(pwm_ledb)); // These identifiers match up to the DT node identifiers static const struct pwm_dt_spec *_leds[3] = { &_ledr, &_ledg, &_ledb, }; if (!device_is_ready(_ledr.dev)) { LOG_ERR("Error: PWM device %s is not ready", _ledr.dev->name); return -ENODEV; } else if (!device_is_ready(_ledg.dev)) { LOG_ERR("Error: PWM device %s is not ready", _ledg.dev->name); return -ENODEV; } else if (!device_is_ready(_ledb.dev)) { LOG_ERR("Error: PWM device %s is not ready", _ledb.dev->name); return -ENODEV; } int err = pwm_leds_off(LED_ALL); LOG_ERR_AND_RETURN(err, "pwm_leds_off");
and here is the line of code (line 239 in pwm_nrfx.c) that I am referring to that results in all LEDʻs (despite the PWM_POLARITY_INVERTED) setting to 0 and therefore turning on:
int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);