Pulse-width modulation - Peripheral Abstraction Layer (PWM PAL)

Detailed Description

The S32 SDK provides a Peripheral Abstraction Layer for the PWM mode.

The PWM PAL driver allows to generate PWM signals. It was designed to be portable across all platforms and IPs which support PWM features.

How to integrate PWM in your application

Unlike the other drivers, PWM PAL modules need to include a configuration file named pwm_pal_cfg.h, which allows the user to specify which IPSs are used and how many resources are allocated for each of them (state structures). The following code example shows how to configure one instance for each available SPI IPs.

#ifndef PWM_PAL_cfg_H
#define PWM_PAL_cfg_H
/* Define which IP instance will be used in current project */
#define PWM_OVER_FTM
#define PWM_OVER_EMIOS
#define PWM_OVER_ETIMER
/* Define the resources necessary for current project */
#define NO_OF_FTM_INSTS_FOR_PWM 1U
#define NO_OF_EMIOS_INSTS_FOR_PWM 1U
#define NO_OF_ETIMER_INSTS_FOR_PWM 1U
#endif /* PWM_PAL_cfg_H */

The following table contains the matching between platforms and available IPs

IP/MCUS32K116S32K142S32K144S32K146S32K148MPC5748GMPC5746CMPC5744P
FTM YES YES YES YES YES NO NO NO
eMIOS NO NO NO NO NO YES YES NO
ETIMERNO NO NO NO NO NO NO YES

In order to use the PWM PAL driver it must be first initialized it using function PWM_Init. Once initialized, it cannot be initialized again for the same SPI module instance until it is de-initialized, using PWM_Denit. Different SPI module instances can work independently of each other.

After initialization the duty cycle and pwm period can be updated with these functions: PWM_UpdateDuty and PWM_UpdatePeriod. The measurement unit for duty and period is clock ticks, so the application should be aware about the clock frequency of the timebase used by PWM channel.

Due to hardware limitation period changing for a specific channel can change the period for other channels if they share the same timebase. Also, for FTM all channels must have the same period and type.

Important Notes

Example code

The following code explains how to define the configuration structures and how to initialize and update duty cycle on S32K1xx platforms with FTM.

/* Timebase */
pwm_ftm_timebase_t pwm_pal1Timebase =
{
.prescaler = FTM_CLOCK_DIVID_BY_1,
.deadtimePrescaler = FTM_DEADTIME_DIVID_BY_1
};
/* Channels */
pwm_channel_t pwm_pal1Channels[3] =
{
{
.channel = 0,
.channelType = PWM_EDGE_ALIGNED,
.period = 5000,
.duty = 2500,
.polarity = PWM_ACTIVE_HIGH,
.insertDeadtime = false,
.deadtime = 0,
.enableComplementaryChannel = false,
.complementaryChannelPolarity = PWM_DUPLICATED,
.timebase = &pwm_pal1Timebase
},
{
.channel = 1,
.channelType = PWM_EDGE_ALIGNED,
.period = 5000,
.duty = 1000,
.polarity = PWM_ACTIVE_HIGH,
.insertDeadtime = false,
.deadtime = 0,
.enableComplementaryChannel = false,
.complementaryChannelPolarity = PWM_DUPLICATED,
.timebase = &pwm_pal1Timebase
},
{
.channel = 2,
.channelType = PWM_EDGE_ALIGNED,
.period = 5000,
.duty = 100,
.polarity = PWM_ACTIVE_HIGH,
.insertDeadtime = false,
.deadtime = 0,
.enableComplementaryChannel = false,
.complementaryChannelPolarity = PWM_DUPLICATED,
.timebase = &pwm_pal1Timebase
},
};
/* Initialization configuration */
pwm_global_config_t pwm_pal1Config =
{
.pwmChannels = pwm_pal1Channels,
.numberOfPwmChannels = 3
};
/* Instance configuration */
pwm_instance_t pwm_pal1Instance =
{
.instIdx = 0,
};
bool increaseDutyCycle = true;
uint16_t dutyCycle = 0;
/* This example doesn't includes pins and clock setup */
PWM_Init(&pwm_pal1Instance, &pwm_pal1Config);
while(1)
{
if (increaseDutyCycle == false)
{
dutyCycle--;
if (dutyCycle < 1)
increaseDutyCycle = true;
}
else
{
dutyCycle++;
if (dutyCycle > 5000)
increaseDutyCycle = false;
}
/* Update PWM channels */
PWM_UpdateDuty(&pwm_pal1Instance, 0,dutyCycle);
}
<p>
The following code explains how to define the configuration structures and how to initialize and update duty cycle on MPC574X platforms with eMIOS.
</p>
@code
/* Timebase */
/* Timebases */
pwm_emios_timebase_t BUS_A_Timebase =
{
.name = BUS_A,
.internalPrescaler = EMIOS_CLOCK_DIVID_BY_1,
};
/* Channels */
pwm_channel_t pwm_pal1Channels[1] =
{
{
.channel = 0,
.channelType = PWM_EDGE_ALIGNED,
.period = 5000,
.duty = 2500,
.polarity = PWM_ACTIVE_HIGH,
.timebase = &BUS_A_Timebase
},
};
/* Initialization configuration */
pwm_global_config_t pwm_pal1Configs =
{
.pwmChannels = pwm_pal1Channels,
.numberOfPwmChannels = 1,
};
/* Instance configuration */
pwm_instance_t pwm_pal1Instance =
{
.instType = PWM_INST_TYPE_EMIOS,
.instIdx = 0,
};
bool increaseDutyCycle = true;
uint16_t dutyCycle = 0;
/* This example doesn't includes pins and clock setup */
PWM_Init(&pwm_pal1Instance, &pwm_pal1Config);
while(1)
{
if (increaseDutyCycle == false)
{
dutyCycle--;
if (dutyCycle < 1)
increaseDutyCycle = true;
}
else
{
dutyCycle++;
if (dutyCycle > 5000)
increaseDutyCycle = false;
}
/* Update PWM channels */
PWM_UpdateDuty(&pwm_pal1Instance, 0,dutyCycle);
}

