Hardware Abstraction Layer (HAL)
PWM (Pulse Width Modulator)

General Description

High level interface for interacting with the pulse width modulator (PWM) hardware resource.

The PWM driver can be used to generate periodic digital waveforms with configurable frequency and duty cycle. The driver allows assigning the PWM output and an optional inverted output to supplied pins. The driver supports interrupt generation on PWM terminal count and compare events.

Features

Quick Start

See Snippet 1: Simple PWM initialization and output to pin for a code snippet that generates a signal with the specified frequency and duty cycle on the specified pin.

Code snippets

Snippet 1: Simple PWM initialization and output to pin

The following snippet initializes a PWM resource and assigns the output to the supplied pin using cyhal_pwm_init.
The clock parameter clk is optional and need not be provided (NULL), to generate and use an available clock resource with a default frequency.
The clock frequency and the duty cycle is set using cyhal_pwm_set_duty_cycle.
cyhal_pwm_start starts the PWM output on the pin.

cy_rslt_t rslt;
cyhal_pwm_t pwm_obj;
/* Initialize PWM on the supplied pin and assign a new clock */
rslt = cyhal_pwm_init(&pwm_obj, P0_0, NULL);
/* Set a duty cycle of 50% and frequency of 1Hz */
rslt = cyhal_pwm_set_duty_cycle(&pwm_obj, 50, 1);
/* Start the PWM output */
rslt = cyhal_pwm_start(&pwm_obj);

Snippet 2: Starting and stopping the PWM output

cyhal_pwm_start and cyhal_pwm_stop functions can be used after PWM initialization to start and stop the PWM output.

cy_rslt_t rslt;
cyhal_pwm_t pwm_obj;
/* Initialize PWM on the supplied pin and assign a new clock */
rslt = cyhal_pwm_init(&pwm_obj, P0_0, NULL);
CY_ASSERT(CY_RSLT_SUCCESS == rslt);
/* Set a duty cycle of 50% and frequency of 1Hz */
rslt = cyhal_pwm_set_duty_cycle(&pwm_obj, 50, 1);
for (;;)
{
/* Stop the PWM output */
rslt = cyhal_pwm_stop(&pwm_obj);
/* Delay for observing the output */
/* (Re-)start the PWM output */
rslt = cyhal_pwm_start(&pwm_obj);
/* Delay for observing the output */
}

Snippet 3: Advanced PWM output to pin

cyhal_pwm_init_adv can be used to specify advanced PWM options like an additional inverted PWM output, pulse alignment (left, right, center) and run mode (one-shot or continuous). The following snippet initializes a left-aligned, continuous running PWM assigned to the supplied pin. The inverted output is assigned to a second pin (compl_pin).

cy_rslt_t rslt;
cyhal_pwm_t pwm_obj;
/* Initialize a left-aligned, continuous running PWM signal and assign normal and inverted outputs to pins */
rslt = cyhal_pwm_init_adv(&pwm_obj, P0_0, P0_1, CYHAL_PWM_LEFT_ALIGN, true, 0, false, NULL);
/* Set a duty cycle of 80% on the normal PWM output with a frequency of 1kHz */
rslt = cyhal_pwm_set_duty_cycle(&pwm_obj, 80, 1000);
/* Start the PWM output */
rslt = cyhal_pwm_start(&pwm_obj);

Snippet 4: Interrupts on PWM events

PWM events like hitting the terminal count or a compare event can be used to trigger a callback function.
cyhal_pwm_enable_event() can be used to enable one or more events to trigger the callback function.

void pwm_event_handler(void *callback_arg, cyhal_pwm_event_t event);
void snippet_cyhal_pwm_events(void)
{
cy_rslt_t rslt;
cyhal_pwm_t pwm_obj;
/* Initialize PWM on the supplied pin and assign a new clock */
rslt = cyhal_pwm_init(&pwm_obj, P0_0, NULL);
CY_ASSERT(CY_RSLT_SUCCESS == rslt);
/* Set a duty cycle of 50% and frequency of 1Hz */
rslt = cyhal_pwm_set_duty_cycle(&pwm_obj, 50, 1);
CY_ASSERT(CY_RSLT_SUCCESS == rslt);
/* Register a callback function (pwm_event_handler) to execute on event trigger */
cyhal_pwm_register_callback(&pwm_obj, pwm_event_handler, NULL);
/* Enable all events to trigger the callback */
/* Start the PWM output */
rslt = cyhal_pwm_start(&pwm_obj);
CY_ASSERT(CY_RSLT_SUCCESS == rslt);
}
void pwm_event_handler(void *callback_arg, cyhal_pwm_event_t event)
{
(void)callback_arg;
{
/* Compare event triggered */
/* Insert application code to handle event */
}
{
/* Terminal count event triggered */
/* Insert application code to handle event */
}
}

