The latest development version of this page may be more current than this released 3.7.0 version.

Pulse Width Modulation (PWM)

Overview

API Reference

group pwm_interface

PWM Interface.

Since

1.0

Version

1.0.0

PWM capture configuration flags

PWM_CAPTURE_TYPE_PERIOD

PWM pin capture captures period.

PWM_CAPTURE_TYPE_PULSE

PWM pin capture captures pulse width.

PWM_CAPTURE_TYPE_BOTH

PWM pin capture captures both period and pulse width.

PWM_CAPTURE_MODE_SINGLE

PWM pin capture captures a single period/pulse width.

PWM_CAPTURE_MODE_CONTINUOUS

PWM pin capture captures period/pulse width continuously.

PWM period set helpers

The period cell in the PWM specifier needs to be provided in nanoseconds.

However, in some applications it is more convenient to use another scale.

PWM_NSEC(x)

Specify PWM period in nanoseconds.

PWM_USEC(x)

Specify PWM period in microseconds.

PWM_MSEC(x)

Specify PWM period in milliseconds.

PWM_SEC(x)

Specify PWM period in seconds.

PWM_HZ(x)

Specify PWM frequency in hertz.

PWM_KHZ(x)

Specify PWM frequency in kilohertz.

PWM polarity flags

The PWM_POLARITY_* flags are used with pwm_set_cycles(), pwm_set() or pwm_configure_capture() to specify the polarity of a PWM channel.

The flags are on the lower 8bits of the pwm_flags_t

PWM_POLARITY_NORMAL

PWM pin normal polarity (active-high pulse).

PWM_POLARITY_INVERTED

PWM pin inverted polarity (active-low pulse).

Defines

PWM_DT_SPEC_GET_BY_NAME(node_id, name)

Static initializer for a struct pwm_dt_spec.

This returns a static initializer for a struct pwm_dt_spec given a devicetree node identifier and an index.

Example devicetree fragment:

n: node {
    pwms = <&pwm1 1 1000 PWM_POLARITY_NORMAL>,
           <&pwm2 3 2000 PWM_POLARITY_INVERTED>;
    pwm-names = "alpha", "beta";
};

Example usage:

const struct pwm_dt_spec spec =
    PWM_DT_SPEC_GET_BY_NAME(DT_NODELABEL(n), alpha);

// Initializes 'spec' to:
// {
//         .dev = DEVICE_DT_GET(DT_NODELABEL(pwm1)),
//         .channel = 1,
//         .period = 1000,
//         .flags = PWM_POLARITY_NORMAL,
// }

The device (dev) must still be checked for readiness, e.g. using device_is_ready(). It is an error to use this macro unless the node exists, has the ‘pwms’ property, and that ‘pwms’ property specifies a PWM controller, a channel, a period in nanoseconds and optionally flags.

Parameters:
  • node_id – Devicetree node identifier.

  • name – Lowercase-and-underscores name of a pwms element as defined by the node’s pwm-names property.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_INST_GET_BY_NAME(inst, name)

Static initializer for a struct pwm_dt_spec from a DT_DRV_COMPAT instance.

Parameters:
  • inst – DT_DRV_COMPAT instance number

  • name – Lowercase-and-underscores name of a pwms element as defined by the node’s pwm-names property.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_GET_BY_NAME_OR(node_id, name, default_value)

Like PWM_DT_SPEC_GET_BY_NAME(), with a fallback to a default value.

If the devicetree node identifier ‘node_id’ refers to a node with a property ‘pwms’, this expands to PWM_DT_SPEC_GET_BY_NAME(node_id, name). The default_value parameter is not expanded in this case. Otherwise, this expands to default_value.

Parameters:
  • node_id – Devicetree node identifier.

  • name – Lowercase-and-underscores name of a pwms element as defined by the node’s pwm-names property

  • default_value – Fallback value to expand to.

Returns:

Static initializer for a struct pwm_dt_spec for the property, or default_value if the node or property do not exist.

PWM_DT_SPEC_INST_GET_BY_NAME_OR(inst, name, default_value)

Like PWM_DT_SPEC_INST_GET_BY_NAME(), with a fallback to a default value.

Parameters:
  • inst – DT_DRV_COMPAT instance number

  • name – Lowercase-and-underscores name of a pwms element as defined by the node’s pwm-names property.

  • default_value – Fallback value to expand to.

Returns:

Static initializer for a struct pwm_dt_spec for the property, or default_value if the node or property do not exist.

PWM_DT_SPEC_GET_BY_IDX(node_id, idx)

Static initializer for a struct pwm_dt_spec.

This returns a static initializer for a struct pwm_dt_spec given a devicetree node identifier and an index.

Example devicetree fragment:

