How to setup and use PWM on SP7021 demo board V3

The goal of this document is to illustrate how to setup and use PWM on SP7021 demo board V3. Refer to picture of SP7021 demo board V3, there is a 40-pin pin-header of Raspberry Pi compatible on the board. This document will illustrate how to setup pins 35, 38, 36 and 40 to output channel 0 ~ 3 of PWM of SP7021.

1. Schematics

Refer to pin-assignment of Raspberry Pi compatible pin-header of SP7021 demo board V3, pins 35, 38, 37 and 40 are connected to GPIO_P4_4 (G_MX[36]), GPIO_P4_5 (G_MX[37]), GPIO_P4_6 (G_MX[38]) and GPIO_P4_7 (G_MX[39]) of SP7021, respectively.

2. Modify device-tree source

Modify device-tree node pwm in device-tree source file linux/kernel/arch/arm/boot/dts/sp7021-demov3.dts to setup PWM:

&pwm { pinctrl-names = "default"; pinctrl-0 = <&pins_pwm>; status = "okay"; };

Note that pwm is a label to node pwm@9c007a00.

Also, modify dts node pinmux_pwm-pins to setup pins of channel 0 to 3 of PWM to GPIO_P4_4 (G_MX[36]), GPIO_P4_5 (G_MX[37]), GPIO_P4_6 (G_MX[38]) and GPIO_P4_7 (G_MX[39]), respectively:

pins_pwm: pinmux_pwm-pins { sunplus,pins = < SPPCTL_IOPAD(36, SPPCTL_PCTL_G_PMUX, MUXF_PWM0, 0) SPPCTL_IOPAD(37, SPPCTL_PCTL_G_PMUX, MUXF_PWM1, 0) SPPCTL_IOPAD(38, SPPCTL_PCTL_G_PMUX, MUXF_PWM2, 0) SPPCTL_IOPAD(39, SPPCTL_PCTL_G_PMUX, MUXF_PWM3, 0) >; };

Note that node pinmux_pwm-pins is a sub-node of node pctl. PWM0 is assigned to G_MX36. PWM1 is assigned to G_MX37. PWM2 is assigned to G_MX38. PWM3 is assigned to G_MX39.

Please note that to comply with Linux rules, after version 5.10.59, 4 property-names of pin node of SP7021 are changed as shown in table below:

5.4.35

5.10.59

5.4.35

5.10.59

sppctl,function

function

sppctl,groups

groups

sppctl,pins

sunplus,pins

sppctl,zero_func

sunplus,zerofunc

3. Enable Linux PWM driver

Run make kconfig in project top directory. When “Linux/arm Kernel Configuration” menu pops up, move cursor to go to “Device Drivers” and enable “Pulse-width Modulation (PWM) support”. Refer to screenshot below:

4. Build Linux image

Go to top folder. Run make config to select to build image for “SP7021 Demo Board (V3)”. And then select boot device: eMMC or SD card. After make config completes, run make all to build Linux image.

5. Boot Linux

Boot Linux with the built image.

6. Check out pin-assignment of PWM device

Run cat /sys/kernel/debug/pinctrl/pinctl/pinmux-pins to get report of pin-assignment of all GPIO. Refer to screenshot of portion of the report, P4_04 ~ P4_07 are claimed to PWM0 ~ PWM3:

7. Use the PWM from userspace

A simple sysfs interface is provided to use PWM from userspace. It is located at ‘/sys/class/pwm/pwmchipN’, where N is the base of PWM controller. SP7021 has only one PWM controller. N is 0. Inside the folder you will find: npwm, export, unexport and etc. Refer screenshot below, content of folder pwmchip0 is listed:

Files:

  • npwm: The number of PWM channels this chip supports (read-only).

  • export: Exports a PWM channel for use with sysfs (write-only).

  • unexport: Unexports a PWM channel from sysfs (write-only).

SP7021 PWM controller supports 8 channels. Refer to screenshot below:

To export PWM0, PWM1, PWM2 and PWM3, issue commands in Linux shell as below:

/ # 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

When a PWM channel is exported, a folder pwmX will be created in the folder pwmchipN. X is the number of the channel exported. Refer screenshot below, content of folder pwmchip0 is listed. Folder pwm0, pwm1, pwm2 and pwm3 are created:

Refer screenshot below, content of folder pwm0 is listed:

Files:

  • period: The period of PWM signal (read/write). Unit is nanosecond.

  • duty_cycle: The active time of PWM signal (read/write). Unit is nanosecond. It must be less than period.

  • polarity: Changes the polarity of PWM signal (read/write). Value is either “normal” or “inversed”.

  • enable: Enable/disable the PWM signal (read/write). Value is either 0 (disabled) or 1 (enabled).

Note that SP7021 does not support “inversed” polarity.

To set PWM0 to 1 kHz, 25% duty, PWM1 to 2k Hz, 50% duty, PWM2 to 1 kHz 75% duty and PWM3 to 1 kHz, 50% duty, issue commands in Linux shell as below:

Refer to snapshot of oscilloscope which was captured while PWM0, PWM1, PWM2 and PWM3 signal are outputting.

where C1 (yellow) is PWM0 signal, C2 (red) is PWM1 signal, C3 (blue) is PMW2 signal, and C4 (green) is PWM3 signal. Z1, Z2, Z3 and Z4 are zoom-in of C1, C2, C3 and C4, respectively. Period of PWM0 and PWM3 is 1 millisecond. Period of PWM1 and PWM2 is 0.5 millisecond. Duty cycle of PWM0 is 25%. Duty cycle of PMW1 is 50%. Duty cycle of PWM2 is 75%. Duty cycle of PWM3 is 50%.