How to use any PWM on Radxa Zero (sysfs)

Good day, friends!
I try to use PWM for my LED to be able to provide a pulsating/dimming effect (from bright to dim and back). For that I’m wanted to use sysfs to achieve this. Sysfs is currently working with GPIO pins.

Using the latest DietPi OS, I enabled the device tree overlay for PWM in /boot/dietpiEnv.txt by adding the line user_overlays=dietpi-usb-otg meson-g12a-pwm-c-on-gpiox-8 meson-g12a-pwmao-a-on-gpioao-11. After reboot I can confirm that two new chips were detected by sysfs with the command cat /sys/kernel/debug/pwm

root@DietPi:/boot# cat /sys/kernel/debug/pwm
# PWMAO
platform/ffd1a000.pwm, 2 PWM devices
 pwm-0   (sysfs               ): requested enabled period: 1000000 ns duty: 900000 ns polarity: inverse
 pwm-1   (sysfs               ): requested enabled period: 1000000 ns duty: 900000 ns polarity: inverse
# Always here, assume wifi modulation
platform/ffd19000.pwm, 2 PWM devices
 pwm-0   (wifi32k             ): requested enabled period: 30518 ns duty: 15259 ns polarity: normal
 pwm-1   (sysfs               ): requested enabled period: 100000 ns duty: 90000 ns polarity: normal
# PWM
platform/ff807000.pwm, 2 PWM devices
 pwm-0   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
 pwm-1   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
# Always here, assume cpu overclocking
platform/ff802000.pwm, 2 PWM devices
 pwm-0   ((null)              ): period: 0 ns duty: 0 ns polarity: normal
 pwm-1   (regulator-vddcpu    ): requested enabled period: 1250 ns duty: 175 ns polarity: normal

Another output pwmchip4 -> PWM and pwmchip6->PWMAO

root@DietPi:/boot# ls /sys/class/pwm/
pwmchip0  pwmchip2  pwmchip4  pwmchip6

I aim to activate the LED that is connected to PIN_40 (GPIOAO_11, PWMAO_A) and ground. For now I assume that pwmchip6 is controlling PWMAO. Because that chip appeared after I added meson-g12a-pwmao-a-on-gpioao-11 in dietpiEnv.txt.

Configuring both available channels result in no change. LED is not enabled.

# Enable channels
echo 0 > /sys/class/pwm/pwmchip6/export
echo 1 > /sys/class/pwm/pwmchip6/export

echo 1000000 > /sys/class/pwm/pwmchip6/pwm0/period
echo 900000 > /sys/class/pwm/pwmchip6/pwm0/duty_cycle
echo 1 > /sys/class/pwm/pwmchip6/pwm0/enable

echo 1000000 > /sys/class/pwm/pwmchip6/pwm1/period
echo 900000 > /sys/class/pwm/pwmchip6/pwm1/duty_cycle
echo 1 > /sys/class/pwm/pwmchip6/pwm1/enable

echo normal > /sys/class/pwm/pwmchip6/pwm1/polarity 
echo normal > /sys/class/pwm/pwmchip6/pwm0/polarity

Test GPIO PIN_40. This enables the LED and its very dim.

export gpio=423
echo $gpio > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio${gpio}/direction
echo 1 > /sys/class/gpio/gpio${gpio}/value

How it is usually done? Have you some examples? I activated every channel on both chips and connected the LED to every PIN where PWM is labeled.

Sysfs is mandatory since the application will be written in nodejs using some npm wrapper packages around sysfs

Thanks in advance!

1 Like

Sounds like PWM is working, you just need to find the correct period and duty cycle. 1kHz might be too high for the LED you’re trying to drive.

I tried different values by removing one zero on period and duty cycle down to 1000 period.

Turns out the the naming is somehow inconsistent.

List the kind of PWM of each chip with

cat /sys/class/pwm/pwmchip0/device/modalias  
cat /sys/class/pwm/pwmchip2/device/modalias  
cat /sys/class/pwm/pwmchip4/device/modalias  
cat /sys/class/pwm/pwmchip6/device/modalias 

You will get something like

of:NpwmT(null)Camlogic,meson-g12a-ao-pwm-cd
of:NpwmT(null)Camlogic,meson-g12a-ao-pwm-ab
of:NpwmT(null)Camlogic,meson-g12a-ee-pwm
of:NpwmT(null)Camlogic,meson-g12a-ee-pwm

Now I know exactly where PWMAO_A (PIN40) is located, meson-g12a-ao-pwm-ab @ pwmchip2, channel pwm0.

Code to enable the LED with PWM on PIN40.

echo 0 > /sys/class/pwm/pwmchip2/export
echo 10000 > /sys/class/pwm/pwmchip2/pwm0/period
echo 9000 > /sys/class/pwm/pwmchip2/pwm0/duty_cycle
echo 1 > /sys/class/pwm/pwmchip2/pwm0/enable

Somehow other pins don’t work with adjusted values. I also assume *ee-pwm is pwm input, am I right here?