n: node {
    pwms = <&pwm1 1 1000 PWM_POLARITY_NORMAL>,
           <&pwm2 3 2000 PWM_POLARITY_INVERTED>;
};

Example usage:

const struct pwm_dt_spec spec =
    PWM_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), 1);

// Initializes 'spec' to:
// {
//         .dev = DEVICE_DT_GET(DT_NODELABEL(pwm2)),
//         .channel = 3,
//         .period = 2000,
//         .flags = PWM_POLARITY_INVERTED,
// }

The device (dev) must still be checked for readiness, e.g. using device_is_ready(). It is an error to use this macro unless the node exists, has the ‘pwms’ property, and that ‘pwms’ property specifies a PWM controller, a channel, a period in nanoseconds and optionally flags.

Parameters:
  • node_id – Devicetree node identifier.

  • idx – Logical index into ‘pwms’ property.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_INST_GET_BY_IDX(inst, idx)

Static initializer for a struct pwm_dt_spec from a DT_DRV_COMPAT instance.

Parameters:
  • inst – DT_DRV_COMPAT instance number

  • idx – Logical index into ‘pwms’ property.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_GET_BY_IDX_OR(node_id, idx, default_value)

Like PWM_DT_SPEC_GET_BY_IDX(), with a fallback to a default value.

If the devicetree node identifier ‘node_id’ refers to a node with a property ‘pwms’, this expands to PWM_DT_SPEC_GET_BY_IDX(node_id, idx). The default_value parameter is not expanded in this case. Otherwise, this expands to default_value.

Parameters:
  • node_id – Devicetree node identifier.

  • idx – Logical index into ‘pwms’ property.

  • default_value – Fallback value to expand to.

Returns:

Static initializer for a struct pwm_dt_spec for the property, or default_value if the node or property do not exist.

PWM_DT_SPEC_INST_GET_BY_IDX_OR(inst, idx, default_value)

Like PWM_DT_SPEC_INST_GET_BY_IDX(), with a fallback to a default value.

Parameters:
  • inst – DT_DRV_COMPAT instance number

  • idx – Logical index into ‘pwms’ property.

  • default_value – Fallback value to expand to.

Returns:

Static initializer for a struct pwm_dt_spec for the property, or default_value if the node or property do not exist.

PWM_DT_SPEC_GET(node_id)

Equivalent to PWM_DT_SPEC_GET_BY_IDX(node_id, 0).

Parameters:
  • node_id – Devicetree node identifier.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_INST_GET(inst)

Equivalent to PWM_DT_SPEC_INST_GET_BY_IDX(inst, 0).

See also

PWM_DT_SPEC_GET

Parameters:
  • inst – DT_DRV_COMPAT instance number

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_GET_OR(node_id, default_value)

Equivalent to PWM_DT_SPEC_GET_BY_IDX_OR(node_id, 0, default_value).

Parameters:
  • node_id – Devicetree node identifier.

  • default_value – Fallback value to expand to.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

PWM_DT_SPEC_INST_GET_OR(inst, default_value)

Equivalent to PWM_DT_SPEC_INST_GET_BY_IDX_OR(inst, 0, default_value).

Parameters:
  • inst – DT_DRV_COMPAT instance number

  • default_value – Fallback value to expand to.

Returns:

Static initializer for a struct pwm_dt_spec for the property.

Typedefs

typedef uint16_t pwm_flags_t

Provides a type to hold PWM configuration flags.

The lower 8 bits are used for standard flags. The upper 8 bits are reserved for SoC specific flags.

See also

PWM_CAPTURE_FLAGS.

typedef void (*pwm_capture_callback_handler_t)(const struct device *dev, uint32_t channel, uint32_t period_cycles, uint32_t pulse_cycles, int status, void *user_data)

PWM capture callback handler function signature.

Note

The callback handler will be called in interrupt context.

Note

CONFIG_PWM_CAPTURE must be selected to enable PWM capture support.

Param dev:

[in] PWM device instance.

Param channel:

PWM channel.

Param period_cycles:

Captured PWM period width (in clock cycles). HW specific.

Param pulse_cycles:

Captured PWM pulse width (in clock cycles). HW specific.

Param status:

Status for the PWM capture (0 if no error, negative errno otherwise. See pwm_capture_cycles() return value descriptions for details).

Param user_data:

User data passed to pwm_configure_capture()

Functions

int pwm_set_cycles(const struct device *dev, uint32_t channel, uint32_t period, uint32_t pulse, pwm_flags_t flags)

Set the period and pulse width for a single PWM output.

The PWM period and pulse width will synchronously be set to the new values without glitches in the PWM signal, but the call will not block for the change to take effect.

Passing 0 as pulse will cause the pin to be driven to a constant inactive level. Passing a non-zero pulse equal to period will cause the pin to be driven to a constant active level.

