This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Zephyr, setting PWM to other output than the default ones.

Hi,

I have been working on Zephyr for the past weeks and have been able to set multiple GPIOs, interrupts and RF functionnalities. But so far, I thought I could handle the PWMs well, until today. I found out every time I try to set PWM outputs to other pins than the default ones, nothing happened.

To be precise, if I put my LEDs on the default output of the nRF52840 demoboard everything is fine. But nothing happen on any other outputs.

To set things up, I write this fragment of overlay : 

/ {
    pwmleds { 
        pwm_led_0 {
            pwms = <&pwm0 17>;
            status = "okay";
        };
        pwm_led1: pwm_led1 {
            pwms = <&pwm0 19>;
            status = "okay";
        };
        pwm_led2: pwm_led2 {
            pwms = <&pwm0 21>;
            status = "okay";
        };
        pwm_led3: pwm_led3 {
            pwms = <&pwm0 23>;
            status = "okay";
        };
    };

    aliases {
        pwm-led0 = &pwm_led0;
        pwm-led1 = &pwm_led1;
        pwm-led2 = &pwm_led2;
        pwm-led3 = &pwm_led3;
    };
};

&pwm0 {
    status = "okay";
    ch0-pin = <17>;
    ch0-inverted;
    ch1-pin = <19>;
    ch1-inverted;
    ch2-pin = <21>;
    ch2-inverted;
    ch3-pin = <23>;
    ch3-inverted;
};






Then the PWMs are set up in the main.c like this : 

#define PWM_LED0_NODE	DT_ALIAS(pwm_led0)
#define PWM_LED1_NODE	DT_ALIAS(pwm_led1)
#define PWM_LED2_NODE	DT_ALIAS(pwm_led2)
#define PWM_LED3_NODE	DT_ALIAS(pwm_led3)

#if DT_NODE_HAS_STATUS(PWM_LED0_NODE, okay)
#define PWM0_CTLR	    DT_PWMS_CTLR(PWM_LED0_NODE)
#define PWM0_CHANNEL	DT_PWMS_CHANNEL(PWM_LED0_NODE)
#define PWM0_FLAGS   	DT_PWMS_FLAGS(PWM_LED0_NODE)
#else
#error "Unsupported board: pwm-led0 devicetree alias is not defined"
#define PWM0_CTLR	    DT_INVALID_NODE
#define PWM0_CHANNEL	0
#define PWM0_FLAGS	    0
#endif

#if DT_NODE_HAS_STATUS(PWM_LED1_NODE, okay)
#define PWM1_CTLR	    DT_PWMS_CTLR(PWM_LED1_NODE)
#define PWM1_CHANNEL	DT_PWMS_CHANNEL(PWM_LED1_NODE)
#define PWM1_FLAGS   	DT_PWMS_FLAGS(PWM_LED1_NODE)
#else
#error "Unsupported board: pwm-led1 devicetree alias is not defined"
#define PWM1_CTLR	    DT_INVALID_NODE
#define PWM1_CHANNEL   	0
#define PWM1_FLAGS    	0
#endif

#if DT_NODE_HAS_STATUS(PWM_LED2_NODE, okay)
#define PWM2_CTLR	        DT_PWMS_CTLR(PWM_LED2_NODE)
#define PWM2_CHANNEL	    DT_PWMS_CHANNEL(PWM_LED2_NODE)
#define PWM2_FLAGS	        DT_PWMS_FLAGS(PWM_LED2_NODE)
#else
#error "Unsupported board: pwm-led2 devicetree alias is not defined"
#define PWM2_CTLR	    DT_INVALID_NODE
#define PWM2_CHANNEL  	0
#define PWM2_FLAGS	    0
#endif

#if DT_NODE_HAS_STATUS(PWM_LED3_NODE, okay)
#define PWM3_CTLR	        DT_PWMS_CTLR(PWM_LED3_NODE)
#define PWM3_CHANNEL	    DT_PWMS_CHANNEL(PWM_LED3_NODE)
#define PWM3_FLAGS	        DT_PWMS_FLAGS(PWM_LED3_NODE)
#else
#error "Unsupported board: pwm-led2 devicetree alias is not defined"
#define PWM3_CTLR	    DT_INVALID_NODE
#define PWM3_CHANNEL  	0
#define PWM3_FLAGS	    0
#endif

uint32_t max_period = 255*100;
pwm_red = 255*100;
pwm_green = 255*100;
pwm_blue = 255*100;

void init()
{

    int ret;

    ret = pwm_pin_set_usec(pwm0, PWM0_CHANNEL, max_period, pwm_red, PWM0_FLAGS);
	if (ret) {
		printk("Error %d: failed to set pulse width\n", ret);
		return;
	}

	ret = pwm_pin_set_usec(pwm1, PWM1_CHANNEL, max_period, pwm_green, PWM1_FLAGS);
	if (ret) {
		printk("Error %d: failed to set pulse width\n", ret);
		return;
	}

	ret = pwm_pin_set_usec(pwm2, PWM2_CHANNEL, max_period, pwm_blue, PWM2_FLAGS);
	if (ret) {
		printk("Error %d: failed to set pulse width\n", ret);
		return;
	}

	ret = pwm_pin_set_usec(pwm3, PWM3_CHANNEL, max_period, pwm_white, PWM3_FLAGS);
	if (ret) {
		printk("Error %d: failed to set pulse width\n", ret);
		return;
	}
}

I may add that the output pins are indeed changing as the default ones are not working anymore with this configuration.

Best regards,

Charles

Related