Important
In the nRF54LS05 DK the LEDs are connected to the GPIO Port 0. The PWM peripheral in the nRF54LS05A/B SoCs has access only to Port 1. Due to that fact the exercise is not supported on nRF54LS05 DK. A an alternative the external LED can be connected to another unused GPIO Pin from Port 1 (the overlay file with PWM configuration will be needed for that case )
In this exercise, we will use a generated PWM signal to control an LED on the DK.
You will practice using the PWM API in nRF Connect SDK to initialize a PWM device and learn how changing the PWM period and pulse affects the behavior of the LED.
This exercise will show you how to use Zephyrs API to get and use a predefined pwm compatible node.
Exercise steps
Open the code base of the exercise by navigating to Create a new application in the nRF Connect for VS Code extension, select Copy a sample, and search for Lesson 4 – Exercise 1.
Alternatively, in the GitHub repository for this course, go to the base code for this exercise, found in l4/l4_e1.
1. Enable the PWM module in your application.
1.1 Enable the PWM module and set the logging level.
Add the following lines to the prj.conf file
CONFIG_PWM=y
CONFIG_PWM_LOG_LEVEL_DBG=yKconfigCONFIG_PWM– Enables config options for PWM driversCONFIG_PWM_LOG_LEVEL_DBG– Sets log level for the PWM log module
1.2 Enable LED and LED PWM.
Add the following lines to the prj.conf file
CONFIG_LED=y
CONFIG_LED_PWM=yKconfigCONFIG_LED– Includes the LED driversCONFIG_LED_PWM– Enables driver for PWM LEDs
1.3 Include the relevant PWM header files
Add the following lines in main.c
#include <zephyr/device.h>
#include <zephyr/drivers/pwm.h>C2. Define the desired PWM period and pulse
Define the PWM period and pulse, as the macros PWM_PERIOD_NS and PWM_PULSE_NS
Add the following lines to main.c
#define PWM_PERIOD_NS 20000000
#define PWM_PULSE_WIDTH 1400000C3. Initialize the PWM LED device on the hardware.
3.1 Get the node identifier through its alias pwm_led0.
Using DT_ALIAS(), which takes an alias and returns the device’s node identifier.
#define PWM_LED0 DT_ALIAS(pwm_led0)C3.2 Initialize and populate the struct pwm_dt_spec using PWM_DT_SPEC_GET().
We want to get the device pointer, pin number, and pin configuration flags through pwm_dt_spec. This can be done using the API-specific PWM_DT_SPEC_GET(), which takes the node identifier, and populates the struct pwm_dt_spec with the information from that device.
static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(PWM_LED0);C3.3 Check if the device is ready.
Now we need to verify if the device is ready to use, using pwm_is_ready_dt(), which has the following signature
Add the following code snippet in main.c
if (!pwm_is_ready_dt(&pwm_led0)) {
LOG_ERR("Error: PWM device %s is not ready\n", pwm_led0.dev->name);
return 0;
}C4. Control the LED with the control signal generated from the PWM.
We will use pwm_set_dt() to set the period and pulse width of the device after initializing it.
Add the following code snippet in main.c
err = pwm_set_dt(&pwm_led0, PWM_PERIOD_NS, PWM_PULSE_WIDTH);
if (err) {
LOG_ERR("Error in pwm_set_dt(), err: %d", err);
return 0;
}C5. Build and flash the application to your device.
LED1 on your device should glow slightly.
Try changing the pulse and/or period and observe the changes. If the value is set too high or too low, it may be out of range of what your hardware can reach.
For instance, let’s set the parameters to
#define PWM_PERIOD_NS 100000000
#define PWM_PULSE_WIDTH 14000000CNotice that the LED is now blinking very quickly.
The solution for this exercise can be found in the GitHub repository, l4/l4_e1_sol.