Difference between revisions of "Linux PWM Pulse Width Modulator"

From RidgeRun Developer Connection
Jump to: navigation, search
(Created page with "=Introduction= The following document has information about the Pulse Width Modulators available for the TX2 and how to control them. There are eight PWMs available for the T...")
 
m
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
=Introduction=
+
<seo title="Pulse Width Modulator | Linux PWM for NVIDIA Jetson TX2 | RidgeRun" titlemode="replace" keywords="GStreamer,  PWM, Linux PWM, GstRrWebRTC, Pulse Width Modulator, Embedded Linux, Nvidia, Xilinx, TI, NXP, Freescale, Embedded Linux SDK, GStreamer Multimedia Framework, Gstreamer Plugin,PWM API, sysfs, configure PWM, enable PWM, disable PWM,Verify PWM, Linux PWM, PWM"  description="This wiki has information about the Pulse Width Modulators available for the TX2 and how to control them."></seo>
The following document has information about the Pulse Width Modulators available for the TX2 and how to control them.
 
  
There are eight PWMs available for the TX2:
+
==Introduction to Linux PWM Pulse Width Modulator for NVIDIA Jetson TX2 ==
 +
The following document has information about the Pulse Width Modulators available for the Jetson TX2 and how to control them.
  
[[File:tx2_pwms.png|600px|OTPM TX2 PWMs]]
+
There are eight PWMs available for the Jetson TX2:
  
=Activating TX2 PWM=
+
[[File:Tx2_pwms.png|600px|OTPM TX2 PWMs]]
  
The TX2's pulse width modulators can be controlled at user space level using sysfs interface or at driver level using the PWM API.
+
==Activating Jetson TX2 PWM==
  
==Control PWM through sysfs==
+
The Jetson TX2 pulse width modulators can be controlled at user space level using sysfs interface or at driver level using the PWM API.
 +
 
 +
===Control PWM through sysfs===
  
 
There are available 4 PWMs to be controlled at user space level. This interface allow the user to set the desired period and duty cycle and then activate or disable the PWM selected.
 
There are available 4 PWMs to be controlled at user space level. This interface allow the user to set the desired period and duty cycle and then activate or disable the PWM selected.
Line 16: Line 18:
 
In /sys/class/pwm, you will find four directories corresponding to the first fourth PWMs available:
 
In /sys/class/pwm, you will find four directories corresponding to the first fourth PWMs available:
  
<pre>
+
<pre style="background:#d6e4f1">
 
pwmchip0 --> GP_PWM1
 
pwmchip0 --> GP_PWM1
 
pwmchip1 --> GP_PWM2
 
pwmchip1 --> GP_PWM2
Line 25: Line 27:
 
In order to set the configuration of one of the PWMs, you should export it first. Then, set the period, duty cycle and enable state as the following:
 
In order to set the configuration of one of the PWMs, you should export it first. Then, set the period, duty cycle and enable state as the following:
  
<pre>
+
<pre style="background:#d6e4f1">
 
echo 0 > /sys/class/pwm/pwmchip0/export
 
echo 0 > /sys/class/pwm/pwmchip0/export
 
cd /sys/class/pwm/pwmchip0/pwm0
 
cd /sys/class/pwm/pwmchip0/pwm0
Line 35: Line 37:
 
In the example above, the pulse activated (PWM1) has a frequency of 50 KHz (1/20us) and 50% of duty cycle (10000/20000 * 100).
 
In the example above, the pulse activated (PWM1) has a frequency of 50 KHz (1/20us) and 50% of duty cycle (10000/20000 * 100).
  
===Control Fan PWM (sysfs)===
+
====Control Fan PWM (sysfs)====
  
 
Jetson EVM only has pins exposed for the PWM signal that controls the fan, so in order to verify that the PWM is working correctly use the pin 4 on J15 Connector.
 
Jetson EVM only has pins exposed for the PWM signal that controls the fan, so in order to verify that the PWM is working correctly use the pin 4 on J15 Connector.
  
====Disable Fan driver====
+
=====Disable Fan driver=====
  
 
As the PWM4 is already used by a driver that controls the fan, you should disable this driver in order to control the PWM manually.
 
As the PWM4 is already used by a driver that controls the fan, you should disable this driver in order to control the PWM manually.
Line 45: Line 47:
 
Apply below change on '''hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-power-tree-p3489-1000-a00-00.dtsi'''
 
Apply below change on '''hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-power-tree-p3489-1000-a00-00.dtsi'''
  
<pre>
+
<pre style="background:#d6e4f1">
 
