# SFBHWPWM.h File Reference

Support for h/w-based Pulse Width Modulation. More...

`#include "SFBTypes.h"`

Include dependency graph for SFBHWPWM.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

## Enumerations
enum | PWMChannelModes { PWM_INACTIVE, PWM_SINGLE_EDGE, PWM_DOUBLE_EDGE, PWM_CHANNEL_MODES_MAX }
| The operational modes of a PWM channel. More...
enum | PWMIndices { PWM_BODY_RGB_RED_PIN, PWM_BODY_RGB_GREEN_PIN, PWM_BODY_RGB_BLUE_PIN, PWM_NORTH_LED_PIN, PWM_SOUTH_LED_PIN, PWM_EAST_LED_PIN, PWM_WEST_D0_PIN, PWM_WEST_D2_PIN, PWM_WEST_D3_PIN, PWM_EAST_D1_PIN, PWM_EAST_D3_PIN }
| The possible 'pwmIndex' values. More...
## Functions
void | PWMStart ()
| Power up, initialize and activate the PWM block.
void | PWMStop ()
| Deactivate and power down the PWM blcok.
void | PWMSetMode (u32 pwmIndex, u32 mode)
| Set the operating mode of (the channel of) a PWM-capable pin.
void | PWMSetWidth (u32 pwmIndex, u32 width, bool commit=true)
| Sets the duty cycle of (the channel of) a PWM-capable pin.
u32 | PWMGetWidth (u32 pwmIndex)
| Gets the current pulse width a PWM-active pin.
int | PWMFindIndex (int sfbPin)
| Find the PWMIndices value corresponding to a given sfbPin.
u32 | PWMGetPin (u32 pwmIndex)
| Given a legal PWMIndices value, this method returns the SFB pin number of the corresponding pin.
u32 | PWMGetChannel (u32 pwmIndex)
| Given a legal PWMIndices value, this method returns the PWM 'channel number' of the corresponding pin.

## Detailed Description

Support for h/w-based Pulse Width Modulation.

See the LPC23xx user manual (lpc23xx_um.pdf) Chapter 24 for details of operation

Author:
  David H. Ackley.

Date:
  (C) 2009 All rights reserved.

Code License:
  The GNU Lesser General Public License

License Note:
  All code samples shown in documentation are placed into the public domain.

## Enumeration Type Documentation

enum PWMChannelModes

The operational modes of a PWM channel.

All channels start out as PWM_INACTIVE.

Enumerator:

  PWM_INACTIVE | Channel unused.
  PWM_SINGLE_EDGE | Single-edge mode (Channel on at 1, off at PWMSetWidth time).
  PWM_DOUBLE_EDGE | Double-edged mode (see LPC23xx manual for details).

enum PWMIndices

The possible 'pwmIndex' values.

The h/w PWM system can generate pulses on up to six different pins simultaneously, and each of the six pulse widths can be controlled individually. In calls to the PWM methods, these indices specify which pwmIndex -- and thus which pin -- is to be affected. Note there are only six 'PWM channels', but there are 12 possible values listed here -- this is because each channel can be routed to more than one pin, if desired. On the flip side, that means certain pairs of pins listed here cannot have different pulse widths when used with h/w PWM.

For example, consider the following sequence

          PWMStart();

          PWMSetMode(PWM_NORTH_LED_PIN,PWM_SINGLE_EDGE);   // Fire up PWM on North LED
          PWMSetWidth(PWM_NORTH_LED_PIN, 7000);            // Set North LED to 30% brightness (70% high==off)

          PWMSetMode(PWM_WEST_D2_PIN,PWM_SINGLE_EDGE);     // Also, fire up West D2 for a servo
          PWMSetWIdth(PWM_WEST_D2_PIN, 750);               // Set West D2 to 1500usec width

          pprintf("L N=%d\n",PWMGetWidth(PWM_NORTH_LED_PIN));  // Unexpectedly prints 'L N=750'!

in which changing one width (that of PWM_WEST_D2_PIN) causes an apparently unrelated width (that of PWM_NORTH_LED_PIN) to change. Why does it happen? Because `PWMGetChannel(PWM_NORTH_LED_PIN)` and `PWMGetChannel(PWM_WEST_D0_PIN)` are both equal to 4. See PWMGetChannel for details.