API Reference

 PWM HAL Results
 PWM specific return codes.
 

Macros

#define cyhal_pwm_init(obj, pin, clk)   (cyhal_pwm_init_adv(obj, pin, NC, (pin & 1) ? CYHAL_PWM_RIGHT_ALIGN : CYHAL_PWM_LEFT_ALIGN, true, 0u, (bool)(pin & 1), clk))
 Initialize the PWM out peripheral and configure the pin This is similar to the cyhal_pwm_init_adv() but uses defaults for some of the more advanced setup options. More...
 

Typedefs

typedef void(* cyhal_pwm_event_callback_t) (void *callback_arg, cyhal_pwm_event_t event)
 Handler for PWM interrupts.
 

Enumerations

enum  cyhal_pwm_event_t {
  CYHAL_PWM_IRQ_NONE = 0,
  CYHAL_PWM_IRQ_TERMINAL_COUNT = 1 << 0,
  CYHAL_PWM_IRQ_COMPARE = 1 << 1,
  CYHAL_PWM_IRQ_ALL = (1 << 2) - 1
}
 PWM interrupt triggers. More...
 
enum  cyhal_pwm_alignment_t {
  CYHAL_PWM_LEFT_ALIGN = 0,
  CYHAL_PWM_RIGHT_ALIGN = 1,
  CYHAL_PWM_CENTER_ALIGN = 2
}
 PWM alignment. More...
 

Functions

cy_rslt_t cyhal_pwm_init_adv (cyhal_pwm_t *obj, cyhal_gpio_t pin, cyhal_gpio_t compl_pin, cyhal_pwm_alignment_t pwm_alignment, bool continuous, uint32_t dead_time_us, bool invert, const cyhal_clock_t *clk)
 Initialize the PWM out peripheral and configure the pin. More...
 
void cyhal_pwm_free (cyhal_pwm_t *obj)
 Deinitialize the PWM object. More...
 
cy_rslt_t cyhal_pwm_set_period (cyhal_pwm_t *obj, uint32_t period_us, uint32_t pulse_width_us)
 Set the number of microseconds for the PWM period & pulse width. More...
 
cy_rslt_t cyhal_pwm_set_duty_cycle (cyhal_pwm_t *obj, float duty_cycle, uint32_t frequencyhal_hz)
 Set the PWM duty cycle and frequency. More...
 
cy_rslt_t cyhal_pwm_start (cyhal_pwm_t *obj)
 Starts the PWM generation and outputs on pin and compl_pin. More...
 
cy_rslt_t cyhal_pwm_stop (cyhal_pwm_t *obj)
 Stops the PWM generation and outputs on pin and compl_pin. More...
 
void cyhal_pwm_register_callback (cyhal_pwm_t *obj, cyhal_pwm_event_callback_t callback, void *callback_arg)
 Register a PWM interrupt handler. More...
 
void cyhal_pwm_enable_event (cyhal_pwm_t *obj, cyhal_pwm_event_t event, uint8_t intr_priority, bool enable)
 Configure PWM event enablement. More...
 

Macro Definition Documentation

◆ cyhal_pwm_init

#define cyhal_pwm_init (   obj,
  pin,
  clk 
)    (cyhal_pwm_init_adv(obj, pin, NC, (pin & 1) ? CYHAL_PWM_RIGHT_ALIGN : CYHAL_PWM_LEFT_ALIGN, true, 0u, (bool)(pin & 1), clk))

Initialize the PWM out peripheral and configure the pin This is similar to the cyhal_pwm_init_adv() but uses defaults for some of the more advanced setup options.

See Snippet 1: Simple PWM initialization and output to pin.

Parameters
[out]objPointer to a PWM object. The caller must allocate the memory for this object but the init function will initialize its contents.
[in]pinThe PWM pin to initialize. This pin is required, it cannot be NC (No Connect).
[in]clkAn optional, pre-allocated clock to use, if NULL a new clock will be allocated
Returns
The status of the init request.

Enumeration Type Documentation

◆ cyhal_pwm_event_t

PWM interrupt triggers.

Enumerator
CYHAL_PWM_IRQ_NONE 

No interrupts.

CYHAL_PWM_IRQ_TERMINAL_COUNT 

Interrupt on terminal count match event.

CYHAL_PWM_IRQ_COMPARE 

Interrupt on compare match event.

CYHAL_PWM_IRQ_ALL 

Interrupt on any events.

