How to configure 2 PWM pins with same frequency and duty cycle but opposite polarity

I'm developing a product with the nRF52840, using Zephyr (Toolchain & SDK version 2.7.0).  Is there a way to set up two PWM outputs having the same frequency and duty cycle, but with opposite polarity (such that when one pin goes high, the other goes low, and vice-versa)?

I'll also need to start and stop the outputs together (or at least close to it).

Thanks in advance for any help,

--mkj

Parents
  • I also got it working in a slightly different way, see here

    6165.pwm.zip

    The trick i used was to use this below in the overlay where I set one pin to inverted

    &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, 0, 13)>,
                        <NRF_PSEL(PWM_OUT1, 0, 14)>;
                nordic,drive-mode = <NRF_DRIVE_H0H1>;
            };
        };
    
        pwm0_sleep: pwm0_sleep {
            group1 {
                psels = <NRF_PSEL(PWM_OUT0, 0, 13)>,
                        <NRF_PSEL(PWM_OUT1, 0, 14)>;
                nordic,drive-mode = <NRF_DRIVE_H0H1>;
            };
        };
    };

    And in the code I drove both pins same but one should be inverted since it is forced from overlay

       // Configure PWM_OUT0 (normal polarity)
        if (pwm_set(pwm_dev, PWM_CHANNEL0, PWM_PERIOD_USEC, pulse_width, PWM_POLARITY_NORMAL)) {
            printk("Failed to configure PWM channel 0\n");
        } else {
            printk("PWM channel 0 configured: 50%% duty cycle, normal polarity\n");
        }
    
        // Configure PWM_OUT1 (inverted polarity)
        if (pwm_set(pwm_dev, PWM_CHANNEL1, PWM_PERIOD_USEC, pulse_width, PWM_POLARITY_INVERTED)) {
            printk("Failed to configure PWM channel 1\n");
        } else {
            printk("PWM channel 1 configured: 50%% duty cycle, inverted polarity\n");
        }

    I guess there are many ways to do it.

Reply
  • I also got it working in a slightly different way, see here

    6165.pwm.zip

    The trick i used was to use this below in the overlay where I set one pin to inverted

    &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, 0, 13)>,
                        <NRF_PSEL(PWM_OUT1, 0, 14)>;
                nordic,drive-mode = <NRF_DRIVE_H0H1>;
            };
        };
    
        pwm0_sleep: pwm0_sleep {
            group1 {
                psels = <NRF_PSEL(PWM_OUT0, 0, 13)>,
                        <NRF_PSEL(PWM_OUT1, 0, 14)>;
                nordic,drive-mode = <NRF_DRIVE_H0H1>;
            };
        };
    };

    And in the code I drove both pins same but one should be inverted since it is forced from overlay

       // Configure PWM_OUT0 (normal polarity)
        if (pwm_set(pwm_dev, PWM_CHANNEL0, PWM_PERIOD_USEC, pulse_width, PWM_POLARITY_NORMAL)) {
            printk("Failed to configure PWM channel 0\n");
        } else {
            printk("PWM channel 0 configured: 50%% duty cycle, normal polarity\n");
        }
    
        // Configure PWM_OUT1 (inverted polarity)
        if (pwm_set(pwm_dev, PWM_CHANNEL1, PWM_PERIOD_USEC, pulse_width, PWM_POLARITY_INVERTED)) {
            printk("Failed to configure PWM channel 1\n");
        } else {
            printk("PWM channel 1 configured: 50%% duty cycle, inverted polarity\n");
        }

    I guess there are many ways to do it.

Children
No Data
Related