Pulse Width Modulation (PWM)
Overview
API Reference
- group pwm_interface
PWM Interface.
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.
See also
- 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.
See also
- 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)
. Thedefault_value
parameter is not expanded in this case. Otherwise, this expands todefault_value
.See also
- 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.
See also
- 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.
See also
- 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.
See also
- 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)
. Thedefault_value
parameter is not expanded in this case. Otherwise, this expands todefault_value
.See also
- 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.
See also
- 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)
.See also
See also
- 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
See also
- 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)
.See also
See also
- 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)
.See also
See also
- 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
-
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-zeropulse
equal toperiod
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:
The period specified inpwm_set(spec->dev, spec->channel, period, pulse, spec->flags)
spec
is ignored. This API call can be used when the period specified in Devicetree needs to be changed at runtime.See also
- 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)
See also
- 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
See also
See also
See also
See also
See also
-
PWM_CAPTURE_TYPE_PERIOD