PWM on more than 2 pins?

I think most of us have got a single servo running on the BBB by now. Has anyone succeeded in using 3 or more PWM channels at the same time?

I find that if I:

$ echo am33xx_pwm > /sys/devices/bone_capemgr.8/slots

$ echo bone_pwm_P8_13 > /sys/devices/bone_capemgr.8/slots

$ echo bone_pwm_P8_19 > /sys/devices/bone_capemgr.8/slots

$ echo bone_pwm_P9_14 > /sys/devices/bone_capemgr.8/slots

$ echo bone_pwm_P9_16 > /sys/devices/bone_capemgr.8/slots

Then directories /sys/devices/ocp.2/pwm_test_P8_13.xx and pwm_test_P9_14.xx contain the expected files and subdirectories:

driver duty modalias period polarity power run subsystem uevent

while directories /sys/devices/ocp.2/pwm_test_P8_19.xx and pwm_test_P9_16.xx only contain:

modalias power subsystem uevent

The uevent files for P8_13 and P9_14 both contain the line ‘DRIVER=pwm_test’ which is missing from the uevent files for P8_19 and P9_16.

The output on pins P8_13 and P9_14 behaves as expected when I write to their period and duty files.

Pins P8_19 and P9_16 are fixed high or low (depending on the history of tests run on them).

If I reverse the order in which I load the PWM modules, P8_19 and P9_16 are good, P8_13 and P9_14 are bad.

I notice that after loading the PWM module on, say, P8_13, the output on the second pin for that EHR, P8_19 immediately goes high.
(This may be indicative of the driver messing up the 2nd channel while configuring the 1st.)

Very occasionally, a second PWM channel can be opened on one of the EHRs. When this happens, writes to the channel’s period file return error ‘invalid argument’.

I’ve observed the same behavior on Angstrom 6/20 and 8/21 (in desperation I downloaded a copy from the developer’s site).
I’ve tested this with the PWM pins unconnected, connected to LEDs through serial resistors, connected to a 7404 and connected to L293Ds.
I’ve tested this with the Adafruit BBIO library (0.17), shell commands as above, and using a homebrew python SYSFS front-end.

Is there a bug in the test_pwm driver or am I missing some step in initializing the PWM channels?

From the reference manual:
EHPWM1 can be configured for EITHER P9_14 pr P_16[EHPWM1A or EHPWM1B]
EHPWM2 can be configured for EITHER P8_13 or P8_19

You can also use the PRU’s PWM device for a third pin on P9_28 but keep in mind that the PRU is not supported for hobbyist use so I don’t know how much code is available for it.

Thank you garyamort.

On further investigation I find that I can enable PWM on:

P8_13 OR P8_19 (EHRPWM2B, EHRPWM2A),
P9_14 OR P9_16 (EHRPWM1A, EHRPWM1B),
P9_21 OR P9_22 (EHRPWM0B, EHRPWM0A).

Three PWM pins is enough for now. If I need more I’ll add a PIC to the mix.

Actually that is not exactly true. There are 3 onboard EHRPWM modules, each with two outputs. However, PWM frequency must be same for both outputs of a EHRPWM share the same PWM frequency (but can have independent duty cycles and, iirc, polarity). See AM335x SRM.

The problem is that the Linux kernel driver for the AM335x EHRPWM has a bug where it errors out if the requested frequency of both ports don’t match (they’ll never since you can only request one at a time).

You should be able to set frequency of both output but only while adding the cape through device tree for both. Then you can control their duty cycle and polarity (and enable) at runtime through sysfs.

I’d be happy to have 6 PWM pins running at 3 frequencies. As a work-around I was going to use the Arduino Motor & Servo shield’s shift-register to toggle between servos.

Do you know if the kernel driver is receiving any attention? (I haven’t found the Angstrom equivalent of Launchpad yet.)

any one know how to acess pwm slots in
/sys/devices/bone_capemgr.9?

I try to just change from 8 to 9 and did not work.

I use bbb black with ubuntu precise and I cant find
/sys/devices/ocp.2/helper.14/AIN7
or
/sys/devices/platform/tsc/ain1

those ports are only availible by default in anstrong?

Either browse through the files to know your devices correct bone_capemgr number or try this

cd /sys/devices/
ls

cd capemgr.x (choose from the list and replace the number for x)