There is a low power pwm in nRF5 SDK. I can not find it in the nRF Connect SDK. Any suggestion how to achieve the same using nRF Connect SDK?
There is a low power pwm in nRF5 SDK. I can not find it in the nRF Connect SDK. Any suggestion how to achieve the same using nRF Connect SDK?
Hi,
There is a SW PWM library in the nRF Connect SDK as well, which can be enabled by CONFIG_PWM_NRF5_SW. This can be used with a TIMER or RTC for time keeping, and if RTC is used, this would be more or less equivalent with the low power PWM library in the nRF5 SDK.
Thank you. I will give it a try. What is the maximum frequency? Will I be able to dive a piezo at 4kHz?
Thank you. I will give it a try. What is the maximum frequency? Will I be able to dive a piezo at 4kHz?
The RTC is 32.768 kHz and you can get a toggle on every tick, so that should be OK.
As a side note, this implementation use PPI and GPIOTE also with the RTC, which is different than the low power PWM library in the nRF5 SDK (where only RTC and SW was used via the app_timer library). That frees up the CPU, but which is more power efficient of this and the low_power PWM library in the nRF5 SDK probably depend on the frequency (as PPI usage will increase the idle current, but you will avoid th e high current consumption of the CPU on every change). So for lower frequencies (probably much lower than 4 kHz though I have not measured this), it might be more efficient to do this with kernel timers and setting and clearing GPIOs yourself. If you would like to do that, you could look at the low-power PWM library implementation for inspiration and implement something like that yourself.
Einar Thorsrud unfortunately I need some more support. I am totally new to nRF and Zephyr.
I am using nRF Connect SDK 2.1.2 and the nRF52840 development kit. I have modified the prj.conf file and added CONFIG_PWM_NRF5_SW:
CONFIG_PRINTK=y CONFIG_LOG=y # PWM CONFIG_PWM=y CONFIG_PWM_NRF5_SW=y #CONFIG_PWM_LOG_LEVEL_DBG=y
I have modified the Fade LED Sample to use two PWM channels:
/* * Copyright (c) 2016 Intel Corporation * Copyright (c) 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ /** * @file Sample app to demonstrate PWM-based LED fade */ #include <zephyr/zephyr.h> #include <zephyr/sys/printk.h> #include <zephyr/device.h> #include <zephyr/drivers/pwm.h> static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)); static const struct pwm_dt_spec pwm_led1 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1)); #define NUM_STEPS 50U #define SLEEP_MSEC 1000U void main(void) { uint32_t period = PWM_KHZ(4); uint32_t pulse_width = period / 2; //uint32_t pulse_width = 0U; //uint32_t step = pwm_led1.period / NUM_STEPS; //uint8_t dir = 1U; int ret; bool state = false; printk("PWM-based LED fade\n"); if (!device_is_ready(pwm_led0.dev)) { printk("Error: PWM device %s is not ready\n", pwm_led0.dev->name); return; } if (!device_is_ready(pwm_led1.dev)) { printk("Error: PWM device %s is not ready\n", pwm_led1.dev->name); return; } while (1) { if (state) { pulse_width = 0; state = false; } else { pulse_width = period / 2; state = true; } ret = pwm_set_dt(&pwm_led0, period, pulse_width); if (ret) { printk("Error %d: failed to set pulse width\n", ret); return; } ret = pwm_set_dt(&pwm_led1, period, pulse_width); if (ret) { printk("Error %d: failed to set pulse width\n", ret); return; } k_sleep(K_MSEC(SLEEP_MSEC)); } }
I have added an app.overlay file to modify the Device Tree:
/ { pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { pwms = <&sw_pwm 0 PWM_KHZ(4) PWM_POLARITY_INVERTED>; }; pwm_led1: pwm_led_1 { pwms = <&sw_pwm 1 PWM_KHZ(4) PWM_POLARITY_NORMAL>; }; }; aliases { pwm-led1 = &pwm_led1; }; }; &sw_pwm { status ="okay"; channel-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>, <&gpio0 14 GPIO_ACTIVE_LOW>; clock-prescaler = <0>; generator = < &rtc0>; };
Added the sw_pwm to use the RTC and added the pwm-led information.
The result on the P0.13 and P0.14 is exactly as I have expected:
but in VS Code I get the flowing "error" during the proj.conf edit:
CONFIG_PWM_NRF5_SW was assigned the value y, but got the value n. Missing dependencies:
DT_HAS_NORDIC_NRF_SW_PWM_ENABLED
I have tried to search the GitHub for some cluses: https://github.com/zephyrproject-rtos/zephyr/search?q=DT_HAS_NORDIC_NRF_SW_PWM_ENABLED but I still do not know what I am doing wrong and how to fix the missing dependency on: DT_HAS_NORDIC_NRF_SW_PWM_ENABLED.
That is odd. When I test essentially exactly what you did here this works on my end. I get this log:
*** Booting Zephyr OS build v3.2.99-ncs1 *** PWM-based LED fade [00:00:00.258,728] <dbg> pwm_nrf5_sw: pwm_nrf5_sw_set_cycles: channel 0, period 8, pulse 4 [00:00:00.267,761] <dbg> pwm_nrf5_sw: pwm_nrf5_sw_set_cycles: channel 1, period 8, pulse 4showing that the SW implementation is sued, and I can also put a breakpoint in zephyr/drivers/pwm/pwm_nrf5_sw.c to verify that it is the case.
How does this look in your end? Can you double check that the overlay files are used? If they are, then you should see that CONFIG_PWM_NRF5_SW=y in build/zephyr/.config. Is it?
Einar Thorsrud thank you very much for taking the time and checking it on your end.
Can you double check that the overlay files are used?
The app.overlay is used - without it I get a build break as the pwm_led1 is undefined.
If they are, then you should see that CONFIG_PWM_NRF5_SW=y in build/zephyr/.config
I see CONFIG_PWM_NRF5_SW=y in build/zephyr/.config:
As you can see I have set CONFIG_PWM_LOG_LEVEL_DBG=y to mimic your settings. I still see the same "error":
At this point I will assume this is a minor issue related to VS Code and how it does the on the fly parsing. I will try to update to nRF Connect SDK 2.2.0 during the weekend and let you know if it changes something.
BTW - is there a way to add an offset between PWM cannel 0 and PWM channel 1? I have seen some discussions how to do in the legacy nRF5 SDK, but I do not know how to do it in Zephyr using nRF Connect SDK.
Hi,
pmochocki said:At this point I will assume this is a minor issue related to VS Code and how it does the on the fly parsing.
Yes, that seems likely (although it is a bit strange that I don't see the same on my end).
pmochocki said:BTW - is there a way to add an offset between PWM cannel 0 and PWM channel 1? I have seen some discussions how to do in the legacy nRF5 SDK, but I do not know how to do it in Zephyr using nRF Connect SDK.
There is no direct support for that. It might be possible to achieve it somehow, but I am not able to suggest anything specific.