# PWM
## Overview
Pulse width modulation (PWM) is a method used to digitally encode analog signal levels and convert them into pulses. It can be used for motor control and backlight brightness adjustment.
The PWM APIs provide a set of functions for operating a PWM device, including those for:
- Obtaining and releasing a PWM device handle
- Setting the PWM period, signal ON-state time, and polarity
- Enabling and disabling a PWM device
- Obtaining and setting PWM parameters
### PwmConfig Structure
**Table 1** PwmConfig structure
| Parameter| Description|
| -------- | ------------------------------------------------------------ |
| duty | Time that a signal is in the ON state, in ns.|
| period | Time for a signal to complete an on-and-off cycle, in ns.|
| number | Number of square waves to generate. A positive value indicates the number of square waves to generate. The value 0 means to generate square waves repeatedly.|
| polarity | PWM signal polarity, which can be **PWM\_NORMAL\_POLARITY** or **PWM\_INVERTED\_POLARITY**.|
| status | PWM device status, which can be enabled or disabled.|
## Available APIs
**Table 2** PWM device APIs
Category |
API |
Description |
Operating PWM handles |
PwmOpen |
Opens the handle of a PWM device. |
PwmClose |
Closes the handle of a PWM device. |
Enabling or disabling PWM |
PwmEnable |
Enables a PWM device. |
PwmDisable |
Disables a PWM device. |
Performing PWM configuration |
PwmSetPeriod |
Sets the PWM period. |
PwmSetDuty |
Sets the signal ON-state time. |
PwmSetPolarity |
Sets the PWM signal polarity. |
Setting or obtaining the PWM configuration |
PwmSetConfig |
Sets PWM device parameters. |
PwmGetConfig |
Obtains PWM device parameters. |
|
|
|
>![](W:\doc\docs\en\device-dev\public_sys-resources\icon-note.gif) **NOTE:**
>The PWM module can be used in kernel mode but not in user mode.
## Usage Guidelines
### How to Use
During the OS startup process, the driver management module loads the PWM driver based on the configuration file. Then, the PWM driver detects the PWM device and initializes the driver.
[Figure 1](#fig1_PWM_des) shows the general process of using the PWM module.
**Figure 1** Process of using the PWM module
![](figures/process-of-using-PWM.png)
### Opening a PWM Device Handle
Before performing operations on a PWM device, call **PwmOpen** to open the device handle.
```c
DevHandle PwmOpen(uint32_t num);
```
**Table 3** PwmOpen
| Parameter| Description|
| ---------- | ----------------------- |
| num | PWM device number.|
| **Return Value** | **Description**|
| handle | Handle of the PWM device obtained.|
| NULL | The operation fails.|
```c
uint32_t num = 0; /* PWM device number. */
DevHandle handle = NULL;
/* Obtain the PWM device handle. */
handle = PwmOpen(num);
if (handle == NULL) {
/* Error handling. */
}
```
### Closing a PWM Device Handle
Close a PWM device to release resources.
```c
void PwmClose(DevHandle handle);
```
**Table 4** PwmClose
| Parameter| Description|
| ------ | ----------- |
| handle | PWM device handle to close.|
```c
/* Close a PWM device handle. */
PwmClose(handle);
```
### Enabling a PWM Device
Enable a PWM device.
```c
int32_t PwmEnable(DevHandle handle);
```
**Table 5** PwmEnable
| Parameter| Description|
| ---------- | -------------- |
| handle | PWM device handle.|
| **Return Value** | **Description** |
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
/* Enable a PWM device. */
ret = PwmEnable(handle);
if (ret != 0) {
/* Error handling. */
}
```
### Disabling a PWM Device
Disable a PWM device.
```c
int32_t PwmDisable(DevHandle handle);
```
**Table 6** PwmDisable
| Parameter| Description|
| ---------- | -------------- |
| handle | PWM device handle.|
| **Return Value** | **Description** |
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
/* Disable a PWM device. */
ret = PwmDisable(handle);
if (ret != 0) {
/* Error handling. */
}
```
### Setting the PWM Period
Set the PWM period.
```c
int32_t PwmSetPeriod(DevHandle handle, uint32_t period);
```
**Table 7** PwmSetPeriod
| Parameter| Description|
| ---------- | ------------------------ |
| handle | PWM device handle.|
| period | PWM period to set, in ns.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
/* Set the PWM period to 50000000 ns.*/
ret = PwmSetPeriod(handle, 50000000);
if (ret != 0) {
/* Error handling. */
}
```
### Setting the PWM Signal ON-State Time
Set the time that the PWM signal is in the ON state.
```c
int32_t PwmSetDuty(DevHandle handle, uint32_t duty);
```
**Table 8** PwmSetDuty
| Parameter| Description|
| ---------- | ---------------------------- |
| handle | PWM device handle.|
| duty | Time that the signal is in the ON state, in ns.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
/* Set the signal ON-state time to 25000000 ns. */
ret = PwmSetDuty(handle, 25000000);
if (ret != 0) {
/* Error handling. */
}
```
### Setting the PWM Polarity
Set the signal polarity for a PWM device.
```c
int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity);
```
**Table 9** PwmSetPolarity
| Parameter| Description|
| ---------- | ------------------- |
| handle | PWM device handle.|
| polarity | Polarity to set, which can be **PWM\_NORMAL\_POLARITY** or **PWM\_INVERTED\_POLARITY**.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
/* Set the PWM polarity to PWM_INVERTED_POLARITY. */
ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);
if (ret != 0) {
/* Error handling. */
}
```
### Setting PWM Device Parameters
Set PWM device parameters.
```c
int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config);
```
**Table 10** PwmSetConfig
| Parameter| Description|
| ---------- | -------------- |
| handle | PWM device handle.|
| *config | Pointer to PWM parameters.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
struct PwmConfig pcfg;
pcfg.duty = 25000000; /* Set the signal ON-state time to 25000000 ns. */
pcfg.period = 50000000; /* Set the PWM period to 50000000 ns. */
pcfg.number = 0; /* Generate square waves repeatedly. */
pcfg.polarity = PWM_INVERTED_POLARITY; /* Set the PWM polarity to PWM_INVERTED_POLARITY. */
pcfg.status = PWM_ENABLE_STATUS; /* Set the running status to Enabled. */
/* Set PWM device parameters. */
ret = PwmSetConfig(handle, &pcfg);
if (ret != 0) {
/* Error handling. */
}
```
### Obtaining PWM Device Parameters
Obtain PWM device parameters.
```c
int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config);
```
**Table 11** PwmGetConfig
| Parameter| Description|
| ---------- | -------------- |
| handle | PWM device handle.|
| *config | Pointer to PWM parameters.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative number| The operation fails.|
```c
int32_t ret;
struct PwmConfig pcfg;
/* Obtain PWM device parameters. */
ret = PwmGetConfig(handle, &pcfg);
if (ret != 0) {
/* Error handling. */
}
```
## Usage Example
The following example shows how to use the APIs to implement a PWM driver and manage the PWM device.
```
void PwmTestSample(void)
{
int32_t ret;
uint32_t num;
DevHandle handle = NULL;
struct PwmConfig pcfg;
pcfg.duty = 20000000; /* Set the signal ON-state time to 20000000 ns. */
pcfg.period = 40000000; /* Set the PWM period to 40000000 ns. */
pcfg.number = 100; /* Generate 100 square waves. */
pcfg.polarity = PWM_NORMAL_POLARITY; /* Set the polarity to PWM_NORMAL_POLARITY. */
pcfg.status = PWM_ENABLE_STATUS; /* Set the running status to Enabled. */
/* Enter the PWM device number. */
num = 1;
/* Open the PWM device handle. */
handle = PwmOpen(num);
if (handle == NULL) {
HDF_LOGE("PwmOpen: failed!\n");
return;
}
/* Set the PWM period to 50000000 ns.*/
ret = PwmSetPeriod(handle, 50000000);
if (ret != 0) {
HDF_LOGE("PwmSetPeriod: failed, ret %d\n", ret);
goto _ERR;
}
/* Set the signal ON-state time to 25000000 ns. */
ret = PwmSetDuty(handle, 25000000);
if (ret != 0) {
HDF_LOGE("PwmSetDuty: failed, ret %d\n", ret);
goto _ERR;
}
/* Set the PWM polarity to PWM_INVERTED_POLARITY. */
ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);
if (ret != 0) {
HDF_LOGE("PwmSetPolarity: failed, ret %d\n", ret);
goto _ERR;
}
/* Obtain PWM device parameters. */
ret = PwmGetConfig(handle, &pcfg);
if (ret != 0) {
HDF_LOGE("PwmGetConfig: failed, ret %d\n", ret);
goto _ERR;
}
/* Enable the PWM device. */
ret = PwmEnable(handle);
if (ret != 0) {
HDF_LOGE("PwmEnable: failed, ret %d\n", ret);
goto _ERR;
}
/* Set PWM device parameters. */
ret = PwmSetConfig(handle, &pcfg);
if (ret != 0) {
HDF_LOGE("PwmSetConfig: failed, ret %d\n", ret);
goto _ERR;
}
/* Disable the PWM device. */
ret = PwmDisable(handle);
if (ret != 0) {
HDF_LOGE("PwmDisable: failed, ret %d\n", ret);
goto _ERR;
}
_ERR:
/* Close the PWM device handle. */
PwmClose(handle);
}
```