How to use the PWM lines

This article illustrates how to use the SPI interface on the Acme Systems Linux boards based on Microchip SAMG2x, SAMA5D3x and SAMD2x CPUs

PWM Kernel modules

Two drivers are provided by Atmel in the Kernel mainstream to generate the PWM signals

These drivers exposes a sysfs user space interface to manage the PWM signals.

Driver for Timer Counter Block PWB

Device Drivers  ---> 
  [*] Pulse-Width Modulation (PWM) Support  --->
    <*>   Atmel TC Block PWM support 

Related links

Using the PWM sysfs user space interface

The PWM sysfs at startup interface will create a directory called /sys/class/pwm/pwmchip0.

For any PWM line you want to use you have to export it.

~# echo 0 > /sys/class/pwm/pwmchip0/export
~# echo 1 > /sys/class/pwm/pwmchip0/export
~# echo 2 > /sys/class/pwm/pwmchip0/export
~# echo 3 > /sys/class/pwm/pwmchip0/export
...

To use again that line ad generic GPIO you can unexport it:

~# echo 0 > /sys/class/pwm/pwmchip0/unexport
~# echo 1 > /sys/class/pwm/pwmchip0/unexport
~# echo 2 > /sys/class/pwm/pwmchip0/unexport
~# echo 3 > /sys/class/pwm/pwmchip0/unexport
...

For any exported channel a directory called pwmX wil be created with the following structure:

/sys/class/pwm/pwmchip0/pwmX/
      |-- duty_cycle (r/w) duty cycle (in nanoseconds)
      |-- enable     (r/w) enable/disable PWM
      |-- period     (r/w) period (in nanoseconds)
      |-- polarity   (r/w) polarity of PWM
      |-- power
      `-- uevent

The follow example illustrate how enable a PWM signale with a period of 1mS with a 0.5mS of duty cycle:

~# echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period
~# echo 500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
~# echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable

PWM

Acqua

pwm0: pwm@f002c000 {
    pinctrl-names = "default";
    pinctrl-0 = <   
                    &pinctrl_pwm0_pwmh0
                    &pinctrl_pwm0_pwml0
                    &pinctrl_pwm0_pwmh1 
                    &pinctrl_pwm0_pwml1
                    &pinctrl_pwm0_pwmh2 
                    &pinctrl_pwm0_pwml2
                    &pinctrl_pwm0_pwmh3 
                    &pinctrl_pwm0_pwml3
                    >;
    status = "okay";
};

pinctrl@fffff200 {
    board {
        pinctrl_pwm0_pwmh0: pwm0_pwmh0 {
            atmel,pins =
                < AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwml0: pwm0_pwml0 {
            atmel,pins =
                < AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwmh1: pwm0_pwmh1 {
            atmel,pins =
                < AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwml1: pwm0_pwml1 {
            atmel,pins =
                < AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwmh2: pwm0_pwmh2 {
            atmel,pins =
                < AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwml2: pwm0_pwml2 {
            atmel,pins =
                < AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwmh3: pwm0_pwmh3 {
            atmel,pins =
                < AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
        pinctrl_pwm0_pwml3: pwm0_pwml3 {
            atmel,pins =
                < AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
    };
};

Aria

pinctrl@fffff400 {
    pwm0 {
        pinctrl_pwm0: pwm0-0 {
            atmel,pins =
            < AT91_PIOC 18 AT91_PERIPH_C AT91_PINCTRL_NONE
              AT91_PIOC 19 AT91_PERIPH_C AT91_PINCTRL_NONE
              AT91_PIOC 20 AT91_PERIPH_C AT91_PINCTRL_NONE
              AT91_PIOC 21 AT91_PERIPH_C AT91_PINCTRL_NONE >;
        };
    };
};

pwm0: pwm@f8034000 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pwm0>;
    status = "okay";
};

Arietta

pinctrl@fffff400 {
    pwm0 {
        pinctrl_pwm0: pwm0-0 {
            atmel,pins =
            < AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE
              AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE
              AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE
              AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE >;
        };
    };
};

Credits

Many thanks to Nicolas Ferre and Boris Brezillon for their help.

Sergio Tanzilli
Systems designer, webmaster of www.acmesystems.it and founder of Acme Systems srl

Personal email: tanzilli@acmesystems.it
Web pages: https://www.acmesystems.it --- https://www.acmestudio.it
Github repositories: https://github.com/tanzilli --- https://github.com/acmesystems
Telegram group dedicated to the Acme Systems boards: https://t.me/acmesystemssrl