Enumerator:

  PWM_BODY_RGB_RED_PIN | PWM the RGB Red LED.
  PWM_BODY_RGB_GREEN_PIN | PWM the RGB Green LED.
  PWM_BODY_RGB_BLUE_PIN | PWM the RGB Blue LED.
  PWM_NORTH_LED_PIN | PWM the North LED.
  PWM_SOUTH_LED_PIN | PWM the South LED.
  PWM_EAST_LED_PIN | PWM the East LED.
  PWM_WEST_D0_PIN | PWM the West D0 pin.
  PWM_WEST_D2_PIN | PWM the West D2 pin.
  PWM_WEST_D3_PIN | PWM the West D3 pin.
  PWM_EAST_D1_PIN | PWM the East D1 pin.
  PWM_EAST_D3_PIN | PWM the East D3 pin.

## Function Documentation

int PWMFindIndex | ( | int | sfbPin | ) |

Find the PWMIndices value corresponding to a given sfbPin.

Not all SFB pins are capable of h/w supported PWM operation; those that are all have values assigned in PWMIndices. This finds the PWMIndices value of a given sfbPin if it exists

Parameters:

  | sfbPin | Pin number to search for its corresponding PWMIndices value.

Returns:
  The PWMIndices value corresponding to sfbPin, or -1 if sfbPin is not capable of h/w supported PWM.

u32 PWMGetChannel | ( | u32 | pwmIndex | ) |

Given a legal PWMIndices value, this method returns the PWM 'channel number' of the corresponding pin.

For reference, the assignment of PWMIndices to channels is:

PWM channel number | Associated PWMIndices
1 | BODY_RGB_GREEN_PIN
2 | BODY_RGB_RED_PIN, WEST_D0_PIN
3 | BODY_RGB_BLUE_PIN, WEST_D3_PIN
4 | NORTH_LED_PIN, WEST_D2_PIN
5 | SOUTH_LED_PIN, EAST_D1_PIN
6 | EAST_LED_PIN, EAST_D3_PIN

Parameters:

  | pwmIndex | The PWMIndices value

Returns:
  A PWM channel number, in the range of 1..6.

Blinks:
  E_API_MAX_RANGE if pwmIndex is not in the PWMIndices range

u32 PWMGetPin | ( | u32 | pwmIndex | ) |

Given a legal PWMIndices value, this method returns the SFB pin number of the corresponding pin.

Parameters:

  | pwmIndex | The PWMIndices value

Returns:
  The SFB pin number used by this PWMIndices value.

Blinks:
  E_API_MAX_RANGE if pwmIndex is not in the PWMIndices range

u32 PWMGetWidth | ( | u32 | pwmIndex | ) |

Gets the current pulse width a PWM-active pin.

Returns a value in the same units as set in PWMSetWidth.

Parameters:

  | pwmIndex | one of the PWMIndices values, denoting the PWM-capable pin of interest

Blinks:
  E_API_MAX_RANGE if pwmIndex is not in the PWMIndices range

void PWMSetMode | ( | u32 | pwmIndex,
|  | u32 | mode |
| ) |  |  |

Set the operating mode of (the channel of) a PWM-capable pin.

If the mode is PWM_INACTIVE, that pin's mode is set to REFLEX_MODE, otherwise is it set to HW_MODE and the relevant PWM registers are configured as specified. After PWMSetMode is used with a mode other than PWM_INACTIVE, PWMSetWidth should be used to specify the duty cycle of the pulse.

Parameters:

  | pwmIndex | one of the PWMIndices values, denoting the PWM-capable pin of interest
  | mode | one of the PWMChannelModes values, specifiying how the associated channel will act

Blinks:
  E_API_MAX_RANGE if pwmIndex is not in the PWMIndices range

Blinks:
  E_API_MAX_RANGE if mode is not in the PWMChannelModes range

void PWMSetWidth | ( | u32 | pwmIndex,
|  | u32 | width,
|  | bool | commit = `true` |
| ) |  |  |

Sets the duty cycle of (the channel of) a PWM-capable pin.

The repetition rate of the PWM is 50Hz, producing a 20,000 usecs period. width is in the range of 1..10000 and is in units of 2usecs or 0.01% of maximum width. For example, width values of 500-1000 produce pulse times of 1ms-2ms (the typical full-throw range of servo pulses), and a width of 10000 produces a 50% duty cycle pulse. Optional argument commit determines whether to 'release' this width change now. If commit is specified and `false`, this width change will not take effect until the next PWMSetWidth with commit unspecified or set to `true`. If a number of widths should be changed simultaneously, use commit equals `false` on all but the last call.

Parameters:

  | pwmIndex | one of the PWMIndices values, denoting the PWM-capable pin of interest
  | width | number of 2usec units one of the PWMChannelModes values, specifiying how the associated channel will act
  | commit | whether this change should take effect ASAP or be deferred.

Blinks:
  E_API_MAX_RANGE if pwmIndex is not in the PWMIndices range