提交 b5c184bc 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 11feca6b
...@@ -143,7 +143,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information re ...@@ -143,7 +143,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
3. Initialize the **GpioCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Init** and **Release**) to instantiate **GpioMethod** in **GpioCntlr** (so that the underlying driver functions can be called). 3. Initialize the **GpioCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Init** and **Release**) to instantiate **GpioMethod** in **GpioCntlr** (so that the underlying driver functions can be called).
- Defining a custom structure - Defining a custom structure
To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **gpio_config.hcs** file to initialize the members in the custom structure and pass important parameters, such as the GPIO group number and the number of pins, to the **GpioCntlr** object at the core layer. To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **gpio_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the GPIO group number and the number of pins, to the **GpioCntlr** object at the core layer.
``` ```
......
...@@ -9,19 +9,19 @@ High Definition Multimedia Interface (HDMI) is an audio and video transmission p ...@@ -9,19 +9,19 @@ High Definition Multimedia Interface (HDMI) is an audio and video transmission p
### Basic Concepts ### Basic Concepts
- TMDS is used to transmit audio, video, and various auxiliary data. - TMDS<br>Transmits audio, video, and various auxiliary data.
- Display data channel (DDC) allows the TX and RX ends to obtain the transmitting and receiving capabilities. However, HDMI only needs to unidirectionally obtain the capabilities of the RX end (display). - Display data channel (DDC)<br>Allows the TX and RX ends to obtain the transmitting and receiving capabilities. However, HDMI only needs to unidirectionally obtain the capabilities of the RX end (display).
- Consumer Electronics Control (CEC) enables interaction between the HDMI TX and RX devices. - Consumer Electronics Control (CEC)<br> Enables interaction between the HDMI TX and RX devices.
- Fixed rate link (FRL) allows the maximum TMDS bandwidth to be increased from 18 Gbit/s to 48 Gbit/s. - Fixed rate link (FRL)<br>Allows the maximum TMDS bandwidth to be increased from 18 Gbit/s to 48 Gbit/s.
- High-bandwidth Digital Content Protection (HDCP) prevents copying of digital audio and video content being transmitted across devices. - High-bandwidth Digital Content Protection (HDCP)<br>Prevents copying of digital audio and video content being transmitted across devices.
### Working Principles ### Working Principles
In the HDF, the HDMI module uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device to increase memory resources. In the HDF, the HDMI module uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
**Figure 1** Independent service mode **Figure 1** Independent service mode
...@@ -121,17 +121,17 @@ struct HdmiCntlrOps { ...@@ -121,17 +121,17 @@ struct HdmiCntlrOps {
The HDMI module adaptation involves the following steps: The HDMI module adaptation involves the following steps:
- Instantiate the driver entry. 1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure. - Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF. - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Configure attribute files. - Add the **deviceNode** information to the **device_info.hcs** file.
- Add the **deviceNode** information to the **device_info.hcs** file. - (Optional) Add the **hdmi_config.hcs** file.
- (Optional) Add the **hdmi_config.hcs** file. 3. Instantiate the HDMI controller object.
- Initialize **HdmiCntlr**.
- Instantiate **HdmiCntlrOps** in **HdmiCntlr**.
- Instantiate the HDMI controller object. ### Development Example
- Initialize **HdmiCntlr**.
- Instantiate **HdmiCntlrOps** in **HdmiCntlr**.
1. Instantiate the driver entry. 1. Instantiate the driver entry.
...@@ -158,7 +158,7 @@ The HDMI module adaptation involves the following steps: ...@@ -158,7 +158,7 @@ The HDMI module adaptation involves the following steps:
Configure HDMI controller information from the first node. This node specifies a type of HDMI controllers rather than a specific HDMI controller. In this example, there is only one HDMI controller. If there are multiple HDMI controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **hdmi_config** file. Configure HDMI controller information from the first node. This node specifies a type of HDMI controllers rather than a specific HDMI controller. In this example, there is only one HDMI controller. If there are multiple HDMI controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **hdmi_config** file.
- **device_info.hcs** configuration example: - **device_info.hcs** configuration example
```c ```c
root { root {
...@@ -177,7 +177,7 @@ The HDMI module adaptation involves the following steps: ...@@ -177,7 +177,7 @@ The HDMI module adaptation involves the following steps:
} }
``` ```
- **hdmi_config.hcs** configuration example: - **hdmi_config.hcs** configuration example
```c ```c
root { root {
...@@ -235,7 +235,7 @@ The HDMI module adaptation involves the following steps: ...@@ -235,7 +235,7 @@ The HDMI module adaptation involves the following steps:
> ![](../public_sys-resources/icon-note.gif) **NOTE** > ![](../public_sys-resources/icon-note.gif) **NOTE**
> >
> >
> To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **hdmi_config.hcs** file to initialize the members in the custom structure and pass important parameters, such as the device number and bus number, to the **HdmiCntlr** object at the core layer. > To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **hdmi_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number and bus number, to the **HdmiCntlr** object at the core layer.
```c ```c
struct HdmiAdapterHost { struct HdmiAdapterHost {
...@@ -403,15 +403,15 @@ The HDMI module adaptation involves the following steps: ...@@ -403,15 +403,15 @@ The HDMI module adaptation involves the following steps:
**Input parameter**: **Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information. **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**Return value**: **Return value**:
No value is returned. No value is returned.
**Function description**: **Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** callback in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. Releases the memory and deletes the controller. This function assigns values to the **Release** callback in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
```c ```c
static void HdmiAdapterRelease(struct HdfDeviceObject *obj) static void HdmiAdapterRelease(struct HdfDeviceObject *obj)
{ {
...@@ -422,6 +422,6 @@ The HDMI module adaptation involves the following steps: ...@@ -422,6 +422,6 @@ The HDMI module adaptation involves the following steps:
HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// Customized memory release function. A forced conversion from HdmiCntlr to HimciAdapterHost is involved in the process. HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// Customized memory release function. A forced conversion from HdmiCntlr to HimciAdapterHost is involved in the process.
} }
``` ```
> ![](../public_sys-resources/icon-note.gif) **NOTE**<br> > ![](../public_sys-resources/icon-note.gif) **NOTE**<br>
> All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations. > All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
# MIPI DSI # MIPI DSI
## Overview ## Overview
The Display Serial Interface \(DSI\) is a specification stipulated by the Mobile Industry Processor Interface \(MIPI\) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals \(usually LCDs or similar display devices\) in serial mode, or reads information such as status and pixel from the peripherals. The Display Serial Interface (DSI) is a specification stipulated by the Mobile Industry Processor Interface (MIPI) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals (usually LCDs or similar display devices) in serial mode, or reads information such as status and pixel from the peripherals.
MIPI DSI is capable of working in both high speed (HS) mode and low power (LP) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode.
MIPI DSI is capable of working in both high speed \(HS\) mode and low power \(LP\) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode. The figure below shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals.
[Figure 1](#fig1122611461203) shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals.
**Figure 1** DSI transmitting and receiving interface<a name="fig1122611461203"></a> **Figure 1** DSI TX and RX interfaces
![](figures/dsi-transmitting-and-receiving-interface.png "dsi-transmitting-and-receiving-interface")
![image](figures/DSI-TX-RX_interface.png)
## Available APIs ## Available APIs
**Table 1** APIs for MIPI DSI **Table 1** MIPI DSI APIs
<a name="table4199102313245"></a> | Category| API|
<table><thead align="left"><tr id="row1619910238244"><th class="cellrowborder" valign="top" width="26.619999999999997%" id="mcps1.2.4.1.1"><p id="p141991023182411"><a name="p141991023182411"></a><a name="p141991023182411"></a>Capability</p> | -------- | -------- |
</th> | MIPI DSI configuration| -&nbsp;**MipiDsiSetCfg**: sets MIPI DSI attributes.<br>-&nbsp;**MipiDsiGetCfg**: obtains the MIPI DSI configuration.|
<th class="cellrowborder" valign="top" width="28.910000000000004%" id="mcps1.2.4.1.2"><p id="p1199102315247"><a name="p1199102315247"></a><a name="p1199102315247"></a>Function</p> | MIPI DSI device handle| -&nbsp;**MipiDsiOpen**: opens a MIPI DSI device handle.<br>-&nbsp;**MipiDsiClose**: closes a MIPI DSI device handle.|
</th> | MIPI DSI device mode| -&nbsp;**MipiDsiSetLpMode**: sets LP mode for a device.<br>-&nbsp;**MipiDsiSetHsMode**: sets HS mode for a device.|
<th class="cellrowborder" valign="top" width="44.47%" id="mcps1.2.4.1.3"><p id="p719918232240"><a name="p719918232240"></a><a name="p719918232240"></a>Description</p> | MIPI DSI commands| -&nbsp;**MipiDsiTx**: sends commands to a display device.<br>- &nbsp;**MipiDsiRx**: reads data of the specified length.|
</th>
</tr> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
</thead> > All APIs described in this document can be called only in kernel mode.
<tbody><tr id="row15199023172414"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p919902312413"><a name="p919902312413"></a><a name="p919902312413"></a>Setting/Obtaining MIPI DSI configuration parameters</p>
</td>
<td class="cellrowborder" valign="top" width="28.910000000000004%" headers="mcps1.2.4.1.2 "><p id="p21995232243"><a name="p21995232243"></a><a name="p21995232243"></a>MipiDsiSetCfg</p>
</td>
<td class="cellrowborder" valign="top" width="44.47%" headers="mcps1.2.4.1.3 "><p id="p919911233240"><a name="p919911233240"></a><a name="p919911233240"></a>Sets configuration parameters for a MIPI DSI device.</p>
</td>
</tr>
<tr id="row171996232248"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p7199623152412"><a name="p7199623152412"></a><a name="p7199623152412"></a>MipiDsiGetCfg</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1119919235248"><a name="p1119919235248"></a><a name="p1119919235248"></a>Obtains configuration parameters of a MIPI DSI device.</p>
</td>
</tr>
<tr id="row91994239242"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p101998233245"><a name="p101998233245"></a><a name="p101998233245"></a>Obtaining /Releasing device handles</p>
</td>
<td class="cellrowborder" valign="top" width="28.910000000000004%" headers="mcps1.2.4.1.2 "><p id="p51991323112415"><a name="p51991323112415"></a><a name="p51991323112415"></a>MipiDsiOpen</p>
</td>
<td class="cellrowborder" valign="top" width="44.47%" headers="mcps1.2.4.1.3 "><p id="p11991623182415"><a name="p11991623182415"></a><a name="p11991623182415"></a>Obtains a MIPI DSI device handle.</p>
</td>
</tr>
<tr id="row12199192352411"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p131991123172412"><a name="p131991123172412"></a><a name="p131991123172412"></a>MipiDsiClose</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p520062313249"><a name="p520062313249"></a><a name="p520062313249"></a>Releases a specified MIPI DSI device handle.</p>
</td>
</tr>
<tr id="row7200152382417"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p8200202312241"><a name="p8200202312241"></a><a name="p8200202312241"></a>Setting the LP or HS mode</p>
</td>
<td class="cellrowborder" valign="top" width="28.910000000000004%" headers="mcps1.2.4.1.2 "><p id="p6200192318247"><a name="p6200192318247"></a><a name="p6200192318247"></a>MipiDsiSetLpMode</p>
</td>
<td class="cellrowborder" valign="top" width="44.47%" headers="mcps1.2.4.1.3 "><p id="p16200192319240"><a name="p16200192319240"></a><a name="p16200192319240"></a>Sets LP mode for a MIPI DSI device.</p>
</td>
</tr>
<tr id="row122001523182417"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p22009236249"><a name="p22009236249"></a><a name="p22009236249"></a>MipiDsiSetHsMode</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p22001423192418"><a name="p22001423192418"></a><a name="p22001423192418"></a>Sets HS mode for a MIPI DSI device.</p>
</td>
</tr>
<tr id="row52002237248"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p10200162332412"><a name="p10200162332412"></a><a name="p10200162332412"></a>Reading/Sending commands</p>
</td>
<td class="cellrowborder" valign="top" width="28.910000000000004%" headers="mcps1.2.4.1.2 "><p id="p19200142315249"><a name="p19200142315249"></a><a name="p19200142315249"></a>MipiDsiTx</p>
</td>
<td class="cellrowborder" valign="top" width="44.47%" headers="mcps1.2.4.1.3 "><p id="p1020082319243"><a name="p1020082319243"></a><a name="p1020082319243"></a>Sends a display command set (DCS) command for sending data.</p>
</td>
</tr>
<tr id="row6200162372416"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p18200112392417"><a name="p18200112392417"></a><a name="p18200112392417"></a>MipiDsiRx</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p9200102312249"><a name="p9200102312249"></a><a name="p9200102312249"></a>Receives a DCS command for reading data with the specified length.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE**<br> All functions described in this document can be called only in kernel space.
## Usage Guidelines ## Usage Guidelines
### How to Use ### How to Use
The figure below illustrates how to use the APIs. The figure below shows the general process of using the MIPI DSI driver APIs.
**Figure 2** Using MIPI DSI driver APIs **Figure 2** Using MIPI DSI driver APIs
![](figures/using-mipi-dsi-process.png) ![image](figures/using-MIPI-DSI-process.png)
### Obtaining a MIPI DSI Device Handle<a name="section5126155683811"></a>
### Opening a MIPI DSI Device Handle
Before performing MIPI DSI communication, obtain a MIPI DSI device handle by calling **MipiDsiOpen**. This function returns a MIPI DSI device handle with a specified channel ID.
Before performing MIPI DSI communication, open a MIPI DSI device handle by calling **MipiDsiOpen()**. This function returns the MIPI DSI device handle of the specified channel ID.
DevHandle MipiDsiOpen\(uint8\_t id\);
**Table 2** Description of **MipiDsiOpen** ```
DevHandle MipiDsiOpen(uint8_t id);
<a name="table7603619123820"></a> ```
<table><thead align="left"><tr id="row1060351914386"><th class="cellrowborder" valign="top" width="20.66%" id="mcps1.2.3.1.1"><p id="p14603181917382"><a name="p14603181917382"></a><a name="p14603181917382"></a><strong id="b824620346298"><a name="b824620346298"></a><a name="b824620346298"></a>Parameter</strong></p>
</th> **Table 2** Description of MipiDsiOpen
<th class="cellrowborder" valign="top" width="79.34%" id="mcps1.2.3.1.2"><p id="p36031519183819"><a name="p36031519183819"></a><a name="p36031519183819"></a><strong id="b465435112910"><a name="b465435112910"></a><a name="b465435112910"></a>Description</strong></p>
</th> | **Parameter**| **Description**|
</tr> | -------- | -------- |
</thead> | id | MIPI DSI channel ID.|
<tbody><tr id="row960361918383"><td class="cellrowborder" valign="top" width="20.66%" headers="mcps1.2.3.1.1 "><p id="p8603161903818"><a name="p8603161903818"></a><a name="p8603161903818"></a>id</p> | **Return Value**| **Description**|
</td> | NULL | The operation failed.|
<td class="cellrowborder" valign="top" width="79.34%" headers="mcps1.2.3.1.2 "><p id="p19603111916381"><a name="p19603111916381"></a><a name="p19603111916381"></a>MIPI DSI channel ID.</p> | Device handle| The operation is successful. The MIPI DSI device handle of the specified channel ID (data type is **DevHandle**) is returned.|
</td>
</tr> For example, open the MIPI DSI device handle of channel **0**:
<tr id="row11410612183019"><td class="cellrowborder" valign="top" width="20.66%" headers="mcps1.2.3.1.1 "><p id="p460381915385"><a name="p460381915385"></a><a name="p460381915385"></a><strong id="b132118377294"><a name="b132118377294"></a><a name="b132118377294"></a>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="79.34%" headers="mcps1.2.3.1.2 "><p id="p96031619153812"><a name="p96031619153812"></a><a name="p96031619153812"></a><strong id="b1661638162915"><a name="b1661638162915"></a><a name="b1661638162915"></a>Description</strong></p>
</td>
</tr>
<tr id="row15410111273017"><td class="cellrowborder" valign="top" width="20.66%" headers="mcps1.2.3.1.1 "><p id="p1060418195389"><a name="p1060418195389"></a><a name="p1060418195389"></a>NULL</p>
</td>
<td class="cellrowborder" valign="top" width="79.34%" headers="mcps1.2.3.1.2 "><p id="p760471912388"><a name="p760471912388"></a><a name="p760471912388"></a>Failed to receive the specified command.</p>
</td>
</tr>
<tr id="row1241081213303"><td class="cellrowborder" valign="top" width="20.66%" headers="mcps1.2.3.1.1 "><p id="p5604719133811"><a name="p5604719133811"></a><a name="p5604719133811"></a>Device handle</p>
</td>
<td class="cellrowborder" valign="top" width="79.34%" headers="mcps1.2.3.1.2 "><p id="p3604181933818"><a name="p3604181933818"></a><a name="p3604181933818"></a>MIPI DSI device handle with a specified channel ID, whose data type is <strong id="b643184319293"><a name="b643184319293"></a><a name="b643184319293"></a>DevHandle</strong>.</p>
</td>
</tr>
</tbody>
</table>
The following example shows how to obtain a MIPI DSI device handle with the channel ID **0**:
``` ```
DevHandle mipiDsiHandle = NULL; /* Device handle */ DevHandle mipiDsiHandle = NULL; /* Device handle */
chnId = 0; /* MIPI DSI channel ID */ chnId = 0; /* MIPI DSI channel ID */
/* Obtain the MIPI DSI device handle based on a specified channel ID. */ /* Open the MIPI DSI device handle. */
mipiDsiHandle = MipiDsiOpen(chnId); mipiDsiHandle = MipiDsiOpen(chnId);
if (mipiDsiHandle == NULL) { if (mipiDsiHandle == NULL) {
HDF_LOGE("MipiDsiOpen: failed\n"); HDF_LOGE("MipiDsiOpen: failed\n");
...@@ -139,311 +74,205 @@ if (mipiDsiHandle == NULL) { ...@@ -139,311 +74,205 @@ if (mipiDsiHandle == NULL) {
} }
``` ```
### Setting MIPI DSI Configuration Parameters<a name="section201164274344"></a>
- Set MIPI DSI configuration parameters by calling the following function:
int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\);
**Table 3** Description of **MipiDsiSetCfg**
<a name="table10692555281"></a>
<table><thead align="left"><tr id="row116914559288"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1169195516288"><a name="p1169195516288"></a><a name="p1169195516288"></a><strong id="b1804534152914"><a name="b1804534152914"></a><a name="b1804534152914"></a>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p769125512286"><a name="p769125512286"></a><a name="p769125512286"></a><strong id="b461693511292"><a name="b461693511292"></a><a name="b461693511292"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row4691155142812"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p66935515288"><a name="p66935515288"></a><a name="p66935515288"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p863714348217"><a name="p863714348217"></a><a name="p863714348217"></a>MIPI DSI device handle.</p>
</td>
</tr>
<tr id="row469145572817"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p46915519287"><a name="p46915519287"></a><a name="p46915519287"></a>cfg</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p76995518289"><a name="p76995518289"></a><a name="p76995518289"></a>Pointer to MIPI DSI configuration parameters.</p>
</td>
</tr>
<tr id="row16913554284"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p16955512812"><a name="p16955512812"></a><a name="p16955512812"></a><strong id="b1696737132913"><a name="b1696737132913"></a><a name="b1696737132913"></a>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p206945502813"><a name="p206945502813"></a><a name="p206945502813"></a><strong id="b42104011299"><a name="b42104011299"></a><a name="b42104011299"></a>Description</strong></p>
</td>
</tr>
<tr id="row146914556283"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p669175582818"><a name="p669175582818"></a><a name="p669175582818"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p169205511283"><a name="p169205511283"></a><a name="p169205511283"></a>Succeeded in setting MIPI DSI configuration parameters.</p>
</td>
</tr>
<tr id="row5694558283"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p269175516286"><a name="p269175516286"></a><a name="p269175516286"></a>Negative value</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p11691554280"><a name="p11691554280"></a><a name="p11691554280"></a>Failed to set MIPI DSI configuration parameters.</p>
</td>
</tr>
</tbody>
</table>
```
int32_t ret;
struct MipiCfg cfg = {0};
/* Configuration parameters of the connected device are as follows: */
cfg.lane = DSI_4_LANES;
cfg.mode = DSI_CMD_MODE;
cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS;
cfg.format = FORMAT_RGB_24_BIT;
cfg.pixelClk = 174;
cfg.phyDataRate = 384;
cfg.timingInfo.hsaPixels = 50;
cfg.timingInfo.hbpPixels = 55;
cfg.timingInfo.hlinePixels = 1200;
cfg.timingInfo.yResLines = 1800;
cfg.timingInfo.vbpLines = 33;
cfg.timingInfo.vsaLines = 76;
cfg.timingInfo.vfpLines = 120;
cfg.timingInfo.xResPixels = 1342;
/* Set MIPI DSI configuration parameters. */
ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
if (ret != 0) {
HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
return -1;
}
```
- Obtain MIPI DSI configuration parameters by calling the following function:
int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\);
**Table 4** Description of **MipiDsiGetCfg**
<a name="table7709554280"></a>
<table><thead align="left"><tr id="row670115515282"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p470205515287"><a name="p470205515287"></a><a name="p470205515287"></a><strong id="b14806334142912"><a name="b14806334142912"></a><a name="b14806334142912"></a>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p270755162817"><a name="p270755162817"></a><a name="p270755162817"></a><strong id="b6618113519294"><a name="b6618113519294"></a><a name="b6618113519294"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row57014555286"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p11701155172815"><a name="p11701155172815"></a><a name="p11701155172815"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p57015510283"><a name="p57015510283"></a><a name="p57015510283"></a>MIPI DSI device handle.</p>
</td>
</tr>
<tr id="row1870155192815"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p137115572815"><a name="p137115572815"></a><a name="p137115572815"></a>cfg</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p771195522818"><a name="p771195522818"></a><a name="p771195522818"></a>Pointer to MIPI DSI configuration parameters.</p>
</td>
</tr>
<tr id="row12718555283"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1871175515289"><a name="p1871175515289"></a><a name="p1871175515289"></a><strong id="b8698737142912"><a name="b8698737142912"></a><a name="b8698737142912"></a>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p771955182813"><a name="p771955182813"></a><a name="p771955182813"></a><strong id="b84194010291"><a name="b84194010291"></a><a name="b84194010291"></a>Description</strong></p>
</td>
</tr>
<tr id="row1071155582812"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p6718551282"><a name="p6718551282"></a><a name="p6718551282"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p171195516285"><a name="p171195516285"></a><a name="p171195516285"></a>Succeeded in receiving the specified command.</p>
</td>
</tr>
<tr id="row97135519282"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p11711355162815"><a name="p11711355162815"></a><a name="p11711355162815"></a>Negative value</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p77116555286"><a name="p77116555286"></a><a name="p77116555286"></a>Failed to receive the specified command.</p>
</td>
</tr>
</tbody>
</table>
``` ### Setting MIPI DSI Attributes
int32_t ret;
struct MipiCfg cfg;
memset(&cfg, 0, sizeof(struct MipiCfg));
ret = MipiDsiGetCfg(mipiDsiHandle, &cfg);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: GetMipiCfg fail!\n", __func__);
return HDF_FAILURE;
}
```
### Sending/Receiving the Pointer to a Command<a name="section199401342173415"></a> - Call **MipiDsiSetCfg()** to set MIPI DSI attributes.
- Send the pointer to a specified command by calling the following function: ```
int32_t MipiDsiSetCfg(DevHandle handle, struct MipiCfg *cfg);
int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); ```
**Table 5** Description of **MipiDsiTx** **Table 3** Description of MipiDsiSetCfg
<a name="table1018490043"></a> | **Parameter**| **Description**|
<table><thead align="left"><tr id="row31848013417"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1415816132411"><a name="p1415816132411"></a><a name="p1415816132411"></a><strong id="b1280873492913"><a name="b1280873492913"></a><a name="b1280873492913"></a>Parameter</strong></p> | -------- | -------- |
</th> | handle | MIPI DSI device handle.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p11158111316410"><a name="p11158111316410"></a><a name="p11158111316410"></a><strong id="b1461953592915"><a name="b1461953592915"></a><a name="b1461953592915"></a>Description</strong></p> | cfg | Pointer to the buffer that stores the MIPI DSI configuration.|
</th> | **Return Value**| **Description**|
</tr> | 0 | The operation is successful.|
</thead> | Negative value| The operation failed.|
<tbody><tr id="row10184701945"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p104891871157"><a name="p104891871157"></a><a name="p104891871157"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p204891671156"><a name="p204891671156"></a><a name="p204891671156"></a>MIPI DSI device handle.</p>
</td>
</tr>
<tr id="row928111518418"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p4282955412"><a name="p4282955412"></a><a name="p4282955412"></a>cmd</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p7282752412"><a name="p7282752412"></a><a name="p7282752412"></a>Pointer to the command to be sent.</p>
</td>
</tr>
<tr id="row17393154515328"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p8158313248"><a name="p8158313248"></a><a name="p8158313248"></a><strong id="b969917374296"><a name="b969917374296"></a><a name="b969917374296"></a>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p161591413741"><a name="p161591413741"></a><a name="p161591413741"></a><strong id="b1351140142912"><a name="b1351140142912"></a><a name="b1351140142912"></a>Description</strong></p>
</td>
</tr>
<tr id="row339324593215"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p103191916578"><a name="p103191916578"></a><a name="p103191916578"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1231981611712"><a name="p1231981611712"></a><a name="p1231981611712"></a>Succeeded in sending the specified command.</p>
</td>
</tr>
<tr id="row15393184519323"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p531916166716"><a name="p531916166716"></a><a name="p531916166716"></a>Negative value</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p93191161174"><a name="p93191161174"></a><a name="p93191161174"></a>Failed to send the specified command.</p>
</td>
</tr>
</tbody>
</table>
```
int32_t ret; ```
struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); int32_t ret;
if (cmd == NULL) { struct MipiCfg cfg = {0};
return HDF_FAILURE;
} /* The display device configuration is as follows: */
cmd->dtype = DTYPE_DCS_WRITE; cfg.lane = DSI_4_LANES;
cmd->dlen = 1; cfg.mode = DSI_CMD_MODE;
cmd->payload = OsalMemCalloc(sizeof(uint8_t)); cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS;
if (cmd->payload == NULL) { cfg.format = FORMAT_RGB_24_BIT;
HdfFree(cmd); cfg.pixelClk = 174;
return HDF_FAILURE; cfg.phyDataRate = 384;
} cfg.timingInfo.hsaPixels = 50;
*(cmd->payload) = DTYPE_GEN_LWRITE; cfg.timingInfo.hbpPixels = 55;
MipiDsiSetLpMode(mipiHandle); cfg.timingInfo.hlinePixels = 1200;
ret = MipiDsiTx(mipiHandle, cmd); cfg.timingInfo.yResLines = 1800;
MipiDsiSetHsMode(mipiHandle); cfg.timingInfo.vbpLines = 33;
if (ret != HDF_SUCCESS) { cfg.timingInfo.vsaLines = 76;
HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret); cfg.timingInfo.vfpLines = 120;
HdfFree(cmd->payload); cfg.timingInfo.xResPixels = 1342;
HdfFree(cmd); /* Set the display device configuration. */
return HDF_FAILURE; ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
} if (ret != 0) {
HdfFree(cmd->payload); HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
HdfFree(cmd); return -1;
``` }
```
- Call **MipiDsiGetCfg()** to obtain the MIPI DSI configuration.
```
int32_t MipiDsiGetCfg(DevHandle handle, struct MipiCfg *cfg);
```
**Table 4** Description of MipiDsiGetCfg
| **Parameter**| **Description**|
| -------- | -------- |
| handle | MIPI DSI device handle.|
| cfg | Pointer to the buffer that stores the MIPI DSI configuration.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative value| The operation failed.|
- Receive a specified command by calling the following function:
```
int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); int32_t ret;
struct MipiCfg cfg;
**Table 6** Description of **MipiDsiRx** memset(&cfg, 0, sizeof(struct MipiCfg));
ret = MipiDsiGetCfg(mipiDsiHandle, &cfg);
<a name="table223910318361"></a> if (ret != HDF_SUCCESS) {
<table><thead align="left"><tr id="row924033173613"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p16240143143611"><a name="p16240143143611"></a><a name="p16240143143611"></a><strong id="b19809334172910"><a name="b19809334172910"></a><a name="b19809334172910"></a>Parameter</strong></p> HDF_LOGE("%s: GetMipiCfg fail!\n", __func__);
</th> return HDF_FAILURE;
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p32401031113610"><a name="p32401031113610"></a><a name="p32401031113610"></a><strong id="b4620163552915"><a name="b4620163552915"></a><a name="b4620163552915"></a>Description</strong></p> }
</th> ```
</tr>
</thead>
<tbody><tr id="row024043193619"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p16231153542520"><a name="p16231153542520"></a><a name="p16231153542520"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p122311535122518"><a name="p122311535122518"></a><a name="p122311535122518"></a>MIPI DSI device handle.</p>
</td>
</tr>
<tr id="row192401331163613"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p8706172453614"><a name="p8706172453614"></a><a name="p8706172453614"></a>cmd</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p0706424183610"><a name="p0706424183610"></a><a name="p0706424183610"></a>Pointer to the command to be received.</p>
</td>
</tr>
<tr id="row12646535173616"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p16465359364"><a name="p16465359364"></a><a name="p16465359364"></a>readLen</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p564617356360"><a name="p564617356360"></a><a name="p564617356360"></a>Length of the data to read.</p>
</td>
</tr>
<tr id="row919916426361"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p11199942153616"><a name="p11199942153616"></a><a name="p11199942153616"></a>out</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p91991042143618"><a name="p91991042143618"></a><a name="p91991042143618"></a>Pointer to the read data.</p>
</td>
</tr>
<tr id="row14240133143619"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1723253542518"><a name="p1723253542518"></a><a name="p1723253542518"></a><strong id="b47011237142916"><a name="b47011237142916"></a><a name="b47011237142916"></a>Return Value</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p223217356253"><a name="p223217356253"></a><a name="p223217356253"></a><strong id="b15616408294"><a name="b15616408294"></a><a name="b15616408294"></a>Description</strong></p>
</td>
</tr>
<tr id="row424093120369"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1123203518257"><a name="p1123203518257"></a><a name="p1123203518257"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p62324353251"><a name="p62324353251"></a><a name="p62324353251"></a>Succeeded in receiving the specified command.</p>
</td>
</tr>
<tr id="row18241531153610"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p42321635122517"><a name="p42321635122517"></a><a name="p42321635122517"></a>Negative value</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p323283510252"><a name="p323283510252"></a><a name="p323283510252"></a>Failed to receive the specified command.</p>
</td>
</tr>
</tbody>
</table>
```
int32_t ret;
uint8_t readVal = 0;
struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); ### Sending Commands or Reading Data
if (cmdRead == NULL) {
return HDF_FAILURE;
}
cmdRead->dtype = DTYPE_DCS_READ;
cmdRead->dlen = 1;
cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
if (cmdRead->payload == NULL) {
HdfFree(cmdRead);
return HDF_FAILURE;
}
*(cmdRead->payload) = DDIC_REG_STATUS;
MipiDsiSetLpMode(mipiDsiHandle);
ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal);
MipiDsiSetHsMode(mipiDsiHandle);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
HdfFree(cmdRead->payload);
HdfFree(cmdRead);
return HDF_FAILURE;
}
HdfFree(cmdRead->payload);
HdfFree(cmdRead);
```
### Releasing the MIPI DSI Device Handle<a name="section161011610357"></a> - Call **MipiDsiTx()** to send commands.
```
int32_t MipiDsiTx(PalHandle handle, struct DsiCmdDesc *cmd);
```
**Table 5** Description of MipiDsiTx
| **Parameter**| **Description**|
| -------- | -------- |
| handle | MIPI DSI device handle.|
| cmd | Pointer to the commands to send.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative value| The operation failed.|
After the MIPI DSI communication, release the MIPI DSI device handle by calling the following function:
```
int32_t ret;
struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
if (cmd == NULL) {
return HDF_FAILURE;
}
cmd->dtype = DTYPE_DCS_WRITE;
cmd->dlen = 1;
cmd->payload = OsalMemCalloc(sizeof(uint8_t));
if (cmd->payload == NULL) {
HdfFree(cmd);
return HDF_FAILURE;
}
*(cmd->payload) = DTYPE_GEN_LWRITE;
MipiDsiSetLpMode(mipiHandle);
ret = MipiDsiTx(mipiHandle, cmd);
MipiDsiSetHsMode(mipiHandle);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret);
HdfFree(cmd->payload);
HdfFree(cmd);
return HDF_FAILURE;
}
HdfFree(cmd->payload);
HdfFree(cmd);
```
- Call **MipiDsiRx()** to read data of the specified length.
```
int32_t MipiDsiRx(DevHandle handle, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
```
**Table 6** Description of MipiDsiRx
| **Parameter**| **Description**|
| -------- | -------- |
| handle | MIPI DSI device handle.|
| cmd | Pointer to the commands.|
| readLen | Length of the data to read.|
| out | Pointer to the buffer that stores the data read.|
| **Return Value**| **Description**|
| 0 | The operation is successful.|
| Negative value| The operation failed.|
void MipiDsiClose\(DevHandle handle\);
```
int32_t ret;
uint8_t readVal = 0;
struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
if (cmdRead == NULL) {
return HDF_FAILURE;
}
cmdRead->dtype = DTYPE_DCS_READ;
cmdRead->dlen = 1;
cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
if (cmdRead->payload == NULL) {
HdfFree(cmdRead);
return HDF_FAILURE;
}
*(cmdRead->payload) = DDIC_REG_STATUS;
MipiDsiSetLpMode(mipiDsiHandle);
ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal);
MipiDsiSetHsMode(mipiDsiHandle);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
HdfFree(cmdRead->payload);
HdfFree(cmdRead);
return HDF_FAILURE;
}
HdfFree(cmdRead->payload);
HdfFree(cmdRead);
```
### Closing a MIPI DSI Device Handle
Call **MipiDsiClose()** to close the MIPI DSI device handle after the operation is complete.
```
void MipiDsiClose(DevHandle handle);
```
This function releases the resources requested by **MipiDsiOpen**. This function releases the resources requested by **MipiDsiOpen**.
**Table 7** Description of **MipiDsiClose** **Table 7** Description of MipiDsiClose
<a name="table72517953115"></a>
<table><thead align="left"><tr id="row1525793312"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p115402031153111"><a name="p115402031153111"></a><a name="p115402031153111"></a><strong id="b1487612133120"><a name="b1487612133120"></a><a name="b1487612133120"></a>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p65406313319"><a name="p65406313319"></a><a name="p65406313319"></a><strong id="b6397192316313"><a name="b6397192316313"></a><a name="b6397192316313"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1926109193116"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p105419317318"><a name="p105419317318"></a><a name="p105419317318"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p132442255912"><a name="p132442255912"></a><a name="p132442255912"></a>MIPI DSI device handle.</p>
</td>
</tr>
</tbody>
</table>
| Parameter| Description|
| -------- | -------- |
| handle | MIPI DSI device handle.|
``` ```
MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */ MipiDsiClose(mipiHandle); /* Close the MIPI DSI device handle. */
``` ```
## Usage Example<a name="section17470126123520"></a>
## Development Example
The following is an example of using a MIPI DSI device: The following is an example of using a MIPI DSI device:
``` ```
#include "hdf.h" #include "hdf.h"
#include "mipi_dsi_if.h" #include "mipi_dsi_if.h"
...@@ -456,13 +285,13 @@ void PalMipiDsiTestSample(void) ...@@ -456,13 +285,13 @@ void PalMipiDsiTestSample(void)
/* Device channel ID */ /* Device channel ID */
chnId = 0; chnId = 0;
/* Obtain the MIPI DSI device handle based on a specified channel ID. */ /* Open the MIPI DSI device handle of the specified channel ID. */
mipiDsiHandle = MipiDsiOpen(chnId); mipiDsiHandle = MipiDsiOpen(chnId);
if (mipiDsiHandle == NULL) { if (mipiDsiHandle == NULL) {
HDF_LOGE("MipiDsiOpen: failed!\n"); HDF_LOGE("MipiDsiOpen: failed!\n");
return; return;
} }
/* MIPI DSI configuration parameters */ /* Set MIPI DSI attributes. */
struct MipiCfg cfg = {0}; struct MipiCfg cfg = {0};
cfg.lane = DSI_4_LANES; cfg.lane = DSI_4_LANES;
cfg.mode = DSI_CMD_MODE; cfg.mode = DSI_CMD_MODE;
...@@ -478,13 +307,13 @@ void PalMipiDsiTestSample(void) ...@@ -478,13 +307,13 @@ void PalMipiDsiTestSample(void)
cfg.timingInfo.vsaLines = 76; cfg.timingInfo.vsaLines = 76;
cfg.timingInfo.vfpLines = 120; cfg.timingInfo.vfpLines = 120;
cfg.timingInfo.xResPixels = 1342; cfg.timingInfo.xResPixels = 1342;
/* Set MIPI DSI configuration parameters. */ /* Write the configuration. */
ret = MipiDsiSetCfg(mipiDsiHandle, &cfg); ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
return; return;
} }
/* Send the command for initializing the PANEL register. */ /* Send the command for initializing the panel. */
struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc)); struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
if (cmd == NULL) { if (cmd == NULL) {
return; return;
...@@ -508,7 +337,7 @@ void PalMipiDsiTestSample(void) ...@@ -508,7 +337,7 @@ void PalMipiDsiTestSample(void)
} }
HdfFree(cmd->payload); HdfFree(cmd->payload);
HdfFree(cmd); HdfFree(cmd);
/* Pointer to the register that reads the PANEL status */ /* Read data from the panel register. */
uint8_t readVal = 0; uint8_t readVal = 0;
struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc)); struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
if (cmdRead == NULL) { if (cmdRead == NULL) {
...@@ -533,7 +362,7 @@ void PalMipiDsiTestSample(void) ...@@ -533,7 +362,7 @@ void PalMipiDsiTestSample(void)
} }
HdfFree(cmdRead->payload); HdfFree(cmdRead->payload);
HdfFree(cmdRead); HdfFree(cmdRead);
/* Release the MIPI DSI device handle. */ /* Close the MIPI CSI device handle. */
MipiDsiClose(handle); MipiDsiClose(handle);
} }
``` ```
\ No newline at end of file
# MIPI DSI<a name="EN-US_TOPIC_0000001199825369"></a> # MIPI DSI
## Overview<a name="section1266787503161538"></a> ## Overview
The Display Serial Interface \(DSI\) is a specification developed by the Mobile Industry Processor Interface \(MIPI\) Alliance to reduce the cost of display controllers in mobile devices. In the Hardware Driver Foundation (HDF) framework, the MIPI DSI module uses the service-free mode for API adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the OS system that does not distinguish the user mode and the kernel mode. In the service-free mode, **DevHandle** \(a void pointer\) directly points to the kernel-mode address of the device object. The Display Serial Interface (DSI) is a specification developed by the Mobile Industry Processor Interface (MIPI) Alliance to reduce the cost of display controllers in mobile devices. In the Hardware Driver Foundation (HDF), the MIPI DSI module uses the service-free mode for API adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the operating system (OS) that does not distinguish the user mode and the kernel mode. In the service-free mode, **DevHandle** (a void pointer) directly points to the kernel-mode address of the device object.
**Figure 1** Service-free mode<a name="fig207610236189"></a> **Figure 1** Service-free mode
![](figures/service-free-mode.png "service-free-mode")
## Available APIs<a name="section752964871810"></a> ![](figures/service-free-mode.png "service-free-mode")
MipiDsiCntlrMethod
## Available APIs
**MipiDsiCntlrMethod**:
``` ```
struct MipiDsiCntlrMethod {// Member functions of the core layer structure struct MipiDsiCntlrMethod { // Member functions of the core layer structure
int32_t (*setCntlrCfg)(struct MipiDsiCntlr *cntlr); int32_t (*setCntlrCfg)(struct MipiDsiCntlr *cntlr);
int32_t (*setCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd); int32_t (*setCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd);
int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out); int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
void (*toHs)(struct MipiDsiCntlr *cntlr); void (*toHs)(struct MipiDsiCntlr *cntlr);
void (*toLp)(struct MipiDsiCntlr *cntlr); void (*toLp)(struct MipiDsiCntlr *cntlr);
void (*enterUlps)(struct MipiDsiCntlr *cntlr);//(Optional) Enter the ultra-low power consumption mode. void (*enterUlps)(struct MipiDsiCntlr *cntlr);// (Optional) Enter the Ultra-Low Power State (ULPS).
void (*exitUlps)(struct MipiDsiCntlr *cntlr); // (Optional) Exit the ultra-low power consumption mode. void (*exitUlps)(struct MipiDsiCntlr *cntlr); // (Optional) Exit the ULPS.
int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control. int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control.
int32_t (*attach)(struct MipiDsiCntlr *cntlr);// (Optional) Connect a DSI device to the host. int32_t (*attach)(struct MipiDsiCntlr *cntlr);// (Optional) Attach a DSI device to the host.
}; };
``` ```
**Table 1** Callbacks for the members in the MipiDsiCntlrMethod structure **Table 1** Description of the callback functions in MipiDsiCntlrMethod
<a name="table218771071713"></a>
<table><thead align="left"><tr id="row1188121012177"><th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.1"><p id="p118851010174"><a name="p118851010174"></a><a name="p118851010174"></a>Callback</p>
</th>
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.2"><p id="p121881109177"><a name="p121881109177"></a><a name="p121881109177"></a>Input Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.3"><p id="p1818831011176"><a name="p1818831011176"></a><a name="p1818831011176"></a>Output Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.4"><p id="p1418815106171"><a name="p1418815106171"></a><a name="p1418815106171"></a>Return Value</p>
</th>
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.5"><p id="p10949971916"><a name="p10949971916"></a><a name="p10949971916"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row318920102175"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p01891103178"><a name="p01891103178"></a><a name="p01891103178"></a>setCntlrCfg</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1518931041716"><a name="p1518931041716"></a><a name="p1518931041716"></a><strong id="b14872821599"><a name="b14872821599"></a><a name="b14872821599"></a>cntlr</strong>: structure pointer to the MIPI DSI controller.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p51893103174"><a name="p51893103174"></a><a name="p51893103174"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p15189111019176"><a name="p15189111019176"></a><a name="p15189111019176"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p918911010174"><a name="p918911010174"></a><a name="p918911010174"></a>Sets controller parameters.</p>
</td>
</tr>
<tr id="row10189210151713"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p518991017171"><a name="p518991017171"></a><a name="p518991017171"></a>setCmd</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p177917412215"><a name="p177917412215"></a><a name="p177917412215"></a><strong id="b4791144113213"><a name="b4791144113213"></a><a name="b4791144113213"></a>cntlr</strong>: structure pointer to the MIPI DSI controller. </p>
<p id="p12189131018174"><a name="p12189131018174"></a><a name="p12189131018174"></a><strong id="b192414338012"><a name="b192414338012"></a><a name="b192414338012"></a>cmd</strong>: structure pointer to the input instruction.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p191891210111710"><a name="p191891210111710"></a><a name="p191891210111710"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p15189201019178"><a name="p15189201019178"></a><a name="p15189201019178"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p15190110141710"><a name="p15190110141710"></a><a name="p15190110141710"></a>Sends instructions to a display device.</p>
</td>
</tr>
<tr id="row2190161061714"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p111901810181715"><a name="p111901810181715"></a><a name="p111901810181715"></a>getCmd</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p121902101179"><a name="p121902101179"></a><a name="p121902101179"></a><strong id="b516432716114"><a name="b516432716114"></a><a name="b516432716114"></a>cntlr</strong>: structure pointer to the MIPI DSI controller.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p1519018101171"><a name="p1519018101171"></a><a name="p1519018101171"></a>cmd: structure pointer to the instruction to output.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p101904107171"><a name="p101904107171"></a><a name="p101904107171"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p519061031710"><a name="p519061031710"></a><a name="p519061031710"></a>Reads instructions from the display device.</p>
</td>
</tr>
<tr id="row1919071016171"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p16190131051710"><a name="p16190131051710"></a><a name="p16190131051710"></a>toHs</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p151906102178"><a name="p151906102178"></a><a name="p151906102178"></a><strong id="b159559351014"><a name="b159559351014"></a><a name="b159559351014"></a>cntlr</strong>: structure pointer to the MIPI DSI controller.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p10190181031720"><a name="p10190181031720"></a><a name="p10190181031720"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p019015102174"><a name="p019015102174"></a><a name="p019015102174"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p2190310101715"><a name="p2190310101715"></a><a name="p2190310101715"></a>Sets the high-speed mode.</p>
</td>
</tr>
<tr id="row01911510161718"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p10191141081717"><a name="p10191141081717"></a><a name="p10191141081717"></a>toLp</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p819121011714"><a name="p819121011714"></a><a name="p819121011714"></a><strong id="b189629351219"><a name="b189629351219"></a><a name="b189629351219"></a>cntlr</strong>: structure pointer to the MIPI DSI controller.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p3191510171717"><a name="p3191510171717"></a><a name="p3191510171717"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p8191110151714"><a name="p8191110151714"></a><a name="p8191110151714"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p1919121091712"><a name="p1919121091712"></a><a name="p1919121091712"></a>Sets the low-power mode.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section545182932161538"></a>
The MIPI DSI module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF\_INIT** to register the **HdfDriverEntry** instance with the HDF framework.
2. Configure attribute files.
- Add the **deviceNode** information to the **device\_info.hcs** file.
- \(Optional\) Add the **mipidsi\_config.hcs** file.
3. Instantiate the MIPI DSI controller object.
- Initialize **MipiDsiCntlr**.
- Instantiate **MipiDsiCntlrMethod** in the **MipiDsiCntlr** object.
For details, see [Available APIs](#available-apis). | Function| Input Parameter| Output Parameter| Return Value| Description|
| -------- | -------- | -------- | -------- | -------- |
| setCntlrCfg | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets controller parameters.|
| setCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>cmd: structure pointer to the commands to send.| –| HDF_STATUS| Sends commands to a display device.|
| getCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: pointer to the command description structure.<br>**readLen**: length of the data to read.| **out**: structure pointer to the data obtained.| HDF_STATUS| Reads data by sending commands.|
| toHs | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the high speed (HS) mode.|
| toLp | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the low power (LP) mode.|
4. \(Optional\) Debug the driver.
For new drivers, verify basic functions, for example, verify the information returned after the connect operation and whether data is successfully transmitted.
## How to Develop
The MIPI DSI module adaptation involves the following steps:
## Development Example<a name="section1167576616161538"></a> 1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Add the **deviceNode** description to the **device_info.hcs** file.
- (Optional) Add the **mipidsi_config.hcs** file.
3. Instantiate the MIPI DSI controller object.
- Initialize **MipiDsiCntlr**.
- Instantiate **MipiDsiCntlrMethod** in the **MipiDsiCntlr** object.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
> For details about the functions in **MipiDsiCntlrMethod**, see [Available APIs](#available-apis).
4. Debug the driver.
(Optional) For new drivers, verify basic functions, for example, check the information returned after the driver is attached and whether data is successfully transmitted.
## Development Example
The following uses **mipi_tx_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
1. Configure the device attributes in **xx_config.hcs** and add the **deviceNode** information to the **device_info.hcs** file. <br>The device attribute values are closely related to the default values or value range of the **MipiDsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, add the **deviceMatchAttr** information to **deviceNode** in the **device_info** file and add the **mipidsi_config** file.
**device_info.hcs** configuration example:
```
root {
device_info {
match_attr = "hdf_manager";
platform :: host {
hostName = "platform_host";
priority = 50;
device_mipi_dsi:: device {
device0 :: deviceNode {
policy = 0;
priority = 150;
permission = 0644;
moduleName = "HDF_MIPI_TX"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
serviceName = "HDF_MIPI_TX"; // (Mandatory) Unique name of the service published by the driver.
}
}
}
}
}
```
2. Instantiate the driver entry.<br/>The driver entry must be a global variable of the **HdfDriverEntry** type (defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. The function pointer members in the **HdfDriverEntry** structure are filled by the vendors' operation functions. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke.
Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
- MIPI DSI driver entry example
```
struct HdfDriverEntry g_mipiTxDriverEntry = {
.moduleVersion = 1,
.Init = Hi35xxMipiTxInit, // See the Init function.
.Release = Hi35xxMipiTxRelease, // See the Release function.
.moduleName = "HDF_MIPI_TX", // (Mandatory) The value must be the same as that in the device_info.hcs file.
};
HDF_INIT(g_mipiTxDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
```
The following uses **mipi\_tx\_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions. 3. Initialize the **MipiDsiCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init** and **Release**) to instantiate **MipiDsiCntlrMethod** in **MipiDsiCntlr** (so that the underlying driver functions can be called).
- Defining a custom structure
1. Generally, you need to configure the device attributes in **xx\_config.hcs** and add the **deviceNode** information to the **device\_info.hcs** file. The device attribute values are closely related to the default values or value range of the **MipiDsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration. To the driver, the custom structure holds parameters and data. Generally, the values in the **config** file are used to initialize the structure members. However, in this example, the MIPI DSI has no device attribute file. Therefore, the basic member structure is similar to that of **MipiDsiCntlr**.
In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, you need to add the **deviceMatchAttr** information to **deviceNode** in the **device\_info** file and add the **mipidsi\_config** file.
```
typedef struct {
unsigned int devno; // Device number
short laneId[LANE_MAX_NUM]; // Lane ID
OutPutModeTag outputMode; // Output mode, which can be CSI mode, DSI Video mode, or DSI Command mode.
VideoModeTag videoMode; // Synchronization mode of the display device
OutputFormatTag outputFormat; // Format of the output DSI image, which can be RGB or YUV.
SyncInfoTag syncInfo; // Settings related to timing
unsigned int phyDataRate; // Data rate, in Mbit/s
unsigned int pixelClk; // Clock, in kHz
} ComboDevCfgTag;
// MipiDsiCntlr is the controller structure at the core layer. The Init function assigns values to the members of MipiDsiCntlr.
struct MipiDsiCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
unsigned int devNo; // Device number
struct MipiCfg cfg;
struct MipiDsiCntlrMethod *ops;
struct OsalMutex lock;
void *priv;
};
```
- Instantiating **MipiDsiCntlrMethod** in **MipiDsiCntlr** (other members are initialized by **Init**)
- **device\_info.hcs** configuration reference
```
static struct MipiDsiCntlrMethod g_method = {
.setCntlrCfg = Hi35xxSetCntlrCfg,
.setCmd = Hi35xxSetCmd,
.getCmd = Hi35xxGetCmd,
.toHs = Hi35xxToHs,
.toLp = Hi35xxToLp,
};
```
- **Init** function
``` **Input parameter**:
root {
device_info {
match_attr = "hdf_manager";
platform :: host {
hostName = "platform_host";
priority = 50;
device_mipi_dsi:: device {
device0 :: deviceNode {
policy = 0;
priority = 150;
permission = 0644;
moduleName = "HDF_MIPI_TX"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry.
serviceName = "HDF_MIPI_TX";// (Mandatory) Unique name of the service published by the driver
}
}
}
}
}
```
2. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type \(defined in **hdf\_device\_desc.h**\), and the value of **moduleName** must be the same as that in **device\_info.hcs**. The function pointer members of the **HdfDriverEntry** structure are filled by the vendors' operation functions. In the HDF framework, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke. **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Generally, HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, HDF calls **Release** to release driver resources and exits. **Return value**:
- MIPI DSI driver entry reference HDF_STATUS<br>The table below lists some status. For more information, see HDF_STATUS in the /drivers/framework/include/utils/hdf_base.h file.
```
struct HdfDriverEntry g_mipiTxDriverEntry = { | Status| Description|
.moduleVersion = 1, | -------- | -------- |
.Init = Hi35xxMipiTxInit, // See the Init function. | HDF_ERR_INVALID_OBJECT | Invalid object.|
.Release = Hi35xxMipiTxRelease, //See the Release function. | HDF_ERR_MALLOC_FAIL | Failed to allocate memory.|
.moduleName = "HDF_MIPI_TX", // (Mandatory) The value must be the same as that in the device_info.hcs file. | HDF_ERR_INVALID_PARAM | Invalid parameter.|
}; | HDF_ERR_IO | I/O error.|
HDF_INIT(g_mipiTxDriverEntry); // Call HDF_INIT to register the driver entry with the HDF framework. | HDF_SUCCESS | Operation successful.|
``` | HDF_FAILURE | Operation failed.|
3. Initialize the **MipiDsiCntlr** object at the core layer, including initializing the vendor custom structure \(transferring parameters and data\), instantiating **MipiDsiCntlrMethod** \(used to call underlying functions of the driver\) in **MipiDsiCntlr**, and implementing the **HdfDriverEntry** member functions \(**Bind**, **Init**, and **Release**\). **Function description**:
- Custom structure reference
To the driver, the custom structure carries parameters and data. The values in the **config** file are used to initialize the structure members. In this example, the MIPI DSI has no device attribute file. Therefore, the basic member structure is similar to that of **MipiDsiCntlr**. Attaches the **MipiDsiCntlrMethod** instance, calls **MipiDsiRegisterCntlr**, and performs other vendor-defined initialization operations.
```
typedef struct {
unsigned int devno; // Device number
short laneId[LANE_MAX_NUM]; // Lane ID
OutPutModeTag outputMode; // Output mode, which can be CSI mode, DSI Video mode, or DSI Command mode.
VideoModeTag videoMode; // Synchronization mode of the display device
OutputFormatTag outputFormat; // Format of the output DSI image, which can be RGB or YUV.
SyncInfoTag syncInfo; // Settings related to timing
unsigned int phyDataRate; // mbps
unsigned int pixelClk; // KHz
} ComboDevCfgTag;
// MipiDsiCntlr is the controller structure at the core layer. Its members are assigned with values by using the Init function.
struct MipiDsiCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
unsigned int devNo; // Device number
struct MipiCfg cfg;
struct MipiDsiCntlrMethod *ops;
struct OsalMutex lock;
void *priv;
};
```
- Instantiate the callback function structure **MipiDsiCntlrMethod** in **MipiDsiCntlr**. Other members are initialized by using the Init function.
```
static struct MipiDsiCntlrMethod g_method = {
.setCntlrCfg = Hi35xxSetCntlrCfg,
.setCmd = Hi35xxSetCmd,
.getCmd = Hi35xxGetCmd,
.toHs = Hi35xxToHs,
.toLp = Hi35xxToLp,
};
```
- Init function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return values:
HDF\_STATUS \(The following table lists some status. For details about other status, see **HDF\_STATUS** in the **//drivers/framework/include/utils/hdf\_base.h** file.\)
<a name="table344041707161538"></a>
<table><thead align="left"><tr id="row1205250994161538"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry1646623665161538p0"><a name="entry1646623665161538p0"></a><a name="entry1646623665161538p0"></a>Status (Value)</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry36551796161538p0"><a name="entry36551796161538p0"></a><a name="entry36551796161538p0"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1245832689161538"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry635453137161538p0"><a name="entry635453137161538p0"></a><a name="entry635453137161538p0"></a>HDF_ERR_INVALID_OBJECT</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1681554112161538p0"><a name="entry1681554112161538p0"></a><a name="entry1681554112161538p0"></a>Invalid object</p>
</td>
</tr>
<tr id="row86233502161538"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry2128705324161538p0"><a name="entry2128705324161538p0"></a><a name="entry2128705324161538p0"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1664050443161538p0"><a name="entry1664050443161538p0"></a><a name="entry1664050443161538p0"></a>Failed to allocate memory</p>
</td>
</tr>
<tr id="row230078441161538"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry325107899161538p0"><a name="entry325107899161538p0"></a><a name="entry325107899161538p0"></a>HDF_ERR_INVALID_PARAM</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry754791216161538p0"><a name="entry754791216161538p0"></a><a name="entry754791216161538p0"></a>Invalid parameter</p>
</td>
</tr>
<tr id="row20758403161538"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1970333605161538p0"><a name="entry1970333605161538p0"></a><a name="entry1970333605161538p0"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1122658595161538p0"><a name="entry1122658595161538p0"></a><a name="entry1122658595161538p0"></a>I/O error</p>
</td>
</tr>
<tr id="row1425117417161538"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1844298129161538p0"><a name="entry1844298129161538p0"></a><a name="entry1844298129161538p0"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry712326009161538p0"><a name="entry712326009161538p0"></a><a name="entry712326009161538p0"></a>Operation successful</p>
</td>
</tr>
<tr id="row1899574933161538"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1964112434161538p0"><a name="entry1964112434161538p0"></a><a name="entry1964112434161538p0"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1481231483161538p0"><a name="entry1481231483161538p0"></a><a name="entry1481231483161538p0"></a>Operation failed</p>
</td>
</tr>
</tbody>
</table>
Function description:
Connects to the **MipiDsiCntlrMethod** instance, calls **MipiDsiRegisterCntlr**, and performs other vendor-defined initialization operations.
```
static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
{
int32_t ret;
g_mipiTx.priv = NULL; // g_mipiTx is a global variable.
// static struct MipiDsiCntlr g_mipiTx {
// .devNo=0
// };
g_mipiTx.ops = &g_method;// Connect to the MipiDsiCntlrMethod instance.
ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
...
return MipiTxDrvInit(0); // (Mandatory) Device initialization customized by the vendor.
}
// mipi_dsi_core.c, core layer file. ```
int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device) static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
{ {
... int32_t ret;
// Define the global variable static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT]. g_mipiTx.priv = NULL; // g_mipiTx is a global variable defined.
if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) { // static struct MipiDsiCntlr g_mipiTx {
(void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock); // .devNo=0
(void)OsalMutexInit(&(cntlr->lock)); //};
g_mipiTx.ops = &g_method;// Attach the MipiDsiCntlrMethod instance.
ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
...
return MipiTxDrvInit(0); // (Mandatory) Device initialization customized by the vendor.
}
// mipi_dsi_core.c file
int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
{
...
// Define the global variable static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT].
if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
(void)OsalMutexInit(&(cntlr->lock));
g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// Initialize MipiDsiHandle.
g_mipiDsihandle[cntlr->devNo].priv = NULL;
cntlr->device = device; // Prerequisites for conversion between HdfDeviceObject and MipiDsiHandle.
device->service = &(cntlr->service); // Prerequisites for conversion between HdfDeviceObject and MipiDsiHandle.
cntlr->priv = NULL;
...
return HDF_SUCCESS;
}
...
return HDF_FAILURE;
}
```
- **Release** function
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**Return value**:
No value is returned.
**Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// Initialize MipiDsiHandle. ```
g_mipiDsihandle[cntlr->devNo].priv = NULL; static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device)
cntlr->device = device; // Enable conversion between HdfDeviceObject and MipiDsiHandle. {
device->service = &(cntlr->service); // Enable conversion between HdfDeviceObject and MipiDsiHandle. struct MipiDsiCntlr *cntlr = NULL;
cntlr->priv = NULL; ...
... cntlr = MipiDsiCntlrFromDevice(device);// A forced conversion from HdfDeviceObject to MipiDsiCntlr is involved.
return HDF_SUCCESS; // return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
} ...
... MipiTxDrvExit(; // (Mandatory) Release the resources occupied by the vendor's devices.
return HDF_FAILURE; MipiDsiUnregisterCntlr(&g_mipiTx); // Empty function
} g_mipiTx.priv = NULL;
``` HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
}
- Release function ```
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return values:
Function description:
Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF framework fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
```
static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device)
{
struct MipiDsiCntlr *cntlr = NULL;
...
cntlr = MipiDsiCntlrFromDevice(device);// A forced conversion from HdfDeviceObject to MipiDsiCntlr is involved.
//return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
...
MipiTxDrvExit(); // (Mandatory) Release the resources occupied by the vendor's devices.
MipiDsiUnregisterCntlr(&g_mipiTx); // Empty function
g_mipiTx.priv = NULL;
HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
}
```
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## Overview ## Overview
In the Hardware Driver Foundation (HDF), the MultiMedia Card (MMC) uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device to increase memory resources. In the Hardware Driver Foundation (HDF), the MultiMedia Card (MMC) uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
**Figure 1** Independent service mode **Figure 1** Independent service mode
...@@ -76,7 +76,7 @@ The MMC module adaptation involves the following steps: ...@@ -76,7 +76,7 @@ The MMC module adaptation involves the following steps:
4. Debug the driver. 4. Debug the driver.
(Optional) For new drivers, verify the basic functions, for example, verify the information returned after the **MmcCntlrOps** instance is attached and whether the device starts successfully. (Optional) For new drivers, verify the basic functions, for example, check the information returned after the **MmcCntlrOps** instance is attached and whether the device starts successfully.
## Development Example ## Development Example
...@@ -202,7 +202,7 @@ The following uses **himci.c** as an example to present the information required ...@@ -202,7 +202,7 @@ The following uses **himci.c** as an example to present the information required
3. Initialize the **MmcCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **MmcCntlrOps** in **MmcCntlr** (so that the underlying driver functions can be called). 3. Initialize the **MmcCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **MmcCntlrOps** in **MmcCntlr** (so that the underlying driver functions can be called).
- Defining a custom structure - Defining a custom structure
To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **mmc_config.hcs** file to initialize the members in the custom structure and pass important parameters to the **MmcCntlr** object at the core layer. To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **mmc_config.hcs** file to initialize the members in the custom structure and passes important parameters to the **MmcCntlr** object at the core layer.
``` ```
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Pulse width modulation (PWM) is a technology that digitally encodes analog signal levels and converts them into pulses. It can be used for motor control and backlight brightness adjustment. Pulse width modulation (PWM) is a technology that digitally encodes analog signal levels and converts 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: The PWM APIs provide a set of functions for operating a PWM device, including those for:
- Opening or closing a PWM device handle - Opening or closing a PWM device handle
- Setting the PWM period, signal ON-state time, and polarity - Setting the PWM period, signal ON-state time, and polarity
...@@ -70,8 +70,8 @@ DevHandle PwmOpen(uint32_t num); ...@@ -70,8 +70,8 @@ DevHandle PwmOpen(uint32_t num);
| -------- | -------- | | -------- | -------- |
| num | PWM device number. | | num | PWM device number. |
| **Return Value** | **Description** | | **Return Value** | **Description** |
| handle | Handle of the PWM device obtained.| | handle | The operation is successful. The handle of the PWM device obtained is returned.|
| NULL | The operation failed. | | NULL | The operation failed. |
Example: Open the device handle of PWM device 0. Example: Open the device handle of PWM device 0.
...@@ -187,13 +187,13 @@ int32_t PwmSetPeriod(DevHandle handle, uint32_t period); ...@@ -187,13 +187,13 @@ int32_t PwmSetPeriod(DevHandle handle, uint32_t period);
| period | PWM period to set, in ns.| | period | PWM period to set, in ns.|
| **Return Value**| **Description** | | **Return Value**| **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative number | The operation failed. | | Negative number | The operation fails. |
``` ```
int32_t ret; int32_t ret;
/* Set the PWM period to 50000000 ns.*/ /* Set the PWM period to 50000000 ns. */
ret = PwmSetPeriod(handle, 50000000); ret = PwmSetPeriod(handle, 50000000);
if (ret != 0) { if (ret != 0) {
/* Error handling. */ /* Error handling. */
...@@ -286,9 +286,9 @@ int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config); ...@@ -286,9 +286,9 @@ int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config);
``` ```
int32_t ret; int32_t ret;
struct PwmConfig pcfg; struct PwmConfig pcfg;
pcfg.duty = 25000000; /* Set the signal ON-state time to 25000000 ns. */ pcfg.duty = 25000000; /* Set the signal ON-state time to 25000000 ns. */
pcfg.period = 50000000; /* Set the PWM period to 50000000 ns. */ pcfg.period = 50000000; /* Set the PWM period to 50000000 ns. */
pcfg.number = 0; /* Generate square waves repeatedly. */ pcfg.number = 0; /* Generate square waves continuously. */
pcfg.polarity = PWM_INVERTED_POLARITY; /* Set the PWM polarity to PWM_INVERTED_POLARITY. */ pcfg.polarity = PWM_INVERTED_POLARITY; /* Set the PWM polarity to PWM_INVERTED_POLARITY. */
pcfg.status = PWM_ENABLE_STATUS; /* Set the running status to Enabled. */ pcfg.status = PWM_ENABLE_STATUS; /* Set the running status to Enabled. */
...@@ -345,7 +345,7 @@ void PwmTestSample(void) ...@@ -345,7 +345,7 @@ void PwmTestSample(void)
DevHandle handle = NULL; DevHandle handle = NULL;
struct PwmConfig pcfg; struct PwmConfig pcfg;
pcfg.duty = 20000000; /* Set the signal ON-state time to 20000000 ns. */ pcfg.duty = 20000000; /* Set the signal ON-state time to 20000000 ns. */
pcfg.period = 40000000; /* Set the PWM period to 40000000 ns. */ pcfg.period = 40000000; /* Set the PWM period to 40000000 ns. */
pcfg.number = 100; /* Generate 100 square waves. */ pcfg.number = 100; /* Generate 100 square waves. */
pcfg.polarity = PWM_NORMAL_POLARITY; /* Set the polarity to PWM_NORMAL_POLARITY. */ pcfg.polarity = PWM_NORMAL_POLARITY; /* Set the polarity to PWM_NORMAL_POLARITY. */
......
# PWM<a name="EN-US_TOPIC_0000001199714793"></a> # PWM
## Overview<a name="section1591602238164144"></a>
In the Hardware Driver Foundation \(HDF\), the Pulse Width Modulator \(PWM\) uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to handle external access requests. After receiving an access request from an API, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDF Device Manager can be directly used. However, you need to configure a device node for each device, which increases the memory usage. ## Overview
**Figure 1** Independent service mode<a name="fig983655084219"></a> In the Hardware Driver Foundation (HDF), the Pulse Width Modulator (PWM) uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
![](figures/independent-service-mode.png "independent-service-mode-10")
## Available APIs<a name="section752964871810"></a> **Figure 1** Independent service mode
PwmMethod ![image](figures/independent-service-mode.png "PWM independent service mode")
## Available APIs
**PwmMethod**:
``` ```
struct PwmMethod { struct PwmMethod {
int32_t (*setConfig)(struct PwmDev *pwm, struct PwmConfig *config); int32_t (*setConfig)(struct PwmDev *pwm, struct PwmConfig *config);
...@@ -19,322 +23,259 @@ struct PwmMethod { ...@@ -19,322 +23,259 @@ struct PwmMethod {
}; };
``` ```
**Table 1** Callbacks for the members in the PwmMethod structure **Table 1** Description of callback functions in PwmMethod
<a name="table11173154124311"></a> | Function| Input Parameter| Return Value| Description|
<table><thead align="left"><tr id="row2173441164311"><th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.1"><p id="p17174144144310"><a name="p17174144144310"></a><a name="p17174144144310"></a>Callback</p> | -------- | -------- | -------- | -------- |
</th> | setConfig | -**pwm**: structure pointer to the PWM controller at the core layer.<br>-**config**: structure pointer to the attributes to set.| HDF_STATUS| Sets attributes.|
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.2"><p id="p21751441154318"><a name="p21751441154318"></a><a name="p21751441154318"></a>Input Parameter</p> | open | **pwm**: structure pointer to the PWM controller at the core layer.| HDF_STATUS| Opens a device.|
</th> | close | **pwm**: structure pointer to the PWM controller at the core layer.| HDF_STATUS| Closes a device.|
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.3"><p id="p191751741144313"><a name="p191751741144313"></a><a name="p191751741144313"></a>Return Value</p>
</th>
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.4"><p id="p5175641154315"><a name="p5175641154315"></a><a name="p5175641154315"></a>Description</p> ## How to Develop
</th>
</tr>
</thead>
<tbody><tr id="row7175154144311"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p3900552134317"><a name="p3900552134317"></a><a name="p3900552134317"></a>setConfig</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p422655084417"><a name="p422655084417"></a><a name="p422655084417"></a><strong id="b25915520521"><a name="b25915520521"></a><a name="b25915520521"></a>pwm</strong>: structure pointer to the PWM controller at the core layer.</p>
<p id="p02275502443"><a name="p02275502443"></a><a name="p02275502443"></a><strong id="b138214155312"><a name="b138214155312"></a><a name="b138214155312"></a>config</strong>: structure pointer to the input attribute value.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p18176184112433"><a name="p18176184112433"></a><a name="p18176184112433"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p5176124164314"><a name="p5176124164314"></a><a name="p5176124164314"></a>Configures attributes.</p>
</td>
</tr>
<tr id="row217654124312"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p121761041144314"><a name="p121761041144314"></a><a name="p121761041144314"></a>open</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p2176941144314"><a name="p2176941144314"></a><a name="p2176941144314"></a><strong id="b53894825318"><a name="b53894825318"></a><a name="b53894825318"></a>pwm</strong>: structure pointer to the PWM controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1317694119435"><a name="p1317694119435"></a><a name="p1317694119435"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p376133118453"><a name="p376133118453"></a><a name="p376133118453"></a>Starts the device.</p>
</td>
</tr>
<tr id="row8176174110439"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p017684174314"><a name="p017684174314"></a><a name="p017684174314"></a>close</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p1217694118437"><a name="p1217694118437"></a><a name="p1217694118437"></a><strong id="b839310895317"><a name="b839310895317"></a><a name="b839310895317"></a>pwm</strong>: structure pointer to the PWM controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p16176104115437"><a name="p16176104115437"></a><a name="p16176104115437"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p10893332114514"><a name="p10893332114514"></a><a name="p10893332114514"></a>Stops the device.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section967396342164144"></a>
The PWM module adaptation involves the following steps: The PWM module adaptation involves the following steps:
1. Instantiate the driver entry. 1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure. - Instantiate the **HdfDriverEntry** structure.
- Call **HDF\_INIT** to register the **HdfDriverEntry** instance with the HDF. - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files. 2. Configure attribute files.
- Add the **deviceNode** information to the **device\_info.hcs** file. - Add the **deviceNode** description to the **device_info.hcs** file.
- \(Optional\) Add the **pwm\_config.hcs** file. - (Optional) Add the **pwm_config.hcs** file.
3. Instantiate the PWM controller object. 3. Instantiate the PWM controller object.
- Initialize **PwmDev**. - Initialize **PwmDev**.
- Instantiate **PwmMethod** in the **PwmDev** object. - Instantiate **PwmMethod** in the **PwmDev** object.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
For details, see [Available APIs](#available-apis). > For details about the functions in **PwmMethod**, see [Available APIs](#available-apis).
4. \(Optional\) Debug the driver. 4. Debug the driver.
For new drivers, verify the basic functions, such as the PWM control status and response to interrupts. (Optional) For new drivers, verify the basic functions, such as the PWM status control and response to interrupts.
## Development Example<a name="section1883877829164144"></a> ## Development Example
The following uses **pwm\_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions. The following uses **pwm_hi35xx.c** as an example to present the information required for implementing device functions.
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type \(defined in **hdf\_device\_desc.h**\), and the value of **moduleName** must be the same as that in **device\_info.hcs**. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke. 1. Instantiate the driver entry.<br/>The driver entry must be a global variable of the **HdfDriverEntry** type (defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke.
Generally, HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, HDF calls **Release** to release driver resources and exits. Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
- PWM driver entry reference PWM driver entry example:
``` ```
struct HdfDriverEntry g_hdfPwm = { struct HdfDriverEntry g_hdfPwm = {
.moduleVersion = 1, .moduleVersion = 1,
.moduleName = "HDF_PLATFORM_PWM",// (Mandatory) The value must be the same as that of moduleName in the .hcs file. .moduleName = "HDF_PLATFORM_PWM",// (Mandatory) The value must be the same as that of moduleName in the .hcs file.
.Bind = HdfPwmBind, .Bind = HdfPwmBind,
.Init = HdfPwmInit, .Init = HdfPwmInit,
.Release = HdfPwmRelease, .Release = HdfPwmRelease,
}; };
// Call HDF_INIT to register the driver entry with the HDF. // Call HDF_INIT to register the driver entry with the HDF.
HDF_INIT(g_hdfPwm); HDF_INIT(g_hdfPwm);
``` ```
2. Add the **deviceNode** information to the **device\_info.hcs** file and configure the device attributes in the **pwm\_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **PwmDev** members at the core layer. If there are multiple devices, you need to add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **pwm\_config** file. 2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **pwm_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **PwmDev** members at the core layer. If there are multiple devices, you need to add the **deviceNode** information to the **device_info** file and add the device attributes to the **pwm_config** file for each device.
- **device\_info.hcs** configuration reference - **device_info.hcs** configuration example
```
root { ```
device_info { root {
platform :: host { device_info {
hostName = "platform_host"; platform :: host {
priority = 50; hostName = "platform_host";
device_pwm :: device {// Configure an HDF device node for each PWM controller. Set this parameter only when there are multiple PWM controllers. priority = 50;
device0 :: deviceNode { device_pwm :: device {// Configure an HDF device node for each PWM controller.
policy = 1; // Publish kernel-mode services. device0 :: deviceNode {
priority = 80; // Driver startup priority policy = 1; // Publish kernel-mode services.
permission = 0644; // Permission to create device nodes for the driver priority = 80; // Driver startup priority
moduleName = "HDF_PLATFORM_PWM"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. permission = 0644; // Permission to create device nodes for the driver.
serviceName = "HDF_PLATFORM_PWM_0";// (Mandatory) Unique name of the service published by the driver moduleName = "HDF_PLATFORM_PWM"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
deviceMatchAttr = "hisilicon_hi35xx_pwm_0";// (Mandatory) Used to configure the private data of the controller. The value must be the same as the controller information in pwm_config.hcs. serviceName = "HDF_PLATFORM_PWM_0"; // (Mandatory) Unique name of the service published by the driver.
// For details about the controller information, see pwm_config.hcs. deviceMatchAttr = "hisilicon_hi35xx_pwm_0";// (Mandatory) Used to configure the private data of the controller.
} // The value must be the same as the controller information in pwm_config.hcs.
device1 :: deviceNode { }
policy = 1; device1 :: deviceNode {
priority = 80; policy = 1;
permission = 0644; priority = 80;
moduleName = "HDF_PLATFORM_PWM"; permission = 0644;
serviceName = "HDF_PLATFORM_PWM_1"; moduleName = "HDF_PLATFORM_PWM";
deviceMatchAttr = "hisilicon_hi35xx_pwm_1"; serviceName = "HDF_PLATFORM_PWM_1";
} deviceMatchAttr = "hisilicon_hi35xx_pwm_1";
} }
} }
} }
} }
``` }
```
- **pwm\_config.hcs** configuration reference - **pwm_config.hcs** configuration example
```
root { ```
platform { root {
pwm_config { platform {
template pwm_device {// (Mandatory) Template configuration. In the template, you can configure the common parameters shared by service nodes. pwm_config {
serviceName = ""; template pwm_device { // (Mandatory) Template configuration. In the template, you can configure the common parameters shared by service nodes.
match_attr = ""; serviceName = "";
num = 0; // (Mandatory) Device number match_attr = "";
base = 0x12070000; // (Mandatory) Used for address mapping num = 0; // (Mandatory) Device number
} base = 0x12070000; // (Mandatory) Used for address mapping
device_0x12070000 :: pwm_device { }
match_attr = "hisilicon_hi35xx_pwm_0";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs. device_0x12070000 :: pwm_device { // Add the HDF node and device node information for each device.
} match_attr = "hisilicon_hi35xx_pwm_0";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
device_0x12070020::pwm_device {// Set this parameter only when there are multiple devices. }
match_attr = "hisilicon_hi35xx_pwm_1"; device_0x12070020 :: pwm_device {
num = 1; match_attr = "hisilicon_hi35xx_pwm_1";
base = 0x12070020; // (Mandatory) Used for address mapping num = 1;
} base = 0x12070020; // (Mandatory) Used for address mapping
} }
} }
} }
``` }
```
3. Initialize the **PwmDev** object at the core layer, including initializing the vendor custom structure \(transferring parameters and data\), instantiating **PwmMethod** \(used to call underlying functions of the driver\) in **PwmDev**, and implementing the **HdfDriverEntry** member functions \(**Bind**, **Init**, and **Release**\). 3. Initialize the **PwmDev** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **PwmMethod** in **PwmDev** (so that the underlying driver functions can be called).
- Custom structure reference - Defining a custom structure
To the driver, the custom structure carries parameters and data. The values in the **pwm\_config.hcs** file are read by HDF, and the structure members are initialized through **DeviceResourceIface**. Some important values, such as the device number, are also passed to the objects at the core layer. To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **pwm_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number, to the **GpioCntlr** object at the core layer.
```
struct HiPwm {
struct PwmDev dev; // (Mandatory) Core layer structure
volatile unsigned char *base;
struct HiPwmRegs *reg; // Device attribute structure, which can be customized.
bool supportPolarity;
};
// PwmDev is the controller structure at the core layer. Its members are assigned with values by using the Init function.
struct PwmDev {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
struct PwmConfig cfg; // Attribute structure. For details, see the description of PwmConfig.
struct PwmMethod *method; // Hook function template
bool busy;
uint32_t num; // Device number
OsalSpinlock lock;
void *priv; // Private data. Generally, the start address of the custom structure is stored to facilitate invoking of the structure.
};
struct PwmConfig {
uint32_t duty; // Time (in ns) when a signal is in the on state.
uint32_t period; // Regular interval (in ns) of PWM
uint32_t number; // Number of consecutive PWMs
uint8_t polarity; // Polarity
// ------------------- | --------------
// PWM_NORMAL_POLARITY | Normal polarity
// PWM_INVERTED_POLARITY | Inverted polarity
//
uint8_t status; // Running status
// ------------------ | -----------------
// PWM_DISABLE_STATUS | Disabled
// PWM_ENABLE_STATUS | Enabled
};
```
- Instantiate the callback function structure **PwmMethod** in **PwmDev**. Other members are initialized by using the **Init** function.
```
// Example in pwm_hi35xx.c: fill the hook function
struct PwmMethod g_pwmOps = {
.setConfig = HiPwmSetConfig,// Configure attributes.
};
```
- Init function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return values:
HDF\_STATUS \(The following table lists some status. For details about other status, see **HDF\_STATUS** in the **//drivers/framework/include/utils/hdf\_base.h** file.\)
<a name="table1057438215164144"></a>
<table><thead align="left"><tr id="row31521027164144"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry1990732428164144p0"><a name="entry1990732428164144p0"></a><a name="entry1990732428164144p0"></a>Status (Value)</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry2123581292164144p0"><a name="entry2123581292164144p0"></a><a name="entry2123581292164144p0"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1749271383164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry202330388164144p0"><a name="entry202330388164144p0"></a><a name="entry202330388164144p0"></a>HDF_ERR_INVALID_OBJECT</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1717598064164144p0"><a name="entry1717598064164144p0"></a><a name="entry1717598064164144p0"></a>Invalid controller object</p>
</td>
</tr>
<tr id="row1715354988164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry450625221164144p0"><a name="entry450625221164144p0"></a><a name="entry450625221164144p0"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry361497788164144p0"><a name="entry361497788164144p0"></a><a name="entry361497788164144p0"></a>Failed to allocate memory</p>
</td>
</tr>
<tr id="row1202091366164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry370837906164144p0"><a name="entry370837906164144p0"></a><a name="entry370837906164144p0"></a>HDF_ERR_INVALID_PARAM</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry353311523164144p0"><a name="entry353311523164144p0"></a><a name="entry353311523164144p0"></a>Invalid parameter</p>
</td>
</tr>
<tr id="row602018308164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1984036607164144p0"><a name="entry1984036607164144p0"></a><a name="entry1984036607164144p0"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1221756048164144p0"><a name="entry1221756048164144p0"></a><a name="entry1221756048164144p0"></a>I/O error</p>
</td>
</tr>
<tr id="row47997479164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1220816374164144p0"><a name="entry1220816374164144p0"></a><a name="entry1220816374164144p0"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1903499126164144p0"><a name="entry1903499126164144p0"></a><a name="entry1903499126164144p0"></a>Initialization successful</p>
</td>
</tr>
<tr id="row2031856197164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry463793674164144p0"><a name="entry463793674164144p0"></a><a name="entry463793674164144p0"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry516362874164144p0"><a name="entry516362874164144p0"></a><a name="entry516362874164144p0"></a>Initialization failed</p>
</td>
</tr>
</tbody>
</table>
Function description:
Initializes the custom structure object and **PwmDev**, and calls the **PwmDeviceAdd** function at the core layer.
```
// The bind function is empty. It can be combined with the init function or implement related operations based on the vendor's requirements.
static int32_t HdfPwmBind(struct HdfDeviceObject *obj)
{
(void)obj;
return HDF_SUCCESS;
}
static int32_t HdfPwmInit(struct HdfDeviceObject *obj)
{
int ret;
struct HiPwm *hp = NULL;
...
hp = (struct HiPwm *)OsalMemCalloc(sizeof(*hp));
...
ret = HiPwmProbe(hp, obj); // (Mandatory) The implementation is as follows:
...
return ret;
}
static int32_t HiPwmProbe(struct HiPwm *hp, struct HdfDeviceObject *obj) ```
{ struct HiPwm {
uint32_t tmp; struct PwmDev dev; // (Mandatory) Core layer structure
struct DeviceResourceIface *iface = NULL; volatile unsigned char *base;
struct HiPwmRegs *reg; // Device attribute structure, which can be customized.
bool supportPolarity;
};
// PwmDev is the controller structure at the core layer. The Init function assigns values to the members of PwmDev.
struct PwmDev {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
struct PwmConfig cfg; // Attribute structure. For details, see the description of PwmConfig.
struct PwmMethod *method; // Hook function template
bool busy;
uint32_t num; // Device number
OsalSpinlock lock;
void *priv; // Private data. Generally, the start address of the custom structure is stored to facilitate invoking of the structure.
};
struct PwmConfig {
uint32_t duty // Time that a signal is in the ON state, in ns.
uint32_t period; // Time for a signal to complete an on-and-off cycle, in ns.
uint32_t number; // Number of square waves to generate.
uint8_t polarity; // Polarity
// ------------------- | --------------
// PWM_NORMAL_POLARITY | Normal polarity
// PWM_INVERTED_POLARITY | Inverted polarity
//
uint8_t status; // Running status
// ------------------ | -----------------
// PWM_DISABLE_STATUS | Disabled
// PWM_ENABLE_STATUS | Enabled
};
```
- Instantiating **PwmMethod** in **PwmDev** (other members are initialized by **Init**)
iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);// Initialize the custom structure HiPwm. ```
... // The following uses pwm_hi35xx.c as an example. Fill the hook function.
struct PwmMethod g_pwmOps = {
hp->reg = (struct HiPwmRegs *)hp->base; // Initialize the custom structure HiPwm. .setConfig = HiPwmSetConfig,// Set attributes.
hp->supportPolarity = false; // Initialize the custom structure HiPwm. };
hp->dev.method = &g_pwmOps; // Connect to the instantiated object of PwmMethod. ```
hp->dev.cfg.duty = PWM_DEFAULT_DUTY_CYCLE; // Initialize PwmDev. - **Init** function
hp->dev.cfg.period = PWM_DEFAULT_PERIOD; // Initialize PwmDev.
hp->dev.cfg.polarity = PWM_DEFAULT_POLARITY; // Initialize PwmDev.
hp->dev.cfg.status = PWM_DISABLE_STATUS; // Initialize PwmDev.
hp->dev.cfg.number = 0; // Initialize PwmDev.
hp->dev.busy = false; // Initialize PwmDev.
if (PwmDeviceAdd(obj, &(hp->dev)) ) != HDF_SUCCESS) {// (Important) Call the core layer function to initialize the hp->dev devices and services.
OsalIoUnmap((void *)hp->base);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
```
- Release function **Input parameter**:
Input parameters: **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. **Return value**:
Return values: HDF_STATUS<br>The table below lists some status. For more information, see HDF_STATUS in the /drivers/framework/include/utils/hdf_base.h file.
| Status| Description|
| -------- | -------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object.|
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory.|
| HDF_ERR_INVALID_PARAM | Invalid parameter.|
| HDF_ERR_IO | I/O error.|
| HDF_SUCCESS | Initialization successful.|
| HDF_FAILURE | Initialization failed.|
Function description: **Function description**:
Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. Initializes the custom structure object and **PwmDev**, and calls the **PwmDeviceAdd** function at the core layer.
```
static void HdfPwmRelease(struct HdfDeviceObject *obj) ```
{ // The bind function is empty. It can be combined with the init function or implement related operations based on the vendor's requirements.
struct HiPwm *hp = NULL; static int32_t HdfPwmBind(struct HdfDeviceObject *obj)
... {
hp = (struct HiPwm *)obj->service;// A forced conversion from HdfDeviceObject to HiPwm is involved. (void)obj;
... return HDF_SUCCESS;
PwmDeviceRemove(obj, &(hp->dev));// (Mandatory) Call the core layer functions to release PwmDev devices and services. A forced conversion from HiPwm to PwmDev is involved in the process. }
HiPwmRemove(hp); //Release HiPwm.
} static int32_t HdfPwmInit(struct HdfDeviceObject *obj)
``` {
\ No newline at end of file int ret;
struct HiPwm *hp = NULL;
...
hp = (struct HiPwm *)OsalMemCalloc(sizeof(*hp));
...
ret = HiPwmProbe(hp, obj); // (Mandatory) The implementation is as follows:
...
return ret;
}
static int32_t HiPwmProbe(struct HiPwm *hp, struct HdfDeviceObject *obj)
{
uint32_t tmp;
struct DeviceResourceIface *iface = NULL;
iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);// Initialize the custom structure HiPwm.
...
hp->reg = (struct HiPwmRegs *)hp->base; // Initialize the custom structure HiPwm.
hp->supportPolarity = false; // Initialize the custom structure HiPwm.
hp->dev.method = &g_pwmOps; // Attach the PwmMethod instance.
hp->dev.cfg.duty = PWM_DEFAULT_DUTY_CYCLE; // Initialize PwmDev.
hp->dev.cfg.period = PWM_DEFAULT_PERIOD; // Initialize PwmDev.
hp->dev.cfg.polarity = PWM_DEFAULT_POLARITY; // Initialize PwmDev.
hp->dev.cfg.status = PWM_DISABLE_STATUS; // Initialize PwmDev.
hp->dev.cfg.number = 0; // Initialize PwmDev.
hp->dev.busy = false; // Initialize PwmDev.
if (PwmDeviceAdd(obj, &(hp->dev)) ) != HDF_SUCCESS) {// (Important) Call the core layer function to initialize hp->dev devices and services.
OsalIoUnmap((void *)hp->base);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
```
- **Release** function
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**Return value**:
No value is returned.
**Function description**:
Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
```
static void HdfPwmRelease(struct HdfDeviceObject *obj)
{
struct HiPwm *hp = NULL;
...
hp = (struct HiPwm *)obj->service;// A forced conversion from HdfDeviceObject to HiPwm is involved.
...
PwmDeviceRemove(obj, &(hp->dev));// (Mandatory) Call the core layer functions to release PwmDev devices and services. A forced conversion from HiPwm to PwmDev is involved in the process.
HiPwmRemove(hp); // Release HiPwm.
}
```
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## Overview ## Overview
The real-time clock (RTC) is a real-time clock device in the operating system. In the Hardware Driver Foundation (HDF), the RTC uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device to increase memory resources. The real-time clock (RTC) is a real-time clock device in the operating system. In the Hardware Driver Foundation (HDF), the RTC uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
**Figure 1** Independent service mode **Figure 1** Independent service mode
...@@ -192,7 +192,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information req ...@@ -192,7 +192,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information req
}; };
``` ```
- Bind function - **Bind** function
Input parameter: Input parameter:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册