Is anyone working on a pwm driver for the 'bone?

The PWM hardware available on the beaglebone seems significantly
different than what's available on the beagleboard. I'd very much like
to take advantage of the PWM modules, but I have not been able to find
evidence of any meaningful progress towards a working driver. So far
I've been able to make progress in other areas, figuring out how to
interface with the ADCs, working through the exercise of dealing with
GPIO both via the driver, and via /dev/mem, and have a few UARTs
running, but I'm going to have to tackle this soon. I have some
background directly programming AVRs, but I feel like embarking on the
mission to scratch build a driver for the ePWM is going to be quite a
tedious (but fun I'm sure) process for me; my first attempts at
tickling the hardware via /dev/mem have been very much less than
successful. If you're working on something similar, or have heard of
someone that is, I'd love to be in touch. In the mean time I'm going
to go back to the books to more thoroughly read (and re-read I'm sure)
the PWMSS segments of the 335x TRM. Next step I suppose will be to
start dissecting some existing driver code to learn something about
that side of things (if anyone has a favorite bit of clean driver code
to take as example I'd love to take a look), and then finally start
gluing it together.

Thanks for any leads!

Hi Steve,

I’m very much in the same boat as you. I’m a software engineer and have
a solid understanding of low level register-level operations but very little
knowledge of kernel development. My main use case fore the BeagleBone
requires PWM and I see nothing concrete in any of the kernels supporting

My idea was to implement the fairly simple API defined in <linux/pwm.h>

What are your thoughts? It wont support some of the advanced features
of the PWMSS on the am335x (chopper, dead-band, etc) but it will be
simple to use and already exists in the kernel, which is nice.

I’m still trying to understand the mechanics of implementing that API and
registering that with the system so a userspace app can make those calls
but I think I can hack something together from examples.

So far all I have though is #include definitions for all of the registers defined
in the technical docs for the pwm subsystem.

I just posted the skeleton here and I’ll try to update as I make progress.

The new angstrom 3.2 kernel for beaglebone has drivers for both the eCAP PWMs and EHR PWMs:

I'm using it on the 7" LCD cape for backlight.



We are working on the PWM. Apparently, one must code up a driver to work with Linux. We should have the code ready next week and will release it to the forum. So far all the features on our bone worked well so we are encouraged. I anyone finds the same problem with PWM let us know.

once pwm is in place what will it take to get the proper frame rate and duty cycle out of the bone for rc servo positioning? (1-2ms pulses in a 20ms frame). How will one specify/set up the desired frame rate and pulse width?


As I said in my mail earlier today, the drivers are already written, working and publically available. No bonescript integration yet, though.

Just found the code for PWM.c. Any examples available to use the module via sysfs?


Koen - I see this branch (:
beaglebone-3.2) has PWM and SPI enabled. Can you give me a pointer on
how to pull this into my OpenEmbedded/bitbake tree? I have set up
(and built a kernel, uImage, etc), but more as a trained monkey
following the instructions! As such, I'm at a bit of a loss of how to
insert your branch of the kernel in...

Thanks for your help.

sak@ubuntu:~/bone/oe$ ls
bitbake.lock build conf pseudodone scripts sources

Where did you find the code for PWM.c? Can you share a link?


Koen - I see this branch (:
beaglebone-3.2) has PWM and SPI enabled. Can you give me a pointer on
how to pull this into my OpenEmbedded/bitbake tree?

does ./ update and you'll get it. Denys pulled in the patches to update it to 3.2.0 last night.



As mentioned by Koen above in this thread, his branch of the kernel sources can be found at looking at the drivers directory I could have sworn I found the pwm subdirectoy containing the code for PWM.c. that said it seems to have disappeared right before my eyes when I went to look again. Koen, was your kernel tree recently updated, possibly leaving that out?


You need one of branches with ‘3.2’ in the name

Koen, thanks for your effort and time. I just built and installed a 3.2 based Angstrom image.

I almost certainly did this wrong, I’m still coming to terms with the whole openembedded setup. What I did seems to have worked though, so for those who are curious here’s what I did.

Following directions under the getting started web page, I did:

git clone git://
cd setup-scripts
./ config beaglebone

Next I edited ~/.oe/environment-oecore, and updated the DISTRO variable to “angstrom-2012.x”
After that, I did:

. ~/.oe/environment-oecore
bitbake systemd-image

That built all of the files I needed to create a (seemingly) working installation. I copied the various bits and pieces onto a card, powered up. The 'bone booted up just fine, and I was able to log in over ssh. I’ve begun installing the required packages to run my platform, but there’s a bit of work to do. I have not yet attached the scope and actually tried the pwm, but poking around in /sys looks promising:

root@minnow_beta:/sys/class# cd pwm
root@minnow_beta:/sys/class/pwm# ls
ecap.0 ecap.1 ehrpwm.0:0 ehrpwm.0:1 ehrpwm.1:0 ehrpwm.1:1

So having typed all that, like I say, I’m sure this wasn’t probably the right way to go about this. If anyone can point me at a link or provide better direction I’ll be sure to pass it along the next time I see the question come up.

Thanks again Koen and the rest of the dev team.


When you do get it working, please post some userspace example code (hopefully in C or python)



I suspect pwm is enabled, but not pinmuxed. Gerald reported some other problems with it as well. I’ll look into it during my flight to the ELC conference since I need to demo it there :slight_smile:


Do I have to build the kernel local? or can I use the latest one from ?


Do I have to build the kernel local? or can I use the latest one from ?

As long as it's a 3.2 based kernel it will have PWM. Pinmuxing can be done in userspace.

Koen, hi. I am clearly doing something wrong; by any chance have you seen stack traces that look like the following, and can you offer any direction? I seem to get something similar if I write a ‘1’ to ‘run’, or try to set a ‘period_freq’. Is there a timer I need to start someplace, or anything like that?


[14334.313849] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa302200
[14334.321857] Internal error: : 1028 [#4]
[14334.325854] Modules linked in: ipv6
[14334.329503] CPU: 0 Tainted: G D (3.2.0+ #1)
[14334.335144] PC is at ehrpwm_pwm_config+0x1d2/0x25e
[14334.340149] LR is at pwm_config+0x4d/0x5a
[14334.344330] pc : [] lr : [] psr: 40000033
[14334.344337] sp : cfbd7ed0 ip : 00000000 fp : 000d9328
[14334.356306] r10: cf9bf208 r9 : cfb53958 r8 : cfb53940
[14334.361752] r7 : 00000002 r6 : 00000000 r5 : cf9bf400 r4 : cf9bf400
[14334.368557] r3 : c28f5c29 r2 : fa302200 r1 : 00000000 r0 : cf9bf400
[14334.375366] Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
[14334.382989] Control: 50c5387d Table: 8f998019 DAC: 00000015
[14334.388979] Process sh (pid: 407, stack limit = 0xcfbd62f0)
[14334.394789] Stack: (0xcfbd7ed0 to 0xcfbd8000)
[14334.399332] 7ec0: cfbd7f00 cf9bf400 00000002 00000002
[14334.407866] 7ee0: cfb53940 cfb53958 cf9bf208 c013bc6f 00000008 cf9bf400 cf9bf400 c013bd7d
[14334.416404] 7f00: 00000008 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[14334.424946] 7f20: cfac5000 c013c0ad c013c091 cfbd7f80 c0168365 c016836f cf9c2130 c00ab5ab
[14334.433487] 7f40: 00000002 cfb7b940 000db408 c00ab509 cfbd7f80 00000000 00000000 c0077a0b
[14334.442029] 7f60: cfb7b940 000db408 cfb7b940 000db408 00000002 00000004 00000000 c0077c2b
[14334.450568] 7f80: 00000000 00000000 00000002 00000000 00000002 000db408 4024d5d0 c000c564
[14334.459111] 7fa0: cfbd6000 c000c3c1 00000002 000db408 00000001 000db408 00000002 00000000
[14334.467652] 7fc0: 00000002 000db408 4024d5d0 00000004 00000002 4006b7f0 000c2d74 000d9328
[14334.476193] 7fe0: 00000000 beb84a00 4018a38c 401dd14c 60000010 00000001 00000000 00000000
[14334.484748] [] (ehrpwm_pwm_config+0x1d2/0x25e) from [] (pwm_config+0x4d/0x5a)
[14334.494011] [] (pwm_config+0x4d/0x5a) from [] (pwm_start+0x1d/0x20)
[14334.502369] [] (pwm_start+0x1d/0x20) from [] (pwm_run_store+0x1d/0x48)
[14334.511008] [] (pwm_run_store+0x1d/0x48) from [] (dev_attr_store+0xb/0x12)
[14334.520006] [] (dev_attr_store+0xb/0x12) from [] (sysfs_write_file+0xa3/0xda)
[14334.529279] [] (sysfs_write_file+0xa3/0xda) from [] (vfs_write+0x5f/0x10c)
[14334.538272] [] (vfs_write+0x5f/0x10c) from [] (sys_write+0x27/0x48)
[14334.546641] [] (sys_write+0x27/0x48) from [] (ret_fast_syscall+0x1/0x44)
[14334.555448] Code: 20ec 10b6 435e b2f1 (8813) f023
[14334.560596] —[ end trace e201b1a995654158 ]—

Any progress in here! ?

i have built the edge version - ~/setup-scripts/build/tmp-

But Have no idea if PWM is working in there? anything?

Arthur - I can't comment on the others' progress, but this looks

I might look into modifying the muxing to work with BeagleBone if it's
not too difficult.