Data Structures

struct  pwm_channel_t
 This structure includes the configuration for each channel Implements : pwm_channel_t_Class. More...
 
struct  pwm_global_config_t
 This structure is the configuration for initialization of PWM channels. Implements : pwm_global_config_t_Class. More...
 

Enumerations

enum  pwm_channel_type_t { PWM_EDGE_ALIGNED = 0, PWM_CENTER_ALIGNED = 1 }
 Defines the channel types Implements : pwm_channel_type_t_Class. More...
 
enum  pwm_polarity_t { PWM_ACTIVE_HIGH = 0, PWM_ACTIVE_LOW = 1 }
 Defines the polarity of pwm channels Implements : pwm_polarity_t_Class. More...
 
enum  pwm_complementarty_mode_t { PWM_DUPLICATED = 0, PWM_INVERTED = 1 }
 Defines the polarity of complementary pwm channels relative to main channel Implements : pwm_complementarty_mode_t_Class. More...
 

Functions

status_t PWM_Init (const pwm_instance_t *const instance, const pwm_global_config_t *config)
 Initialize PWM channels based on config parameter. More...
 
status_t PWM_UpdateDuty (const pwm_instance_t *const instance, uint8_t channel, uint32_t duty)
 Update duty cycle. The measurement unit for duty is clock ticks. More...
 
status_t PWM_UpdatePeriod (const pwm_instance_t *const instance, uint8_t channel, uint32_t period)
 Update period for specific a specific channel. This function changes period for all channels which shares the timebase with targeted channel. More...
 
status_t PWM_OverwriteOutputChannels (const pwm_instance_t *const instance, uint32_t channelsMask, uint32_t channelsValues)
 This function change the output value for some channels. channelsMask select which channels will be overwrite, each bit filed representing one channel: 1 - channel is controlled by channelsValues, 0 - channel is controlled by pwm. channelsValues select output values to be write on corresponding channel. More...
 
status_t PWM_Deinit (const pwm_instance_t *const instance)
 Uninitialised PWM instance. More...
 

Enumeration Type Documentation

Defines the channel types Implements : pwm_channel_type_t_Class.

Enumerator
PWM_EDGE_ALIGNED 

Counter used by this type of channel is in up counting mode and the edge is aligned to PWM period

PWM_CENTER_ALIGNED 

Counter used by this type of channel is in up-down counting mode and the duty is inserted in center of PWM period

Definition at line 64 of file pwm_pal.h.

Defines the polarity of complementary pwm channels relative to main channel Implements : pwm_complementarty_mode_t_Class.

Enumerator
PWM_DUPLICATED 

Complementary channel is the same as main channel

PWM_INVERTED 

Complementary channel is inverted relative to main channel

Definition at line 84 of file pwm_pal.h.

Defines the polarity of pwm channels Implements : pwm_polarity_t_Class.

Enumerator
PWM_ACTIVE_HIGH 

Polarity is active high

PWM_ACTIVE_LOW 

Polarity is active low

Definition at line 74 of file pwm_pal.h.

Function Documentation

status_t PWM_Deinit ( const pwm_instance_t *const  instance)

Uninitialised PWM instance.

Parameters
[in]instanceThe name of the instance
Returns
Error or success status returned by API

Definition at line 723 of file pwm_pal.c.

status_t PWM_Init ( const pwm_instance_t *const  instance,
const pwm_global_config_t config 
)

Initialize PWM channels based on config parameter.

Parameters
[in]instanceThe name of the instance
[in]configThe configuration structure used to initialize PWM modules
Returns
Error or success status returned by API

Definition at line 134 of file pwm_pal.c.

status_t PWM_OverwriteOutputChannels ( const pwm_instance_t *const  instance,
uint32_t  channelsMask,
uint32_t  channelsValues 
)

This function change the output value for some channels. channelsMask select which channels will be overwrite, each bit filed representing one channel: 1 - channel is controlled by channelsValues, 0 - channel is controlled by pwm. channelsValues select output values to be write on corresponding channel.

Parameters
[in]instanceThe name of the instance
[in]channelsMaskThe name mask used to select which channel is overwrite
[in]channelsValuesThe name overwrite values for all channels
Returns
Error or success status returned by API

Definition at line 679 of file pwm_pal.c.

status_t PWM_UpdateDuty ( const pwm_instance_t *const  instance,
uint8_t  channel,
uint32_t  duty 
)

Update duty cycle. The measurement unit for duty is clock ticks.

Parameters
[in]instanceThe name of the instance
[in]channelThe channel which is update
[in]dutyThe duty cycle measured in ticks
Returns
Error or success status returned by API

Definition at line 516 of file pwm_pal.c.

status_t PWM_UpdatePeriod ( const pwm_instance_t *const  instance,
uint8_t  channel,
uint32_t  period 
)

Update period for specific a specific channel. This function changes period for all channels which shares the timebase with targeted channel.

Parameters
[in]instanceThe name of the instance
[in]channelThe channel which is update
[in]periodThe period measured in ticks
Returns
Error or success status returned by API

Definition at line 583 of file pwm_pal.c.