◆ cyhal_pwm_alignment_t

PWM alignment.

Enumerator
CYHAL_PWM_LEFT_ALIGN 

PWM is left aligned (signal starts high and goes low after compare match)

CYHAL_PWM_RIGHT_ALIGN 

PWM is right aligned (signal starts low and goes high after compare match)

CYHAL_PWM_CENTER_ALIGN 

PWM is centered aligned (signal starts and ends low with a center aligned pulse)

Function Documentation

◆ cyhal_pwm_init_adv()

cy_rslt_t cyhal_pwm_init_adv ( cyhal_pwm_t obj,
cyhal_gpio_t  pin,
cyhal_gpio_t  compl_pin,
cyhal_pwm_alignment_t  pwm_alignment,
bool  continuous,
uint32_t  dead_time_us,
bool  invert,
const cyhal_clock_t clk 
)

Initialize the PWM out peripheral and configure the pin.

This is similar to the cyhal_pwm_init() but provides additional setup options.
See Snippet 3: Advanced PWM output to pin.

Parameters
[out]objPointer to a PWM object. The caller must allocate the memory for this object but the init function will initialize its contents.
[in]pinThe PWM pin to initialize. This pin is required, it cannot be NC (No Connect).
[in]compl_pinAn optional, additional inverted output pin.
If supplied, this must be connected to the same PWM instance as pin, for PSoC 6 see Complementary PWM output.
If this output is not needed, use NC (No Connect).
[in]pwm_alignmentPWM alignment: left, right, or center.
[in]continuousPWM run type: continuous (true) or one shot (false).
[in]dead_time_usThe number of micro-seconds for dead time. This is only meaningful if both pin and compl_pin are provided.
[in]invertAn option for the user to invert the PWM output
[in]clkAn optional, pre-allocated clock to use, if NULL a new clock will be allocated.
Returns
The status of the init request
Note
In some cases, it is possible to use a pin designated for non-inverting output as an inverting output and vice versa. Whether this is possible is dependent on the HAL implementation and operating mode. See the implementation specific documentation for details.

◆ cyhal_pwm_free()

void cyhal_pwm_free ( cyhal_pwm_t obj)

Deinitialize the PWM object.

Parameters
[in,out]objThe PWM object

◆ cyhal_pwm_set_period()

cy_rslt_t cyhal_pwm_set_period ( cyhal_pwm_t obj,
uint32_t  period_us,
uint32_t  pulse_width_us 
)

Set the number of microseconds for the PWM period & pulse width.

Parameters
[in]objThe PWM object
[in]period_usThe period in microseconds
[in]pulse_width_usThe pulse width in microseconds
Returns
The status of the period request

◆ cyhal_pwm_set_duty_cycle()

cy_rslt_t cyhal_pwm_set_duty_cycle ( cyhal_pwm_t obj,
float  duty_cycle,
uint32_t  frequencyhal_hz 
)

Set the PWM duty cycle and frequency.

Parameters
[in]objThe PWM object
[in]duty_cycleThe percentage of time the output is high
[in]frequencyhal_hzThe frequency of the PWM in Hz
Returns
The status of the duty cycle request

◆ cyhal_pwm_start()

cy_rslt_t cyhal_pwm_start ( cyhal_pwm_t obj)

Starts the PWM generation and outputs on pin and compl_pin.

Parameters
[in]objThe PWM object
Returns
The status of the start request

◆ cyhal_pwm_stop()

cy_rslt_t cyhal_pwm_stop ( cyhal_pwm_t obj)

Stops the PWM generation and outputs on pin and compl_pin.

Parameters
[in]objThe PWM object
Returns
The status of the stop request

◆ cyhal_pwm_register_callback()

void cyhal_pwm_register_callback ( cyhal_pwm_t obj,
cyhal_pwm_event_callback_t  callback,
void *  callback_arg 
)

Register a PWM interrupt handler.

This function will be called when one of the events enabled by cyhal_pwm_enable_event occurs.

Parameters
[in]objThe PWM object
[in]callbackThe callback handler which will be invoked when the event occurs
[in]callback_argGeneric argument that will be provided to the callback when called

◆ cyhal_pwm_enable_event()

void cyhal_pwm_enable_event ( cyhal_pwm_t obj,
cyhal_pwm_event_t  event,
uint8_t  intr_priority,
bool  enable 
)

Configure PWM event enablement.

When an enabled event occurs, the function specified by cyhal_pwm_register_callback will be called.

Parameters
[in]objThe PWM object
[in]eventThe PWM event type
[in]intr_priorityThe priority for NVIC interrupt events
[in]enableTrue to turn on events, False to turn off