Note

Not all PWM controllers support synchronous, glitch-free updates of the PWM period and pulse width. Depending on the hardware, changing the PWM period and/or pulse width may cause a glitch in the generated PWM signal.

Note

Some multi-channel PWM controllers share the PWM period across all channels. Depending on the hardware, changing the PWM period for one channel may affect the PWM period for the other channels of the same PWM controller.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • period – Period (in clock cycles) set to the PWM. HW specific.

  • pulse – Pulse width (in clock cycles) set to the PWM. HW specific.

  • flags – Flags for pin configuration.

Return values:
  • 0 – If successful.

  • -EINVAL – If pulse > period.

  • -errno – Negative errno code on failure.

int pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles)

Get the clock rate (cycles per second) for a single PWM output.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • cycles[out] Pointer to the memory to store clock rate (cycles per sec). HW specific.

Return values:
  • 0 – If successful.

  • -errno – Negative errno code on failure.

static inline int pwm_set(const struct device *dev, uint32_t channel, uint32_t period, uint32_t pulse, pwm_flags_t flags)

Set the period and pulse width in nanoseconds for a single PWM output.

Note

Utility macros such as PWM_MSEC() can be used to convert from other scales or units to nanoseconds, the units used by this function.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • period – Period (in nanoseconds) set to the PWM.

  • pulse – Pulse width (in nanoseconds) set to the PWM.

  • flags – Flags for pin configuration (polarity).

Return values:
  • 0 – If successful.

  • -ENOTSUP – If requested period or pulse cycles are not supported.

  • -errno – Other negative errno code on failure.

static inline int pwm_set_dt(const struct pwm_dt_spec *spec, uint32_t period, uint32_t pulse)

Set the period and pulse width in nanoseconds from a struct pwm_dt_spec (with custom period).

This is equivalent to:

pwm_set(spec->dev, spec->channel, period, pulse, spec->flags)
The period specified in spec is ignored. This API call can be used when the period specified in Devicetree needs to be changed at runtime.

Parameters:
  • spec[in] PWM specification from devicetree.

  • period – Period (in nanoseconds) set to the PWM.

  • pulse – Pulse width (in nanoseconds) set to the PWM.

Returns:

A value from pwm_set().

static inline int pwm_set_pulse_dt(const struct pwm_dt_spec *spec, uint32_t pulse)

Set the period and pulse width in nanoseconds from a struct pwm_dt_spec.

This is equivalent to:

pwm_set(spec->dev, spec->channel, spec->period, pulse, spec->flags)

Parameters:
  • spec[in] PWM specification from devicetree.

  • pulse – Pulse width (in nanoseconds) set to the PWM.

Returns:

A value from pwm_set().

static inline int pwm_cycles_to_usec(const struct device *dev, uint32_t channel, uint32_t cycles, uint64_t *usec)

Convert from PWM cycles to microseconds.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • cycles – Cycles to be converted.

  • usec[out] Pointer to the memory to store calculated usec.

Return values:
  • 0 – If successful.

  • -ERANGE – If result is too large.

  • -errno – Other negative errno code on failure.

static inline int pwm_cycles_to_nsec(const struct device *dev, uint32_t channel, uint32_t cycles, uint64_t *nsec)

Convert from PWM cycles to nanoseconds.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • cycles – Cycles to be converted.

  • nsec[out] Pointer to the memory to store the calculated nsec.

Return values:
  • 0 – If successful.

  • -ERANGE – If result is too large.

  • -errno – Other negative errno code on failure.

static inline int pwm_configure_capture(const struct device *dev, uint32_t channel, pwm_flags_t flags, pwm_capture_callback_handler_t cb, void *user_data)

Configure PWM period/pulse width capture for a single PWM input.

After configuring PWM capture using this function, the capture can be enabled/disabled using pwm_enable_capture() and pwm_disable_capture().

Note

This API function cannot be invoked from user space due to the use of a function callback. In user space, one of the simpler API functions (pwm_capture_cycles(), pwm_capture_usec(), or pwm_capture_nsec()) can be used instead.

Note

CONFIG_PWM_CAPTURE must be selected for this function to be available.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • flags – PWM capture flags

  • cb[in] Application callback handler function to be called upon capture

  • user_data[in] User data to pass to the application callback handler function

Return values:
  • -EINVAL – if invalid function parameters were given

  • -ENOSYS – if PWM capture is not supported or the given flags are not supported

  • -EIO – if IO error occurred while configuring

  • -EBUSY – if PWM capture is already in progress

int pwm_enable_capture(const struct device *dev, uint32_t channel)

Enable PWM period/pulse width capture for a single PWM input.

The PWM pin must be configured using pwm_configure_capture() prior to calling this function.

