hybridgroup / gobot

Golang framework for robotics, drones, and the Internet of Things (IoT)
https://gobot.io
Other
8.93k stars 1.04k forks source link

New ASUS Tinkerboard firmware "TinkerOS" changed pwm path #818

Closed gen2thomas closed 1 year ago

gen2thomas commented 2 years ago

Currently tinkerboard adaptor uses the sysfs/pwm_pin.go file. The default Path is set to "/sys/class/pwm/pwmchip0" (pwm0 for pin 33 and pwm1 for pin 32). This does not work, at least with the new TinkerOS. After some try and error it seems the path for pin 32 (PWM3) is "/sys/class/pwm/pwmchip3/pwm0" and for pin 33 (PWM2) it is "/sys/class/pwm/pwmchip2/pwm0".

In addition it seems like the call of "newPin.SetPeriod(10000000)" must be done before call of "newPin.InvertPolarity(false)" in the adaptor PWMPin() function.

Also "inverted" is the wrong command for "polarity", it is now "inversed".

This seems to be changed with newer kernels and maybe affect also other adaptors.

I will do some further investigation and can hopefully provide an bugfix for that in a few days.

gen2thomas commented 2 years ago

Lets startup with some debugging notes.

Investigate state

$ ls /sys/class/pwm/
pwmchip0  pwmchip1

pwmchip0 and pwmchip1 seems to be not usable (unknown, which functionality make use of that, maybe fan?)

Activate

When there is no pwm2, pwm3, this can be activated. Open the file /boot/config.txt and add lines/remove comment sign and adjust:

intf:pwm2=on intf:pwm3=on

Then save the file, close and reboot.

After reboot check the state:

$ ls /sys/class/pwm/
pwmchip0  pwmchip1  pwmchip2  pwmchip3

pwmchip2: the pin 33 is usable pwmchip3: the pin 32 is usable

When only one pwm was enabled it will be always "pwmchip2". In this case, the activated pin can be found by investigating the symbolic link of the device:

# ls -la /sys/class/pwm/
total 0
drwxr-xr-x  2 root root 0 Apr 24 14:11 .
drwxr-xr-x 66 root root 0 Apr 24 14:09 ..
lrwxrwxrwx  1 root root 0 Apr 24 14:09 pwmchip0 -> ../../devices/platform/ff680000.pwm/pwm/pwmchip0
lrwxrwxrwx  1 root root 0 Apr 24 14:09 pwmchip1 -> ../../devices/platform/ff680010.pwm/pwm/pwmchip1
lrwxrwxrwx  1 root root 0 Apr 24 14:09 pwmchip2 -> ../../devices/platform/ff680030.pwm/pwm/pwmchip2

ff680020 => pwm2, pin33 ff680030 => pwm3, pin32

Test

For example only pwm3 was activated to use pin32. Connect an oscilloscope or at least a meter to the pin 32.

switch to root user by "su -"

investigate state:

# ls -la /sys/class/pwm/pwmchip2/
total 0
drwxr-xr-x 3 root root    0 Apr 24 14:17 .
drwxr-xr-x 3 root root    0 Apr 24 14:17 ..
lrwxrwxrwx 1 root root    0 Apr 24 14:17 device -> ../../../ff680030.pwm
--w------- 1 root root 4096 Apr 24 14:17 export
-r--r--r-- 1 root root 4096 Apr 24 14:17 npwm
drwxr-xr-x 2 root root    0 Apr 24 14:17 power
lrwxrwxrwx 1 root root    0 Apr 24 14:17 subsystem -> ../../../../../class/pwm
-rw-r--r-- 1 root root 4096 Apr 24 14:17 uevent
--w------- 1 root root 4096 Apr 24 14:17 unexport

Creating pwm0

echo 0 > /sys/class/pwm/pwmchip2/export investigate result:

# ls /sys/class/pwm/pwmchip2/
device  export  npwm  power  pwm0  subsystem  uevent  unexport
# ls /sys/class/pwm/pwmchip2/pwm0/
capture  duty_cycle  enable  period  polarity  power  uevent
# cat /sys/class/pwm/pwmchip2/pwm0/period 
0
# cat /sys/class/pwm/pwmchip2/pwm0/duty_cycle 
0
# cat /sys/class/pwm/pwmchip2/pwm0/enable 
0
# cat /sys/class/pwm/pwmchip2/pwm0/polarity 
inversed

Initialization

Note: Before writing the period all other write actions will cause an error "-bash: echo: write error: Invalid argument"

echo 10000000 > /sys/class/pwm/pwmchip2/pwm0/period # this is a frequency divider for 1GHz (1000 will produce a frequency of 1MHz, 1000000 will cause a frequency of 1kHz, her we got 100Hz)
echo "normal" > /sys/class/pwm/pwmchip2/pwm0/polarity
echo 3000000 > /sys/class/pwm/pwmchip2/pwm0/duty_cycle # this means 30%
echo 1  > /sys/class/pwm/pwmchip2/pwm0/enable

Now we should measure a value of around 1V with the meter, because the basis value is 3.3V and 30% leads to 1V.

Try to inverse the sequence: echo "inversed" > /sys/class/pwm/pwmchip2/pwm0/polarity Now we should measure a value of around 2.3V with the meter, which is the difference of 1V to 3.3V.

If we have attached an oscilloscope we can play around with the values for period and duty_cycle and see what happen.

gen2thomas commented 1 year ago

part of release v2.0.0