EBC Pulse Width Modulation

From eLinux.org
Jump to: navigation, search

thumb‎ Embedded Linux Class by Mark A. Yoder


In a previous exercise (EBC gpio Polling and Interrupts) you saw how to use the gpio to produce a square wave out using a C program and sysfs. I was able to get a 1.5kHz square wave out; however we can do much better using some built in hardware on the Beagle.

In this exercise you will learn how to use the Beagle's pulse width modulation (PWM) hardware using the sysfs interface.

On Chip Peripherals (OCP)

BeagleBone Black has a large number on on chip peripherals. You can see a list with these commands.

bone$ SLOTS=/sys/devices/bone_capemgr.*/slots
bone$ cd /sys/devices/ocp.*
bone$ ls
44e07000.gpio     48046000.timer                 49000000.edma      nop-phy.6
44e09000.serial   48048000.timer                 4a100000.ethernet  nop-phy.7
44e0b000.i2c      4804a000.timer                 53100000.sham      power
44e10448.bandgap  4804c000.gpio                  53500000.aes       rstctl.4
44e35000.wdt      4819c000.i2c                   56000000.sgx       subsystem
44e3e000.rtc      481ac000.gpio                  gpio-leds.8        uevent
47400000.usb      481ae000.gpio                  mmc.11
48042000.timer    48200000.interrupt-controller  mmc.5

The hex numbers are the physical address for the peripheral. Initially the PWM interface doesn't appear.

Pulse Width Modulation

(Note: The PWM interface seems to changing. Some of this may not apply in the future.)

Here's how to see the PWM interface.

bone$ echo am33xx_pwm > $SLOTS
bone$ ls
44e07000.gpio     48046000.timer                 48302000.epwmss    mmc.11
44e09000.serial   48048000.timer                 48304000.epwmss    mmc.5
44e0b000.i2c      4804a000.timer                 48310000.rng       modalias
44e10448.bandgap  4804c000.gpio                  49000000.edma      nop-phy.6
44e35000.wdt      4819c000.i2c                   4a100000.ethernet  nop-phy.7
44e3e000.rtc      481ac000.gpio                  53100000.sham      power
47400000.usb      481ae000.gpio                  53500000.aes       rstctl.4
48042000.timer    48200000.interrupt-controller  56000000.sgx       subsystem
48044000.timer    48300000.epwmss                gpio-leds.8        uevent

Three PWM controllers have appeared. Now, to use PWM on P9_21:

bone$ echo bone_pwm_P9_21 > $SLOTS
bone$ cd /sys/devices/ocp.*/pwm_test_P9_21.*
bone$ ls
driver  duty  modalias  period  polarity  power  run  subsystem  uevent

The units are in ns. Try a 1Hz frequency with a 25% duty cycle

bone$ echo 1000000000 > period
bone$ echo  250000000 > duty
bone$ echo 1 > run

Connect the LED from and watch it flash. Try changing the frequency and duty cycle. You may have to set the duty cycle to 0 to change the frequency. Can you guess why?


Combine the analog in and the PWM by having the pot control the frequency or the duty cycle of the LED.

If you have an oscilloscope try probing pin P9_21. I'm getting a nice clean 1Hz signal, with no variation. Let's try a higher frequency, like 10 MHz.

beagle$ echo  50 > duty_ns
beagle$ echo 100 > period_ns

I'm getting a 9 MHz signal that has lots of ringing. The timer in the bone must be off a bit.

The AM335x PWM Driver's Guide details what eCAP and eHRPWM are and gives some examples.

thumb‎ Embedded Linux Class by Mark A. Yoder