Please note that User Registration has been temporarily disabled due to a recent increase in automated registrations. If anyone needs an account, please request one here: RequestAccount. Thanks for your patience!--Wmat (talk)
Please email User:Wmat if you experience any issues with the Request Account form.

Difference between revisions of "BeagleBoardPWM"

From eLinux.org
Jump to: navigation, search
m (Fixed typo in image syntax)
(Added links to pages covering some other PWM techniques)
Line 1: Line 1:
 
There are three pins capable of [http://en.wikipedia.org/wiki/Pulse-width_modulation PWM (pulse-width modulation)] exposed on the C3/C4 BeagleBoard expansion header.  PWM is useful for control of a number of devices, from LEDs (which can be faded smoothly with PWM) to DC motors.  For robotics, this means that three hobby servos can easily be controlled by the Beagle given nothing more than a simple [[BeagleBoard_Hardware_Interfacing#Level_Shifting | level-shifting]] circuit.
 
There are three pins capable of [http://en.wikipedia.org/wiki/Pulse-width_modulation PWM (pulse-width modulation)] exposed on the C3/C4 BeagleBoard expansion header.  PWM is useful for control of a number of devices, from LEDs (which can be faded smoothly with PWM) to DC motors.  For robotics, this means that three hobby servos can easily be controlled by the Beagle given nothing more than a simple [[BeagleBoard_Hardware_Interfacing#Level_Shifting | level-shifting]] circuit.
 +
 +
Alternative approaches are possible.  [http://github.com/tallakt/servodrive servodrive] is a kernel module that emits servo control PWM using straight GPIO (this page also claims that straight 1.8 V from the Beagle is sufficient to control servos).  [http://thoughtshubham.blogspot.com/2010/04/pwm-generation-in-beagleboard.html This page] shows how to use threading and GPIO to accomplish PWM in userspace.  The rest of this page focuses on use of the OMAP's hardware PWM capabilities.
  
 
== OMAP Mux Configuration ==
 
== OMAP Mux Configuration ==
  
Because the PWM pins are not set as such by default, the OMAP's mux must be configured to expose them before they can be used.  See [[BeagleBoardPinMux]] for more details on this procedure.  The short version is to add the following lines to the definition of <code>board_mux[]</code> in arch/arm/mach-omap2/board-omap3beagle.c (this has been tested with the 2.6.32 OMAP branch of the kernel).
+
Because the PWM pins are not set as such by default, the OMAP's mux must be configured to expose them before they can be used.  See [[BeagleBoardPinMux]] for more details on this procedure.  The short version is to add the following lines to the definition of <code>board_mux[]</code> in arch/arm/mach-omap2/board-omap3beagle.c (this has been tested with the 2.6.33 OMAP branch of the kernel).
  
 
  OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE2|OMAP_PIN_OUTPUT), /* GPT9_PWMEVT, ball AB26, ex pin 4 */
 
  OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE2|OMAP_PIN_OUTPUT), /* GPT9_PWMEVT, ball AB26, ex pin 4 */

Revision as of 05:53, 26 July 2010

There are three pins capable of PWM (pulse-width modulation) exposed on the C3/C4 BeagleBoard expansion header. PWM is useful for control of a number of devices, from LEDs (which can be faded smoothly with PWM) to DC motors. For robotics, this means that three hobby servos can easily be controlled by the Beagle given nothing more than a simple level-shifting circuit.

Alternative approaches are possible. servodrive is a kernel module that emits servo control PWM using straight GPIO (this page also claims that straight 1.8 V from the Beagle is sufficient to control servos). This page shows how to use threading and GPIO to accomplish PWM in userspace. The rest of this page focuses on use of the OMAP's hardware PWM capabilities.

OMAP Mux Configuration

Because the PWM pins are not set as such by default, the OMAP's mux must be configured to expose them before they can be used. See BeagleBoardPinMux for more details on this procedure. The short version is to add the following lines to the definition of board_mux[] in arch/arm/mach-omap2/board-omap3beagle.c (this has been tested with the 2.6.33 OMAP branch of the kernel).

OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE2|OMAP_PIN_OUTPUT), /* GPT9_PWMEVT, ball AB26, ex pin 4 */
OMAP3_MUX(UART2_TX, OMAP_MUX_MODE2|OMAP_PIN_OUTPUT), /* GPT11_PWMEVT, ball AA25, ex pin 6 */
OMAP3_MUX(UART2_RTS, OMAP_MUX_MODE2|OMAP_PIN_OUTPUT), /* GTP10_PWMEVT, ball AB25, ex pin 10 */

Obviously these lines should precede the line terminating the array.

Activating PWM via Timer Registers

PWM output on the BeagleBoard is done via the OMAP processor's general-purpose timer mechanism, described in the OMAP35x TRM in section 16.2.4 (page 2546). To briefly summarize this (and simplify significantly), the general-purpose timer is a continuously-incrementing counter that can be configured to toggle the PWM output high when a certain value is reached, and low when it overflows. By adjusting the first number the duty cycle can be set. Setting the value the counter starts at can be used to set the frequency of the PWM.

"The registers TCRR, TLDR, and TMAR are illustrated as boxes partially-filled from the right.  Lines at the value of TLDR, the value of TMAR, and the end are labeled 'Start', 'Match', and 'Overflow' respectively."

"A square waveform starting at 0, with the beginning labeled as 'Start'.  Where the waveform goes to 1 it is labeled 'Match', and when it returns to zero it is labeled 'Overflow, Start'.  It then repeats."

Each GP timer has a 4K block for memory-mapped registers (see TRM Table 16-12). The start addresses of these blocks for the timers on the BeagleBoard are listed below.

BeagleBoard C4 GP Timer Base Addresses
Timer Base address Expansion header pin
GPTIMER9 0x4904 0000 4
GPTIMER10 0x4808 6000 6
GPTIMER11 0x4808 8000 10

These are the registers relevant to our purpose:

BeagleBoard C4 GP Timer Registers
Name TRM section Offset Description
TCLR 16.3.2.6 (p. 2568) 0x024 Control register.
TCRR 16.3.2.7 (p. 2570) 0x028 The counter. Increments with the clock when the timer is running.
TLDR 16.3.2.8 (p. 2571) 0x02c Timer load register. Holds the value assumed by TCRR when it overflows.
TMAR 16.3.2.11 (p. 2575) 0x038 Value to be compared with the counter.


OMAP3530 PWM library

There is a small library available to simplify manipulating the timer registers via /dev/mem. It is made available under the LGPL 2.1.

Download: omap3530-pwm-1.0.tar.gz

Example usage

{{#source: c|

  1. include <glib.h>
  2. include <errno.h>
  3. include "omap3530-pwm.h"

int main(int argc, char **argv) {

   int mem_fd = pwm_open_devmem();
   if (mem_fd == -1) {
       g_error("Unable to open /dev/mem, are you root?: %s", g_strerror(errno));
   }
   // Set instances 10 and 11 to use the 13 Mhz clock
   pwm_config_clock(mem_fd, TRUE, TRUE);
   guint8 *gpt10 = pwm_mmap_instance(mem_fd, 10);
   // Get the resolution for 20 kHz PWM
   guint32 resolution = pwm_calc_resolution(20000, PWM_FREQUENCY_13MHZ);
   // Set to half duty cycle
   pwm_config_timer(gpt10, resolution, 0.5);
   pwm_munmap_instance(gpt10);
   pwm_close_devmem(mem_fd);

} }}

Links and References