How to use Pulse Width Modulation driver

Last modified by Microchip on 2025/02/28 14:12

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.

  
Board NameConnectorConnector PinPWM SignalLinux Channel
SAM9X60 EKJ14 (mikroBUS)16 (PWM)PWM22
SAMA5D29-CuriosityJ19 (mikroBUS 1)PA31 (PWM)PWML00
J14 (mikroBUS 2)PB0 (PWM)PWMH1
SAMA5D27 WLSOM1 EKJ19 (mikroBUS 1)16 (PWM)PWMH00
J20 (mikroBUS 2)16 (PWM)PWML0
SAMA5D27 SOM1 EKJ25 (mikroBUS 1)1 (PWM)PWML11
J30 (mikroBUS 2)1 (PWM)PWML00
SAMA5D2 XplainedJ201PWML22
2PWMH2
J268PWML2
7PWMH2
SAMA5D3 XplainedJ19PA21PWML00
PA20PWMH0
PA23PWML11
PA31
PB27PWMH1
PA22
SAMA5D4 XplainedJ72PWML00
5PWMH0
3PWML11
6PWMH1
J88PWML00
7PWMH0
3
2PWML11
4
6PWML22
5PWMH2
J154PWML00
26PWMH11
10PWML22
9PWMH2
33PWML33
J174PWML33
J184PWML22
8PWMH2
J197PWML33
8PWMH3
J228PWML33
7PWMH3
J238PWML22
7PWMH2
  

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.

TIP 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:

https://www.linux4sam.org/pub/Linux4SAM/PwmFaq/linux4sam-pwm-documentation-pwm-signal-example.jpg

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

-- https://www.linux4sam.org/pub/Main/UserProfileHeader/default-user-profile.jpg 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