Using a pin both as a GPIO and as a PWM pin. The device tree and the overlay hell.

Hi, we started using nRFConnect SDK a few month ago and we are still having tough time every time we need to implement some configuration not directly available inside some example.

We believe it is mostly our fault because lack of knowledge, anyway I have to say that the learning curve of the Zephyr driver abstraction is quite steep.

Let's start with your example "blinky_pwm" built to run ona nRF52840DK.

It works out of the box but:

Let's say one want to control all the four leds using the same PWM0 peripheral while driving each led with a different PWM comparator (COMP0..COMP3) to achieve different dimming levels for each led.

We tried copy and pasting portions of the .dts file into the overlay one, we tried something like:

&sw_pwm {
	status = "okay";
	channel-gpios = <&gpio0 13 PWM_POLARITY_INVERTED>,<&gpio0 14 PWM_POLARITY_INVERTED>,<&gpio0 15 PWM_POLARITY_INVERTED>,<&gpio0 16 PWM_POLARITY_INVERTED>;
};

&pwm_led0 {
	compatible = "pwm-leds";
	pwms = <&sw_pwm 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};

&pwm_led1 {
	compatible = "pwm-leds";
	pwms = <&sw_pwm 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
&pwm_led2 {
	compatible = "pwm-leds";
	pwms = <&sw_pwm 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
&pwm_led3 {
	compatible = "pwm-leds";
	pwms = <&sw_pwm 3 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};

..but it fails miserably.

Can you help us to achieve using the full 4 PWM channels ?

Moreover what is the correct approach to drive a LED both as GPIO and as PWM (of course not at the same time, but during different application phases)?

Let's say we need to drive the LEDs by means of simple GPIO ON or OFF using the gpio driver during initialization and for some time after reset, then after a specific event we need to switch to PWM driving. Eventually after some other event, we will need to go back to GPIO drive ON/OFF only fashion.

Can you kindly advise on the "correct nRFConnect" approach to follow?

Many thanks in advance and best regards

 Davide

Parents
  • Hello,

    So I took the time to implement something like you suggest. Please have a look at the attached application (tested in ncs v2.5.1):

    hello_world_pwm_gpio_input.zip

    To test on an nRF52840dk, please short P0.11 (button1) and P0.13 (LED1). The way it works is that it starts with 1 second of toggling the LED as a PWM signal. Then it switches over to gpio input on the LED pin. I set up a new button (or switch, really) in nrf52840dk_nrf52840.overlay on P0.13. You can ground the P0.13 directly, but it is easier to test if you short it to button 1 and press the button. The log should let you know when the button is pressed (when the GPIO is in interrupt mode). 

    Best regards,

    Edvin

Reply
  • Hello,

    So I took the time to implement something like you suggest. Please have a look at the attached application (tested in ncs v2.5.1):

    hello_world_pwm_gpio_input.zip

    To test on an nRF52840dk, please short P0.11 (button1) and P0.13 (LED1). The way it works is that it starts with 1 second of toggling the LED as a PWM signal. Then it switches over to gpio input on the LED pin. I set up a new button (or switch, really) in nrf52840dk_nrf52840.overlay on P0.13. You can ground the P0.13 directly, but it is easier to test if you short it to button 1 and press the button. The log should let you know when the button is pressed (when the GPIO is in interrupt mode). 

    Best regards,

    Edvin

Children
No Data
Related