Compiler error regarding PWM configuration

Hi all,

I'm trying to use the nrf Connect SDK and configure PWM to use in one pin from nordif nrf52DK. The final chip will be the nrf52810. I have configured the builder to use the nrf52dk_nrf52810. I was using the "blinky" example and trying to add a PWM configuration to it. I have this configurations:

prj.conf:

# PWM
CONFIG_PWM=y
CONFIG_PWM_NRFX=y

nrf52dk_nrf52810.overlay:

/ {
    gpiocustom {
        compatible = "gpio-keys";
        gpiocus0: gpiocus_0 {
            gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
            label = "Custom gpio 11";
        };
        gpiocus1: gpiocus_1 {
            gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
            label = "Custom gpio 12";
        };
    };

    soc {
        pwm0: pwm@4001c000  {
            compatible = "nordic,nrf-pwm";
            reg = <0x4001c000 0x1000>;
            label = "PWM_0";
            ch0-pin = <22>;
            #pwm-cells = <3>;
        };
    };

    aliases {
        gpiocus0 = &gpiocus0;
        gpiocus1 = &gpiocus1;
        pwm0 = &pwm0;
    };
};

&sw_pwm {
    status = "okay";
    channel-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
};

Anyone can tell me if the sw_pwm needs to be used to generate the pwm? or only with the pwm is enough?

I added this line in the main.c:

#define DT_ALIAS_PWM_0_LABEL DT_ALIAS(pwm0)

And then, when I try to compile I get this error:

In file included from C:\ncs\v2.0.0\zephyr\include\zephyr\devicetree.h:19,
                 from C:\ncs\v2.0.0\zephyr\include\zephyr\arch\arm\aarch32\arch.h:20,
                 from C:\ncs\v2.0.0\zephyr\include\zephyr\arch\cpu.h:19,
                 from C:\ncs\v2.0.0\zephyr\include\zephyr\kernel_includes.h:33,
                 from C:\ncs\v2.0.0\zephyr\include\zephyr\kernel.h:17,
                 from C:\ncs\v2.0.0\zephyr\include\zephyr\zephyr.h:18,
                 from c:\nordics\blinky\src\main.c:7:
../src/main.c: In function 'main':
c:\nordics\blinky\build_2\zephyr\include\generated\devicetree_unfixed.h:4892:36: error: 'DT_N_S_soc_S_pwm_4001c000' undeclared (first use in this function); did you mean 'DT_N_S_soc_S_pwm_4001c000_ORD'?
 4892 | #define DT_N_ALIAS_pwm0            DT_N_S_soc_S_pwm_4001c000
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~~
C:\ncs\v2.0.0\zephyr\include\zephyr\devicetree.h:2991:24: note: in expansion of macro 'DT_N_ALIAS_pwm0'
 2991 | #define DT_CAT(a1, a2) a1 ## a2
      |                        ^~
C:\ncs\v2.0.0\zephyr\include\zephyr\devicetree.h:213:25: note: in expansion of macro 'DT_CAT'
  213 | #define DT_ALIAS(alias) DT_CAT(DT_N_ALIAS_, alias)
      |                         ^~~~~~
c:\nordics\blinky\src\main.c:20:30: note: in expansion of macro 'DT_ALIAS'
   20 | #define DT_ALIAS_PWM_0_LABEL DT_ALIAS(pwm0)

How can I solve it? Also I have tried the nRF5 SDK and it was really easy to get the PWM working, but I will need to use zephyr to implement a bootloader in the future.

Hope you can help me.

Best regards