Note

CONFIG_PWM_CAPTURE must be selected for this function to be available.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

Return values:
  • 0 – If successful.

  • -EINVAL – if invalid function parameters were given

  • -ENOSYS – if PWM capture is not supported

  • -EIO – if IO error occurred while enabling PWM capture

  • -EBUSY – if PWM capture is already in progress

int pwm_disable_capture(const struct device *dev, uint32_t channel)

Disable PWM period/pulse width capture for a single PWM input.

Note

CONFIG_PWM_CAPTURE must be selected for this function to be available.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

Return values:
  • 0 – If successful.

  • -EINVAL – if invalid function parameters were given

  • -ENOSYS – if PWM capture is not supported

  • -EIO – if IO error occurred while disabling PWM capture

int pwm_capture_cycles(const struct device *dev, uint32_t channel, pwm_flags_t flags, uint32_t *period, uint32_t *pulse, k_timeout_t timeout)

Capture a single PWM period/pulse width in clock cycles for a single PWM input.

This API function wraps calls to pwm_configure_capture(), pwm_enable_capture(), and pwm_disable_capture() and passes the capture result to the caller. The function is blocking until either the PWM capture is completed or a timeout occurs.

Note

CONFIG_PWM_CAPTURE must be selected for this function to be available.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • flags – PWM capture flags.

  • period[out] Pointer to the memory to store the captured PWM period width (in clock cycles). HW specific.

  • pulse[out] Pointer to the memory to store the captured PWM pulse width (in clock cycles). HW specific.

  • timeout – Waiting period for the capture to complete.

Return values:
  • 0 – If successful.

  • -EBUSY – PWM capture already in progress.

  • -EAGAIN – Waiting period timed out.

  • -EIO – IO error while capturing.

  • -ERANGE – If result is too large.

static inline int pwm_capture_usec(const struct device *dev, uint32_t channel, pwm_flags_t flags, uint64_t *period, uint64_t *pulse, k_timeout_t timeout)

Capture a single PWM period/pulse width in microseconds for a single PWM input.

This API function wraps calls to pwm_capture_cycles() and pwm_cycles_to_usec() and passes the capture result to the caller. The function is blocking until either the PWM capture is completed or a timeout occurs.

Note

CONFIG_PWM_CAPTURE must be selected for this function to be available.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • flags – PWM capture flags.

  • period[out] Pointer to the memory to store the captured PWM period width (in usec).

  • pulse[out] Pointer to the memory to store the captured PWM pulse width (in usec).

  • timeout – Waiting period for the capture to complete.

Return values:
  • 0 – If successful.

  • -EBUSY – PWM capture already in progress.

  • -EAGAIN – Waiting period timed out.

  • -EIO – IO error while capturing.

  • -ERANGE – If result is too large.

  • -errno – Other negative errno code on failure.

static inline int pwm_capture_nsec(const struct device *dev, uint32_t channel, pwm_flags_t flags, uint64_t *period, uint64_t *pulse, k_timeout_t timeout)

Capture a single PWM period/pulse width in nanoseconds for a single PWM input.

This API function wraps calls to pwm_capture_cycles() and pwm_cycles_to_nsec() and passes the capture result to the caller. The function is blocking until either the PWM capture is completed or a timeout occurs.

Note

CONFIG_PWM_CAPTURE must be selected for this function to be available.

Parameters:
  • dev[in] PWM device instance.

  • channel – PWM channel.

  • flags – PWM capture flags.

  • period[out] Pointer to the memory to store the captured PWM period width (in nsec).

  • pulse[out] Pointer to the memory to store the captured PWM pulse width (in nsec).

  • timeout – Waiting period for the capture to complete.

Return values:
  • 0 – If successful.

  • -EBUSY – PWM capture already in progress.

  • -EAGAIN – Waiting period timed out.

  • -EIO – IO error while capturing.

  • -ERANGE – If result is too large.

  • -errno – Other negative errno code on failure.

static inline bool pwm_is_ready_dt(const struct pwm_dt_spec *spec)

Validate that the PWM device is ready.

Parameters:
  • spec – PWM specification from devicetree

Return values:
  • true – If the PWM device is ready for use

  • false – If the PWM device is not ready for use

struct pwm_dt_spec
#include <pwm.h>

Container for PWM information specified in devicetree.

This type contains a pointer to a PWM device, channel number (controlled by the PWM device), the PWM signal period in nanoseconds and the flags applicable to the channel. Note that not all PWM drivers support flags. In such case, flags will be set to 0.

See also

PWM_DT_SPEC_GET

Public Members

const struct device *dev

PWM device instance.

uint32_t channel

Channel number.

uint32_t period

Period in nanoseconds.

pwm_flags_t flags

Flags.