Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NRF PWM pin default state is high #67179

Closed
siddhantmodi opened this issue Jan 3, 2024 · 6 comments
Closed

NRF PWM pin default state is high #67179

siddhantmodi opened this issue Jan 3, 2024 · 6 comments
Assignees
Labels
area: PWM Pulse Width Modulation bug The issue is a bug, or the PR is fixing a bug platform: nRF Nordic nRFx

Comments

@siddhantmodi
Copy link

Describe the bug
I've set up a custom pin for PWM on my nrf52840dk board - the first thing the main function does is set up a 50kHz signal at a 50% duty cycle. However, the problem is that the pin is getting initialized as HIGH before the code in main even starts running. Line 239 of zephyr/drivers/pwm/pwm_nrfx.c in the pwm_nrfx_init function is the moment where the pin goes HIGH:

int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);

I stepped into the code but couldn't figure out what exact config is determining the initial state.

Please also mention any information which could help others to understand
the problem you're facing:

  • nRF52840DK
  • Stepping through the code to try and identify any parameters that would let me set the initial state

To Reproduce
Steps to reproduce the behavior:

  1. Import the hello_world example
  2. Add the following to the overlay file:
/ {
    pwmleds {
        compatible = "pwm-leds";
        pwm_led0: pwm_led_0 {
            pwms = <&pwm0 0 PWM_USEC(10) PWM_POLARITY_NORMAL>;
        };
    };
};

&pwm0 {
    status = "okay";
    pinctrl-0 = <&pwm0_default>;
    pinctrl-1 = <&pwm0_sleep>;
    pinctrl-names = "default", "sleep";
};

&pinctrl {
    pwm0_default: pwm0_default {
        group1 {
            psels = <NRF_PSEL(PWM_OUT0, 1, 4)>;
        };
    };

    pwm0_sleep: pwm0_sleep {
        group1 {
            psels = <NRF_PSEL(PWM_OUT0, 1, 4)>;
            low-power-enable;
        };
    };
};
  1. Connect up P1.4 to a logic analyzer and see that the pin gets initialized to a HIGH state.

Expected behavior
Either the pin should be LOW or maybe have a config somewhere that dictates what the state should be?

Impact
Annoyance because I can get around this by using the nrfx_pwm API but this affects the native_sim application from building.

Logs and console output
image

Environment (please complete the following information):

  • Linux
  • Zephyr SDK 0.16.4
  • v3.5.0
@siddhantmodi siddhantmodi added the bug The issue is a bug, or the PR is fixing a bug label Jan 3, 2024
Copy link

github-actions bot commented Jan 3, 2024

Hi @siddhantmodi! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

@henrikbrixandersen henrikbrixandersen added the platform: nRF Nordic nRFx label Jan 3, 2024
@henrikbrixandersen henrikbrixandersen added the area: PWM Pulse Width Modulation label Jan 3, 2024
@siddhantmodi
Copy link
Author

I have switched over to using the sw_pwm peripheral and there, if I set up my node like this:

pwmleds {
    compatible = "pwm-leds";
    pwm_led0: pwm_led_0 {
        pwms = <&sw_pwm 0 PWM_USEC(20) PWM_POLARITY_NORMAL>;
    };
};

&sw_pwm {
	status = "okay";
	channel-gpios = <&gpio0 16 (GPIO_ACTIVE_HIGH | PWM_POLARITY_NORMAL)>;
};

I can avoid that initial state of the pin being high. But setting the polarity to NORMAL for the hardware pwm0 node doesn't have the same effect.

@anangl
Copy link
Member

anangl commented Jan 4, 2024

I've set up a custom pin for PWM on my nrf52840dk board - the first thing the main function does is set up a 50kHz signal at a 50% duty cycle. However, the problem is that the pin is getting initialized as HIGH before the code in main even starts running.

That happens because the overlay you are using is incorrect. You are altering the pwm0_default node from the nrf52840dk_nrf52840 board definition and you are only changing the psels property in group1 there. And the nordic,invert property stays set, hence the PWM output pin is initially high.
You should either delete this property or better, as this way you can avoid similar problems, use different names for pinctrl nodes in your overlays (so that new nodes are created), for example pwm0_default_alt and pwm0_sleep_alt in this case.

@sidmodi-mw
Copy link

@anangl Thank you for your attention to this problem. I thought that by redefining group1, I would be overwriting the entire thing, including the removal of nordic,invert.

If I set up the _alt versions of the pinctrl, how do I make sure that pwm0_default_alt gets applied during the boot cycle and not pwm0_default? This line of code from the driver is executed during the initialization:

int ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);

Here, the PINCTRL_STATE_DEFAULT will refer to the item that is at pinctrl-0. Would I just do this?

pinctrl-0 = <&pwm0_default_alt>;
pinctrl-1 = <&pwm0_sleep_alt>;

Thank you!

@sidmodi-mw
Copy link

@anangl I was able to carve some time out today and test it - I can confirm that what you said is correct. I created the two _alt pinctrl nodes and did this

pinctrl-0 = <&pwm0_default_alt>;
pinctrl-1 = <&pwm0_sleep_alt>;

and that solved the issue for me.

I am going to close this ticket.

@sidmodi-mw
Copy link

I am not able to close it - but it is ready to be closed. Thank you for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: PWM Pulse Width Modulation bug The issue is a bug, or the PR is fixing a bug platform: nRF Nordic nRFx
Projects
None yet
Development

No branches or pull requests

4 participants