diff --git a/en/device-dev/bundles/Readme-EN.md b/en/device-dev/bundles/Readme-EN.md
index 2ae8dc847c778c4cef4a191f56f5d3e107a2d1c7..b95e0adea8e0b365a0c1a7736a77c8a8a1643ac2 100644
--- a/en/device-dev/bundles/Readme-EN.md
+++ b/en/device-dev/bundles/Readme-EN.md
@@ -1,20 +1,11 @@
-# Bundle Development
-
-- [Development Specifications](development-specifications.md)
- - [Overview](overview.md)
- - [Bundle Composition](bundle-composition.md)
- - [Bundle Management](bundle-management.md)
- - [Bundle Version](bundle-version.md)
- - [Distribution](distribution.md)
- - [Environment Variables](environment-variables.md)
-
-- [Development Guidelines](development-guidelines.md)
- - [Overview](overview-0.md)
- - [Preparations](preparations.md)
- - [Bundle Development](bundle-development.md)
-
-- [HPM User Guide](hpm-user-guide.md)
- - [Introduction](introduction.md)
- - [Preparations](preparations-1.md)
- - [Development Example](development-example.md)
-
+# Bundle Development
+
+- [Development Specifications](bundles-standard-rules.md)
+- [Development Guidelines](bundles-guide.md)
+ - [Bundle Development](bundles-guide-overview.md)
+ - [Preparations](bundles-guide-prepare.md)
+ - [Bundle Development](bundles-guide-develop.md)
+- [HPM User Guide](bundles-demo.md)
+ - [Introduction](bundles-demo-hpmdescription.md)
+ - [Preparations](bundles-demo-environment.md)
+ - [Development Example](bundles-demo-devsample.md)
\ No newline at end of file
diff --git a/en/device-dev/bundles/bundle-composition.md b/en/device-dev/bundles/bundle-composition.md
deleted file mode 100644
index 754f38a7c428547cacc97f55d0042e6eae62bb75..0000000000000000000000000000000000000000
--- a/en/device-dev/bundles/bundle-composition.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Bundle Composition
-
-- [Code files](#section101483489110)
-- [README File](#section10519101221211)
-- [Metadata Description File](#section45511827111211)
-
-A bundle contains the following contents:
-
-- **src** directory for storing code files or code library
-- **ohos\_bundles** folder for storing dependent bundles \(It is automatically generated during bundle installation, without the need to submit to the code library.\)
-- **README.md** file for describing the bundle
-- **bundle.json** file for declaring metadata of the bundle
-- **LICENSE** file for open-source code
-
- ```
- my-bundle
- |_ohos_bundles
- |_src
- |_bundle.json
- |_README.md
- |_LICENSE
- ```
-
-
-## Code files
-
-Bundle code files are the same as those in a common code directory. The only difference lies in the open APIs \(declared in header files\) of a bundle, which are likely to be referenced by other bundles and need to be declared in the **dirs** of **bundle.json**.
-
-## README File
-
-**README.md** is a bundle self-description file using the markdown syntax. For details, see [Syntax Reference](https://www.markdownguide.org/getting-started/).
-
-To help you easily find and use the desired bundle on the HarmonyOS Package Manager \(HPM\) platform, a **README** file is provided in the root directory of each bundle.
-
-The **README** file may include instructions on how to install, configure, and use the instance code in the bundle, as well as any other information helpful to you.
-
-The **README** file is available in the bundle details page of the HPM platform.
-
-## Metadata Description File
-
-A **bundle.json** file describes the metadata of a bundle. Each bundle has its own **bundle.json** file.
-
-```
-{
- "name": "@myorg/demo-bundle",
- "version": "1.0.0",
- "license": "MIT",
- "description": "bundle description",
- "keywords": ["hos"],
- "tags": ["applications", "drivers"],
- "author": {"name":"","email":"","url":""},
- "contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}],
- "homepage": "http://www.foo.bar.com",
- "repository": "https://git@gitee.com:foo/bar.git",
- "publishAs": "source",
- "dirs": {
- "src": ["src/**/*.c"],
- "headers": ["headers/**/*.h"],
- "bin": ["bin/**/*.o"]
- },
- "scripts": {
- "build": "make"
- },
- "envs": {},
- "ohos": {
- "os": "2.0.0",
- "board": "hi3516",
- "kernel": "liteos-a"
- },
- "rom": "10240",
- "ram": "1024",
- "dependencies": {
- "@myorg/net":"1.0.0"
- }
-}
-```
-
-Each **bundle.json** file has the following fields:
-
-- **name**: a bundle name, which starts with @ and is separated by /, for example, **@myorg/mybundle**
-
-- **version**: a bundle version number, for example, 1.0.0. The version number must comply with the Semantic Versioning Specification \(SemVer\) standards.
-
-- **description**: a brief description of a bundle
-- **dependencies**: bundles that a bundle depends on
-
-- **envs**: parameters required for bundle compilation, including global parameters and dependency parameters.
-
-- **scripts**: commands executable to a bundle, such as those for compiling, building, testing, and burning
-
-- **publishAs**: bundle publishing type, which can be **source**, **binary**, **distribution**, or **code-segment**
-
-- **dirs**: directory structure \(such as the header file\) generated for publishing
-
-- **ram&rom**: statistical information about the estimated read-only memory \(ROM\) and random access memory \(RAM\) usage
-- **ohos**: mappings among OpenHarmony versions, development boards, and kernels, separated by commas \(,\).
-- Extended information: author, home page, code repository, license, tags, and keywords
-- **base** \(only for a distribution\): a base distribution which others inherit from.
-
diff --git a/en/device-dev/bundles/bundle-version.md b/en/device-dev/bundles/bundle-version.md
deleted file mode 100644
index d07118d86a36d626e1ba8a04112560d4fb25d4ad..0000000000000000000000000000000000000000
--- a/en/device-dev/bundles/bundle-version.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Bundle Version
-
-- [Version Number Naming Specifications](#section16893854141310)
-- [Version Publishing](#section43401320171420)
-
-## Version Number Naming Specifications
-
-Each version name allows only lowercase letters, which can be separated by hyphens \(-\) or underscores \(\_\). For example, **bundle** and **my\_bundle** are allowed.
-
-A bundle version number is in the format of _major version number_._minor version number_._revision version number_ or _major version number_._minor version number_._revision version number_-_pre-release version number_, for example, **1.0.0** and **1.0.0-beta**. For details, see [https://semver.org](https://semver.org/).
-
-## Version Publishing
-
-You should upload bundles to the remote repository so that your peers have an option to use them. You can run the following command to upload the bundles:
-
-```
-hpm publish
-```
-
-After this command is executed, the system checks the bundle dependencies and downloads the missing dependencies. If the bundles you uploaded are in binary, the system compiles the entire bundle, generates a binary file, packs the file, and uploads it. If the bundles you uploaded are in another format, the system packs the bundle file in compliance with the defined packing rules and then uploads the file.
-
-Note: To publish a bundle, you need an HPM account for login. After logging in to the HPM platform, register with an organization and apply for authentication. After successful authentication, you will have the permission to publish the bundle.
-
diff --git a/en/device-dev/bundles/development-example.md b/en/device-dev/bundles/bundles-demo-devsample.md
similarity index 95%
rename from en/device-dev/bundles/development-example.md
rename to en/device-dev/bundles/bundles-demo-devsample.md
index 159de560311c2fe03fd03c947fbfa669c060f3fa..4b896d4811456deb410fab4abbab7baac6e2493c 100644
--- a/en/device-dev/bundles/development-example.md
+++ b/en/device-dev/bundles/bundles-demo-devsample.md
@@ -28,7 +28,7 @@ This following uses the Hi3861 platform as an example to describe how to install
Installed.
```
- > **NOTE:**
+ > **NOTE:**
>Run the following command for the Hi3516 platform:
>```
>hpm install @ohos/ip_camera_hi3516dv300
diff --git a/en/device-dev/bundles/preparations-1.md b/en/device-dev/bundles/bundles-demo-environment.md
similarity index 91%
rename from en/device-dev/bundles/preparations-1.md
rename to en/device-dev/bundles/bundles-demo-environment.md
index 6a0981f81bc1c1562946a9f1987eaabc30b50439..6780aa705ee1b918dd9f6d748c286b0deae34476 100644
--- a/en/device-dev/bundles/preparations-1.md
+++ b/en/device-dev/bundles/bundles-demo-environment.md
@@ -25,7 +25,7 @@ ln -s bash /bin/sh
## Node.js
-> **NOTE:**
+> **NOTE:**
>If the Node.js version of the source is outdated, run the following command before running **apt-get install**:
>```
>curl -L https://deb.nodesource.com/setup_12.x | bash
@@ -68,7 +68,7 @@ http_proxy = http://your-proxy-server:port # Configure the HTTP proxy.
https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy.
```
-For details about **hpm-cli** commands, see [HPM Commands](bundle-management.md).
+For details about **hpm-cli** commands, see [HPM Commands](bundles-standard-rules.md).
## Python Environment
@@ -81,7 +81,7 @@ sudo pip3 install setuptools
sudo pip3 install kconfiglib # Install kconfiglib 13.2.0 or later.
```
-> **NOTE:**
+> **NOTE:**
>The preceding method is applicable to Hi3518 and Hi3516 platforms. For Hi3861, run the following commands to install the Python environment:
>```
>sudo apt-get install python3.8
@@ -112,7 +112,7 @@ which mcopy # If mcopy is not found, run the following command:
sudo apt-get install mtools
```
-> **NOTE:**
+> **NOTE:**
>Both Hi3518 and Hi3516 platforms require the file packaging tool. For Hi3861, the tool is not required.
## SCons
@@ -131,9 +131,9 @@ sudo apt-get install mtools
```
**Figure 1** Successful installation \(SCons version requirement: 3.0.4 or later\)
- .png "successful-installation-(scons-version-requirement-3-0-4-or-later)")
+ -25.png "successful-installation-(scons-version-requirement-3-0-4-or-later)-25")
-> **NOTE:**
+> **NOTE:**
>SCons is required for the Hi3861 platform, but not for the Hi3518 or Hi3516 platform.
diff --git a/en/device-dev/bundles/introduction.md b/en/device-dev/bundles/bundles-demo-hpmdescription.md
similarity index 100%
rename from en/device-dev/bundles/introduction.md
rename to en/device-dev/bundles/bundles-demo-hpmdescription.md
diff --git a/en/device-dev/bundles/bundles-demo.md b/en/device-dev/bundles/bundles-demo.md
new file mode 100644
index 0000000000000000000000000000000000000000..846d6b1bde058051ef3212edb3596a2d7ec22396
--- /dev/null
+++ b/en/device-dev/bundles/bundles-demo.md
@@ -0,0 +1,9 @@
+# HPM User Guide
+
+- **[Introduction](bundles-demo-hpmdescription.md)**
+
+- **[Preparations](bundles-demo-environment.md)**
+
+- **[Development Example](bundles-demo-devsample.md)**
+
+
diff --git a/en/device-dev/bundles/bundle-development.md b/en/device-dev/bundles/bundles-guide-develop.md
similarity index 96%
rename from en/device-dev/bundles/bundle-development.md
rename to en/device-dev/bundles/bundles-guide-develop.md
index 09330f69915d1cc850b0125a3e198e4f1c8c163f..d7f0fdad1f664ab9f46ffbee7f40e07ae024dffb 100644
--- a/en/device-dev/bundles/bundle-development.md
+++ b/en/device-dev/bundles/bundles-guide-develop.md
@@ -1,6 +1,6 @@
# Bundle Development
-- [Developing a OpenHarmony Bundle](#section1976410130540)
+- [Developing OpenHarmony Bundles](#section1976410130540)
- [Creating a Bundle](#section717481119145)
- [Modifying a Bundle](#section102861955201410)
- [Using HPM-provided Template to Create a Bundle](#section15882846181510)
@@ -13,13 +13,12 @@
- [Burning](#section1746331545413)
- [Debugging](#section6742131615549)
-## Developing a OpenHarmony Bundle
+## Developing OpenHarmony Bundles
-You have an option to use any of the following methods to develop an OpenHarmony bundle:
+You have an option to use any of the following methods to develop OpenHarmony bundles:
- Develop a brand new bundle from scratch.
- Rewrite code of an existing non-bundle to develop a bundle.
-
- Use HPM-provided bundle templates to quickly develop a bundle.
## Creating a Bundle
@@ -109,7 +108,7 @@ The HPM provides **default** and **simple** templates as well as other templ
You can run the **hpm search -t template** command to search for a template stored on the server.
-
+
Then, select your desired template based on the information below **description**, use the selected template to quickly create the bundle scaffold, and run the following command with the **-t** and **-d** parameters specified:
@@ -159,7 +158,7 @@ executable("hello_world") {
}
```
-> **NOTE:**
+> **NOTE:**
>- **executable** is a built-in template of **gn**. You can run the **gn help executable** command to view how to use this template.
>- **sources** represents the source code path, and **include\_dirs** represents the header file path.
@@ -173,7 +172,7 @@ hpm build
After all building operations are complete, the message "build succeed" is displayed. You need to check the building result.
-
+
## Defining a Distribution
diff --git a/en/device-dev/bundles/overview-0.md b/en/device-dev/bundles/bundles-guide-overview.md
similarity index 49%
rename from en/device-dev/bundles/overview-0.md
rename to en/device-dev/bundles/bundles-guide-overview.md
index 44fc41de4b49eaf811cc9b139d6751613452c21d..a6d16e00da5e950294612bc72454fe531fa3bbdf 100644
--- a/en/device-dev/bundles/overview-0.md
+++ b/en/device-dev/bundles/bundles-guide-overview.md
@@ -1,4 +1,16 @@
-# Overview
+# Bundle Development
+
+- [Overview](#section112136415486)
+- [Preparations](#section12731192104816)
+ - [Hardware Requirements](#section71851750144814)
+ - [Installing Node.js and the hpm-cli Tool](#section675199493)
+ - [\(Optional\) Modifying HPM Configurations](#section1940205015499)
+ - [Downloading OpenHarmony Code](#section42591118155217)
+ - [Installing Dependent Bundles](#section644212530524)
+
+- [Bundle Development](#section15640113715318)
+
+## Overview
This document describes how to develop OpenHarmony bundles and distributions, and how to create, develop, and build code, as well as burn and debug devices by using a command line tool.
@@ -50,5 +62,85 @@ This document describes how to develop OpenHarmony bundles and distributions, an
**Figure 1** Composition of bundles and distributions
-
+
+
+## Preparations
+
+### Hardware Requirements
+
+- Development boards \(examples: Hi3861, Hi3516D V300, and Hi3518E V300\)
+- Host computer \(Windows workstation\)
+- Linux server
+
+**Figure 2** Hardware connections
+
+
+### Installing **Node.js** and the **hpm-cli** Tool
+
+1. Install **Node.js**.
+
+ Download **Node.js** from its official website and install it on your local PC.
+
+ You are advised to install [Node.js](https://nodejs.org/) 12.x \(including npm 6.14.4\) or a later version \(12.13.0 or later is recommended\).
+
+2. Install the **hpm-cli** tool using **npm** delivered with **Node.js**. Run the following command:
+
+ ```
+ npm install -g @ohos/hpm-cli
+ ```
+
+3. Run the following command to check whether the installation is successful. If an HPM version is displayed, the installation is successful.
+
+ ```
+ hpm -V or hpm --version
+ ```
+
+4. \(Optional\) Run the following command to upgrade the HPM version if needed:
+
+ ```
+ npm update -g @ohos/hpm-cli
+ ```
+
+
+### \(Optional\) Modifying HPM Configurations
+
+After the **hpm-cli** tool is installed, run the following command to view HPM configurations:
+
+```
+hpm config
+```
+
+Default HPM configurations are displayed upon the command execution. You can modify the default configurations as required. The following lists common HPM configurations:
+
+```
+registry = https://hpm.harmonyos.com/hpm/registry/api # Configure the address of the HPM registry (mandatory for downloading bundles).
+login = https://hpm.harmonyos.com/hpm/auth/pk # Configure the address for HPM login (mandatory for publishing bundles).
+loginUser = {your-account} # Configure the account for HPM login (mandatory for publishing bundles).
+shellPath = C:\WINDOWS\System32\cmd.exe # Configure the shell for running HPM commands.
+globalRepo = C:\Users\yourname\.global # Configure the path for storing bundles that are installed globally.
+http_proxy = http://your-proxy-server:port # Configure the HTTP proxy.
+https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy.
+```
+
+For details about **hpm-cli** commands, see [HPM Commands](bundles-guide-overview.md).
+
+### Downloading OpenHarmony Code
+
+For details, see [Source Code Acquisition](../get-code/sourcecode-acquire.md).
+
+### Installing Dependent Bundles
+
+The HPM publishes commonly used development tools \(such as those for burning, compiling, and compression\) as bundles. You can run the following command to install these tools. After the command is executed, the system automatically downloads and installs the tools, which need to be installed globally only once.
+
+```
+hpm i -g @ohos/llvm
+hpm i -g @ohos/ninja
+hpm i -g @ohos/gn
+hpm i -g @ohos/hc_gen
+hpm i -g @ohos/sysroot
+```
+
+These are a set of development tools \(such as **gn** and **ninja**\). With these tools, you can start your general bundle development based on source code.
+
+## Bundle Development
diff --git a/en/device-dev/bundles/preparations.md b/en/device-dev/bundles/bundles-guide-prepare.md
similarity index 93%
rename from en/device-dev/bundles/preparations.md
rename to en/device-dev/bundles/bundles-guide-prepare.md
index dedd9b41f76f016fd1a33e1a407113feadabff7f..f706e2c2f8ebf2c8307e60a5595d53eb9799d1c1 100644
--- a/en/device-dev/bundles/preparations.md
+++ b/en/device-dev/bundles/bundles-guide-prepare.md
@@ -8,12 +8,12 @@
## Hardware Requirements
-- Development boards \(examples: Hi3861, Hi3516DV300, and Hi3518EV300\)
+- Development boards \(examples: Hi3861, Hi3516D V300, and Hi3518E V300\)
- Host computer \(Windows workstation\)
- Linux server
**Figure 1** Hardware connections
-
+
## Installing **Node.js** and the **hpm-cli** Tool
@@ -62,11 +62,11 @@ http_proxy = http://your-proxy-server:port # Configure t
https_proxy = http://your-proxy-server:port # Configure the HTTPS proxy.
```
-For details about **hpm-cli** commands, see [HPM Commands](bundle-management.md).
+For details about **hpm-cli** commands, see [HPM Commands](bundles-guide-overview.md).
## Downloading OpenHarmony Code
-For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
+For details, see [Source Code Acquisition](../get-code/sourcecode-acquire.md).
## Installing Dependent Bundles
diff --git a/en/device-dev/bundles/development-guidelines.md b/en/device-dev/bundles/bundles-guide.md
similarity index 30%
rename from en/device-dev/bundles/development-guidelines.md
rename to en/device-dev/bundles/bundles-guide.md
index 6ae82a8f668402df6a4b967fad4fb85af5f59eef..162b7be93ab12c2b1da404fd0fca89f6a3b6e4d4 100644
--- a/en/device-dev/bundles/development-guidelines.md
+++ b/en/device-dev/bundles/bundles-guide.md
@@ -1,9 +1,9 @@
# Development Guidelines
-- **[Overview](overview-0.md)**
+- **[Bundle Development](bundles-guide-overview.md)**
-- **[Preparations](preparations.md)**
+- **[Preparations](bundles-guide-prepare.md)**
-- **[Bundle Development](bundle-development.md)**
+- **[Bundle Development](bundles-guide-develop.md)**
diff --git a/en/device-dev/bundles/bundle-management.md b/en/device-dev/bundles/bundles-standard-rules.md
similarity index 42%
rename from en/device-dev/bundles/bundle-management.md
rename to en/device-dev/bundles/bundles-standard-rules.md
index 4511f3427ca7e4ba140bc844e3c4450fd545daf8..8adaac0e618ca9b141d52d7a4683a8ba3fa086ae 100644
--- a/en/device-dev/bundles/bundle-management.md
+++ b/en/device-dev/bundles/bundles-standard-rules.md
@@ -1,9 +1,162 @@
-# Bundle Management
+# Development Specifications
-- [Dependency](#section12657593129)
-- [HPM Command Reference](#section1258849181312)
+- [Overview](#section1725818533344)
+ - [Definition](#section4821219183514)
+ - [Bundle Division Principles](#section1089794263513)
+ - [Bundle Dependency](#section25701647163710)
-## Dependency
+- [Bundle Composition](#section185538333914)
+ - [Code Files](#section8431268393)
+ - [README File](#section168121548173914)
+ - [Metadata Description File](#section7107181819406)
+
+- [Bundle Management](#section32061634104110)
+ - [Dependency](#section791115242423)
+ - [HPM Command Reference](#section1183205411429)
+
+- [Bundle Version](#section12612142864316)
+ - [Version Number Naming Specifications](#section1487612416432)
+ - [Version Publishing](#section1548171014440)
+
+- [Distribution](#section1264139114413)
+- [Environment Variables](#section15352105174512)
+
+## Overview
+
+This document describes the basic concepts of a bundle and how to define it in compliance with specifications.
+
+### Definition
+
+OpenHarmony software is developed on a per-bundle basis. In terms of the operating system, all software running on OpenHarmony are bundles. Generally, bundles are classified into the following types based on their application scopes:
+
+- Board-level bundles: device hardware-specific bundles, such as **board**, **arch**, and **mcu**
+- System-level bundles: a set of bundles with independent features, such as the kernel, file system, and framework
+- Application-level bundles: applications that provide services to users, such as **wifi\_iot** and **ip\_camera**
+
+Bundles are designed for reuse purposes. Any reusable modules can be defined as bundles. They are classified into the following types based on their forms:
+
+- Source code
+- Binary system
+- Code snippet
+- Distribution
+
+### Bundle Division Principles
+
+In principle, bundles should be grouped at a fine-grained granularity as much as possible to achieve maximum reuse. The following factors are taken into account regarding bundle division:
+
+- Independence: Bundles provide relatively independent features and can be independently built. Each bundle is capable of providing its own APIs and services for external systems.
+- Coupling: If a bundle must depend on another bundle to provide services, they can be coupled to one bundle.
+- Correlation: If a group of bundles jointly implement a feature, and if other bundles never depend on them, the group of bundles can be combined into one bundle.
+
+### Bundle Dependency
+
+A bundle dependency can be mandatory or optional.
+
+- Mandatory dependency: If bundle A must depend on bundle B to implement a feature \(the APIs or services specific to bundle B must be invoked\), bundle B is a mandatory dependency of bundle A.
+- Optional dependency: If bundle C or bundle D is required for bundle A to implement a feature and bundle C and bundle D are interchangeable, bundle C and bundle D are optional dependencies of bundle A.
+
+## Bundle Composition
+
+A bundle contains the following:
+
+- **src** directory for storing code files or code library
+- **ohos\_bundles** folder for storing dependent bundles \(It is automatically generated during bundle installation, without the need to submit to the code library.\)
+- **README.md** file for describing the bundle
+- **bundle.json** file for declaring metadata of the bundle
+- **LICENSE** file for open-source code
+
+ ```
+ my-bundle
+ |_ohos_bundles
+ |_src
+ |_bundle.json
+ |_README.md
+ |_LICENSE
+ ```
+
+
+### Code Files
+
+Bundle code files are the same as those in a common code directory. The only difference lies in the open APIs \(declared in header files\) of a bundle, which are likely to be referenced by other bundles and need to be declared in **dirs** of **bundle.json**.
+
+### README File
+
+**README.md** is a bundle self-description file using the markdown syntax. For details, see [Syntax Reference](https://www.markdownguide.org/getting-started/).
+
+To help you easily find and use the desired bundle on the HarmonyOS Package Manager \(HPM\) platform, a **README** file is provided in the root directory of each bundle.
+
+The **README** file may include instructions on how to install, configure, and use the instance code in the bundle, as well as any other information helpful to you.
+
+The **README** file is available in the bundle details page of the HPM platform.
+
+### Metadata Description File
+
+The **bundle.json** file describes the metadata of a bundle. Each bundle has its own **bundle.json** file.
+
+```
+{
+ "name": "@myorg/demo-bundle",
+ "version": "1.0.0",
+ "license": "MIT",
+ "description": "bundle description",
+ "keywords": ["hos"],
+ "tags": ["applications", "drivers"],
+ "author": {"name":"","email":"","url":""},
+ "contributors":[{"name":"","email":"","url":""},{"name":"","email":"","url":""}],
+ "homepage": "http://www.foo.bar.com",
+ "repository": "https://git@gitee.com:foo/bar.git",
+ "publishAs": "code-segment",
+ "segment":{
+ "destPath":"/the/dest/path"
+ },
+ "dirs": {
+ "src": ["src/**/*.c"],
+ "headers": ["headers/**/*.h"],
+ "bin": ["bin/**/*.o"]
+ },
+ "scripts": {
+ "build": "make"
+ },
+ "envs": {},
+ "ohos": {
+ "os": "2.0.0",
+ "board": "hi3516",
+ "kernel": "liteos-a"
+ },
+ "rom": "10240",
+ "ram": "1024",
+ "dependencies": {
+ "@myorg/net":"1.0.0"
+ }
+}
+```
+
+Each **bundle.json** file has the following fields:
+
+- **name**: a bundle name, which starts with @ and is separated by /, for example, **@myorg/mybundle**
+
+- **version**: a bundle version number, for example, 1.0.0. The version number must comply with the Semantic Versioning Specification \(SemVer\) standards.
+
+- **description**: a brief description of a bundle
+- **dependencies**: bundles that a bundle depends on
+
+- **envs**: parameters required for bundle compilation, including global parameters and dependency parameters.
+
+- **scripts**: commands executable to a bundle, such as commands for compiling, building, testing, and burning
+
+- **publishAs**: bundle publishing type, which can be **source**, **binary**, **distribution**, or **code-segment**
+
+- **segment**: destination path of the code-segment bundle. That is, the destination path of the files contained in the bundle package after the bundle is installed.
+- **dirs**: directory structure \(such as the header file\) generated for publishing
+
+- **ram&rom**: statistical information about the estimated read-only memory \(ROM\) and random access memory \(RAM\) usage
+- **ohos**: mappings among OpenHarmony versions, development boards, and kernels, separated by commas \(,\).
+- Extended information: author, home page, code repository, license, tags, and keywords
+- **base** \(only for a distribution\): a base distribution which others inherit from.
+
+## Bundle Management
+
+### Dependency
A basic **bundle.json** file needs to be enriched by bundle dependencies to implement more complex features. Bundle names and version numbers should be defined in the **dependencies** field of **bundle.json**.
@@ -41,20 +194,20 @@ $ hpm list
| | +--@demo/dist_tools@4.0.0
```
-Alternatively, you can view the dependencies of the current bundle in a graph by running the following command:
+Alternatively, you can run the following command to view the dependencies of the current bundle in a visualized way:
```
-hpm dependencies
+hpm ui
```
-A **deps\_visual** folder is generated in the current directory. The folder contains the **deps.html** and **deps-data.js** files. After you open the **deps.html** file via a browser, you can view bundle dependencies illustrated by a graph, as shown in the following figure.
-
-Each dependency type is indicated by a different color at the corresponding node. You can move the mouse pointer to a node to view the implied information.
+A web service is started on the local host \(by default, the browser is open and the project page is displayed\). Click the project dependency icon on the sidebar. The list of dependent bundles is displayed. Click the button on the right to switch to the tree view. The bundle dependencies are displayed as shown in the following figure.
**Figure 1** Bundle dependencies
-
-## HPM Command Reference
+
+
+
+### HPM Command Reference
You can use the hpm-cli tool to manage the lifecycle of a bundle. The following table describes available HPM commands. \(You can run the **hpm -h** command to get the command details\).
@@ -63,7 +216,7 @@ You can use the hpm-cli tool to manage the lifecycle of a bundle. The following
int32_t DelFeature(struct WifiModule *module, uint16_t featureType);
@@ -118,7 +123,7 @@ The WLAN driver module provides APIs that can be directly called by driver devel
-The WLAN driver module provides APIs for driver developers, such as initializing/deregistering, opening/stopping a **NetDevice**, and obtaining the state of a **NetDevice**. [Table 2](#table74613501475) provides some APIs.
+The WLAN driver module provides APIs for driver developers, such as initializing/deregistering, opening/stopping a **NetDevice**, and obtaining the state of a **NetDevice**. [Table 2](#table74613501475) describes some APIs.
**Table 2** APIs for driver developers of WLAN vendors to implement
@@ -166,7 +171,7 @@ The WLAN driver module provides APIs for driver developers, such as initializing
-The WLAN driver provides the HDI layer with the APIs for creating and destroying an **IWiFi** object and setting the MAC address. [Table 3](#table141076311618) provides some APIs.
+The WLAN driver provides the HDI layer with the APIs for creating and destroying an **IWiFi** object and setting the MAC address. [Table 3](#table141076311618) describes some APIs.
**Table 3** APIs provided by the WLAN HAL module
@@ -227,3 +232,391 @@ The WLAN driver provides the HDI layer with the APIs for creating and destroying
+## Development Guidelines
+
+The WLAN driver is developed based on the HDF and PLATFORM. It provides a unified driver model for WLAN modules of different vendors regardless of the operating system \(OS\) and system on a chip \(SoC\).
+
+### How to Develop
+
+1. Set hardware parameters such as **module** \(different features\) and **chip** in the **wifi\_config.hcs** file.
+2. Parse the **wifi\_config.hcs** file and generate a structure with the configured parameters.
+3. Initialize and create a module.
+4. Mount and initialize the chip.
+5. Initialize the bus.
+6. Mount the upper-layer WPA service.
+
+> **NOTE:**
+>Some of the above adaptation steps have been provided. For details, see [Development Example](#section1395253612512). The steps waiting to be performed by developers include setting configuration parameters based on hardware attributes, adapting and mounting a chip, and performing tests and verification.
+
+## Development Example
+
+This example describes how to initialize a WLAN module. The following uses the Hi3881 WLAN chip as an example:
+
+1. Set parameters for the WLAN module based on hardware attributes.
+
+```
+/* Set parameters in the wlan_platform.hcs file based on hardware attributes. The following is an example of the WLAN platform configuration. */
+hisi :& deviceList {
+ device0 :: deviceInst {
+ deviceInstId = 0;
+ powers {
+ power0 {
+ powerSeqDelay = 0; /* Power supply sequencing delay */
+ powerType = 1; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through general-purpose input/output (GPIO). */
+ gpioId = 1; /* GPIO pin ID */
+ activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */
+ }
+ power1 {
+ powerSeqDelay = 0; /* Power supply sequencing delay */
+ powerType = 0; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through GPIO. */
+ }
+ }
+ reset {
+ resetType = 0; /* Reset type. Value 0 indicates that reset is not supported, and value 1 indicates reset through GPIO. */
+ gpioId = 2; /* GPIO pin ID */
+ activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */
+ resetHoldTime = 30; /* Hold time (ms) for a reset */
+ }
+ bootUpTimeout = 30; /* Boot timeout duration (ms) */
+ bus {
+ busType = 0; /* Bus type. Value 0 indicates secure digital input/output (SDIO). */
+ busId = 2; /* Bus ID */
+ funcNum = [1]; /* SDIO function number */
+ timeout = 1000; /* Timeout duration for data read/write */
+ blockSize = 512; /* Size of the data block to read or write */
+ }
+ }
+}
+/* Add the configuration file wlan_chip_.hcs (for example, wlan_chip_hi3881.hcs) for each chip and set parameters. The following uses the Hi3881 chip as an example. */
+root {
+ wlan_config {
+ hi3881 :& chipList {
+ chipHi3881 :: chipInst {
+ match_attr = "hdf_wlan_chips_hi3881"; /* Match attribute */
+ chipName = "hi3881"; /* WLAN chip name */
+ sdio {
+ vendorId = 0x0296; /* Vendor ID */
+ deviceId = [0x5347]; /* Device ID */
+ }
+ }
+ }
+ }
+}
+```
+
+2. Mount the **init** and **deinit** functions of the WLAN chip and WLAN chip driver.
+
+```
+/* WLAN module initialization and mount process */
+#include "hdf_device_desc.h"
+#include "hdf_wifi_product.h"
+#include "hdf_log.h"
+#include "osal_mem.h"
+#include "hdf_wlan_chipdriver_manager.h"
+#include "securec.h"
+#include "wifi_module.h"
+#include "hi_wifi_api.h"
+#include "hi_types_base.h"
+
+#define HDF_LOG_TAG Hi3881Driver
+
+/* Functions for initializing and deinitializing the WLAN chip */
+int32_t InitHi3881Chip(struct HdfWlanDevice *device);
+int32_t DeinitHi3881Chip(struct HdfWlanDevice *device);
+/* Functions for initializing and deinitializing the WLAN chip driver */
+int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
+int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
+
+/* Initialize mac80211 and mount functions of the chip. */
+hi_void HiMac80211Init(struct HdfChipDriver *chipDriver);
+
+static const char* const HI3881_DRIVER_NAME = "hisi";
+
+/* Mount the WLAN chip driver and the functions of mac80211 and the chip. */
+static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex)
+{
+ struct HdfChipDriver *specificDriver = NULL;
+ if (device == NULL) {
+ HDF_LOGE("%s fail : channel is NULL", __func__);
+ return NULL;
+ }
+ (void)device;
+ (void)ifIndex;
+ specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver));
+ if (specificDriver == NULL) {
+ HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__);
+ return NULL;
+ }
+ if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) {
+ HDF_LOGE("%s fail: memset_s fail!", __func__);
+ OsalMemFree(specificDriver);
+ return NULL;
+ }
+
+ if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) {
+ HDF_LOGE("%s fail : strcpy_s fail", __func__);
+ OsalMemFree(specificDriver);
+ return NULL;
+ }
+ specificDriver->init = Hi3881Init;
+ specificDriver->deinit = Hi3881Deinit;
+
+ HiMac80211Init(specificDriver);
+
+ return specificDriver;
+}
+
+/* Release the WLAN chip driver. */
+static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
+{
+ if (chipDriver == NULL) {
+ return;
+ }
+ if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) {
+ HDF_LOGE("%s:Not my driver!", __func__);
+ return;
+ }
+ OsalMemFree(chipDriver);
+}
+
+static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) {
+ (void)factory;
+ return 1;
+}
+
+/* Register functions related to the WLAN chip. */
+static int32_t HDFWlanRegHisiDriverFactory(void)
+{
+ static struct HdfChipDriverFactory tmpFactory = { 0 };
+ struct HdfChipDriverManager *driverMgr = NULL;
+ driverMgr = HdfWlanGetChipDriverMgr();
+ if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) {
+ HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+ tmpFactory.driverName = HI3881_DRIVER_NAME;
+ tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount;
+ tmpFactory.InitChip = InitHi3881Chip;
+ tmpFactory.DeinitChip = DeinitHi3881Chip;
+ tmpFactory.Build = BuildHi3881Driver;
+ tmpFactory.Release = ReleaseHi3881Driver;
+ tmpFactory.ReleaseFactory = NULL;
+ if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) {
+ HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+
+static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device)
+{
+ (void)device;
+ return HDFWlanRegHisiDriverFactory();
+}
+
+struct HdfDriverEntry g_hdfHisiChipEntry = {
+ .moduleVersion = 1,
+ .Init = HdfWlanHisiChipDriverInit,
+ .moduleName = "HDF_WLAN_CHIPS"
+};
+
+HDF_INIT(g_hdfHisiChipEntry);
+```
+
+```
+#include "hdf_wifi_product.h"
+#include "hi_wifi_api.h"
+#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
+#include "oal_thread.h"
+#include "osal_time.h"
+#endif
+#include "wifi_mac80211_ops.h"
+#include "wal_cfg80211.h"
+#include "net_adpater.h"
+#include "hdf_wlan_utils.h"
+
+#define HDF_LOG_TAG Hi3881Driver
+
+/* Initialize the WLAN chip. */
+int32_t InitHi3881Chip(struct HdfWlanDevice *device)
+{
+ uint8_t maxPortCount = 1;
+ int32_t ret = HI_SUCCESS;
+ uint8_t maxRetryCount = 2;
+ if (device == NULL) {
+ HDF_LOGE("%s:NULL ptr!", __func__);
+ return HI_FAIL;
+ }
+
+ do {
+ if (ret != HI_SUCCESS) {
+ if (device->reset != NULL && device->reset->Reset != NULL) {
+ device->reset->Reset(device->reset);
+ }
+ HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret);
+ }
+ ret = hi_wifi_init(maxPortCount);
+ } while (ret != 0 && --maxRetryCount > 0);
+
+ if (ret != 0) {
+ HDF_LOGE("%s:Init hi3881 driver failed!", __func__);
+ return ret;
+ }
+ return HI_SUCCESS;
+}
+
+/* Deinitialize the WLAN chip. */
+int32_t DeinitHi3881Chip(struct HdfWlanDevice *device)
+{
+ (void)device;
+ int32_t ret = hi_wifi_deinit();
+ if (ret != 0) {
+ HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret);
+ }
+ return ret;
+}
+
+/* Initialize the WLAN chip driver. */
+int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
+{
+ HDF_LOGI("%s: start...", __func__);
+ hi_u16 mode = wal_get_vap_mode();
+ int32_t ret;
+ nl80211_iftype_uint8 type;
+ (void)chipDriver;
+
+ if (mode >= WAL_WIFI_MODE_BUTT) {
+ oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
+ return HI_FAIL;
+ }
+
+ if (mode == WAL_WIFI_MODE_STA) {
+ type = NL80211_IFTYPE_STATION;
+ } else if (mode == WAL_WIFI_MODE_AP) {
+ type = NL80211_IFTYPE_AP;
+ } else {
+ oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
+ return HI_FAIL;
+ }
+
+ ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice);
+ if (ret != HI_SUCCESS) {
+ oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret);
+ }
+ return ret;
+}
+
+/* Deinitialize the WLAN chip driver. */
+int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
+{
+ (void)chipDriver;
+ int32_t ret = wal_deinit_drv_wlan_netdev(netDevice);
+ if (ret != HDF_SUCCESS) {
+ return ret;
+ }
+ return ReleasePlatformNetDevice(netDevice);
+}
+```
+
+3. During the chip initialization, call the **NetDeviceInit\(\)** function to initialize a network device, call the **NetDeviceAdd\(\)** function to add the network device to a protocol stack, and implement some function pointers of **netdev**.
+
+```
+hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len)
+{
+ oal_net_device_stru *netdev = HI_NULL;
+
+ ......
+ /* Initialize the network device and obtain the initialized instance. */
+ netdev = NetDeviceInit(ifname, *len, LITE_OS);
+ oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev));
+ ret = wal_init_netif(type, netdev, wdev);
+
+ ......
+
+ return HI_SUCCESS;
+}
+/* Mount some function pointers of NetDeviceInterFace. */
+oal_net_device_ops_stru g_wal_net_dev_ops =
+{
+ .getStats = wal_netdev_get_stats,
+ .open = wal_netdev_open,
+ .stop = wal_netdev_stop,
+ .xmit = hmac_bridge_vap_xmit,
+ .ioctl = wal_net_device_ioctl,
+ .changeMtu = oal_net_device_change_mtu,
+ .init = oal_net_device_init,
+ .deInit = oal_net_free_netdev,
+#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL))
+ .selectQueue = wal_netdev_select_queue,
+#endif
+ .setMacAddr = wal_netdev_set_mac_addr,
+#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
+ .netifNotify = HI_NULL,
+#endif
+ .specialEtherTypeProcess = SpecialEtherTypeProcess,
+};
+
+hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev)
+{
+ /* Add the network device to a protocol stack. */
+ hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type);
+
+ ......
+
+ return HI_SUCCESS;
+}
+```
+
+4. Implement functions of **WifiMac80211Ops**.
+
+```
+/* Mount some function pointers of mac80211. */
+
+/* MAC-layer APIs for basic capabilities that need to be implemented by the driver */
+static struct HdfMac80211BaseOps g_baseOps = {
+ .SetMode = WalSetMode,
+ .AddKey = WalAddKey,
+ .DelKey = WalDelKey,
+ .SetDefaultKey = WalSetDefaultKey,
+ .GetDeviceMacAddr = WalGetDeviceMacAddr,
+ .SetMacAddr = WalSetMacAddr,
+ .SetTxPower = WalSetTxPower,
+ .GetValidFreqsWithBand = WalGetValidFreqsWithBand,
+ .GetHwCapability = WalGetHwCapability
+};
+
+/* MAC-layer APIs for station capabilities that need to be implemented by the driver */
+static struct HdfMac80211STAOps g_staOps = {
+ .Connect = WalConnect,
+ .Disconnect = WalDisconnect,
+ .StartScan = WalStartScan,
+ .AbortScan = WalAbortScan,
+ .SetScanningMacAddress = WalSetScanningMacAddress,
+};
+
+/* MAC-layer APIs for AP capabilities that need to be implemented by the driver */
+static struct HdfMac80211APOps g_apOps = {
+ .ConfigAp = WalConfigAp,
+ .StartAp = WalStartAp,
+ .StopAp = WalStopAp,
+ .ConfigBeacon = WalChangeBeacon,
+ .DelStation = WalDelStation,
+ .SetCountryCode = WalSetCountryCode,
+ .GetAssociatedStasCount = WalGetAssociatedStasCount,
+ .GetAssociatedStasInfo = WalGetAssociatedStasInfo
+};
+
+/* Initialize mac80211 and mount functions of the chip. */
+hi_void HiMac80211Init(struct HdfChipDriver *chipDriver)
+{
+ if (chipDriver == NULL) {
+ oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__);
+ return;
+ }
+ chipDriver->ops = &g_baseOps;
+ chipDriver->staOps = &g_staOps;
+ chipDriver->apOps = &g_apOps;
+}
+```
+
diff --git a/en/device-dev/driver/lcddevelopment-example.md b/en/device-dev/driver/driver-peripherals-lcd-des.md
similarity index 64%
rename from en/device-dev/driver/lcddevelopment-example.md
rename to en/device-dev/driver/driver-peripherals-lcd-des.md
index 35122ca4fa69878a8c36e658da23082b0c0084e0..2b8dd1543a584339b768c9bc929ea4287ea43ab4 100644
--- a/en/device-dev/driver/lcddevelopment-example.md
+++ b/en/device-dev/driver/driver-peripherals-lcd-des.md
@@ -1,4 +1,76 @@
-# LCD Development Example
+# LCD
+
+- [Overview](#section141575391542)
+ - [API Description](#section14711163785519)
+
+- [Development Guidelines](#section12394223125615)
+ - [How to Develop](#section515923045814)
+
+- [Development Example](#section7441155155813)
+
+## Overview
+
+The Liquid Crystal Display \(LCD\) driver powers on the LCD and initializes internal LCD registers through APIs to enable the LCD to work properly. The display driver is developed based on the hardware driver foundation \([HDF](drive-hdf-overview.md)\). It provides power-on, power-off, and sending of the initialization sequence for LCD hardware across OSs and platforms. The display driver model is shown in [Figure 1](#fig69138814229).
+
+**Figure 1** Architecture of the display driver model
+
+
+- **Display driver model**
+
+ The display driver model consists of the display common driver layer, SoC adapter layer, and third-party chip driver layer. The display driver model is developed based on the HDF and hides the differences between kernel forms through platform and OSAL APIs so the LCD driver can be migrated between different OSs and chip platforms. The display driver connects to the display common HAL, supports the implementation of Hardware Driver Interfaces \(HDIs\), and provides various driver interfaces for the graphics service through the display HDI.
+
+ - Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process upper-layer calls in a centralized manner.
+
+ - SoC adapter layer: decouples the display driver from the SoC driver, configures parameters related to the chip platform, and passes calls from the platform driver layer to the LCD driver layer.
+
+ - Third-party chip driver layer: provides LCD-related APIs for sending the LCD initialization sequence, powering on or off the LCD device, and setting the backlight.
+
+ The display driver model, capabilities, and APIs help you simplify the display driver development and improve the efficiency.
+
+
+### API Description
+
+The LCD interfaces are classified into the Mobile Industry Processor Interface \(MIPI\) Display Serial Interface \(DSI\), Transistor-Transistor Logic \(TTL\) interfaces, and Low Voltage Differential Signaling \(LVDS\) interfaces. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them.
+
+- MIPI DSI
+
+ **Figure 2** MIPI DSI
+ 
+
+ The MIPI DSI is defined by MIPI Alliance. It is mainly used for mobile terminal display. The MIPI DSI is used to transmit image data, in compliance with the MIPI protocol. Generally, control information of the MIPI DSI is sent to the peer IC in the form of MIPI packets through the MIPI DSI. No additional interface is required.
+
+- TTL interface
+
+ **Figure 3** TTL interface
+ 
+
+ TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. They are manufactured using the bipolar process and feature high speed, low power consumption, and multiple types.
+
+ The TTL interface is used to transmit data in parallel mode under the control of control signals. It transmits data signals, clock signals, and control signals \(such as line synchronization signals, frame synchronization signals, and data validity signals\). Generally, the LCD of the TTL interface and the read/write of internal registers require additional peripheral interfaces, such as the Serial Peripheral Interface \(SPI\) and Inter-Integrated Circuit \(I2C\).
+
+
+## Development Guidelines
+
+The display driver model is developed based on the HDF, platform APIs, and APIs at the OS abstraction layer \(OSAL\), and provides a unified driver model for the LCD regardless of the OS \(LiteOS or Linux OS\) and chip platforms \(such as Hi35xx, Hi38xx, and V3S\).
+
+### How to Develop
+
+1. Add the LCD driver-related hardware descriptions.
+2. Add a driver that adapts to the chip at the SoC adapter layer.
+3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for:
+ - Powering on/off the LCD device
+
+ Based on the LCD hardware connection, use the GPIO interfaces provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier.
+
+ - Sending the initialization sequence
+
+ Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier.
+
+
+4. Implement other HDF interfaces as required, for example, the **Release** interface.
+5. Use the HDF to create other device nodes for implementing service logic or debugging as required.
+
+## Development Example
Add the device description.
@@ -106,7 +178,7 @@ The following example shows code for developing an LCD driver:
#define VERTIACL_SYNC_WIDTH 2
#define FRAME_RATE 60
-/* Panel information structure */
+/* PanelInfo structure */
struct PanelInfo {
uint32_t width;
uint32_t height;
diff --git a/en/device-dev/driver/sensor-driver-overview.md b/en/device-dev/driver/driver-peripherals-sensor-des.md
similarity index 43%
rename from en/device-dev/driver/sensor-driver-overview.md
rename to en/device-dev/driver/driver-peripherals-sensor-des.md
index b3d5e86797f93b7c753fdece5fa02adb18f8fbba..5ad5682a94344b9bf86b6d679af80d31318900a6 100644
--- a/en/device-dev/driver/sensor-driver-overview.md
+++ b/en/device-dev/driver/driver-peripherals-sensor-des.md
@@ -1,22 +1,28 @@
-# Sensor Driver Overview
+# Sensor
-- [Introduction](#section667413271505)
-- [Available APIs](#section7255104114110)
+- [Overview](#section3634112111)
+ - [Available APIs](#section188213414114)
-## Introduction
+- [Development Guidelines](#section1140943382)
+ - [How to Develop](#section7893102915819)
+
+- [Development Example](#section257750691)
+- [Test Guidelines](#section106021256121219)
+
+## Overview
The sensor driver module provides APIs for upper-layer sensor services to implement basic sensor capabilities, including querying the sensor list, enabling or disabling a sensor, subscribing to or unsubscribing from sensor data, and setting sensor options. The sensor driver model is developed based on the Hardware Driver Foundation \(HDF\) and supports functions such as cross-OS migration and differentiated device configuration. The following figure shows the architecture of the sensor driver model.
**Figure 1** Architecture of the sensor driver model
-
+
The sensor driver model offers the following APIs:
-- Hardware Driver Interfaces \(HDIs\) for sensors: Facilitate service development.
-- APIs for implementing sensor driver model capabilities: Implement the capabilities of registering, loading, and unregistering sensor drivers as well as detecting sensor devices depending on the HDF, normalize APIs for sensor devices of the same type, and offer APIs for parsing register configurations, abstract APIs for bus access, and abstract platform APIs.
-- APIs to be implemented by developers: Based on the HDF Configuration Source \(HCS\), implement differentiated configuration for sensors of the same type and serialized configuration of sensor device parameters, and offer APIs for some sensor device operations to simplify sensor driver development.
+- Hardware Driver Interfaces \(HDIs\) for sensors: These HDIs facilitate service development.
+- APIs for implementing sensor driver model capabilities: These APIs implement the capabilities of registering, loading, and unregistering sensor drivers as well as detecting sensor devices depending on the HDF. The APIs include normalized APIs for sensor devices of the same type, APIs for parsing register configurations, abstract APIs for bus access, and abstract platform APIs.
+- APIs to be implemented by developers: Based on the HDF Configuration Source \(HCS\), developers can implement differentiated configuration for sensors of the same type and serialized configuration of sensor device parameters. Some sensor device operations can be abstracted as APIs to simplify sensor driver development.
-## Available APIs
+### Available APIs
The following table lists the APIs provided by the sensor driver model.
@@ -199,7 +205,7 @@ The following table lists the APIs that need to be implemented by driver develop
|
int32_t init(void)
|
-Initializes the configuration of a sensor device after it is detected successfully.
+ | Initializes the configuration of a sensor device after it is detected.
|
int32_t GetInfo(struct SensorBasicInfo *info)
@@ -240,5 +246,684 @@ The following table lists the APIs that need to be implemented by driver develop
-For details about the API implementation, see the [sensor driver development example](sensor-driver-development-example.md).
+For details about the API implementation, see [Development Example](#section257750691).
+
+## Development Guidelines
+
+Regardless of the OS and system on a chip \(SoC\), the sensor driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for sensor devices. This section uses the acceleration sensor as an example to describe how to develop a sensor driver.
+
+### How to Develop
+
+1. Register the acceleration sensor driver. The HDF provides a unified driver management model. The HDF identifies and loads the target module driver based on the configuration of the acceleration sensor module.
+2. Initialize and deinitialize the acceleration sensor driver. Using the **init** function, the HDF starts loading the sensor device driver and allocating configuration resources for sensor device data, respectively. Using the **release** function, the HDF releases the resources and configurations loaded by the driver.
+3. Parse the configurations of the acceleration sensor register group. For different types of sensors, you must configure their respective HCS configuration files in the HCS, check whether the sensor device is in position during the device driver startup, and then load the corresponding configuration file to generate the configuration structure object.
+4. Implement APIs for acceleration sensor driver operations. The driver APIs for various types of sensors, such as **init**, **GetInfo**, **Enable**, **Disable**, **SetBatch**, **SetMode**, **SetOption**, and **ReadSensorData**, are normalized to deliver sensor driver configurations and report sensor data.
+
+> **NOTE:**
+>The sensor driver model provides a collection of APIs to implement sensor driver capabilities, including the driver device management, abstract bus and platform operation, general configuration, and configuration parsing capabilities. For details about the APIs, see [Table 2](#table1156812588320). You need to implement the following APIs: some operations to perform on sensors \([Table 3](#table1083014911336)\), differentiated data configuration of the sensor HCS, and verification of basic driver functions.
+
+## Development Example
+
+This section uses a code example to demonstrate how to load and start the acceleration sensor driver based on the HDF driver model. For details about the mechanism, see [Driver Development](driver-hdf-development.md). This example uses the Bosch BMI160 acceleration sensor that communicates over I2C.
+
+1. Register the driver entry of the acceleration sensor.
+
+- Implementation of the entry function
+
+```
+/* Register the entry structure object of the acceleration sensor. */
+struct HdfDriverEntry g_sensorAccelDevEntry = {
+ .moduleVersion = 1, /* Version of the acceleration sensor module */
+ .moduleName = "HDF_SENSOR_ACCEL", /* Name of the acceleration sensor module. The value must be the same as that of moduleName in the device_info.hcs file. */
+ .Bind = BindAccelDriver, /* Binding function of the acceleration sensor */
+ .Init = InitAccelDriver, /* Initialization function of the acceleration sensor */
+ .Release = ReleaseAccelDriver, /* Resource release function of the acceleration sensor */
+};
+
+/* Call HDF_INIT to register the driver entry with the HDF. When loading the driver, the HDF calls the Bind function first and then the Init function. If the Init function fails to be called, the HDF will call Release to release the driver resource and exit.
+HDF_INIT(g_sensorAccelDevEntry);
+```
+
+- Acceleration sensor configuration
+
+The acceleration sensor model uses the HCS as the configuration source code. For details about the HCS configuration fields, see [Driver Configuration Management](driver-hdf-manage.md).
+
+```
+/* HCS configuration of the acceleration sensor device */
+device_sensor_accel :: device {
+ device0 :: deviceNode {
+ policy = 1; /* Policy for providing the driver service */
+ priority = 105; /* Driver startup priority (0–200). A larger value indicates a lower priority. The default value 100 is recommended. The sequence for loading devices with the same priority is random. */
+ preload = 2; /* Field for specifying whether to load the driver. The value 0 means to load the driver, and 2 means the opposite. */
+ permission = 0664; /* Permission for the driver to create device nodes */
+ moduleName = "HDF_SENSOR_ACCEL"; /* Driver name. The value must be the same as that of moduleName in the driver entry structure. */
+ serviceName = "sensor_accel"; /* Name of the service provided by the driver. The name must be unique. */
+ deviceMatchAttr = "hdf_sensor_accel_driver"; /* Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver. */
+ }
+}
+```
+
+1. Initialize and deinitialize the acceleration sensor driver.
+
+- Initialization entry function **init**
+
+```
+/* Bind the service provided by the acceleration sensor driver to the HDF. */
+int32_t BindAccelDriver(struct HdfDeviceObject *device)
+{
+ CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
+
+ static struct IDeviceIoService service = {
+ .object = {0},
+ .Dispatch = DispatchAccel,
+ };
+ device->service = &service;
+
+ return HDF_SUCCESS;
+}
+/* After detecting that the device is in position, call RegisterAccelChipOps to register the differentiation adaptation function. */
+int32_t RegisterAccelChipOps(struct AccelOpsCall *ops)
+{
+ struct AccelDrvData *drvData = NULL;
+
+ CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM);
+
+ drvData = AccelGetDrvData();
+ drvData->ops.Init = ops->Init;
+ drvData->ops.ReadData = ops->ReadData;
+ return HDF_SUCCESS;
+}
+/* Hook the acceleration sensor driver normalization function. */
+static int32_t InitAccelOps(struct SensorDeviceInfo *deviceInfo)
+{
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ (void)memset_s((void *)deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo));
+ deviceInfo->ops.GetInfo = SetAccelInfo;
+ deviceInfo->ops.Enable = SetAccelEnable;
+ deviceInfo->ops.Disable = SetAccelDisable;
+ deviceInfo->ops.SetBatch = SetAccelBatch;
+ deviceInfo->ops.SetMode = SetAccelMode;
+ deviceInfo->ops.SetOption = SetAccelOption;
+
+ if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo),
+ &drvData->accelCfg->sensorInfo, sizeof(drvData->accelCfg->sensorInfo)) != EOK) {
+ HDF_LOGE("%s: copy sensor info failed", __func__);
+ return HDF_FAILURE;
+ }
+ /* The sensor type ID can be configured in the HCS configuration file or here. */
+ drvData->accelCfg->sensorInfo.sensorTypeId = SENSOR_TAG_ACCELEROMETER;
+ drvData->accelCfg->sensorInfo.sensorId = SENSOR_TAG_ACCELEROMETER;
+
+ return HDF_SUCCESS;
+}
+/* Initialize the sensor register. */
+static int32_t InitAccelAfterConfig(void)
+{
+ struct SensorDeviceInfo deviceInfo;
+
+ if (InitAccelConfig() != HDF_SUCCESS) {
+ HDF_LOGE("%s: init accel config failed", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (InitAccelOps(&deviceInfo) != HDF_SUCCESS) {
+ HDF_LOGE("%s: init accel ops failed", __func__);
+ return HDF_FAILURE;
+ }
+
+ if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
+ HDF_LOGE("%s: add accel device failed", __func__);
+ return HDF_FAILURE;
+ }
+
+ return HDF_SUCCESS;
+}
+/* Call the device detection function to hook the differentiated device function. */
+static int32_t DetectAccelChip(void)
+{
+ int32_t num;
+ int32_t ret;
+ int32_t loop;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+ CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
+
+ num = sizeof(g_accelDetectIfList) / sizeof(g_accelDetectIfList[0]);
+ for (loop = 0; loop < num; ++loop) {
+ if (g_accelDetectIfList[loop].DetectChip != NULL) {
+ ret = g_accelDetectIfList[loop].DetectChip(drvData->accelCfg);
+ if (ret == HDF_SUCCESS) {
+ drvData->detectFlag = true;
+ break;
+ }
+ }
+ }
+
+ if (loop == num) {
+ HDF_LOGE("%s: detect accel device failed", __func__);
+ drvData->detectFlag = false;
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+/* The entry function of the acceleration sensor driver is used to initialize the structure object of the sensor private data, allocate space for the HCS data configuration object of the sensor, invoke the entry function for initializing the sensor HCS data configuration, detect whether the sensor device is in position, create the sensor data reporting timer, implement the sensor normalization API, and register the sensor device. */
+int32_t InitAccelDriver(struct HdfDeviceObject *device)
+{
+ /* Obtain the private data structure object of the sensor. */
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ /* When detecting sensors of the same type from different vendors, the function checks whether this type of sensors is in position. If yes, it no longer detects the other sensors of this type and directly returns the result. */
+ if (drvData->detectFlag) {
+ HDF_LOGE("%s: accel sensor have detected", __func__);
+ return HDF_SUCCESS;
+ }
+
+ CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
+ /* Allocate space for the private data structure objects for storing sensor data configurations. The allocated space needs to be released when the driver is released. */
+ drvData->accelCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*cfg));
+ if (drvData->accelCfg == NULL) {
+ HDF_LOGE("%s: malloc sensor config data failed", __func__);
+ return HDF_FAILURE;
+ }
+
+ drvData->accelCfg->regCfgGroup = &g_regCfgGroup[0];
+ /* Initializing the sensor configuration data aims to parse the configuration information of the sensor communication bus, basic sensor information, sensor attributes, whether the sensor is in position, and register group information. */
+ if (GetSensorBaseConfigData(device->property, drvData->accelCfg) != HDF_SUCCESS) {
+ HDF_LOGE("%s: get sensor base config failed", __func__);
+ goto Base_CONFIG_EXIT;
+ }
+
+ if (DetectAccelChip() != HDF_SUCCESS) {
+ HDF_LOGE("%s: accel sensor detect device no exist", __func__);
+ goto DETECT_CHIP_EXIT;
+ }
+ drvData->detectFlag = true;
+ if (ParseSensorRegConfig(drvData->accelCfg) != HDF_SUCCESS) {
+ HDF_LOGE("%s: detect sensor device failed", __func__);
+ goto REG_CONFIG_EXIT;
+ }
+
+ if (InitAccelAfterConfig() != HDF_SUCCESS) {
+ HDF_LOGE("%s: init accel after config failed", __func__);
+ goto INIT_EXIT;
+ }
+
+ HDF_LOGI("%s: init accel driver success", __func__);
+ return HDF_SUCCESS;
+
+INIT_EXIT:
+ DestroySensorThread(&drvData->thread, &drvData->threadStatus);
+ (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER);
+REG_CONFIG_EXIT:
+ ReleaseSensorAllRegConfig(drvData->accelCfg);
+ (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg);
+DETECT_CHIP_EXIT:
+ drvData->detectFlag = false;
+BASE_CONFIG_EXIT:
+ drvData->accelCfg->root = NULL;
+ drvData->accelCfg->regCfgGroup = NULL;
+ OsalMemFree(drvData->accelCfg);
+ drvData->accelCfg = NULL;
+ return HDF_FAILURE;
+}
+
+/* Release the resources allocated during driver initialization. */
+void ReleaseAccelDriver(struct HdfDeviceObject *device)
+{
+ (void)device;
+ struct AccelDrvData *drvData = NULL;
+
+ drvData = AccelGetDrvData();
+ (void)DestroySensorThread(&drvData->thread, &drvData->threadStatus);
+ (void)DeleteSensorDevice(SENSOR_TAG_ACCELEROMETER);
+ drvData->detectFlag = false;
+
+ if (drvData->accelCfg != NULL) {
+ drvData->accelCfg->root = NULL;
+ drvData->accelCfg->regCfgGroup = NULL;
+ ReleaseSensorAllRegConfig(drvData->accelCfg);
+ (void)ReleaseSensorBusHandle(&drvData->accelCfg->busCfg);
+ OsalMemFree(drvData->accelCfg);
+ drvData->accelCfg = NULL;
+ }
+
+ drvData->initStatus = false;
+}
+```
+
+1. Configure the acceleration sensor register group.
+
+You only need to configure the acceleration sensor data according to the template. Template configuration parsing has been implemented via the **InitSensorConfigData** function and only needs to be called during initialization. If new configuration items are added, you need to modify this function accordingly.
+
+```
+Acceleration sensor data configuration template (accel_config.hcs)
+root {
+ sensorAccelConfig {
+ accelChipConfig {
+ /* Sensor information template */
+ template sensorInfo {
+ sensorName = "accelerometer"; /* Acceleration sensor name. The value contains a maximum of 16 bytes. */
+ vendorName = "borsh_bmi160"; /* Sensor vendor name. The value contains a maximum of 16 bytes. */
+ firmwareVersion = "1.0"; /* Sensor firmware version. The default value is 1.0. The value contains a maximum of 16 bytes. */
+ hardwareVersion = "1.0"; /* Sensor hardware version. The default value is 1.0. The value contains a maximum of 16 bytes. */
+ sensorTypeId = 1; /* Sensor type ID. For details, see SensorTypeTag. */
+ sensorId = 1; /* Sensor ID, which is defined by the sensor driver developer. The SensorTypeTag enums are recommended. */
+ maxRange = 8; /* Maximum measurement range of the sensor. Set this parameter based on your business requirements. */
+ precision = 0; /* Sensor accuracy, which is used together with sensor data reporting. For details, see SensorEvents. */
+ power = 230; /* Power consumption of the sensor */
+ }
+ /* Template of the bus type and configuration information used by the sensor */
+ template sensorBusConfig {
+ busType = 0; /* 0:i2c 1:spi */
+ busNum = 6; /* Device ID allocated to the sensor on the chip */
+ busAddr = 0; /* Address allocated to the sensor on the chip */
+ regWidth = 1; /* Width of the sensor register address */
+ regBigEndian = 0; /* Endian mode of the sensor register */
+ }
+ /* Sensor attribute template */
+ template sensorAttr {
+ chipName = ""; /* Sensor chip name */
+ chipIdRegister = 0xf; /* Address of the register detecting whether the sensor is in position */
+ chipIdValue = 0xd1; /* Value of the register detecting whether the sensor is in position */
+ }
+ }
+ }
+}
+
+/* You can modify the template configuration based on the differences of sensor devices. If no modification is made, the default template configuration is used. */
+root {
+ sensorAccelConfig {
+ accel_bmi160_chip_config : accelChipConfig {
+ match_attr = "hdf_sensor_accel_driver"; /* The value must be the same as the match_attr field configured for the acceleration sensor. */
+ accelInfo :: sensorInfo {
+ vendorName = "borsh_bmi160";
+ sensorTypeId = 1;
+ sensorId = 1;
+ }
+ accelBusConfig :: sensorBusConfig {
+ busType = 0; /* I2C communication mode */
+ busNum = 6;
+ busAddr = 0x68;
+ regWidth = 1; /* 1-byte bit width */
+ }
+ accelAttr :: sensorAttr {
+ chipName = "bmi160";
+ chipIdRegister = 0x00;
+ chipIdValue = 0xd1;
+ }
+ accelRegConfig {
+ /* regAddr: Register address
+ value: Register value
+ mask: Mask of the register value
+ len: Length (in bytes) of the register value
+ delay: Register delay (in milliseconds)
+ opsType: Operation type. The options can be 0 (no operation), 1 (read), 2 (write), 3 (read and check), and 4 (bit update).
+ calType: Calculation type. The options can be 0 (none), 1 (write), 2 (negate), 3 (XOR) 4, (left shift), and 5 (right shift).
+ shiftNum: Number of shifts
+ debug: Debugging switch. The value can be 0 (disabled) or 1 (enabled).
+ save: Data saving switch. The value can be 0 (not save data) or 1 (save data).
+ */
+ /* Groups of sensor register operations. Registers can be configured in sequence based on the groups. */
+ /* Register address, register value, mask of the register value, data length of the register value, register delay, operation type, calculation type, number of shifts, debugging switch, data saving switch */
+ /* Initialize the register groups. */
+ initSeqConfig = [
+ 0x7e, 0xb6, 0xff, 1, 5, 2, 0, 0, 0, 0,
+ 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
+ ];
+ /* Enable the register groups. */
+ enableSeqConfig = [
+ 0x7e, 0x11, 0xff, 1, 5, 2, 0, 0, 0, 0,
+ 0x41, 0x03, 0xff, 1, 0, 2, 0, 0, 0, 0,
+ 0x40, 0x08, 0xff, 1, 0, 2, 0, 0, 0, 0
+ ];
+ /* Disable the register groups. */
+ disableSeqConfig = [
+ 0x7e, 0x10, 0xff, 1, 5, 2, 0, 0, 0, 0
+ ];
+ }
+ }
+ }
+}
+```
+
+1. Implement APIs for acceleration sensor driver operations.
+
+You need to implement normalized APIs based on sensor types.
+
+```
+/* Leave a function empty if it is not used. */
+static int32_t SetAccelInfo(struct SensorBasicInfo *info)
+{
+ (void)info;
+
+ return HDF_ERR_NOT_SUPPORT;
+}
+/* Deliver the configuration of enabling the register groups. */
+static int32_t SetAccelEnable(void)
+{
+ int32_t ret;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
+ ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: accel sensor disable config failed", __func__);
+ return HDF_FAILURE;
+ }
+
+ drvData->threadStatus = SENSOR_THREAD_RUNNING;
+
+ return HDF_SUCCESS;
+}
+/* Deliver the configuration of disabling the register groups. */
+static int32_t SetAccelDisable(void)
+{
+ int32_t ret;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ CHECK_NULL_PTR_RETURN_VALUE(drvData->accelCfg, HDF_ERR_INVALID_PARAM);
+
+ ret = SetSensorRegCfgArray(&drvData->accelCfg->busCfg, drvData->accelCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: accel sensor disable config failed", __func__);
+ return HDF_FAILURE;
+ }
+
+ drvData->threadStatus = SENSOR_THREAD_STOPPED;
+
+ return HDF_SUCCESS;
+}
+/* Set the sampling interval and data reporting interval of the sensor. */
+static int32_t SetAccelBatch(int64_t samplingInterval, int64_t interval)
+{
+ (void)interval;
+
+ struct AccelDrvData *drvData = AccelGetDrvData();
+ drvData->interval = samplingInterval;
+
+ return HDF_SUCCESS;
+}
+/* Set the data reporting mode of the sensor. Currently, the real-time mode is supported. */
+static int32_t SetAccelMode(int32_t mode)
+{
+ return (mode == SENSOR_WORK_MODE_REALTIME) ? HDF_SUCCESS : HDF_FAILURE;
+}
+/* Set the sensor options. */
+static int32_t SetAccelOption(uint32_t option)
+{
+ (void)option;
+ return HDF_ERR_NOT_SUPPORT;
+}
+```
+
+- Differentiated processing APIs
+
+ ```
+ /* If a device is detected, register the differentiated processing function to the accel driver model. */
+ int32_t DetectAccelBim160Chip(struct SensorCfgData *data)
+ {
+ int32_t ret;
+ struct AccelOpsCall ops;
+ CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
+
+ if (strcmp(ACCEL_CHIP_NAME_BMI160, data->sensorAttr.chipName) != 0) {
+ return HDF_SUCCESS;
+ }
+ ret = InitAccelPreConfig();
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: init BMI160 bus mux config", __func__);
+ return HDF_FAILURE;
+ }
+ if (DetectSensorDevice(data) != HDF_SUCCESS) {
+ return HDF_FAILURE;
+ }
+
+ /* Differentiated processing function */
+ ops.Init = InitBmi160;
+ ops.ReadData = ReadBmi160Data;
+ ret = RegisterAccelChipOps(&ops);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: register BMI160 accel failed", __func__);
+ (void)ReleaseSensorBusHandle(&data->busCfg);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+ }
+ /* Initialization processing function */
+ static int32_t InitBmi160(struct SensorCfgData *data)
+ {
+ int32_t ret;
+
+ CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
+ ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: bmi160 sensor init config failed", __func__);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+ }
+ /* Data processing function */
+ int32_t ReadBmi160Data(struct SensorCfgData *data)
+ {
+ int32_t ret;
+ struct AccelData rawData = { 0, 0, 0 };
+ int32_t tmp[ACCEL_AXIS_NUM];
+ struct SensorReportEvent event;
+
+ (void)memset_s(&event, sizeof(event), 0, sizeof(event));
+
+ ret = ReadBmi160RawData(data, &rawData, &event.timestamp);
+ if (ret != HDF_SUCCESS) {
+ return HDF_FAILURE;
+ }
+
+ event.sensorId = SENSOR_TAG_ACCELEROMETER;
+ event.option = 0;
+ event.mode = SENSOR_WORK_MODE_REALTIME;
+
+ rawData.x = rawData.x * BMI160_ACC_SENSITIVITY_2G;
+ rawData.y = rawData.y * BMI160_ACC_SENSITIVITY_2G;
+ rawData.z = rawData.z * BMI160_ACC_SENSITIVITY_2G;
+
+ tmp[ACCEL_X_AXIS] = (rawData.x * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT;
+ tmp[ACCEL_Y_AXIS] = (rawData.y * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT;
+ tmp[ACCEL_Z_AXIS] = (rawData.z * SENSOR_1K_UNIT) / SENSOR_CONVERT_UNIT;
+
+ event.dataLen = sizeof(tmp);
+ event.data = (uint8_t *)&tmp;
+ ret = ReportSensorEvent(&event);
+ return ret;
+ }
+ ```
+
+- Data processing function
+
+Create a sensor timer to periodically sample data based on the configured sampling interval and report the data to the data subscriber.
+
+```
+/* Scheduled working thread of the sensor */
+static int32_t ReadAccelDataThreadWorker(void *arg)
+{
+ (void)arg;
+ int64_t interval;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ drvData->threadStatus = SENSOR_THREAD_START;
+ while (true) {
+ if (drvData->threadStatus == SENSOR_THREAD_RUNNING) {
+ if (drvData->ops.ReadData != NULL) {
+ (void)drvData->ops.ReadData(drvData->accelCfg);
+ }
+ interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT));
+ OsalMSleep(interval);
+ } else if (drvData->threadStatus == SENSOR_THREAD_DESTROY) {
+ break;
+ } else {
+ OsalMSleep(ACC_DEFAULT_SAMPLING_200_MS / SENSOR_CONVERT_UNIT / SENSOR_CONVERT_UNIT);
+ }
+
+ if ((!drvData->initStatus) || (drvData->interval < 0) || drvData->threadStatus != SENSOR_THREAD_RUNNING) {
+ continue;
+ }
+ }
+
+ return HDF_SUCCESS;
+}
+/* Create a sensor timer and initialize the sensor device. */
+static int32_t InitAccelConfig(void)
+{
+ int32_t ret;
+ struct AccelDrvData *drvData = AccelGetDrvData();
+
+ if (drvData->threadStatus != SENSOR_THREAD_NONE && drvData->threadStatus != SENSOR_THREAD_DESTROY) {
+ HDF_LOGE("%s: accel thread have created", __func__);
+ return HDF_SUCCESS;
+ }
+
+ ret = CreateSensorThread(&drvData->thread, ReadAccelDataThreadWorker, "hdf_sensor_accel", drvData);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: accel create thread failed", __func__);
+ drvData->threadStatus = SENSOR_THREAD_NONE;
+ return HDF_FAILURE;
+ }
+
+ CHECK_NULL_PTR_RETURN_VALUE(drvData->ops.Init, HDF_ERR_INVALID_PARAM);
+
+ ret = drvData->ops.Init(drvData->accelCfg);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: accel create thread failed", __func__);
+ drvData->threadStatus = SENSOR_THREAD_NONE;
+ return HDF_FAILURE;
+ }
+ drvData->initStatus = true;
+ return HDF_SUCCESS;
+}
+```
+
+- Major data structures
+
+```
+/* Sensor conversion units */
+#define SENSOR_CONVERT_UNIT 1000
+#define SENSOR_1K_UNIT 1024
+/* Sensitivity conversion value of the sensor with a 2g measurement range */
+#define BMI160_ACC_SENSITIVITY_2G 61
+/* Address of the sensor data sampling register */
+#define BMI160_ACCEL_X_LSB_ADDR 0X12
+#define BMI160_ACCEL_X_MSB_ADDR 0X13
+#define BMI160_ACCEL_Y_LSB_ADDR 0X14
+#define BMI160_ACCEL_Y_MSB_ADDR 0X15
+#define BMI160_ACCEL_Z_LSB_ADDR 0X16
+#define BMI160_ACCEL_Z_MSB_ADDR 0X17
+/* Data dimension of the sensor */
+enum AccelAxisNum {
+ ACCEL_X_AXIS = 0,
+ ACCEL_Y_AXIS = 1,
+ ACCEL_Z_AXIS = 2,
+ ACCEL_AXIS_NUM = 3,
+};
+/* Each dimension of the sensor */
+struct AccelData {
+ int32_t x;
+ int32_t y;
+ int32_t z;
+};
+/* Private data structure of the sensor */
+struct AccelDrvData {
+ bool detectFlag;
+ uint8_t threadStatus;
+ uint8_t initStatus;
+ int64_t interval;
+ struct SensorCfgData *accelCfg;
+ struct OsalThread thread;
+ struct AccelOpsCall ops;
+};
+/* Differentiation adaptation function */
+struct AccelOpsCall {
+ int32_t (*Init)(struct SensorCfgData *data);
+ int32_t (*ReadData)(struct SensorCfgData *data);
+};
+```
+
+## Test Guidelines
+
+After the driver is developed, you can develop self-test cases in the sensor unit test to verify the basic functions of the driver. The developer self-test platform is used as the test environment.
+
+```
+/* Specify whether to report sensor data. */
+static int32_t g_sensorDataFlag = 0;
+/* Retain the address of the sensor interface instance. */
+static const struct SensorInterface *g_sensorDev = nullptr;
+
+/* Register the data reporting function. */
+static int SensorTestDataCallback(struct SensorEvents *event)
+{
+ if (event == nullptr) {
+ return -1;
+ }
+ float *data = (float*)event->data;
+ printf("time [%lld] sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", event->timestamp,
+ event->sensorId, (*data), *(data + 1), *(data + g_axisZ));
+ if (*data > 1e-5) {
+ g_sensorDataFlag = 1;
+ }
+ return 0;
+}
+/* Initialize the sensor interface instance before executing the test cases. */
+void HdfSensorTest::SetUpTestCase()
+{
+ g_sensorDev = NewSensorInterfaceInstance();
+ if (g_sensorDev == nullptr) {
+ printf("test sensorHdi get Module instace failed\n\r");
+ }
+}
+/* Release case resources. */
+void HdfSensorTest::TearDownTestCase()
+{
+ if (g_sensorDev != nullptr) {
+ FreeSensorInterfaceInstance();
+ g_sensorDev = nullptr;
+ }
+}
+/* Verify the sensor driver. */
+HWTEST_F(HdfSensorTest,TestAccelDriver_001, TestSize.Level0)
+{
+ int32_t sensorInterval = 1000000000; /* Data sampling interval, in nanoseconds */
+ int32_t pollTime = 5; /* Data sampling duration, in seconds */
+ int32_t accelSensorId = 1; /* Acceleration sensor type ID, which is 1 */
+ int32_t count = 0;
+ int ret;
+ struct SensorInformation *sensorInfo = nullptr;
+
+ ret = g_sensorDev->Register(SensorTestDataCallback)
+ EXPECT_EQ(SENSOR_NULL_PTR, ret);
+
+ ret = g_sensorDev->GetAllSensors(&sensorInfo, &count);
+ EXPECT_EQ(0, ret);
+ if (sensorInfo == nullptr) {
+ EXPECT_NE(nullptr, sensorInfo);
+ return;
+ }
+ /* Print the obtained sensor list. */
+ for (int i = 0; i < count; i++) {
+ printf("get sensoriId[%d], info name[%s]\n\r", sensorInfo[i]->sensorId, sensorInfo[i]->sensorName);
+ }
+ ret = g_sensorDev->Enable(accelSensorId);
+ EXPECT_EQ(0, ret);
+ g_sensorDataFlag = 0;
+
+ ret = g_sensorDev->SetBatch(accelSensorId, sensorInterval, pollTime);
+ EXPECT_EQ(0, ret);
+ /* Observe the printed data within the period specified by pollTime. */
+ OsalSleep(pollTime);
+ EXPECT_EQ(1, g_sensorDataFlag);
+
+ ret = g_sensorDev->Disable(accelSensorId);
+ g_sensorDataFlag = 0;
+ EXPECT_EQ(0, ret);
+
+ ret = g_sensorDev->Unregister();
+ EXPECT_EQ(0, ret);
+}
+```
diff --git a/en/device-dev/driver/touchscreendevelopment-example.md b/en/device-dev/driver/driver-peripherals-touch-des.md
similarity index 57%
rename from en/device-dev/driver/touchscreendevelopment-example.md
rename to en/device-dev/driver/driver-peripherals-touch-des.md
index 8d49343af5e1b1c2e1aaaa1fc113d75f2dc8a540..f4bfd35be3cf06492694b92bf2b7711e703a409e 100644
--- a/en/device-dev/driver/touchscreendevelopment-example.md
+++ b/en/device-dev/driver/driver-peripherals-touch-des.md
@@ -1,14 +1,124 @@
-# Touchscreen Development Example
+# TOUCHSCREEN
-- [Device Description Configuration](#section85281142102317)
-- [Board-level Hardware Configuration and Private Data Configuration](#section189081946192410)
-- [Adding the Touchscreen Driver](#section19856687253)
+- [Overview](#section175431838101617)
+ - [Available APIs](#section17667171301711)
+
+- [Development Guidelines](#section65745222184)
+ - [How to Develop](#section865734181916)
+
+- [Development Example](#section263714411191)
+ - [Add the touchscreen driver-related descriptions.](#section18249155619195)
+ - [Board-level Hardware Configuration and Private Data Configuration](#section3571192072014)
+ - [Adding the Touchscreen Driver](#section6356758162015)
+
+
+## Overview
+
+- **Functions of the Touchscreen driver**
+
+ The Touchscreen driver is used to power on its integrated circuit \(IC\), configure and initialize hardware pins, register interrupts, configure Inter-Integrated Circuit \(I2C\) or SPI APIs, set input-related configurations, and download and update firmware.
+
+
+- **Layers of the Touchscreen driver**
+
+ This section describes how to develop the touchscreen driver based on the input driver model. [Figure 1](#fig6251184817261) shows an overall architecture of the touchscreen driver.
+
+ The input driver is developed based on the hardware driver foundation \(HDF\), platform APIs, and operating system abstraction layer \(OSAL\) APIs. It provides hardware driver capabilities through the input Hardware Driver Interfaces \(HDIs\) for upper-layer input services to control the touchscreen.
+
+
+**Figure 1** Architecture of the input driver model
+
+
+- **Input driver model**
+
+ The input driver model mainly consists of the device manager, common drivers, and chip drivers. The platform data channel provides capabilities for sending data generated by the touchscreen from the kernel to the user space. The driver model adapts to different touchscreen devices and hardware platforms via the configuration file, improving the efficiency of the touchscreen development. The description for each part of the input driver model is as follows:
+
+ - Input device manager: provides input device drivers with the APIs for registering or unregistering input devices and manages the input device list.
+
+ - Input common driver: provides common abstract drivers \(such as the touchscreen common driver\) of various input devices for initializing the board-level hardware, processing hardware interrupts, and registering input devices with the input device manager.
+
+ - Input chip driver: provides different chip drivers of each vendor. You can minimize the workload for the input chip driver development by calling differentiated APIs reserved by the input platform driver.
+
+ - Event hub: provides a unified data reporting channel, which enables input devices to report input events.
+
+ - HDF input config: parses and manages the board-level configuration as well as the private configuration of input devices.
+
+
+- **Advantages of developing drivers based on the HDF**
+
+ The touchscreen driver is developed based on the [HDF](driver-hdf-development.md) and is implemented via calls to the OSAL and platform APIs, including bus APIs and OS native APIs \(such as memory, lock, thread, and timer\). The OSAL and platform APIs hide the differences of underlying hardware, so that the touchscreen driver can be migrated across platforms and OSs. In this regard, you can develop the touchscreen driver only once but deploy it on multiple devices.
+
+
+### Available APIs
+
+Based on the attributes of the pins, interfaces on the touchscreens can be classified into the following types:
+
+- Power interfaces
+- I/O control interfaces
+- Communications interfaces
+
+**Figure 2** Common pins of the touchscreen
+
+
+The interfaces shown in the figure are described as follows:
+
+1. **Power interfaces**
+ - LDO\_1P8: 1.8 V digital circuits
+ - LDO\_3P3: 3.3 V analog circuits
+
+ Generally, the touchscreen driver IC is separated from the LCD driver IC. In this case, the touchscreen driver IC requires both 1.8 V and 3.3 V power supplies. Nowadays, the touchscreen driver IC and LCD driver IC can be integrated. Therefore, the touchscreen, requires only the 1.8 V power supply, and the 3.3 V power required internally is supplied by the LCD VSP power \(typical value: 5.5 V\) in the driver IC.
+
+
+2. **I/O control interfaces**
+ - RESET: reset pin, which is used to reset the driver IC on the host when suspending or resuming the system.
+ - INT: interrupt pin, which needs to be set to the input direction and pull-up status during driver initialization. After detecting an external touch signal, the driver triggers the interrupt by operating the interrupt pin. The driver reads the touch reporting data in the ISR function.
+
+3. **Communications interfaces**
+ - I2C: Since only a small amount of touch data is reported by the touchscreen, I2C is used to transmit the reported data. For details about the I2C protocol and interfaces, see [I2C](drive-platform-i2c-des.md#section1695201514281).
+ - SPI: In addition to touch reporting data coordinates, some vendors need to obtain basic capacitance data. Therefore, Serial Peripheral Interface \(SPI\) is used to transmit such huge amount of data. For details about the SPI protocol and interfaces, see [SPI](drive-platform-spi-des.md#section71363452477).
+
+
+## Development Guidelines
+
+Regardless of the OS and system on a chip \(SoC\), the input driver is developed based on the HDF, platform, and OSAL APIs to provide a unified driver model for touchscreen devices.
+
+- The following uses the touchscreen driver as an example to describe the loading process of the input driver model:
+
+ \(1\) Complete the device description configuration, such as the loading priority, board-level hardware information, and private data, by referring to the existing template.
+
+ \(2\) Load the input device management driver. The input management driver is loaded automatically by the HDF to create and initialize the device manager.
+
+ \(3\) Load the platform driver. The platform driver is loaded automatically by the HDF to parse the board-level configuration, initialize the hardware, and provide the API for registering the touchscreen.
+
+ \(4\) Load the touchscreen driver. The touchscreen driver is loaded automatically by the HDF to instantiate the touchscreen device, parse the private data, and implement differentiated APIs provided by the platform.
+
+ \(5\) Register the instantiated touchscreen device with the platform driver. Then bind this device to the platform driver, and complete touchscreen initialization such as interrupt registration and power-on and power-off.
+
+ \(6\) Instantiate the input device and register it with the input manager after the touchscreen is initialized.
+
+
+### How to Develop
+
+1. Add the touchscreen driver-related descriptions.
+
+ Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [Driver Development](driver-hdf-development.md#section1969312275533).
+
+2. Complete the board-level configuration and private data configuration of the touchscreen.
+
+ Configure the required I/O pins. For example, configure a register for the I2C pin reserved for the touchscreen to use I2C for transmitting data.
+
+3. Implement differentiated adaptation APIs of the touchscreen.
+
+ Use the platform APIs to perform operations for the reset pins, interrupt pins, and power based on the communications interfaces designed for boards. For details about the GPIO-related operations, see [GPIO](drive-platform-gpio-des.md#section259614242196).
+
+
+## Development Example
This example describes how to develop the touchscreen driver.
-## Device Description Configuration
+### Add the touchscreen driver-related descriptions.
-The information about modules of the input driver model is shown as follows and enables the HDF to load the modules in sequence. For details, see [Driver Development](driver-development.md).
+The information about modules of the input driver model is shown as follows and enables the HDF to load the modules in sequence. For details, see [Driver Development](driver-hdf-development.md).
```
input :: host {
@@ -51,9 +161,9 @@ input :: host {
}
```
-## Board-level Hardware Configuration and Private Data Configuration
+### Board-level Hardware Configuration and Private Data Configuration
-The following describes the configuration of the board-level hardware and private data of the touchscreen. You can modify the configuration based on the service requirements.
+The following describes the configuration of the board-level hardware and private data of the touchscreen. You can modify the configuration based on service requirements.
```
root {
@@ -140,7 +250,7 @@ root {
}
```
-## Adding the Touchscreen Driver
+### Adding the Touchscreen Driver
The following example shows how to implement the differentiated APIs provided by the platform driver to obtain and parse the touchscreen data. You can adjust the development process based on the board and touchscreen in use.
diff --git a/en/device-dev/driver/driver-peripherals.md b/en/device-dev/driver/driver-peripherals.md
new file mode 100644
index 0000000000000000000000000000000000000000..02e7a9e357a6eb7484f8a0eea5a486c3a90b396a
--- /dev/null
+++ b/en/device-dev/driver/driver-peripherals.md
@@ -0,0 +1,11 @@
+# Peripherals
+
+- **[LCD](driver-peripherals-lcd-des.md)**
+
+- **[TOUCHSCREEN](driver-peripherals-touch-des.md)**
+
+- **[Sensor](driver-peripherals-sensor-des.md)**
+
+- **[WLAN](driver-peripherals-external-des.md)**
+
+
diff --git a/en/device-dev/driver/gpiousage-guidelines.md b/en/device-dev/driver/driver-platform-gpio-des.md
similarity index 57%
rename from en/device-dev/driver/gpiousage-guidelines.md
rename to en/device-dev/driver/driver-platform-gpio-des.md
index 67c29e26454fde7b66ef285e993d01d08f09d8ba..045a23db3e998a174fd191525fd04742b9ca86a8 100644
--- a/en/device-dev/driver/gpiousage-guidelines.md
+++ b/en/device-dev/driver/driver-platform-gpio-des.md
@@ -1,23 +1,108 @@
-# GPIO Usage Guidelines
-
-- [How to Use](#section1583613406410)
-- [Determining a GPIO Pin Number](#section135943361443)
-- [Using APIs to Operate GPIO Pins](#section69151114115315)
-
-## How to Use
+# GPIO
+
+- [Overview](#section1635911016188)
+ - [Available APIs](#section17715915181611)
+
+- [Usage Guidelines](#section259614242196)
+ - [How to Use](#section103477714216)
+ - [Determining a GPIO Pin Number](#section370083272117)
+ - [Using APIs to Operate GPIO Pins](#section13604050132118)
+
+- [Usage Example](#section25941262111)
+
+## Overview
+
+Generally, a general-purpose input/output \(GPIO\) controller manages all GPIO pins by group. Each group of GPIO pins is associated with one or more registers. The GPIO pins are operated by reading data from and writing data to the registers.
+
+The GPIO APIs define a set of standard functions for performing operations on GPIO pins, including:
+
+- Setting the pin direction, which can be input or output \(High impedance is not supported currently.\)
+
+- Reading and writing level values, which can be low or high
+- Setting an interrupt service routine \(ISR\) function and interrupt trigger mode for a pin
+- Enabling or disabling a pin interrupt
+
+### Available APIs
+
+**Table 1** APIs available for the GPIO driver
+
+
+Capability
+ |
+Function
+ |
+Description
+ |
+
+
+GPIO read/write
+ |
+GpioRead
+ |
+Reads the level value of a GPIO pin.
+ |
+
+GpioWrite
+ |
+Writes the level value of a GPIO pin.
+ |
+
+GPIO settings
+ |
+GpioSetDir
+ |
+Sets the direction for a GPIO pin.
+ |
+
+GpioGetDir
+ |
+Obtains the direction for a GPIO pin.
+ |
+
+GPIO interrupt settings
+ |
+GpioSetIrq
+ |
+Sets the ISR function for a GPIO pin.
+ |
+
+GpioUnSetIrq
+ |
+Cancels the setting of the ISR function for a GPIO pin.
+ |
+
+GpioEnableIrq
+ |
+Enables a GPIO interrupt.
+ |
+
+GpioDisableIrq
+ |
+Disables a GPIO interrupt.
+ |
+
+
+
+
+> **NOTE:**
+>All functions provided in this document can be called only in kernel mode.
+
+## Usage Guidelines
+
+### How to Use
The GPIO APIs use the GPIO pin number to specify a pin. [Figure 1](#fig1399416053717) shows the general process of using a GPIO.
**Figure 1** Process of using a GPIO
-
+
-## Determining a GPIO Pin Number
+### Determining a GPIO Pin Number
The method for converting GPIO pin numbers varies according to the GPIO controller model, parameters, and controller driver of different system on chips \(SoCs\).
-- Hi3516D V300
+- Hi3516DV300
A controller manages 12 groups of GPIO pins. Each group contains 8 GPIO pins.
@@ -25,7 +110,7 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
Example: GPIO number of GPIO10\_3 = 10 x 8 + 3 = 83
-- Hi3518E V300
+- Hi3518EV300
A controller manages 10 groups of GPIO pins. Each group contains 10 GPIO pins.
@@ -34,7 +119,7 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
Example: GPIO pin number of GPIO7\_3 = 7 x 10 + 3 = 73
-## Using APIs to Operate GPIO Pins
+### Using APIs to Operate GPIO Pins
- Set the direction for a GPIO pin.
@@ -42,12 +127,12 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
int32\_t GpioSetDir\(uint16\_t gpio, uint16\_t dir\);
- **Table 1** Description of GpioSetDir
+ **Table 2** Description of GpioSetDir
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -60,36 +145,37 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| Direction to set.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
|
- The setting is successful.
+ | Succeeded in setting the direction for a GPIO pin.
|
Negative value
|
- The setting failed.
+ | Failed to set the direction for a GPIO pin.
|
+
- Read or write the level value for a GPIO pin.
To read the level value of a GPIO pin, call the following function:
int32\_t GpioRead\(uint16\_t gpio, uint16\_t \*val\);
- **Table 2** Description of GpioRead
+ **Table 3** Description of GpioRead
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -102,9 +188,9 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| Pointer to the level value.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
@@ -124,12 +210,12 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
int32\_t GpioWrite\(uint16\_t gpio, uint16\_t val\);
- **Table 3** Description of GpioWrite
+ **Table 4** Description of GpioWrite
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -142,9 +228,9 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| Level value to write.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
@@ -194,12 +280,12 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
int32\_t GpioSetIrq\(uint16\_t gpio, uint16\_t mode, GpioIrqFunc func, void \*arg\);
- **Table 4** Description of GpioSetIrq
+ **Table 5** Description of GpioSetIrq
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -222,37 +308,37 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| Pointer to the parameters passed to the ISR function.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
|
- The setting is successful.
+ | Succeeded in setting the ISR function for a GPIO pin.
|
Negative value
|
- The setting failed.
+ | Failed to set the ISR function for a GPIO pin.
|
- > **CAUTION:**
+ > **CAUTION:**
>Only one ISR function can be set for a GPIO pin at a time. If **GpioSetIrq** is called repeatedly, the previous IRS function will be replaced.
If the ISR function is no longer required, call the following function to cancel the setting:
int32\_t GpioUnSetIrq\(uint16\_t gpio\);
- **Table 5** Description of GpioUnSetIrq
+ **Table 6** Description of GpioUnSetIrq
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -260,14 +346,14 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| GPIO pin number.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
|
- The ISR function is canceled.
+ | Succeeded in canceling the ISR function.
|
Negative value
@@ -282,12 +368,12 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
int32\_t GpioEnableIrq\(uint16\_t gpio\);
- **Table 6** Description of GpioEnableIrq
+ **Table 7** Description of GpioEnableIrq
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -295,14 +381,14 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| GPIO pin number.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
|
- The GPIO interrupt is enabled.
+ | Succeeded in enabling a GPIO interrupt.
|
Negative value
@@ -313,19 +399,19 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
|
- > **CAUTION:**
- >The configured ISR function can be responded only after the ISR function is enabled.
+ > **CAUTION:**
+ >The configured ISR function can be responded only after the GPIO interrupt is enabled.
Use the following function to disable the GPIO interrupt:
int32\_t GpioDisableIrq\(uint16\_t gpio\);
- **Table 7** Description of GpioDisableIrq
+ **Table 8** Description of GpioDisableIrq
- Parameter
+ Parameter
|
- Description
+ | Description
|
gpio
@@ -333,19 +419,19 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
| GPIO pin number.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
|
- The GPIO interrupt is disabled.
+ | Succeeded in disabling a GPIO interrupt.
|
Negative value
|
- Failed to disable the GPIO interrupt.
+ | Failed to disable a GPIO interrupt.
|
@@ -393,3 +479,82 @@ The method for converting GPIO pin numbers varies according to the GPIO controll
```
+## Usage Example
+
+In this example, we test the interrupt trigger of a GPIO pin as follows: Set the ISR function for the pin, set the trigger mode to rising edge and failing edge, write high and low levels to the pin alternately to generate level fluctuation, and observe the execution of the ISR function.
+
+Select an idle GPIO pin. This example uses a Hi3516D V300 development board and GPIO pin GPIO10\_3, which is numbered GPIO83.
+
+You can select an idle GPIO pin based on the development board and schematic diagram.
+
+```
+#include "gpio_if.h"
+#include "hdf_log.h"
+#include "osal_irq.h"
+#include "osal_time.h"
+
+static uint32_t g_irqCnt;
+
+/* ISR function */
+static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data)
+{
+ HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data);
+ g_irqCnt++; /* If the ISR function is triggered, the number of global interrupts is incremented by 1. */
+ return GpioDisableIrq(gpio);
+}
+
+/* Test case function */
+static int32_t TestCaseGpioIrqEdge(void)
+{
+ int32_t ret;
+ uint16_t valRead;
+ uint16_t mode;
+ uint16_t gpio = 83; /* Number of the GPIO pin to test */
+ uint32_t timeout;
+
+ /* Set the output direction for the pin. */
+ ret = GpioSetDir(gpio, GPIO_DIR_OUT);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret);
+ return ret;
+ }
+
+ /* Disable the interrupt of the pin. */
+ ret = GpioDisableIrq(gpio);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret);
+ return ret;
+ }
+
+ /* Set the ISR function for the pin. The trigger mode is both rising edge and falling edge. */
+ mode = OSAL_IRQF_TRIGGER_RISING | OSAL_IRQF_TRIGGER_FALLING;
+ HDF_LOGE("%s: mode:%0x\n", __func__, mode);
+ ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret);
+ return ret;
+ }
+
+ /* Enable the interrupt for this pin. */
+ ret = GpioEnableIrq(gpio);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret);
+ (void)GpioUnSetIrq(gpio);
+ return ret;
+ }
+
+ g_irqCnt = 0; /* Reset the global counter. */
+ timeout = 0; /* Reset the waiting time. */
+ /* Wait for the ISR function of this pin to trigger. The timeout duration is 1000 ms. */
+ while (g_irqCnt <= 0 && timeout < 1000) {
+ (void)GpioRead(gpio, &valRead);
+ (void)GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW);
+ HDF_LOGE("%s: wait irq timeout:%u\n", __func__, timeout);
+ OsalMDelay(200); /* wait for irq trigger */
+ timeout += 200;
+ }
+ (void)GpioUnSetIrq(gpio);
+ return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE;
+}
+```
+
diff --git a/en/device-dev/driver/i2c-usage-guidelines.md b/en/device-dev/driver/driver-platform-i2c-des.md
similarity index 37%
rename from en/device-dev/driver/i2c-usage-guidelines.md
rename to en/device-dev/driver/driver-platform-i2c-des.md
index 9a207bcc3878e779d7345ae5b14b18b0b4cdc46b..7b70a9fbd022795d0bdbfd142626fdeecf61346d 100644
--- a/en/device-dev/driver/i2c-usage-guidelines.md
+++ b/en/device-dev/driver/driver-platform-i2c-des.md
@@ -1,31 +1,94 @@
-# I2C Usage Guidelines
+# I2C
-- [How to Use](#section333203315215)
-- [Opening an I2C Controller](#section123631358135713)
-- [Performing I2C Communication](#section11091522125812)
-- [Closing an I2C Controller](#section13519505589)
+- [Overview](#section5361140416)
+ - [Available APIs](#section459052019177)
-## How to Use
+- [Usage Guidelines](#section1695201514281)
+ - [How to Use](#section1338373417288)
+ - [Opening an I2C Controller](#section13751110132914)
+ - [Performing I2C Communication](#section9202183372916)
+ - [Closing an I2C Controller](#section19481164133018)
-[Figure 1](#fig166181128151112) illustrates the process of an I2C device.
+- [Usage Example](#section5302202015300)
-**Figure 1** Process of using an I2C device
+## Overview
+- The Inter-Integrated Circuit \(I2C\) is a simple, bidirectional, and synchronous serial bus that uses merely two wires.
+- In an I2C communication, one controller communicates with one or more devices through the serial data line \(SDA\) and serial clock line \(SCL\), as shown in [Figure 1](#fig1135561232714).
-
+- I2C data transfer must begin with a **START** condition and end with a **STOP** condition. Data is transmitted byte-by-byte from the most significant bit to the least significant bit.
+- Each I2C node is recognized by a unique address and can serve as either a controller or a device. When the controller needs to communicate with a device, it writes the device address to the bus through broadcast. A device matching this address sends a response to set up a data transfer channel.
-## Opening an I2C Controller
+- The I2C APIs define a set of common functions for I2C data transfer, including:
+
+ - I2C controller management: opening or closing an I2C controller
+ - I2C message transfer: custom transfer by using a message array
+
+ **Figure 1** Physical connection diagram for I2C
+ 
+
+
+### Available APIs
+
+**Table 1** APIs available for the I2C driver
+
+
+Capability
+ |
+Function
+ |
+Description
+ |
+
+
+I2C controller management
+ |
+I2cOpen
+ |
+Opens an I2C controller.
+ |
+
+I2cClose
+ |
+Closes an I2C controller.
+ |
+
+I2C message transfer
+ |
+I2cTransfer
+ |
+Performs a custom transfer.
+ |
+
+
+
+
+> **NOTE:**
+>All functions provided in this document can be called only in kernel mode.
+
+## Usage Guidelines
+
+### How to Use
+
+[Figure 2](#fig166181128151112) illustrates the process of an I2C device.
+
+**Figure 2** Process of using an I2C device
+
+
+
+
+### Opening an I2C Controller
Call the following function to open an I2C controller:
DevHandle I2cOpen\(int16\_t number\);
-**Table 1** Description of I2cOpen
+**Table 2** Description of I2cOpen
-Parameter
+Parameter
|
-Description
+ | Description
|
@@ -34,9 +97,9 @@ DevHandle I2cOpen\(int16\_t number\);
I2C controller ID.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
NULL
@@ -65,18 +128,18 @@ if (i2cHandle == NULL) {
}
```
-## Performing I2C Communication
+### Performing I2C Communication
Use the following function for message transfer:
int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\);
-**Table 2** Description of I2cTransfer
+**Table 3** Description of I2cTransfer
-Parameter
+Parameter
|
-Description
+ | Description
|
@@ -95,9 +158,9 @@ int32\_t I2cTransfer\(DevHandle handle, struct I2cMsg \*msgs, int16\_t count\);
Length of the message array.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
Positive integer
@@ -126,7 +189,7 @@ msgs[0].addr = 0x5A; /* The address of the device to write the data is 0x5A.
msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */
msgs[1].buf = rbuff; /* Data to read */
msgs[1].len = 2; /* The length of the data to read is 2. */
-msgs[1].addr = 0x5A; /* The address of the device to read the data is 0x5A. */
+msgs[1].addr = 0x5A; /* The address of the device to read is 0x5A. */
msgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ is configured, indicating the read operation. */
/* Perform a custom transfer to transfer two messages. */
ret = I2cTransfer(i2cHandle, msgs, 2);
@@ -136,19 +199,19 @@ if (ret != 2) {
}
```
-> **CAUTION:**
+> **CAUTION:**
>- The device address in the **I2cMsg** structure does not contain the read/write flag bit. The read/write information is transferred by the read/write control bit in the member variable **flags**.
>- The **I2cTransfer** function does not limit the number of message structures, which is determined by the I2C controller.
>- The **I2cTransfer** function does not limit the data length of each message structure, which is determined by the I2C controller.
->- The **I2cTransfer** function may cause the system to sleep and therefore cannot be invoked in the interrupt context.
+>- The **I2cTransfer** function may cause the system to sleep and therefore cannot be called in the interrupt context.
-## Closing an I2C Controller
+### Closing an I2C Controller
Call the following function to close the I2C controller after the communication is complete:
-void I2cClose\(DevHandle handle\);
+void I2cClose\(DevHandle \*handle\);
-**Table 3** Description of I2cClose
+**Table 4** Description of I2cClose
Parameter
@@ -169,3 +232,195 @@ void I2cClose\(DevHandle handle\);
I2cClose(i2cHandle); /* Close the I2C controller. */
```
+## Usage Example
+
+This example describes how to use I2C APIs with an I2C device on a development board.
+
+This example shows a simple register read/write operation on TouchPad on a Hi3516D V300 development board. The basic hardware information is as follows:
+
+- SoC: hi3516dv300
+
+- Touch IC: The I2C address is 0x38, and the bit width of Touch IC's internal register is 1 byte.
+
+- Schematic diagram: TouchPad is mounted to I2C controller 3. The reset pin of Touch IC is GPIO3.
+
+In this example, first we reset Touch IC. \(The development board supplies power to Touch IC by default after being powered on, and this use case does not consider the power supply\). Then, we perform a read/write operation on an internal register to test whether the I2C channel is normal.
+
+> **NOTE:**
+>The example focuses on I2C device access and verifies the I2C channel. The read and write values of the device register are not concerned. The behavior caused by the read and write operations on the register is determined by the device itself.
+
+Example:
+
+```
+#include "i2c_if.h" /* Header file of I2C APIs */
+#include "gpio_if.h" /* Header file of GPIO APIs */
+#include "hdf_log.h" /* Header file for log APIs */
+#include "osal_io.h" /* Header file of I/O read and write APIs */
+#include "osal_time.h" /* Header file of delay and sleep APIs */
+
+/* Define a TP device structure to store I2C and GPIO hardware information. */
+struct TpI2cDevice {
+ uint16_t rstGpio; /* Reset pin */
+ uint16_t busId; /* I2C bus ID */
+ uint16_t addr; /* I2C device address */
+ uint16_t regLen; /* Register bit width */
+ DevHandle i2cHandle; /* I2C controller handle */
+};
+
+/* I2C pin I/O configuration. For details, see the SoC register manual. */
+#define I2C3_DATA_REG_ADDR 0x112f008c /* Address of the SDA pin configuration register of I2C controller 3
+#define I2C3_CLK_REG_ADDR 0x112f0090 /* Address of the SCL pin configuration register of I2C controller 3
+#define I2C_REG_CFG 0x5f1 /* Configuration values of SDA and SCL pins of I2C controller 3
+
+static void TpSocIoCfg(void)
+{
+ /* Set the I/O function of the two pins corresponding to I2C controller 3 to I2C. */
+ OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR));
+ OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR));
+}
+
+/* Initialize the reset pin of the TP. Pull up the pin for 20 ms, pull down the pin for 50 ms, and then pull up the pin for 20 ms to complete the resetting. */
+static int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice)
+{
+ int32_t ret;
+
+ /* Set the output direction for the reset pin. */
+ ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret);
+ return ret;
+ }
+
+ ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret);
+ return ret;
+ }
+ OsalMSleep(20);
+
+ ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set rst low fail!:%d", __func__, ret);
+ return ret;
+ }
+ OsalMSleep(50);
+
+ ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: set rst high fail!:%d", __func__, ret);
+ return ret;
+ }
+ OsalMSleep(20);
+
+ return HDF_SUCCESS;
+}
+
+/* Use I2cTransfer to encapsulate a register read/write auxiliary function. Use flag to indicate the read or write operation. */
+static int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr,
+ unsigned char *regData, unsigned int dataLen, uint8_t flag)
+{
+ int index = 0;
+ unsigned char regBuf[4] = {0};
+ struct I2cMsg msgs[2] = {0};
+
+ /* Perform length adaptation for the single- or dual-byte register. */
+ if (tpDevice->regLen == 1) {
+ regBuf[index++] = regAddr & 0xFF;
+ } else {
+ regBuf[index++] = (regAddr >> 8) & 0xFF;
+ regBuf[index++] = regAddr & 0xFF;
+ }
+
+ /* Fill in the I2cMsg message structure. */
+ msgs[0].addr = tpDevice->addr;
+ msgs[0].flags = 0; /* The flag is 0, indicating the write operation. */
+ msgs[0].len = tpDevice->regLen;
+ msgs[0].buf = regBuf;
+
+ msgs[1].addr = tpDevice->addr;
+ msgs[1].flags = (flag == 1)? I2C_FLAG_READ: 0; /* Add the read flag. */
+ msgs[1].len = dataLen;
+ msgs[1].buf = regData;
+
+ if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) {
+ HDF_LOGE("%s: i2c read err", __func__);
+ return HDF_FAILURE;
+ }
+ return HDF_SUCCESS;
+}
+
+/* TP register read function */
+static inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr,
+ unsigned char *regData, unsigned int dataLen)
+{
+ return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1);
+}
+
+/* TP register write function */
+static inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr,
+ unsigned char *regData, unsigned int dataLen)
+{
+ return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0);
+}
+
+/* Main entry of I2C */
+static int32_t TestCaseI2c(void)
+{
+ int32_t i;
+ int32_t ret;
+ unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC };
+ unsigned char bufRead[7] = {0};
+ static struct TpI2cDevice tpDevice;
+
+ /* I/O pin function configuration */
+ TpSocIoCfg();
+
+ /* Initialize TP device information. */
+ tpDevice.rstGpio = 3;
+ tpDevice.busId = 3;
+ tpDevice.addr = 0x38;
+ tpDevice.regLen = 1;
+ tpDevice.i2cHandle = NULL;
+
+ /* Initialize the GPIO pin. */
+ ret = TestCaseGpioInit(&tpDevice);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: gpio init fail!:%d", __func__, ret);
+ return ret;
+ }
+
+ /* Open an I2C controller. */
+ tpDevice.i2cHandle = I2cOpen(tpDevice.busId);
+ if (tpDevice.i2cHandle == NULL) {
+ HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId);
+ return -1;
+ }
+
+ /* Continuously write 7-byte data to register 0xD5 of TP-IC. */
+ ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret);
+ I2cClose(tpDevice.i2cHandle);
+ return -1;
+ }
+ OsalMSleep(10);
+
+ /* Continuously read 7-byte data from register 0xDO of TP-IC. */
+ ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret);
+ I2cClose(tpDevice.i2cHandle);
+ return -1;
+ }
+
+ HDF_LOGE("%s: tp i2c write&read reg success!", __func__);
+ for (i = 0; i < 7; i++) {
+ HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]);
+ }
+
+ /* Close the I2C controller. */
+ I2cClose(tpDevice.i2cHandle);
+ return ret;
+}
+```
+
diff --git a/en/device-dev/driver/driver-platform-mipidsi-des.md b/en/device-dev/driver/driver-platform-mipidsi-des.md
new file mode 100644
index 0000000000000000000000000000000000000000..250a419f0ee64f2364f03478a247bb11c0ff6d90
--- /dev/null
+++ b/en/device-dev/driver/driver-platform-mipidsi-des.md
@@ -0,0 +1,554 @@
+# MIPI DSI
+
+- [Overview](#section16806142183217)
+ - [Available APIs](#section129611916132011)
+
+- [Usage Guidelines](#section037231715335)
+ - [How to Use](#section49299119344)
+ - [Obtains a MIPI DSI device handle.](#section5126155683811)
+ - [Setting MIPI DSI Configuration Parameters](#section201164274344)
+ - [Sending/Receiving the Pointer to a Command](#section199401342173415)
+ - [Releasing the MIPI DSI Device Handle](#section161011610357)
+
+- [Usage Example](#section17470126123520)
+
+## 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.
+
+- 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.
+- [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
+ 
+
+
+### Available APIs
+
+**Table 1** APIs for MIPI DSI
+
+
+Capability
+ |
+Function
+ |
+Description
+ |
+
+
+Setting/Obtaining MIPI DSI configuration parameters
+ |
+MipiDsiSetCfg
+ |
+Sets configuration parameters for a MIPI DSI device.
+ |
+
+MipiDsiGetCfg
+ |
+Obtains configuration parameters of a MIPI DSI device.
+ |
+
+Obtaining /Releasing device handles
+ |
+MipiDsiOpen
+ |
+Obtains a MIPI DSI device handle.
+ |
+
+MipiDsiClose
+ |
+Releases a specified MIPI DSI device handle.
+ |
+
+Setting the LP or HS mode
+ |
+MipiDsiSetLpMode
+ |
+Sets LP mode for a MIPI DSI device.
+ |
+
+MipiDsiSetHsMode
+ |
+Sets HS mode for a MIPI DSI device.
+ |
+
+Reading/Sending commands
+ |
+MipiDsiTx
+ |
+Sends a display command set (DCS) command for sending data.
+ |
+
+MipiDsiRx
+ |
+Receives a DCS command for reading data with the specified length.
+ |
+
+
+
+
+> **NOTE:**
+>All functions described in this document can be called only in kernel space.
+
+## Usage Guidelines
+
+### How to Use
+
+[Figure 2](#fig99821771782) shows the process of using a MIPI DSI device.
+
+**Figure 2** Process of using a MIPI DSI device
+
+
+
+
+### Obtains 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.
+
+DevHandle MipiDsiOpen\(uint8\_t id\);
+
+**Table 2** Description of **MipiDsiOpen**
+
+
+Parameter
+ |
+Description
+ |
+
+
+id
+ |
+MIPI DSI channel ID.
+ |
+
+Return Value
+ |
+Description
+ |
+
+NULL
+ |
+Failed to receive the specified command.
+ |
+
+Device handle
+ |
+MIPI DSI device handle with a specified channel ID, whose data type is DevHandle.
+ |
+
+
+
+
+The following example shows how to obtain a MIPI DSI device handle with the channel ID **0**:
+
+```
+DevHandle mipiDsiHandle = NULL; /* Device handle */
+chnId = 0; /* MIPI DSI channel ID */
+
+/* Obtain the MIPI DSI device handle based on a specified channel ID. */
+mipiDsiHandle = MipiDsiOpen(chnId);
+if (mipiDsiHandle == NULL) {
+ HDF_LOGE("MipiDsiOpen: failed\n");
+ return;
+}
+```
+
+### Setting MIPI DSI Configuration Parameters
+
+- Set MIPI DSI configuration parameters by calling the following function:
+
+int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\);
+
+**Table 3** Description of **MipiDsiSetCfg**
+
+
+Parameter
+ |
+Description
+ |
+
+
+handle
+ |
+MIPI DSI device handle.
+ |
+
+cfg
+ |
+Pointer to MIPI DSI configuration parameters.
+ |
+
+Return Value
+ |
+Description
+ |
+
+0
+ |
+Succeeded in setting MIPI DSI configuration parameters.
+ |
+
+Negative value
+ |
+Failed to set MIPI DSI configuration parameters.
+ |
+
+
+
+
+```
+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(g_handle, &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**
+
+
+Parameter
+ |
+Description
+ |
+
+
+handle
+ |
+MIPI DSI device handle.
+ |
+
+cfg
+ |
+Pointer to MIPI DSI configuration parameters.
+ |
+
+Return Value
+ |
+Description
+ |
+
+0
+ |
+Succeeded in receiving the specified command.
+ |
+
+Negative value
+ |
+Failed to receive the specified command.
+ |
+
+
+
+
+```
+int32_t ret;
+struct MipiCfg cfg;
+memset(&cfg, 0, sizeof(struct MipiCfg));
+ret = MipiDsiGetCfg(g_handle, &cfg);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: GetMipiCfg fail!\n", __func__);
+ return HDF_FAILURE;
+}
+```
+
+### Sending/Receiving the Pointer to a Command
+
+- Send the pointer to a specified command by calling the following function:
+
+int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\);
+
+**Table 5** Description of **MipiDsiTx**
+
+
+Parameter
+ |
+Description
+ |
+
+
+handle
+ |
+MIPI DSI device handle.
+ |
+
+cmd
+ |
+Pointer to the command to be sent.
+ |
+
+Return Value
+ |
+Description
+ |
+
+0
+ |
+Succeeded in sending the specified command.
+ |
+
+Negative value
+ |
+Failed to send the specified command.
+ |
+
+
+
+
+```
+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);
+```
+
+- Receive a specified command by calling the following function:
+
+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 command to be received.
+ |
+
+readLen
+ |
+Length of the data to read.
+ |
+
+out
+ |
+Pointer to the read data.
+ |
+
+Return Value
+ |
+Description
+ |
+
+0
+ |
+Succeeded in receiving the specified command.
+ |
+
+Negative value
+ |
+Failed to receive the specified command.
+ |
+
+
+
+
+```
+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(g_handle);
+ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal);
+MipiDsiSetHsMode(g_handle);
+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
+
+After the MIPI DSI communication, release the MIPI DSI device handle by calling the following function:
+
+void MipiDsiClose\(DevHandle handle\);
+
+This function releases the resources requested by **MipiDsiOpen**.
+
+**Table 7** Description of **MipiDsiClose**
+
+
+Parameter
+ |
+Description
+ |
+
+
+handle
+ |
+MIPI DSI device handle.
+ |
+
+
+
+
+```
+MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */
+```
+
+## Usage Example
+
+The following is an example of using a MIPI DSI device:
+
+```
+#include "hdf.h"
+#include "mipi_dsi_if.h"
+
+void PalMipiDsiTestSample(void)
+{
+ uint8_t chnId;
+ int32_t ret;
+ DevHandle handle = NULL;
+
+ /* Device channel ID */
+ chnId = 0;
+ /* Obtain the MIPI DSI device handle based on a specified channel ID. */
+ handle = MipiDsiOpen(chnId);
+ if (handle == NULL) {
+ HDF_LOGE("MipiDsiOpen: failed!\n");
+ return;
+ }
+ /* MIPI DSI configuration parameters */
+ struct MipiCfg cfg = {0};
+ 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(g_handle, &cfg);
+ if (ret != 0) {
+ HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
+ return;
+ }
+ /* Send the command for initializing the PANEL register. */
+ struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
+ if (cmd == NULL) {
+ return;
+ }
+ cmd->dtype = DTYPE_DCS_WRITE;
+ cmd->dlen = 1;
+ cmd->payload = OsalMemCalloc(sizeof(uint8_t));
+ if (cmd->payload == NULL) {
+ HdfFree(cmd);
+ return;
+ }
+ *(cmd->payload) = DTYPE_GEN_LWRITE;
+ MipiDsiSetLpMode(mipiHandle);
+ ret = MipiDsiTx(mipiHandle, cmd);
+ MipiDsiSetHsMode(mipiHandle);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret);
+ HdfFree(cmd->payload);
+ HdfFree(cmd);
+ return;
+ }
+ HdfFree(cmd->payload);
+ HdfFree(cmd);
+ /* Pointer to the register that reads the PANEL status */
+ uint8_t readVal = 0;
+ struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
+ if (cmdRead == NULL) {
+ return;
+ }
+ cmdRead->dtype = DTYPE_DCS_READ;
+ cmdRead->dlen = 1;
+ cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
+ if (cmdRead->payload == NULL) {
+ HdfFree(cmdRead);
+ return;
+ }
+ *(cmdRead->payload) = DDIC_REG_STATUS;
+ MipiDsiSetLpMode(g_handle);
+ ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal);
+ MipiDsiSetHsMode(g_handle);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
+ HdfFree(cmdRead->payload);
+ HdfFree(cmdRead);
+ return;
+ }
+ HdfFree(cmdRead->payload);
+ HdfFree(cmdRead);
+ /* Release the MIPI DSI device handle. */
+ MipiDsiClose(handle);
+}
+```
+
diff --git a/en/device-dev/driver/rtc-usage-guidelines.md b/en/device-dev/driver/driver-platform-rtc-des.md
similarity index 61%
rename from en/device-dev/driver/rtc-usage-guidelines.md
rename to en/device-dev/driver/driver-platform-rtc-des.md
index 3d0a2f6638021e4ab54ec680a06b134a873685b8..66e8a08cf14f76bd8e32165491c4387567db8f66 100644
--- a/en/device-dev/driver/rtc-usage-guidelines.md
+++ b/en/device-dev/driver/driver-platform-rtc-des.md
@@ -1,52 +1,158 @@
-# RTC Usage Guidelines
+# RTC
-- [How to Use](#section620515765714)
-- [Creating an RTC Device Handle](#section0702183665711)
-- [Releasing the RTC Device Handle](#section639962619542)
-- [Registering RtcAlarmCallback](#section123631358135713)
-- [Performing RTC-related Operations](#section11091522125812)
+- [Overview](#section104842041574)
+ - [Available APIs](#section3373340142215)
-## How to Use
+- [Usage Guidelines](#section20636145604113)
+ - [How to Use](#section16919828134215)
+ - [Creating an RTC Device Handle](#section1131212144310)
+ - [Releasing the RTC Device Handle](#section10744117144314)
+ - [Registering RtcAlarmCallback](#section14839440184320)
+ - [Performing RTC-related Operations](#section161927578433)
+
+- [Usage Example](#section1186111020456)
+
+## Overview
+
+The real-time clock \(RTC\) driver provides precise real time for the operating system \(OS\). If the OS is powered off, the RTC driver continues to keep track of the system time using an external battery.
+
+### Available APIs
+
+**Table 1** APIs provided by the RTC driver
+
+
+Capability
+ |
+Function
+ |
+Description
+ |
+
+
+RTC handle
+ |
+RtcOpen
+ |
+Opens the RTC device to obtain its handle.
+ |
+
+RtcClose
+ |
+Releases a specified handle of the RTC device.
+ |
+
+RTC time
+ |
+RtcReadTime
+ |
+Reads time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.
+ |
+
+RtcWriteTime
+ |
+Writes time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.
+ |
+
+RTC alarm
+ |
+RtcReadAlarm
+ |
+Reads the RTC alarm time that was set last time.
+ |
+
+RtcWriteAlarm
+ |
+Writes the RTC alarm time based on the alarm index.
+ |
+
+RtcRegisterAlarmCallback
+ |
+Registers RtcAlarmCallback that will be invoked when an alarm is generated at the specified time.
+ |
+
+RtcAlarmInterruptEnable
+ |
+Enables or disables RTC alarm interrupts.
+ |
+
+RTC configuration
+ |
+RtcGetFreq
+ |
+Reads the frequency of the external crystal oscillator connected to the RTC driver.
+ |
+
+RtcSetFreq
+ |
+Sets the frequency of the external crystal oscillator connected to the RTC driver.
+ |
+
+RtcReset
+ |
+Resets the RTC.
+ |
+
+Custom register
+ |
+RtcReadReg
+ |
+Reads the configuration of a custom RTC register based on the register index.
+ |
+
+RtcWriteReg
+ |
+Writes the configuration of a custom RTC register based on the register index.
+ |
+
+
+
+
+> **NOTE:**
+>All functions provided in this document can be called only in kernel mode.
+
+## Usage Guidelines
+
+### How to Use
During the OS startup, the HDF loads the RTC driver based on the configuration file. The RTC driver detects the RTC component and initializes the driver.
-[Figure 1](#fig166181128151112) illustrates the process of an RTC device.
+[Figure 1](#fig166181128151112) illustrates the process of using an RTC device.
**Figure 1** Process of using an RTC device
-
+
-## Creating an RTC Device Handle
+### Creating an RTC Device Handle
-After the RTC driver is loaded successfully, you can use the API provided by the HDF and call APIs of the RTC driver.
+After the RTC driver is loaded, you can use the API provided by the HDF and call APIs of the RTC driver.
-> **NOTE:**
+> **NOTE:**
>Currently, only one RTC device is supported in the OS.
DevHandle RtcOpen\(void\);
-**Table 1** Description of **RtcOpen**
+**Table 2** Description of RtcOpen
-Parameter
+Parameter
|
-Description
+ | Description
|
void
|
-N/A
+ | NA
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
handle
|
-Returns the pointer if the operation is successful.
+ | Returns the if the operation is successful.
|
NULL
@@ -67,23 +173,23 @@ if (handle == NULL) {
}
```
-## Releasing the RTC Device Handle
+### Releasing the RTC Device Handle
You can call the following function to release the RTC device handle, thereby releasing resources of the device:
void RtcClose\(DevHandle handle\);
-**Table 2** Description of **RtcClose**
+**Table 3** Description of RtcClose
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle
+ | RTC device handle.
|
@@ -94,24 +200,24 @@ void RtcClose\(DevHandle handle\);
RtcClose(handle);
```
-## Registering RtcAlarmCallback
+### Registering RtcAlarmCallback
After the OS is started, call the following function to register **RtcAlarmCallback**, which will be invoked when an alarm is generated at the specified time:
int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\);
-**Table 3** Description of **RtcRegisterAlarmCallback**
+**Table 4** Description of RtcRegisterAlarmCallback
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
alarmIndex
@@ -124,9 +230,9 @@ int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmInd
| Callback that will be invoked when an alarm is generated at the specified time.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -136,7 +242,7 @@ int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmInd
|
Negative value
|
-The operation fails.
+ | The operation fails.
|
@@ -153,7 +259,7 @@ int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex)
} else if (alarmIndex == RTC_ALARM_INDEX_B) {
/* Process alarm B. */
} else {
- /* Process the error. */
+ /* Process the error. */
}
return 0;
}
@@ -165,25 +271,25 @@ if (ret != 0) {
}
```
-## Performing RTC-related Operations
+### Performing RTC-related Operations
- Reading RTC time
-Call the following function to read time information from the RTC driver, including the year, month, the day fo the week, day, hour, minute, second, and millisecond:
+Call the following function to read time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond:
int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\);
-**Table 4** Description of **RtcReadTime**
+**Table 5** Description of RtcReadTime
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
time
@@ -191,9 +297,9 @@ int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\);
| Pointer to the time information read from the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -226,17 +332,17 @@ Call the following function to set the RTC time:
int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\);
-**Table 5** Description of **RtcWriteTime**
+**Table 6** Description of RtcWriteTime
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
time
@@ -244,9 +350,9 @@ int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\);
| Pointer to the time information written into the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -262,7 +368,7 @@ int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\);
|
-> **NOTE:**
+> **NOTE:**
>The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week.
```
@@ -290,17 +396,17 @@ Call the following function to read the alarm time:
int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\);
-**Table 6** Description of **RtcReadAlarm**
+**Table 7** Description of RtcReadAlarm
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
alarmIndex
@@ -313,9 +419,9 @@ int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct R
| Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -348,17 +454,17 @@ Call the following function to set the RTC alarm time based on the alarm index:
int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\);
-**Table 7** Description of **RtcWriteAlarm**
+**Table 8** Description of RtcWriteAlarm
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
alarmIndex
@@ -371,9 +477,9 @@ int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct
| Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -383,13 +489,13 @@ int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct
|
Negative value
|
-The operation fails.
+ | The operation fails.
|
-> **NOTE:**
+> **NOTE:**
>The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week.
```
@@ -413,21 +519,21 @@ if (ret != 0) {
- Enabling or disabling alarm interrupts
-Before performing alarm operations, use this function to enable alarm interrupts, so that **RtcAlarmCallback** will be called when the alarm is not generated upon a timeout.
+Before performing alarm operations, use the following function to enable alarm interrupts, so that **RtcAlarmCallback** will be called when the alarm is not generated upon a timeout:
int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\);
-**Table 8** Description of **RtcAlarmInterruptEnable**
+**Table 9** Description of RtcAlarmInterruptEnable
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
alarmIndex
@@ -437,12 +543,12 @@ int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmInde
|
enable
|
-Whether to enable RTC alarm interrupts. Value 1 means to enable alarm interrupts and value 0 means to disable alarm interrupts.
+ | Whether to enable RTC alarm interrupts. The value 1 means to enable alarm interrupts and 0 means to disable alarm interrupts.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -474,27 +580,27 @@ Call the following function to read the frequency of the external crystal oscill
int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\);
-**Table 9** Description of **RtcGetFreq**
+**Table 10** Description of RtcGetFreq
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
freq
|
-Frequency to set for the external crystal oscillator, in Hz.
+ | Pointer to the frequency to set for the external crystal oscillator, in Hz.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -527,27 +633,27 @@ Call the following function to set the frequency of the external crystal oscilla
int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\);
-**Table 10** Description of **RtcSetFreq**
+**Table 11** Description of RtcSetFreq
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
freq
|
-Frequency to set for the external crystal oscillator, in Hz.
+ | Frequency to set for the external crystal oscillator, in Hz
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -576,26 +682,26 @@ if (ret != 0) {
- Resetting the RTC driver
-Call the following function to perform a reset on the RTC driver. After the reset, the registers are restored to the default values:
+Call the following function to perform a reset on the RTC driver \(after the reset, the registers are restored to the default values\):
int32\_t RtcReset\(DevHandle handle\);
-**Table 11** Description of **RtcReset**
+**Table 12** Description of RtcReset
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -627,32 +733,32 @@ Call the following function to read the configuration of a custom RTC register b
int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\);
-**Table 12** Description of **RtcReadReg**
+**Table 13** Description of RtcReadReg
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
usrDefIndex
|
-Index of the custom register.
+ | Index of the custom register
|
value
|
-Register value.
+ | Pointer to the register value
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -686,32 +792,32 @@ Call the following function to configure a register based on the specified regis
int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\);
-**Table 13** Description of **RtcWriteReg**
+**Table 14** Description of RtcWriteReg
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the RTC device handle.
+ | RTC device handle.
|
usrDefIndex
|
-Index of the custom register.
+ | Index of the custom register
|
value
|
-Register value.
+ | Register value
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -739,3 +845,100 @@ if (ret != 0) {
}
```
+## Usage Example
+
+This section describes the process of using RTC APIs:
+
+1. During the OS startup, the HDF identifies the RTC component in the system.
+2. The HDF initializes and creates the RTC device.
+3. You can perform operations on the RTC device by calling different APIs.
+4. Call the **RtcClose** function to release the device handle and device resources.
+
+Example:
+
+```
+#include "rtc_if.h"
+int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex)
+{
+ if (alarmIndex == RTC_ALARM_INDEX_A) {
+ /* Process alarm A. */
+ printf("RTC Alarm A callback function\n\r");
+ } else if (alarmIndex == RTC_ALARM_INDEX_B) {
+ /* Process alarm B. */
+ printf("RTC Alarm B callback function\n\r");
+ } else {
+ /* Process the error. */
+ }
+ return 0;
+}
+
+void RtcTestSample(void)
+{
+ int32_t ret;
+ struct RtcTime tm;
+ struct RtcTime alarmTime;
+ uint32_t freq;
+ DevHandle handle = NULL;
+
+ /* Obtain the RTC device handle. */
+ handle = RtcOpen();
+ if (handle == NULL) {
+ /* Process the error. */
+ }
+ /* Register RtcAlarmCallback for alarm A. */
+ ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback);
+ if (ret != 0) {
+ /* Process the error. */
+ }
+ /* Set the RTC external crystal frequency. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */
+ freq = 32768; /* 32768 Hz */
+ ret = RtcSetFreq(handle, freq);
+ if (ret != 0) {
+ /* Process the error. */
+ }
+ /* Enable the RTC alarm interrupts. */
+ ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1);
+ if (ret != 0) {
+ /* Process the error. */
+ }
+ /* Set the RTC time to 2020/01/01 00:00:10 .990. */
+ tm.year = 2020;
+ tm.month = 01;
+ tm.day = 01;
+ tm.hour= 0;
+ tm.minute = 0;
+ tm.second = 10;
+ tm.millisecond = 990;
+ /* Write the RTC time information. */
+ ret = RtcWriteTime(handle, &tm);
+ if (ret != 0) {
+ /* Process the error. */
+ }
+ /* Set the RTC alarm time to 2020/01/01 00:00:30 .100. */
+ alarmTime.year = 2020;
+ alarmTime.month = 01;
+ alarmTime.day = 01;
+ alarmTime.hour = 0;
+ alarmTime.minute = 0;
+ alarmTime.second = 30;
+ alarmTime.millisecond = 100;
+ /* Set the alarm time information for RTC_ALARM_INDEX_A. When the specified time is reached, "RTC Alarm A callback function" is printed. */
+ ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime);
+ if (ret != 0) {
+ /* Process the error. */
+ }
+
+ /* Read the RTC real time. */
+ ret = RtcReadTime(handle, &tm);
+ if (ret != 0) {
+ /* Process the error. */
+ }
+ sleep(5)
+ printf("RTC read time:\n\r");
+ printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u",
+ tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond);
+ /* Release the RTC device handle. */
+ RtcClose(handle);
+}
+```
+
diff --git a/en/device-dev/driver/sdiousage-guidelines.md b/en/device-dev/driver/driver-platform-sdio-des.md
similarity index 61%
rename from en/device-dev/driver/sdiousage-guidelines.md
rename to en/device-dev/driver/driver-platform-sdio-des.md
index 402cf305ebb98196a477530f749e0bc07f9710bd..4b5a27d35334ab5e75cbf0ea3cddffd9fd9341d3 100644
--- a/en/device-dev/driver/sdiousage-guidelines.md
+++ b/en/device-dev/driver/driver-platform-sdio-des.md
@@ -1,63 +1,215 @@
-# SDIO Usage Guidelines
+# SDIO
-- [How to Use](#section1962415610383)
-- [Opening an SDIO Controller](#section814751015461)
-- [Claiming a Host Exclusively](#section49274582455)
-- [Enabling the SDIO Device](#section1431520410489)
-- [Claiming an SDIO IRQ](#section3662781537)
-- [Performing SDIO Communication](#section391941913484)
-- [Releasing the SDIO IRQ](#section56205204481)
-- [Disabling the SDIO Device](#section181181621124815)
-- [Releasing the Exclusively Claimed Host](#section657117215486)
-- [Closing an SDIO Controller](#section1898172114818)
+- [Overview](#section1155271783811)
+ - [Available APIs](#section08064247248)
-## How to Use
+- [Usage Guidelines](#section1878939192515)
+ - [How to Use](#section1490685512255)
+ - [Opening an SDIO Controller](#section10782428132616)
+ - [Claiming a Host Exclusively](#section11263172312715)
+ - [Enabling the SDIO Device](#section17861486271)
+ - [Claiming an SDIO IRQ](#section521213262286)
+ - [Performing SDIO Communication](#section85661522153420)
+ - [Releasing the SDIO IRQ](#section1683449352)
+ - [Disabling the SDIO Device](#section15379324143611)
+ - [Releasing the Exclusively Claimed Host](#section536018263713)
+ - [Closing an SDIO Controller](#section4752739183716)
-[Figure 1](spiusage-guidelines.md#fig23885455594) illustrates the process of using an SDIO.
+- [Usage Example](#section376910122382)
-**Figure 1** Process of using an SDIO
+## Overview
+- Secure Digital Input/Output \(SDIO\) is a peripheral interface evolved from the Secure Digital \(SD\) memory card interface. The SDIO interface is compatible with SD memory cards and can be connected to devices that support the SDIO interface.
+- SDIO is widely used. Currently, many smartphones support SDIO, and many SDIO peripherals are developed for connections to smartphones. Common SDIO peripherals include WLAN, GPS, cameras, and Bluetooth.
+- The SDIO bus has two ends, named host and device. All communication starts when the host sends a command. The device can communicate with the host as long as it can parse the command of the host. An SDIO host can connect to multiple devices, as shown in the figure below.
-
+ - CLK signal: clock signal sent from the host to the device
+ - VDD signal: power signal
+ - VSS signal: ground signal
+ - D0-3 signal: four data lines. The DAT1 signal cable is multiplexed as the interrupt line. In 1-bit mode, DAT0 is used to transmit data. In 4-bit mode, DAT0 to DAT3 are used to transmit data.
+ - CMD signal: used by the host to send commands and the device to respond to commands.
-## Opening an SDIO Controller
+ **Figure 1** Connections between the host and devices in SDIO
+
+
+ 
+
+- The SDIO interface defines a set of common methods for operating an SDIO device, including opening and closing an SDIO controller, exclusively claiming and releasing the host, enabling and disabling devices, claiming and releasing an SDIO IRQ, reading and writing data based on SDIO, and obtaining and setting common information.
+
+### Available APIs
+
+**Table 1** APIs available for the SDIO driver
+
+
+Capability
+ |
+Function
+ |
+Description
+ |
+
+
+SDIO device opening/closing
+ |
+SdioOpen
+ |
+Opens an SDIO controller with a specified bus number.
+ |
+
+SdioClose
+ |
+Closes an SDIO controller.
+ |
+
+SDIO reading/writing
+ |
+SdioReadBytes
+ |
+Incrementally reads a given length of data from a specified SDIO address.
+ |
+
+SdioWriteBytes
+ |
+Incrementally writes a given length of data into a specified SDIO address.
+ |
+
+SdioReadBytesFromFixedAddr
+ |
+Reads a given length of data from a fixed SDIO address.
+ |
+
+SdioWriteBytesToFixedAddr
+ |
+Writes a given length of data into a fixed SDIO address.
+ |
+
+SdioReadBytesFromFunc0
+ |
+Reads a given length of data from the address space of SDIO function 0.
+ |
+
+SdioWriteBytesToFunc0
+ |
+Writes a given length of data into the address space of SDIO function 0.
+ |
+
+SDIO block size setting
+ |
+SdioSetBlockSize
+ |
+Sets the block size.
+ |
+
+SDIO common information retrieval/setting
+ |
+SdioGetCommonInfo
+ |
+Obtains common information.
+ |
+
+SdioSetCommonInfo
+ |
+Sets common information.
+ |
+
+SDIO data flushing
+ |
+SdioFlushData
+ |
+Flushes data.
+ |
+
+SDIO host exclusively claiming or releasing
+ |
+SdioClaimHost
+ |
+Claims a host exclusively.
+ |
+
+SdioReleaseHost
+ |
+Releases the exclusively claimed host.
+ |
+
+SDIO device enablement
+ |
+SdioEnableFunc
+ |
+Enables an SDIO device.
+ |
+
+SdioDisableFunc
+ |
+Disables an SDIO device.
+ |
+
+SDIO IRQ claiming/releasing
+ |
+SdioClaimIrq
+ |
+Claims an SDIO IRQ.
+ |
+
+SdioReleaseIrq
+ |
+Releases an SDIO IRQ.
+ |
+
+
+
+
+> **NOTE:**
+>All functions provided in this document can be called only in kernel mode.
+
+## Usage Guidelines
+
+### How to Use
+
+[Figure 2](#fig1343742311264) illustrates the process of using an SDIO.
+
+**Figure 2** Process of using an SDIO
+
+
+
+
+### Opening an SDIO Controller
Before performing SDIO communication, obtain the device handle of an SDIO controller by calling **SdioOpen**. This function returns the device handle of the SDIO controller with a specified bus number.
DevHandle SdioOpen\(int16\_t mmcBusNum, struct SdioFunctionConfig \*config\);
-**Table 1** Parameters and return values of SdioOpen
+**Table 2** Parameters and return values of SdioOpen
-
-Parameter
+
+Parameter
|
-Description
+ | Description
|
-mmcBusNum
+ | mmcBusNum
|
-Bus number.
+ | Bus number.
|
-config
+ | config
|
-SDIO functionality configurations.
+ | SDIO functionality configurations.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
-NULL
+ | NULL
|
-Failed to obtain the device handle of an SDIO controller.
+ | Failed to obtain the device handle of an SDIO controller.
|
-Device handle
+ | Device handle
|
-Device handle of an SDIO controller.
+ | Device handle of an SDIO controller.
|
@@ -78,24 +230,24 @@ if (handle == NULL) {
}
```
-## Claiming a Host Exclusively
+### Claiming a Host Exclusively
After obtaining the device handle of an SDIO controller, exclusively claim the host before performing subsequent operations on the SDIO device.
void SdioClaimHost\(DevHandle handle\);
-**Table 2** Parameter description of SdioClaimHost
+**Table 3** Parameter description of SdioClaimHost
-
-Parameter
+
+Parameter
|
-Description
+ | Description
|
-handle
+ | handle
|
-Device handle of an SDIO controller.
+ | Device handle of an SDIO controller.
|
@@ -107,13 +259,13 @@ The following example shows how to exclusively claim a host.
SdioClaimHost(handle); /* Claim a host exclusively. */
```
-## Enabling the SDIO Device
+### Enabling the SDIO Device
Before accessing a register, enable the SDIO device.
int32\_t SdioEnableFunc\(DevHandle handle\);
-**Table 3** Parameters and return values of SdioEnableFunc
+**Table 4** Parameters and return values of SdioEnableFunc
Parameter
@@ -127,9 +279,9 @@ int32\_t SdioEnableFunc\(DevHandle handle\);
| Device handle of an SDIO controller.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -156,13 +308,13 @@ if (ret != 0) {
}
```
-## Claiming an SDIO IRQ
+### Claiming an SDIO IRQ
Before SDIO communication, claim an SDIO IRQ.
int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\);
-**Table 4** Parameters and return values of SdioClaimIrq
+**Table 5** Parameters and return values of SdioClaimIrq
Parameter
@@ -181,9 +333,9 @@ int32\_t SdioClaimIrq\(DevHandle handle, SdioIrqHandler \*handler\);
| Pointer to the SDIO IRQ function.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -220,7 +372,7 @@ if (ret != 0) {
}
```
-## Performing SDIO Communication
+### Performing SDIO Communication
- Incrementally write a given length of data into the SDIO device.
@@ -228,7 +380,7 @@ The corresponding function is as follows:
int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\);
-**Table 5** Parameters and return values of SdioWriteBytes
+**Table 6** Parameters and return values of SdioWriteBytes
Parameter
@@ -257,9 +409,9 @@ int32\_t SdioWriteBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint
| Length of the data to write.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -294,7 +446,7 @@ The corresponding function is as follows:
int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\);
-**Table 6** Parameters and return values of SdioReadBytes
+**Table 7** Parameters and return values of SdioReadBytes
Parameter
@@ -323,9 +475,9 @@ int32\_t SdioReadBytes\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint3
| Length of the data to read.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -360,7 +512,7 @@ if (ret != 0) {
int32\_t SdioWriteBytesToFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\);
- **Table 7** Parameters and return values of SdioWriteBytesToFixedAddr
+ **Table 8** Parameters and return values of SdioWriteBytesToFixedAddr
Parameter
@@ -391,12 +543,12 @@ if (ret != 0) {
|
scatterLen
|
- Length of the scatter list. If the value is not 0, the data is of the scatter list type.
+ | Length of the scatter list. If the value is not 0, the data is of the scatter list type.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
@@ -431,7 +583,7 @@ if (ret != 0) {
int32\_t SdioReadBytesFromFixedAddr\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size, uint32\_t scatterLen\);
- **Table 8** Parameters and return values of SdioReadBytesFromFixedAddr
+ **Table 9** Parameters and return values of SdioReadBytesFromFixedAddr
Parameter
@@ -462,12 +614,12 @@ if (ret != 0) {
|
scatterLen
|
- Length of the scatter list. If the value is not 0, the data is of the scatter list type.
+ | Length of the scatter list. If the value is not 0, the data is of the scatter list type.
|
- Return Value
+ | Return Value
|
- Description
+ | Description
|
0
@@ -497,13 +649,13 @@ if (ret != 0) {
```
-- Write a given length of data into the address space of SDIO function 0.
+- Writes a given length of data into the address space of SDIO function 0.
Currently, only 1-byte data can be written. The corresponding function is as follows:
int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\);
-**Table 9** Parameters and return values of SdioWriteBytesToFunc0
+**Table 10** Parameters and return values of SdioWriteBytesToFunc0
Parameter
@@ -532,9 +684,9 @@ int32\_t SdioWriteBytesToFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t add
| Length of the data to write.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -562,13 +714,13 @@ if (ret != 0) {
}
```
-- Read a given length of data from the address space of SDIO function 0.
+- Reads a given length of data from the address space of SDIO function 0.
Currently, only 1-byte data can be read. The corresponding function is as follows:
int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t addr, uint32\_t size\);
-**Table 10** Parameters and return values of SdioReadBytesFromFunc0
+**Table 11** Parameters and return values of SdioReadBytesFromFunc0
Parameter
@@ -597,9 +749,9 @@ int32\_t SdioReadBytesFromFunc0\(DevHandle handle, uint8\_t \*data, uint32\_t ad
| Length of the data to read.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -627,13 +779,13 @@ if (ret != 0) {
}
```
-## Releasing the SDIO IRQ
+### Releasing the SDIO IRQ
After the SDIO communication, release the SDIO IRQ.
int32\_t SdioReleaseIrq\(DevHandle handle\);
-**Table 11** Parameters and return values of SdioReleaseIrq
+**Table 12** Parameters and return values of SdioReleaseIrq
Parameter
@@ -647,9 +799,9 @@ int32\_t SdioReleaseIrq\(DevHandle handle\);
| Device handle of an SDIO controller.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -676,13 +828,13 @@ if (ret != 0) {
}
```
-## Disabling the SDIO Device
+### Disabling the SDIO Device
After the SDIO communication, disable the SDIO device.
int32\_t SdioDisableFunc\(DevHandle handle\);
-**Table 12** Parameters and return values of SdioDisableFunc
+**Table 13** Parameters and return values of SdioDisableFunc
Parameter
@@ -696,9 +848,9 @@ int32\_t SdioDisableFunc\(DevHandle handle\);
| Device handle of an SDIO controller.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -725,13 +877,13 @@ if (ret != 0) {
}
```
-## Releasing the Exclusively Claimed Host
+### Releasing the Exclusively Claimed Host
After the SDIO communication, release the exclusively claimed host.
void SdioReleaseHost\(DevHandle handle\);
-**Table 13** Parameter description of SdioReleaseHost
+**Table 14** Parameter description of SdioReleaseHost
Parameter
@@ -754,7 +906,7 @@ The following example shows how to release the exclusively claimed host.
SdioReleaseHost(handle); /* Release the exclusively claimed host. */
```
-## Closing an SDIO Controller
+### Closing an SDIO Controller
After the SDIO communication, close the SDIO controller.
@@ -762,7 +914,7 @@ void SdioClose\(DevHandle handle\);
This function releases the resources requested.
-**Table 14** Parameter description of SdioClose
+**Table 15** Parameter description of SdioClose
Parameter
@@ -785,3 +937,132 @@ The following example shows how to close an SDIO controller.
SdioClose(handle); /* Close an SDIO controller. */
```
+## Usage Example
+
+The following example shows how to use an SDIO device. First, open an SDIO controller whose bus number is 1, exclusively claim a host, enable the SDIO device, claim an SDIO IRQ, and then perform SDIO communication \(such as reading and writing\). After the SDIO communication, release the SDIO IRQ, disable the SDIO device, release the host, and close the SDIO controller.
+
+```
+#include "hdf_log.h"
+#include "sdio_if.h"
+
+#define TEST_FUNC_NUM 1 /* The I/O function whose ID is 1 is used. */
+#define TEST_FBR_BASE_ADDR 0x100 /* FBR base address of the I/O function whose ID is 1 */
+#define TEST_ADDR_OFFSET 9 /* Address offset of the register to read or write */
+#define TEST_DATA_LEN 3 /* Length of the data to read or write */
+#define TEST_BLOCKSIZE 2 /* Size of a data block, in bytes */
+
+/* Implement the SDIO IRQ function based on the application. */
+static void SdioIrqFunc(void *data)
+{
+ if (data == NULL) {
+ HDF_LOGE("SdioIrqFunc: data is NULL.\n");
+ return;
+ }
+ /* You need to add specific implementations. */
+}
+
+void SdioTestSample(void)
+{
+ int32_t ret;
+ DevHandle handle = NULL;
+ uint8_t data[TEST_DATA_LEN] = {0};
+ struct SdioFunctionConfig config = {1, 0x123, 0x456};
+ uint8_t val;
+ uint32_t addr;
+
+ /* Open an SDIO controller whose bus number is 1. */
+ handle = SdioOpen(1, &config);
+ if (handle == NULL) {
+ HDF_LOGE("SdioOpen: failed!\n");
+ return;
+ }
+ /* Claim a host exclusively. */
+ SdioClaimHost(handle);
+ /* Enable the SDIO device. */
+ ret = SdioEnableFunc(handle);
+ if (ret != 0) {
+ HDF_LOGE("SdioEnableFunc: failed, ret %d\n", ret);
+ goto ENABLE_ERR;
+ }
+ /* Claim an SDIO IRQ. */
+ ret = SdioClaimIrq(handle, SdioIrqFunc);
+ if (ret != 0) {
+ HDF_LOGE("SdioClaimIrq: failed, ret %d\n", ret);
+ goto CLAIM_IRQ_ERR;
+ }
+ /* Set the block size to 2 bytes. */
+ ret = SdioSetBlockSize(handle, TEST_BLOCKSIZE);
+ if (ret != 0) {
+ HDF_LOGE("SdioSetBlockSize: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Read 3-byte data from the incremental address of an SDIO device. */
+ addr = TEST_FBR_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET;
+ ret = SdioReadBytes(handle, data, addr, TEST_DATA_LEN);
+ if (ret != 0) {
+ HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Write 3-byte data into the incremental address of an SDIO device. */
+ ret = SdioWriteBytes(handle, data, addr, TEST_DATA_LEN);
+ if (ret != 0) {
+ HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Read 1-byte data from the SDIO device. */
+ ret = SdioReadBytes(handle, &val, addr, 1);
+ if (ret != 0) {
+ HDF_LOGE("SdioReadBytes: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Write 1-byte data into the SDIO device. */
+ ret = SdioWriteBytes(handle, &val, addr, 1);
+ if (ret != 0) {
+ HDF_LOGE("SdioWriteBytes: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Read 3-byte data from the fixed address of an SDIO device. */
+ ret = SdioReadBytesFromFixedAddr(handle, data, addr, TEST_DATA_LEN, 0);
+ if (ret != 0) {
+ HDF_LOGE("SdioReadBytesFromFixedAddr: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Write 1-byte data to the fixed address of an SDIO device. */
+ ret = SdioWriteBytesToFixedAddr(handle, data, addr, 1, 0);
+ if (ret != 0) {
+ HDF_LOGE("SdioWriteBytesToFixedAddr: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Read 1-byte data from SDIO function 0. */
+ addr = 0x02;
+ ret = SdioReadBytesFromFunc0(handle, &val, addr, 1);
+ if (ret != 0) {
+ HDF_LOGE("SdioReadBytesFromFunc0: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+ /* Write 1-byte data into SDIO function 0. */
+ ret = SdioWriteBytesToFunc0(handle, &val, addr, 1);
+ if (ret != 0) {
+ HDF_LOGE("SdioWriteBytesToFunc0: failed, ret %d\n", ret);
+ goto COMM_ERR;
+ }
+COMM_ERR:
+ /* Release the SDIO IRQ. */
+ ret = SdioReleaseIrq(handle);
+ if (ret != 0) {
+ HDF_LOGE("SdioReleaseIrq: failed, ret %d\n", ret);
+ }
+CLAIM_IRQ_ERR:
+ /* Disable the SDIO device. */
+ ret = SdioDisableFunc(handle);
+ if (ret != 0) {
+ HDF_LOGE("SdioDisableFunc: failed, ret %d\n", ret);
+ }
+ENABLE_ERR:
+ /* Release the exclusively claimed host. */
+ SdioReleaseHost(handle);
+ /* Close an SDIO controller. */
+ SdioClose(handle);
+}
+```
+
diff --git a/en/device-dev/driver/spiusage-guidelines.md b/en/device-dev/driver/driver-platform-spi-des.md
similarity index 51%
rename from en/device-dev/driver/spiusage-guidelines.md
rename to en/device-dev/driver/driver-platform-spi-des.md
index f5f9c482c055005b3544881cf16ef8e4e197abc3..b2c1b31147091e2d28ff902727f8ec7c1abfef80 100644
--- a/en/device-dev/driver/spiusage-guidelines.md
+++ b/en/device-dev/driver/driver-platform-spi-des.md
@@ -1,33 +1,143 @@
-# SPI Usage Guidelines
+# SPI
-- [How to Use](#section691514116412)
-- [Obtaining an SPI Device Handle](#section12372204616215)
-- [Obtaining SPI Device Configuration Parameters](#section17121446171311)
-- [Setting SPI Device Configuration Parameters](#section97691946634)
-- [Performing SPI Communication](#section197116254416)
-- [Destroying the SPI Device Handle](#section117661819108)
+- [Overview](#section193356154511)
+ - [Available APIs](#section232141411476)
-## How to Use
+- [Usage Guidelines](#section71363452477)
+ - [How to Use](#section32846814820)
+ - [Obtaining an SPI Device Handle](#section1927265711481)
+ - [Obtaining SPI Device Configuration Parameters](#section541133418493)
+ - [Setting SPI Device Configuration Parameters](#section7870106145010)
+ - [Performing SPI Communication](#section13324155195013)
+ - [Destroying the SPI Device Handle](#section19661632135117)
-[Figure 1](#fig23885455594) shows the process of using an SPI device.
+- [Usage Example](#section06541058155120)
-**Figure 1** Process of using an SPI device
+## Overview
+- Serial Peripheral Interface \(SPI\) is a serial bus specification used for high-speed, full-duplex, and synchronous communication.
+- SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital \(A/D\) converters.
+- SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires:
+ - SCLK: clock signals output from the SPI controller
+ - MOSI: data output from the SPI controller and input into an SPI device
+ - MISO: data output from an SPI device and input into the SPI controller
+ - CS: signals enabled by an SPI device and controlled by the SPI controller
-
-## Obtaining an SPI Device Handle
+- [Figure 1](#fig15227181812587) shows the connection between one SPI controller and two SPI devices \(device A and device B\). In this figure, device A and device B share three pins \(SCLK, MISO, and MOSI\) of the controller. CS0 of device A and CS1 of device B are connected to CS0 and CS1 of the controller, respectively.
+
+**Figure 1** SPI controller/device connection
+
+
+
+
+- SPI communication is usually initiated by the SPI controller and is operated as follows:
+
+1. A single SPI device is selected at a time via the CS to communicate with the SPI controller.
+2. Clock signals are provided for the selected SPI device via the SCLK.
+3. The SPI controller sends data to SPI devices via the MOSI, and receives data from SPI devices via the MISO.
+
+- SPI can work in one of the following four modes, equivalent to one of the four possible states for Clock Polarity \(CPOL\) and Clock Phase \(CPHA\):
+ - If both CPOL and CPHA are **0**, the clock signal level is low in the idle state and data is sampled on the first clock edge.
+ - If CPOL is **0** and CPHA is **1**, the clock signal level is low in the idle state and data is sampled on the second clock edge.
+ - If CPOL is **1** and CPHA is **0**, the clock signal level is high in the idle state and data is sampled on the first clock edge.
+ - If both CPOL and CPHA are **1**, the clock signal level is high in the idle state and data is sampled on the second clock edge.
+
+
+- SPI defines a set of common functions for operating an SPI device, including those for:
+ - Obtaining and releasing the handle of an SPI device.
+ - Reading or writing data of a specified length from or into an SPI device.
+ - Customizing data reading or writing via **SpiMsg**.
+ - Obtaining and setting SPI device configuration parameters.
+
+
+> **NOTE:**
+>Currently, these functions are only applicable in the communication initiated by the SPI controller.
+
+### Available APIs
+
+**Table 1** APIs for the SPI driver
+
+
+Capability
+ |
+Function
+ |
+Description
+ |
+
+
+SPI device handle obtaining/releasing
+ |
+SpiOpen
+ |
+Obtains an SPI device handle.
+ |
+
+SpiClose
+ |
+Releases an SPI device handle.
+ |
+
+SPI reading/writing
+ |
+SpiRead
+ |
+Reads data of a specified length from an SPI device.
+ |
+
+SpiWrite
+ |
+Writes data of a specified length into an SPI device.
+ |
+
+SpiTransfer
+ |
+Transfers SPI data.
+ |
+
+SPI device configuration
+
+ |
+SpiSetCfg
+ |
+Sets configuration parameters for an SPI device.
+ |
+
+SpiGetCfg
+ |
+Obtains configuration parameters of an SPI device.
+ |
+
+
+
+
+> **NOTE:**
+>All functions provided in this document can be called only in kernel space.
+
+## Usage Guidelines
+
+### How to Use
+
+[Figure 2](#fig23885455594) shows the process of using an SPI device.
+
+**Figure 2** Process of using an SPI device
+
+
+
+
+### Obtaining an SPI Device Handle
Before performing SPI communication, obtain an SPI device handle by calling **SpiOpen**. This function returns an SPI device handle with a specified bus number and CS number.
DevHandle SpiOpen\(const struct SpiDevInfo \*info\);
-**Table 1** Description of **SpiOpen**
+**Table 2** Description of **SpiOpen**
-Parameter
+Parameter
|
-Description
+ | Description
|
info
@@ -35,9 +145,9 @@ DevHandle SpiOpen\(const struct SpiDevInfo \*info\);
| Pointer to the SPI device descriptor.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
NULL
@@ -69,23 +179,23 @@ if (spiHandle == NULL) {
}
```
-## Obtaining SPI Device Configuration Parameters
+### Obtaining SPI Device Configuration Parameters
After obtaining the SPI device handle, obtain the SPI device configuration parameters by calling the following function:
int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
-**Table 2** Description of **SpiGetCfg**
+**Table 3** Description of **SpiGetCfg**
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the SPI device handle.
+ | SPI device handle.
|
cfg
@@ -93,9 +203,9 @@ int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
| Pointer to SPI device configuration parameters.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -114,29 +224,29 @@ int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
```
int32_t ret;
struct SpiCfg cfg = {0}; /* SPI configuration information */
-ret = PalSpiSetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */
+ret = SpiGetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */
if (ret != 0) {
HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret);
}
```
-## Setting SPI Device Configuration Parameters
+### Setting SPI Device Configuration Parameters
After obtaining the SPI device handle, set SPI device configuration parameters by calling the following function:
int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
-**Table 3** Description of **SpiSetCfg**
+**Table 4** Description of **SpiSetCfg**
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the SPI device handle.
+ | SPI device handle.
|
cfg
@@ -144,9 +254,9 @@ int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
| Pointer to SPI device configuration parameters.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -165,8 +275,8 @@ int32\_t SpiSetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
```
int32_t ret;
struct SpiCfg cfg = {0}; /* SPI configuration information */
-cfg.mode = SPI_MODE_LOOP; /* Communicate in loopback mode. */
-cfg.comMode = PAL_SPI_POLLING_TRANSFER; /* Communicate in polling mode. */
+cfg.mode = SPI_MODE_LOOP; /* Communication in loopback mode */
+cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* Communication in polling mode */
cfg.maxSpeedHz = 115200; /* Maximum transmission frequency */
cfg.bitsPerWord = 8; /* The width of per word to be read or written is 8 bits. */
ret = SpiSetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */
@@ -175,25 +285,25 @@ if (ret != 0) {
}
```
-## Performing SPI Communication
+### Performing SPI Communication
-- Writing data of a specified length into an SPI device
+- Writing data of a specific length into an SPI device
To write data into an SPI device only once, call the following function:
int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\);
-**Table 4** Description of **SpiWrite**
+**Table 5** Description of **SpiWrite**
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the SPI device handle.
+ | SPI device handle.
|
buf
@@ -206,9 +316,9 @@ int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\);
| Length of the data to write.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -227,30 +337,30 @@ int32\_t SpiWrite\(DevHandle handle, uint8\_t \*buf, uint32\_t len\);
```
int32_t ret;
uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78};
-/* Write data of a specified length into an SPI device. */
+/* Write data of a specific length into an SPI device. */
ret = SpiWrite(spiHandle, wbuff, 4);
if (ret != 0) {
HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
}
```
-- Reading data of a specified length from an SPI device
+- Reading data of a specific length from an SPI device
To read data from an SPI device only once, call the following function:
int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\);
-**Table 5** Description of **SpiRead**
+**Table 6** Description of **SpiRead**
-Parameter
+Parameter
|
-Description
+ | Description
|
handle
|
-Pointer to the SPI device handle.
+ | SPI device handle.
|
buf
@@ -263,9 +373,9 @@ int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\);
| Length of the data to read.
|
-Return Value
+ | Return Value
|
-Description
+ | Description
|
0
@@ -284,7 +394,7 @@ int32\_t SpiRead\(DevHandle handle, uint8\_t \*buf, uint32\_t len\);
```
int32_t ret;
uint8_t rbuff[4] = {0};
-/* Read data of a specified length from an SPI device. */
+/* Read data of a specific length from an SPI device. */
ret = SpiRead(spiHandle, rbuff, 4);
if (ret != 0) {
HDF_LOGE("SpiRead: failed, ret %d\n", ret);
@@ -297,17 +407,17 @@ To launch a custom transfer, call the following function:
int32\_t SpiTransfer\(DevHandle handle, struct SpiMsg \*msgs, uint32\_t count\);
-**Table 6** Description of **SpiTransfer**
+**Table 7** Description of **SpiTransfer**
- |
|
|
|
|
|
|
|
|
|
|
---|
|
---|
|
|
|
|
|
|
|
|
|
|
|
---|
|
---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---|
|
|
|
|
---|
|
|
---|
|
|
---|
|
|
|
|
|
|
|
|
|
|
|