Parents
  • Hi,

    The devicetree files in nRF Connect SDK 2.0.0 does not contain PWM configuration for nrf52dk_nrf52810, so that needs to be added, for instance in form of an overlay. However, the overlay file you provided does not seem correct.

    I suggest you test with the PWM sample (zephyr\samples\basic\blinky_pwm\), but modify the overlay file for the board (zephyr\samples\basic\blinky_pwm\boards\nrf52dk_nrf52810.overlay) so that it looks like this:

    &pinctrl {
    	pwm0_default: pwm0_default {
    		group1 {
    			psels = <NRF_PSEL(PWM_OUT0, 0, 17)>;
    			nordic,invert;
    		};
    	};
    
    	pwm0_sleep: pwm0_sleep {
    		group1 {
    			psels = <NRF_PSEL(PWM_OUT0, 0, 17)>;
    			low-power-enable;
    		};
    	};
    };
    
    / {
    	pwmleds {
    		compatible = "pwm-leds";
    		pwm_led0: pwm_led_0 {
    			pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
    		};
    	};
    
        aliases {
            pwm-led0 = &pwm_led0;
        };
    };
    
    &pwm0 {
    	status = "okay";
    	pinctrl-0 = <&pwm0_default>;
    	pinctrl-1 = <&pwm0_sleep>;
    	pinctrl-names = "default", "sleep";
    };
    

    With that the sample should build and run correctly nrf52dk_nrf52810, and you can use this as a reference for other changes that might be needed for other configurations.

  • Hi Eianar,

    Thanks for your reply. I'll try your suggestion. In the meanwhile I take a look at this comment: https://devzone.nordicsemi.com/f/nordic-q-a/88796/the-simplest-use-of-pwm-driver

    This can be a better solution to use PWM? because I can see all the configuration in the main.c file.

    Best regards.

Reply Children
  • Hi,

    You can use the nrfx driver directly instead of the Zephyr PWM API, yes. I am not sure you can say it is better or worse, that probably depend on the use case. But it is different, and gives you better access to all the HW features. For just simple PWM use cases both would do, and the Zephyr API would be more portable (if that is relevant).

  • Hi Einar and thanks again for your reply.

    Regarding the nrf52dk_nrf52810.overlay, I have to add the line "sw_pwm" in order to use the PWM? because using that example, without that the compiler give me another error before start the compiling process.

    Best regards.

  • Hi,

    No, you do not need to add "sw_pwm". The nRF52810 also has PWM HW. I just tested again now, and the sample zephyr/samples/basic/blinky_pwm/ works out of the box with this overlay file: 7532.nrf52dk_nrf52810.overlay.

    Does it still not work? If now, where did you add the overlay file, and what error do you get when you try to build?

  • Hi Einar, sorry for the delay in my response.

    If I use the .overlay file that you sent now it builds, but when I want to use the PWM I can't initiate it (when the binary is flashed in the board, it gives an error)

    Also I have another question. I'm using the following code to use the PWM:

    static int pwm_init(void)
    {
    	static nrfx_pwm_config_t const config0 =
        {
            .output_pins =
            {
                22,						// channel 0
                23,						// channel 1
                NRFX_PWM_PIN_NOT_USED,	// channel 2
                NRFX_PWM_PIN_NOT_USED	// channel 3
            },
            .irq_priority = 5,
            .base_clock   = NRF_PWM_CLK_500kHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = PWM_COUNTERTOP,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO
        };
        return (nrfx_pwm_init(&my_pwm, &config0, NULL, NULL) == NRFX_SUCCESS) ? 0 : -1;
    
    }

    It's ok to use this code in order to use PWM? For me is more clear to use it this way, but there is another option?

    Also, I want to add a long press button function but I can't find a good example to use it.

    Hope you can help me.

    Best regards

  • Hi,

    clake said:
    If I use the .overlay file that you sent now it builds, but when I want to use the PWM I can't initiate it (when the binary is flashed in the board, it gives an error)

    Which error do you get?

    clake said:
    It's ok to use this code in order to use PWM? For me is more clear to use it this way, but there is another option?

    Here you are using nrfx, so you are effectively bypassing the Zephyr PWM API. That is OK, but the required config is a bit different. You may find the unofficial NRFX PWM Simple Example useful for that (it is not entirely up to date, but shows the main principles).

Related