---
name: "pwmgen"
section: "9"
platform: "linux"
package: "linuxcnc-uspace"
version: "1:2.9.4-2+deb13u1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/pwmgen"
---

# pwmgen(9)

software PWM/PDM generation

## NAME

pwmgen - software PWM/PDM generation

## SYNOPSIS

**loadrt pwmgen output\_type=***type0*\[,*type1*...\]

## DESCRIPTION

**pwmgen** is used to generate PWM (pulse width modulation) or PDM (pulse density modulation) signals. The maximum PWM frequency and the resolution is quite limited compared to hardware-based approaches, but in many cases software PWM can be very useful. If better performance is needed, a hardware PWM generator is a better choice.

**pwmgen** supports a maximum of eight channels. The number of channels actually loaded depends on the number of *type* values given. The value of each *type* determines the outputs for that channel.

- type 0: single output A single output pin, **pwm**, whose duty cycle is determined by the input value for positive inputs, and which is off (or at **min-dc**) for negative inputs.

  Suitable for single ended circuits.

- type 1: pwm/direction

  Two output pins, **pwm** and **dir**.  The duty cycle on **pwm** varies as a function of the input value. **dir** is low for positive inputs and high for negative inputs.

- type 2: up/down

  Two output pins, **up** and **down**. For positive inputs, the PWM/PDM waveform appears on **up**, while **down** is low. For negative inputs, the waveform appears on **down**, while **up** is low. Suitable for driving the two sides of an H-bridge to generate a bipolar output.

## FUNCTIONS

- **pwmgen.make-pulses** (no floating-point)

  Generates the actual PWM waveforms, using information computed by **update**. Must be called as frequently as possible, to maximize the attainable PWM frequency and resolution, and minimize jitter. Operates on all channels at once.

- **pwmgen.update** (uses floating point)

  Accepts an input value, performs scaling and limit checks, and converts it into a form usable by **make-pulses** for PWM/PDM generation. Can (and should) be called less frequently than **make-pulses**. Operates on all channels at once.

## PINS

- **pwmgen.***N***.enable** bit in

  Enables PWM generator *N* - when false, all **pwmgen.***N* output pins are low.

- **pwmgen.***N***.value** float in

  Commanded value.  When **value** = 0.0, duty cycle is 0%, and when **value** = ±**scale**, duty cycle is ± 100% (subject to **min-dc** and **max-dc** limitations).

- **pwmgen.***N***.pwm** bit out (output types 0 and 1 only)

  PWM/PDM waveform.

- **pwmgen.***N***.dir** bit out (output type 1 only)

  Direction output: low for forward, high for reverse.

- **pwmgen.***N***.up** bit out (output type 2 only)

  PWM/PDM waveform for positive input values, low for negative inputs.

- **pwmgen.***N***.down** bit out (output type 2 only)

  PWM/PDM waveform for negative input values, low for positive inputs.

- **pwmgen.***N***.curr-dc** float out

  The current duty cycle, after all scaling and limits have been applied. Range is from -1.0 to +1.0.

- **pwmgen.***N***.max-dc** float in/out

  The maximum duty cycle.  A value of 1.0 corresponds to 100%. This can be useful when using transistor drivers with bootstrapped power supplies, since the supply requires some low time to recharge.

- **pwmgen.***N***.min-dc** float in/out

  The minimum duty cycle.  A value of 1.0 corresponds to 100%. Note that when the pwm generator is disabled, the outputs are constantly low, regardless of the setting of **min-dc**.

- **pwmgen.***N***.scale** float in/out

  - **pwmgen.***N***.offset** float in/out

  These parameters provide a scale and offset from the **value** pin to the actual duty cycle. The duty cycle is calculated according to *dc = (value/scale) + offset*, with 1.0 meaning 100%.

- **pwmgen.***N***.pwm-freq** float in/out

  PWM frequency in Hz.  The upper limit is half of the frequency at which **make-pulses** is invoked, and values above that limit will be changed to the limit. If **dither-pwm** is false, the value will be changed to the nearest integer submultiple of the **make-pulses** frequency. A value of zero produces Pulse Density Modulation instead of Pulse Width Modulation.

- **pwmgen.***N***.dither-pwm** bit in/out

  Because software-generated PWM uses a fairly slow timebase (several to many microseconds), it has limited resolution. For example, if **make-pulses** is called at a 20 kHz rate, and **pwm-freq** is 2 kHz, there are only 10 possible duty cycles. If **dither-pwm** is false, the commanded duty cycle will be rounded to the nearest of those values. Assuming **value** remains constant, the same output will repeat every PWM cycle. If **dither-pwm** is true, the output duty cycle will be dithered between the two closest values, so that the long-term average is closer to the desired level. **dither-pwm** has no effect if **pwm-freq** is zero (PDM mode), since PDM is an inherently dithered process.
