adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
439 stars 328 forks source link

Add PWMOut support for BeagleBone #240

Open pdp7 opened 4 years ago

pdp7 commented 4 years ago

After discussing with @RobertCNelson, I have learned that pwmchip numbering in Linux is not deterministic. Therefore, the mapping between a pin and the pwm chip/channel can change between boots:

debian@beaglebone:~$ ls -ltar /sys/class/pwm
total 0
drwxr-xr-x  2 root root 0 Jan 13 20:15 .
drwxr-xr-x 63 root root 0 Jan 13 20:15 ..
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-7:0 -> ../../devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip7/pwm-7:0
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwmchip0 -> ../../devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-0:0 -> ../../devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0/pwm-0:0
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwmchip7 -> ../../devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip7
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-3:0 -> ../../devices/platform/ocp/48302000.epwmss/48302100.ecap/pwm/pwmchip3/pwm-3:0
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-1:1 -> ../../devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1/pwm-1:1
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-6:0 -> ../../devices/platform/ocp/48304000.epwmss/48304100.ecap/pwm/pwmchip6/pwm-6:0
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-4:1 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip4/pwm-4:1
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwmchip3 -> ../../devices/platform/ocp/48302000.epwmss/48302100.ecap/pwm/pwmchip3
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-7:1 -> ../../devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip7/pwm-7:1
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwmchip1 -> ../../devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwmchip6 -> ../../devices/platform/ocp/48304000.epwmss/48304100.ecap/pwm/pwmchip6
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-1:0 -> ../../devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1/pwm-1:0
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwmchip4 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip4
lrwxrwxrwx  1 root root 0 Jan 13 20:15 pwm-4:0 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip4/pwm-4:0

This is not a Beagle/AM3358 specific issue. This is an issue effecting in the PWM subsystem in Linux kernel.

The BeagleBoard.org Debian image that @RobertCNelson builds solves this by creating deterministic symlinks using udev rules: https://github.com/rcn-ee/repos/blob/master/bb-customizations/suite/stretch/debian/81-pwm-noroot.rules

debian@beaglebone:~$ ls -ltar /dev/pwm
total 0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ecap0 -> /sys/class/pwm/pwm-0:0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ehrpwm0b -> /sys/class/pwm/pwm-1:1
lrwxrwxrwx  1 root root   22 Jan  1  2000 ehrpwm0a -> /sys/class/pwm/pwm-1:0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ehrpwm1a -> /sys/class/pwm/pwm-4:0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ecap1 -> /sys/class/pwm/pwm-3:0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ecap2 -> /sys/class/pwm/pwm-6:0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ehrpwm1b -> /sys/class/pwm/pwm-4:1
lrwxrwxrwx  1 root root   22 Jan  1  2000 ehrpwm2a -> /sys/class/pwm/pwm-7:0
lrwxrwxrwx  1 root root   22 Jan  1  2000 ehrpwm2b -> /sys/class/pwm/pwm-7:1

I need to modfiy src/adafruit_blinka/microcontroller/am335x/sysfs_pwmout.py so that it uses these deterministic /dev/pwm entries in order for there the correct mapping between the P8/P9 pin and the corresponding peripheral.

Furthermore, the EHRPWM blocks contain a and b outputs. These can have independent duty cycles but must have the same frequency. I need to represent that tight coupling in the code. Attempting to set EHRPWM0A and EHRPWM0B to different frequencies will fail.

pdp7 commented 4 years ago

@makermelissa please assign to me

pdp7 commented 4 years ago

For example on the BeagleBone Black, there is

/sys/class/pwm/pwmchip0/
/sys/class/pwm/pwmchip1/
/sys/class/pwm/pwmchip3/
/sys/class/pwm/pwmchip4/
/sys/class/pwm/pwmchip6/
/sys/class/pwm/pwmchip7/

But the pin they point to can change between boots.

Whereas, these mappings in /dev/pwm will not change between boot:

/dev/pwm/ecap1
/dev/pwm/ecap2
/dev/pwm/ehrpwm0a
/dev/pwm/ehrpwm0b
/dev/pwm/ehrpwm1a
/dev/pwm/ehrpwm1b
/dev/pwm/ehrpwm2a
/dev/pwm/ehrpwm2b