pwm-fan {
 
pwm-fan {
 
+ status = "disabled";
 
+ status = "disabled";
Line 52: Line 54:
 
</pre>
 
</pre>
  
====Fix vdd_fan regulator state====
+
=====Fix vdd_fan regulator state=====
  
 
The Fan controller has a GPIO that has to be set to low in order to allow the PWM activation, so you can modify the device-tree to set the initial value to low and keep this state to reduce complexity regarding PWM activation.
 
The Fan controller has a GPIO that has to be set to low in order to allow the PWM activation, so you can modify the device-tree to set the initial value to low and keep this state to reduce complexity regarding PWM activation.
Line 58: Line 60:
 
Apply below change on '''hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi'''
 
Apply below change on '''hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi'''
  
<pre>
+
<pre style="background:#d6e4f1">
 
vdd_fan: regulator@13 {
 
vdd_fan: regulator@13 {
 
compatible = "regulator-fixed-sync";
 
compatible = "regulator-fixed-sync";
Line 72: Line 74:
 
'''Note:''' You can also, disable this regulator and control manually vdd_fan GPIO (244) according to your needs.
 
'''Note:''' You can also, disable this regulator and control manually vdd_fan GPIO (244) according to your needs.
  
====Configure and Enable Fan PWM====
+
=====Configure and Enable Fan PWM=====
  
 
Fan is controlled by GP_PWM4, so you in order to configure this PWM, you should apply the configuration to '''pwmchip3'''.
 
Fan is controlled by GP_PWM4, so you in order to configure this PWM, you should apply the configuration to '''pwmchip3'''.
  
<pre>
+
<pre style="background:#d6e4f1">
 
echo 0 > /sys/class/pwm/pwmchip3/export
 
echo 0 > /sys/class/pwm/pwmchip3/export
 
cd /sys/class/pwm/pwmchip3/pwm0
 
cd /sys/class/pwm/pwmchip3/pwm0
Line 84: Line 86:
 
</pre>
 
</pre>
  
====Verify PWM activation====
+
=====Verify PWM activation=====
  
 
Measure the PWM output on pin 4 of J15 Connector using an oscilloscope. You should see the pulse when you enable the PWM and you could measure frequency and duty cycle to validate this procedure.
 
Measure the PWM output on pin 4 of J15 Connector using an oscilloscope. You should see the pulse when you enable the PWM and you could measure frequency and duty cycle to validate this procedure.
  
==Enable PWM using the API==
+
===Enable PWM using the API===
  
 
A driver can configure and activate a PWM in a similar way to a the GPIOs are set. In order to do this, you should define the desired PWM in your corresponding driver node in your device-tree and implement the logic to parse and control this PWM in the driver.
 
A driver can configure and activate a PWM in a similar way to a the GPIOs are set. In order to do this, you should define the desired PWM in your corresponding driver node in your device-tree and implement the logic to parse and control this PWM in the driver.
  
===Control Fan PWM (API)===
+
====Control Fan PWM (API)====
  
 
In the following example, we are going to control the GP_PWM4 so, make sure you have the fan driver disabled and fix vdd_fan regulator to be in low state as explained in [[#Control_Fan_PWM_(sysfs)|Control Fan PWM (sysfs)]]
 
In the following example, we are going to control the GP_PWM4 so, make sure you have the fan driver disabled and fix vdd_fan regulator to be in low state as explained in [[#Control_Fan_PWM_(sysfs)|Control Fan PWM (sysfs)]]
  
====Define the PWM in the Device-Tree====
+
=====Define the PWM in the Device-Tree=====
  
 
In the example below, the GP_PWM4 is defined in the AR1335 sensor node to start in low state and with a period of 45334 (~45 us).
 
In the example below, the GP_PWM4 is defined in the AR1335 sensor node to start in low state and with a period of 45334 (~45 us).
<pre>
+
<pre style="background:#d6e4f1">
 
ar1335_a@37 {
 
ar1335_a@37 {
 
compatible = "nvidia,ar1335";
 
compatible = "nvidia,ar1335";
Line 110: Line 112:
 
</pre>
 
</pre>
  
====Add API header====
+
=====Add API header=====
  
 
In the driver, add the following include:
 
In the driver, add the following include:
<pre>
+
<pre style="background:#d6e4f1">
 
#include <linux/pwm.h>
 
#include <linux/pwm.h>
 
</pre>
 
</pre>
  
====Get the PWM resource====
+
=====Get the PWM resource=====
  
 
In the driver, use the devm_pwm_get() function to pass to it the consumer device.
 
In the driver, use the devm_pwm_get() function to pass to it the consumer device.
  
<pre>
+
<pre style="background:#d6e4f1">
 
priv->pwm_dev = devm_pwm_get(&client->dev, NULL);
 
priv->pwm_dev = devm_pwm_get(&client->dev, NULL);
 
if (IS_ERR(priv->pwm_dev)) {
 
if (IS_ERR(priv->pwm_dev)) {
Line 134: Line 136:
 
</pre>
 
</pre>
  
====Configure PWM====
+
=====Configure PWM=====
  
 
Use pwm_config() method to set the duty cycle and period, in the example below the pulse is configured with a frequency  of 60 Hz and 50% of duty cycle.
 
Use pwm_config() method to set the duty cycle and period, in the example below the pulse is configured with a frequency  of 60 Hz and 50% of duty cycle.
  
pwm_config(priv->pwm_dev, 8333333, 16666667);
+
<pre style="background:#d6e4f1">
 +
pwm_config(priv->pwm_dev, 8333333, 16666667);
 +
</pre>
  
====Enable PWM====
+
=====Enable PWM=====
  
 
Once the PWM is configured, activate it like this:
 
Once the PWM is configured, activate it like this:
  
pwm_enable(priv->pwm_dev);
+
<pre style="background:#d6e4f1">
 +
pwm_enable(priv->pwm_dev);
 +
</pre>
  
====Disable PWM====
+
=====Disable PWM=====
  
 
In order to disable PWM, use the following method:
 
In order to disable PWM, use the following method:
  
pwm_diable(priv->pwm_dev);
+
<pre style="background:#d6e4f1">
 +
pwm_diable(priv->pwm_dev);
 +
</pre>
  
====Verify PWM====
+
=====Verify PWM=====
  
 
Using this methods you should be able to control the PWM and you can verify the output measuring pin 4 (J15 Connector).
 
Using this methods you should be able to control the PWM and you can verify the output measuring pin 4 (J15 Connector).
 +
 +
 +
===Allow low PWM frequency configuration===
 +
 +
For the latest Linux for Tegra (L4T-32), it's necessary to add extra device-tree configuration to allow lower frequency configuration for PWMs.
 +
 +
====Example====
 +
For example the frequency range of operation for PWM3 is "400 Hz and below" as described in the TRM. However, with the default configuration this PWM can't be configured to use a frequency below ~50 Hz and it's necessary to specify the minimum frequency limit in the corresponding device-tree node.
 +
 +
<br>The following change will allow to configure PWM3 to 30 Hz:
 +
<pre style="background:#d6e4f1">
 +
pwm@32a0000 {
 +
    pwm-minimum-frequency-hz = <30>; /* required rate in Hz */
 +
};
 +
</pre>
 +
 +
{{ContactUs}}
  
 
[[Category: Jetson]]
 
[[Category: Jetson]]

Latest revision as of 19:40, 12 February 2020

Introduction to Linux PWM Pulse Width Modulator for NVIDIA Jetson TX2

The following document has information about the Pulse Width Modulators available for the Jetson TX2 and how to control them.

There are eight PWMs available for the Jetson TX2:

OTPM TX2 PWMs

Activating Jetson TX2 PWM

The Jetson TX2 pulse width modulators can be controlled at user space level using sysfs interface or at driver level using the PWM API.

Control PWM through sysfs

There are available 4 PWMs to be controlled at user space level. This interface allow the user to set the desired period and duty cycle and then activate or disable the PWM selected.

In /sys/class/pwm, you will find four directories corresponding to the first fourth PWMs available:

pwmchip0 --> GP_PWM1
pwmchip1 --> GP_PWM2
pwmchip2 --> GP_PWM3
pwmchip3 --> GP_PWM4 (Fan)

In order to set the configuration of one of the PWMs, you should export it first. Then, set the period, duty cycle and enable state as the following:

echo 0 > /sys/class/pwm/pwmchip0/export
cd /sys/class/pwm/pwmchip0/pwm0
echo 20000 > period
echo 10000 > duty_cycle
echo 1 > enable

In the example above, the pulse activated (PWM1) has a frequency of 50 KHz (1/20us) and 50% of duty cycle (10000/20000 * 100).

Control Fan PWM (sysfs)

Jetson EVM only has pins exposed for the PWM signal that controls the fan, so in order to verify that the PWM is working correctly use the pin 4 on J15 Connector.

Disable Fan driver

As the PWM4 is already used by a driver that controls the fan, you should disable this driver in order to control the PWM manually.

Apply below change on hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-power-tree-p3489-1000-a00-00.dtsi

pwm-fan {
+ 	status = "disabled";
 	vdd-fan-supply = <&vdd_fan>;
 };
Fix vdd_fan regulator state

The Fan controller has a GPIO that has to be set to low in order to allow the PWM activation, so you can modify the device-tree to set the initial value to low and keep this state to reduce complexity regarding PWM activation.

Apply below change on hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-cvb-prod-p2597-b00-p3310-1000-a00-00.dtsi

vdd_fan: regulator@13 {
	compatible = "regulator-fixed-sync";
	reg = <13>;
	regulator-name = "vdd-fan";
	regulator-min-microvolt = <5000000>;
	regulator-max-microvolt = <5000000>;
	gpio = <&gpio_i2c_0_74 4 0>;
+	enable-active-high;
};

Note: You can also, disable this regulator and control manually vdd_fan GPIO (244) according to your needs.

Configure and Enable Fan PWM

Fan is controlled by GP_PWM4, so you in order to configure this PWM, you should apply the configuration to pwmchip3.

echo 0 > /sys/class/pwm/pwmchip3/export
cd /sys/class/pwm/pwmchip3/pwm0
echo 20000 > period
echo 10000 > duty_cycle
echo 1 > enable
Verify PWM activation

Measure the PWM output on pin 4 of J15 Connector using an oscilloscope. You should see the pulse when you enable the PWM and you could measure frequency and duty cycle to validate this procedure.

Enable PWM using the API

A driver can configure and activate a PWM in a similar way to a the GPIOs are set. In order to do this, you should define the desired PWM in your corresponding driver node in your device-tree and implement the logic to parse and control this PWM in the driver.

Control Fan PWM (API)

In the following example, we are going to control the GP_PWM4 so, make sure you have the fan driver disabled and fix vdd_fan regulator to be in low state as explained in Control Fan PWM (sysfs)

Define the PWM in the Device-Tree

In the example below, the GP_PWM4 is defined in the AR1335 sensor node to start in low state and with a period of 45334 (~45 us).

ar1335_a@37 {
	compatible = "nvidia,ar1335";
	reg = <0x37>;
	:
        #pwm-cells = <1>;
	pwms = <&tegra_pwm4 0 45334>;
	:
};
Add API header

In the driver, add the following include:

#include <linux/pwm.h>
Get the PWM resource

In the driver, use the devm_pwm_get() function to pass to it the consumer device.

priv->pwm_dev = devm_pwm_get(&client->dev, NULL);
if (IS_ERR(priv->pwm_dev)) {
	err = PTR_ERR(priv->pwm_dev);
	if (err != -EPROBE_DEFER)
		dev_err(&client->dev,
			"Unable to request PWM for fan\n");
	return -EFAULT;
} else {
	dev_info(&client->dev, "Got PWM for fan\n");
}
Configure PWM

Use pwm_config() method to set the duty cycle and period, in the example below the pulse is configured with a frequency of 60 Hz and 50% of duty cycle.

pwm_config(priv->pwm_dev, 8333333, 16666667);
Enable PWM

Once the PWM is configured, activate it like this:

pwm_enable(priv->pwm_dev);
Disable PWM

In order to disable PWM, use the following method:

pwm_diable(priv->pwm_dev);
Verify PWM

Using this methods you should be able to control the PWM and you can verify the output measuring pin 4 (J15 Connector).


Allow low PWM frequency configuration

For the latest Linux for Tegra (L4T-32), it's necessary to add extra device-tree configuration to allow lower frequency configuration for PWMs.

Example

For example the frequency range of operation for PWM3 is "400 Hz and below" as described in the TRM. However, with the default configuration this PWM can't be configured to use a frequency below ~50 Hz and it's necessary to specify the minimum frequency limit in the corresponding device-tree node.


The following change will allow to configure PWM3 to 30 Hz:

pwm@32a0000 {
    pwm-minimum-frequency-hz = <30>; /* required rate in Hz */
};


RidgeRun Resources

Quick Start Client Engagement Process RidgeRun Blog Homepage
Technical and Sales Support RidgeRun Online Store RidgeRun Videos Contact Us

OOjs UI icon message-progressive.svg Contact Us

Visit our Main Website for the RidgeRun Products and Online Store. RidgeRun Engineering informations are available in RidgeRun Professional Services, RidgeRun Subscription Model and Client Engagement Process wiki pages. Please email to support@ridgerun.com for technical questions and contactus@ridgerun.com for other queries. Contact details for sponsoring the RidgeRun GStreamer projects are available in Sponsor Projects page. Ridgerun-logo.svg
RR Contact Us.png