How to use Pulse Width Modulation driver
Introduction
This page describes how PWM could be configured, debugged and used on SAMA5D2 devices. Since linux-4.9-at91 the PWM could be configured using the new Linux PWM framework support called atomic PWM. This allow changing the PWM parameters without the need of disable and re-enable the correspondent PWM channel.
Supported devices
The following table specifies the pins on different boards which could be used as PWM outputs and the correspondent Linux PWM channels.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Kernel support
To enable the Linux kernel PWM support just enable the CONFIG_PWM flag:
make menuconfig Device drivers -> Pulse-Width Modulation (PWM) Support
To enable the SAMA5D2 PWM driver just enable the CONFIG_PWM_ATMEL flag:
make menuconfig Device drivers -> Pulse-Width Modulation (PWM) Support -> Atmel PWM support
PWM configurations
General
Current Linux implementation supports changing of 3 PWM parameters (signal period, signal duty cycle, signal polarity) and to change PWM channel state (enable/disable). The Linux sysfs interface which could be used to configure the PWM parameters is located at:
/sys/class/pwm/*
The PWM chips which are present in the system are listed in /sys/class/pwm
root@sama5d2-xplained:~# ls -l /sys/class/pwm/ total 0 lrwxrwxrwx 1 root root 0 Jun 6 16:06 pwmchip0 -> ../../devices/platform/ahb/ahb:apb/f802c000.pwm/pwm/pwmchip0
The presence of pwmchip0 suggest that there is one PWM chip on the system.
Available PWM channels
To check how many PWM channels could be configured the npwm file could be used. For instance, to check how many PWM channels supports PWM chip pwmchip0 above the following command could be used:
root@sama5d2-xplained:~# cat /sys/class/pwm/pwmchip0/npwm 4
This means pwmchip0 supports 4 PWM channels.
PWM channel export
To configure a PWM channel, fist, the PWM channel needs to be exported. To export a PWM channel the number of the channel needs to be written in /sys/class/pwm/pwmchipX/export file.
root@sama5d2-xplained:~# echo 2 > /sys/class/pwm/pwmchip0/export
After that, the PWM 2 channel is exported in sysfs and it’s parameters could be changed.
root@sama5d2-xplained:~# ls -l /sys/class/pwm/pwmchip0/ total 0 lrwxrwxrwx 1 root root 0 Jun 6 15:17 device -> ../../../f802c000.pwm --w------- 1 root root 4096 Jun 6 15:16 export -r--r--r-- 1 root root 4096 Jun 6 15:17 npwm drwxr-xr-x 2 root root 0 Jun 6 15:17 power drwxr-xr-x 3 root root 0 Jun 6 15:17 pwm2 lrwxrwxrwx 1 root root 0 Jun 6 15:17 subsystem -> ../../../../../../../class/pwm -rw-r--r-- 1 root root 4096 Jun 6 15:15 uevent --w------- 1 root root 4096 Jun 6 15:17 unexport root@sama5d2-xplained:~# ls -l /sys/class/pwm/pwmchip0/pwm2/ total 0 -r--r--r-- 1 root root 4096 Jun 6 15:18 capture -rw-r--r-- 1 root root 4096 Jun 6 15:18 duty_cycle -rw-r--r-- 1 root root 4096 Jun 6 15:18 enable -rw-r--r-- 1 root root 4096 Jun 6 15:18 period -rw-r--r-- 1 root root 4096 Jun 6 15:18 polarity drwxr-xr-x 2 root root 0 Jun 6 15:18 power -rw-r--r-- 1 root root 4096 Jun 6 15:18 uevent
A new fresh exported signal has the following parameters:
period = 0
duty_cycle = 0
polarity = normal
enable = 0
A cat on the files from /sys/class/pwm/pwmchipX/pwmY will print these values.
TIPS:: The capture file could be used to capture the PWM signal. The Atmel products doesn’t support this feature.
Period configuration
To configure period parameter for a PWM channel write the desired period value, in nanoseconds, in period file. For instance, to configure a 0.5 seconds period for PWM 2 channel use the following command:
echo 500000000 > /sys/class/pwm/pwmchip0/pwm2/period
Duty cycle configuration
To configure duty cycle parameter for a PWM channel write the desired duty cycle value, in nanoseconds, in duty_cycle file. For instance, to configure a 0.25 seconds duty cycle for PWM 2 channel use the following command:
echo 250000000 > /sys/class/pwm/pwmchip0/pwm2/duty_cycle
Polarity configuration
Linux PWM implementation defines normal and inversed polarities for PWM signals. To configure signal polarity for a PWM channel write one of these strings to polarity file. For instance, to configure inversed polarity for PWM 2 channel use the following command:
echo inversed > /sys/class/pwm/pwmchip0/pwm2/polarity
Enable/Disable PWM channels
To enable or disable a PWM channel write a 1 or a 0 in the enable file. For instance, to enable PWM 2 channel use the following command:
echo 1 > /sys/class/pwm/pwmchip0/pwm2/enable
Below is a picture with PWM signals (PWMH and PWML) on PWM channel 2, configured with above parameters, on SAMA5D2 Xplained board:
After a channel was exported and configured its parameters could be changed. Starting with linux-4.9-at91 the parameters could be changed on the fly. With version below linux-4.9-at91, if a PWM channel was exported and configured a new configuration imply to first disable the channel, reconfigure and then re-enable it.
Configuring PWM channels via device tree
Besides the sysfs, a Linux PWM channel could be requested by other drivers (e.g. regulators, leds or backlight drivers) with a set of default parameters. This is done using the pwms binding. For instance, the PWM regulator could request PWM channel 2 using the following device tree bindings:
pwm_regulator { compatible = "pwm-regulator"; pwms = <&pwm0 2 500000000 0>; regulator-name = "PWM_REGULATOR"; regulator-min-microvolt = <0>; regulator-max-microvolt = <3300000>; regulator-always-on; };
- the first parameter of pwms binding specify the label of PWM controller in device tree
- the second parameter specifies the PWM channel to be requested by PWM regulator driver
- the third parameter specifies the PWM signal period (in nanoseconds)
- the fourth parameter specifies the PWM signal polarity (0 = normal, 1 = inversed)
Debugging PWM
Linux offers a file in /sys/kernel/debug which could be used to see the state of PWM channels.
root@sama5d2-xplained:~# cat /sys/kernel/debug/pwm platform/f802c000.pwm, 4 PWM devices pwm-0 ((null) ): period: 0 ns duty: 0 ns polarity: normal mode: complementary trigger: none pwm-1 ((null) ): period: 0 ns duty: 0 ns polarity: normal mode: complementary trigger: none pwm-2 (sysfs ): requested enabled period: 500000000 ns duty: 250000000 ns polarity: normal pwm-3 ((null) ): period: 0 ns duty: 0 ns polarity: normal mode: complementary trigger: none
-- Claudiu Beznea - 2017-07-03
Related Topics
Boards
Sama5d29Curiosity
Sam9x75Curiosity
Sam9x60Curiosity
Sam9x60EK
Sama5d27WLSom1EK
Sama5d27Som1EK
Sama5d2PtcEK
Sama5d2Xplained
Sama5d3xek
Sama5d3Xplained
Sama5d4Xplained
Components
Kernel
linux 3.10
linux 3.18
linux 4.1
linux 4.4
linux 4.9
linux 4.14
linux 4.19
linux 5.4,
linux 5.10
linux 5.15
linux 6.1
linux 6.6
Summary
PWM Driver