Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
d31322d7
D
Docs
项目概览
OpenHarmony
/
Docs
大约 1 年 前同步成功
通知
159
Star
292
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
d31322d7
编写于
6月 12, 2023
作者:
O
openharmony_ci
提交者:
Gitee
6月 12, 2023
浏览文件
操作
浏览文件
下载
差异文件
!19440 Platform文档刷新
Merge pull request !19440 from 贾子扬/master
上级
ff9ea225
952ecd1c
变更
33
展开全部
隐藏空白更改
内联
并排
Showing
33 changed file
with
7210 addition
and
6374 deletion
+7210
-6374
zh-cn/device-dev/driver/driver-platform-adc-des.md
zh-cn/device-dev/driver/driver-platform-adc-des.md
+39
-38
zh-cn/device-dev/driver/driver-platform-adc-develop.md
zh-cn/device-dev/driver/driver-platform-adc-develop.md
+333
-302
zh-cn/device-dev/driver/driver-platform-dac-des.md
zh-cn/device-dev/driver/driver-platform-dac-des.md
+53
-46
zh-cn/device-dev/driver/driver-platform-dac-develop.md
zh-cn/device-dev/driver/driver-platform-dac-develop.md
+286
-264
zh-cn/device-dev/driver/driver-platform-gpio-des.md
zh-cn/device-dev/driver/driver-platform-gpio-des.md
+137
-131
zh-cn/device-dev/driver/driver-platform-gpio-develop.md
zh-cn/device-dev/driver/driver-platform-gpio-develop.md
+412
-374
zh-cn/device-dev/driver/driver-platform-hdmi-des.md
zh-cn/device-dev/driver/driver-platform-hdmi-des.md
+171
-141
zh-cn/device-dev/driver/driver-platform-hdmi-develop.md
zh-cn/device-dev/driver/driver-platform-hdmi-develop.md
+61
-44
zh-cn/device-dev/driver/driver-platform-i2c-des.md
zh-cn/device-dev/driver/driver-platform-i2c-des.md
+34
-36
zh-cn/device-dev/driver/driver-platform-i2c-develop.md
zh-cn/device-dev/driver/driver-platform-i2c-develop.md
+260
-243
zh-cn/device-dev/driver/driver-platform-i3c-des.md
zh-cn/device-dev/driver/driver-platform-i3c-des.md
+147
-136
zh-cn/device-dev/driver/driver-platform-i3c-develop.md
zh-cn/device-dev/driver/driver-platform-i3c-develop.md
+195
-172
zh-cn/device-dev/driver/driver-platform-mipicsi-des.md
zh-cn/device-dev/driver/driver-platform-mipicsi-des.md
+422
-300
zh-cn/device-dev/driver/driver-platform-mipicsi-develop.md
zh-cn/device-dev/driver/driver-platform-mipicsi-develop.md
+317
-293
zh-cn/device-dev/driver/driver-platform-mipidsi-des.md
zh-cn/device-dev/driver/driver-platform-mipidsi-des.md
+226
-223
zh-cn/device-dev/driver/driver-platform-mipidsi-develop.md
zh-cn/device-dev/driver/driver-platform-mipidsi-develop.md
+218
-196
zh-cn/device-dev/driver/driver-platform-mmc-develop.md
zh-cn/device-dev/driver/driver-platform-mmc-develop.md
+354
-335
zh-cn/device-dev/driver/driver-platform-pin-des.md
zh-cn/device-dev/driver/driver-platform-pin-des.md
+94
-81
zh-cn/device-dev/driver/driver-platform-pin-develop.md
zh-cn/device-dev/driver/driver-platform-pin-develop.md
+407
-386
zh-cn/device-dev/driver/driver-platform-pwm-des.md
zh-cn/device-dev/driver/driver-platform-pwm-des.md
+98
-80
zh-cn/device-dev/driver/driver-platform-pwm-develop.md
zh-cn/device-dev/driver/driver-platform-pwm-develop.md
+267
-244
zh-cn/device-dev/driver/driver-platform-regulator-des.md
zh-cn/device-dev/driver/driver-platform-regulator-des.md
+107
-87
zh-cn/device-dev/driver/driver-platform-regulator-develop.md
zh-cn/device-dev/driver/driver-platform-regulator-develop.md
+173
-170
zh-cn/device-dev/driver/driver-platform-rtc-des.md
zh-cn/device-dev/driver/driver-platform-rtc-des.md
+254
-162
zh-cn/device-dev/driver/driver-platform-rtc-develop.md
zh-cn/device-dev/driver/driver-platform-rtc-develop.md
+273
-241
zh-cn/device-dev/driver/driver-platform-sdio-des.md
zh-cn/device-dev/driver/driver-platform-sdio-des.md
+260
-221
zh-cn/device-dev/driver/driver-platform-sdio-develop.md
zh-cn/device-dev/driver/driver-platform-sdio-develop.md
+282
-254
zh-cn/device-dev/driver/driver-platform-spi-des.md
zh-cn/device-dev/driver/driver-platform-spi-des.md
+209
-170
zh-cn/device-dev/driver/driver-platform-spi-develop.md
zh-cn/device-dev/driver/driver-platform-spi-develop.md
+377
-338
zh-cn/device-dev/driver/driver-platform-uart-des.md
zh-cn/device-dev/driver/driver-platform-uart-des.md
+72
-50
zh-cn/device-dev/driver/driver-platform-uart-develop.md
zh-cn/device-dev/driver/driver-platform-uart-develop.md
+381
-358
zh-cn/device-dev/driver/driver-platform-watchdog-des.md
zh-cn/device-dev/driver/driver-platform-watchdog-des.md
+69
-56
zh-cn/device-dev/driver/driver-platform-watchdog-develop.md
zh-cn/device-dev/driver/driver-platform-watchdog-develop.md
+222
-202
未找到文件。
zh-cn/device-dev/driver/driver-platform-adc-des.md
浏览文件 @
d31322d7
...
...
@@ -4,29 +4,30 @@
### 功能简介<a name="section2"></a>
ADC(Analog to Digital Converter),即模拟-数字转换器,可将模拟信号转换成对应的数字信号,便于存储与计算等操作。除电源线和地线之外,ADC只需要1根线与被测量的设备进行连接,其物理连线如图1:
ADC(Analog to Digital Converter),即模拟-数字转换器,可将模拟信号转换成对应的数字信号,便于存储与计算等操作。除电源线和地线之外,ADC只需要1根线与被测量的设备进行连接,其物理连线如图1
所示
:
**图 1**
ADC物理连线示意图
<a
name=
"fig1"
></a>
![
](
figures/ADC物理连线示意图.png
"ADC物理连线示意图"
)
![
ADC物理连线示意图
](
figures/ADC物理连线示意图.png
)
ADC接口定义了完成AD转换的通用方法集合,包括:
-
ADC设备管理:打开或关闭ADC设备。
-
ADC读取转换结果:读取AD转换结果。
### 基本概念<a name="section3"></a>
-
分辨率
分辨率指的是ADC模块能够转换的二进制位数,位数越多分辨率越高。
分辨率指的是ADC模块能够转换的二进制位数,位数越多分辨率越高。
-
转换误差
转换误差通常是以输出误差的最大值形式给出。它表示A/D转换器实际输出的数字量和理论上的输出数字量之间的差别。常用最低有效位的倍数表示。
转换误差通常是以输出误差的最大值形式给出。它表示A/D转换器实际输出的数字量和理论上的输出数字量之间的差别。常用最低有效位的倍数表示。
-
转换时间
转换时间是指A/D转换器从转换控制信号到来开始,到输出端得到稳定的数字信号所经过的时间。
转换时间是指A/D转换器从转换控制信号到来开始,到输出端得到稳定的数字信号所经过的时间。
### 运作机制<a name="section4"></a>
...
...
@@ -50,18 +51,18 @@ ADC模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/
<a
name=
"table1"
></a>
| 接口名
| 接口描述
|
| 接口名
| 接口描述
|
| -------- | ---------------- |
| DevHandle AdcOpen(uint32_t number) | 打开ADC设备
|
| void AdcClose(DevHandle handle) | 关闭ADC设备
|
| int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t
\*
val)
| 读取AD转换结果值 |
| DevHandle AdcOpen(uint32_t number) | 打开ADC设备 |
| void AdcClose(DevHandle handle) | 关闭ADC设备 |
| int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t
\*
val) | 读取AD转换结果值 |
### 开发步骤<a name="section9"></a>
使用ADC设备的一般流程如图2所示。
**图 2**
ADC使用流程图
<a
name=
"fig2"
></a>
![
](
figures/ADC使用流程图.png
"ADC使用流程图"
)
**图 2**
ADC使用流程图
<a
name=
"fig2"
></a>
![
ADC使用流程图
](
figures/ADC使用流程图.png
)
#### 打开ADC设备
...
...
@@ -76,23 +77,23 @@ DevHandle AdcOpen(int16_t number);
<a
name=
"table2"
></a>
| 参数
| 参数描述
|
| 参数
| 参数描述
|
| ---------- | ----------------- |
| number
| ADC设备号
|
|
**返回值**
|
**返回值描述**
|
| NULL
| 打开ADC设备失败
|
| 设备句柄
| 打开的ADC设备句柄 |
| number
| int16_t类型,ADC设备号
|
|
**返回值**
|
**返回值描述**
|
| NULL
| 打开ADC设备失败
|
| 设备句柄 | 打开的ADC设备句柄 |
假设系统中存在2个ADC设备,编号从0到1,那么我们现在打开1号设备。
```
c
DevHandle
adcHandle
=
NULL
;
/
* ADC设备句柄 /
DevHandle
adcHandle
=
NULL
;
/
/ ADC设备句柄
/
* 打开ADC设备 */
/
/ 打开ADC设备
adcHandle
=
AdcOpen
(
1
);
if
(
adcHandle
==
NULL
)
{
HDF_LOGE
(
"AdcOpen: fail
\n
"
);
return
;
return
NULL
;
}
```
...
...
@@ -106,14 +107,14 @@ int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val);
<a
name=
"table3"
></a>
| 参数
| 参数描述
|
| 参数
| 参数描述
|
| ---------- | -------------- |
| handle
| ADC设备句柄
|
| channel
| ADC设备通道号
|
| val
| AD转换结果
|
| handle
| DevHandle类型,ADC设备句柄
|
| channel
| uint32_t类型,ADC设备通道号
|
| val
| uint32_t类型指针,AD转换结果
|
|
**返回值**
|
**返回值描述**
|
|
0 | 读取成功
|
| 负数
| 读取失败
|
|
HDF_SUCCESS | 读取成功
|
| 负数
| 读取失败
|
读取转换结果示例(以通道1为例):
...
...
@@ -122,9 +123,9 @@ uint32_t value;
int32_t
ret
;
ret
=
AdcRead
(
adcHandle
,
1
,
&
value
);
if
(
ret
!=
0
)
{
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"ADC read fail!
\n
"
);
return
;
return
ret
;
}
```
...
...
@@ -138,16 +139,16 @@ void AdcClose(DevHandle handle);
<a
name=
"table4"
></a>
| 参数
| 参数描述
|
| 参数
| 参数描述
|
| ------ | ----------- |
| handle | ADC设备句柄 |
| handle |
DevHandle类型,
ADC设备句柄 |
| 返回值 | 返回值描述 |
| 无
| 无
|
| 无
| 无
|
关闭ADC设备示例:
```
c
AdcClose
(
adcHandle
);
/
* 关闭ADC设备 */
AdcClose
(
adcHandle
);
/
/ 关闭ADC设备
```
### 使用实例<a name="section10"></a>
...
...
@@ -163,15 +164,15 @@ AdcClose(adcHandle); /* 关闭ADC设备 */
示例如下:
```
c
#include "adc_if.h"
/
* ADC标准接口头文件 */
#include "hdf_log.h"
/
* 标准日志打印头文件 */
#include "adc_if.h" /
/ ADC标准接口头文件
#include "hdf_log.h" /
/ 标准日志打印头文件
/
* 设备号0,通道号1 */
/
// 设备号0,通道号1
#define ADC_DEVICE_NUM 0
#define ADC_CHANNEL_NUM 1
#define ADC_TEST_NUM 30
/
* ADC例程总入口 */
/
/ ADC例程总入口
static
int32_t
TestCaseAdc
(
void
)
{
int32_t
i
;
...
...
@@ -179,14 +180,14 @@ static int32_t TestCaseAdc(void)
DevHandle
adcHandle
=
NULL
;
uint32_t
readBuf
[
ADC_TEST_NUM
]
=
{
0
};
/
* 打开ADC设备 */
/
/ 打开ADC设备
adcHandle
=
AdcOpen
(
ADC_DEVICE_NUM
);
if
(
adcHandle
==
NULL
)
{
HDF_LOGE
(
"%s: Open ADC%u fail!"
,
__func__
,
ADC_DEVICE_NUM
);
return
-
1
;
}
/
* 连续进行30次AD转换并读取转换结果 */
/
/ 连续进行30次AD转换并读取转换结果
for
(
i
=
0
;
i
<
ADC_TEST_NUM
;
i
++
)
{
ret
=
AdcRead
(
adcHandle
,
ADC_CHANNEL_NUM
,
&
readBuf
[
i
]);
if
(
ret
!=
HDF_SUCCESS
)
{
...
...
@@ -197,7 +198,7 @@ static int32_t TestCaseAdc(void)
}
HDF_LOGI
(
"%s: ADC read successful!"
,
__func__
);
/
* 访问完毕关闭ADC设备 */
/
/ 访问完毕关闭ADC设备
AdcClose
(
adcHandle
);
return
0
;
...
...
zh-cn/device-dev/driver/driver-platform-adc-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-dac-des.md
浏览文件 @
d31322d7
...
...
@@ -7,29 +7,32 @@
DAC(Digital to Analog Converter)是一种通过电流、电压或电荷的形式将数字信号转换为模拟信号的设备,主要用于:
-
作为过程控制计算机系统的输出通道,与执行器相连,实现对生产过程的自动控制。
-
在利用反馈技术的模数转换器设计中,作为重要的功能模块呈现。
DAC接口定义了完成DAC传输的通用方法集合,包括:
-
DAC设备管理:打开或关闭DAC设备。
-
DAC设置目标值:设置DAC设备需要将数字信号转成模拟信号的目标值。
### 基本概念
-
分辨率
分辨率指的是DAC模块能够转换的二进制位数,位数越多分辨率越高。
分辨率指的是DAC模块能够转换的二进制位数,位数越多分辨率越高。
-
转换精度
精度是指输入端加有最大数值时,DAC的实际输出值和理论计算值之差,DAC转换器的转换精度与DAC转换器的集成芯片结构和接口电路配置有关。理想情况下,DAC的转换精度越小越好,因此为了获得更高精度的DAC转换结果,首先要保证选择的DAC转换器具备足够高的分辨率。其次,接口电路的器件或电源存在误差时,会造成DAC转换的误差,若这些误差超过一定程度,就会导致DAC转换错误。
精度是指输入端加有最大数值时,DAC的实际输出值和理论计算值之差,DAC转换器的转换精度与DAC转换器的集成芯片结构和接口电路配置有关。理想情况下,DAC的转换精度越小越好,因此为了获得更高精度的DAC转换结果,首先要保证选择的DAC转换器具备足够高的分辨率。其次,接口电路的器件或电源存在误差时,会造成DAC转换的误差,若这些误差超过一定程度,就会导致DAC转换错误。
-
转换速度
转换速度一般由建立时间决定。从输入由全0突变为全1时开始,到输出电压稳定在FSR±½LSB范围(或以FSR±x%FSR指明范围)内为止,这段时间称为建立时间,它是DAC的最大响应时间,所以用它衡量转换速度的快慢。
转换速度一般由建立时间决定。从输入由全0突变为全1时开始,到输出电压稳定在FSR±½LSB范围(或以FSR±x%FSR指明范围)内为止,这段时间称为建立时间,它是DAC的最大响应时间,所以用它衡量转换速度的快慢。
满量程范围FSR(Full Scale Range),是指DAC输出信号幅度的最大范围,不同的DAC有不同的满量程范围,该范围可以用正、负电流或者正、负电压来限制。
满量程范围FSR(Full Scale Range),是指DAC输出信号幅度的最大范围,不同的DAC有不同的满量程范围,该范围可以用正、负电流或者正、负电压来限制。
最低有效位LSB(Least Significant Byte),指的是一个二进制数字中的第0位(即最低位)。
最低有效位LSB(Least Significant Byte),指的是一个二进制数字中的第0位(即最低位)。
### 运作机制
...
...
@@ -59,10 +62,10 @@ DAC模块提供的主要接口如下所示,具体API详见//drivers/hdf_core/f
**表 1**
DAC驱动API接口功能介绍
| 接口名
| 接口描述
|
| 接口名
| 接口描述
|
| ------------------------------------------------------------------ | ------------ |
| DevHandle DacOpen(uint32_t number)
| 打开DAC设备。
|
| void DacClose(DevHandle handle)
| 关闭DAC设备。
|
| DevHandle DacOpen(uint32_t number)
| 打开DAC设备。
|
| void DacClose(DevHandle handle)
| 关闭DAC设备。
|
| int32_t DacWrite(DevHandle handle, uint32_t channel, uint32_t val) | 设置DA目标值。 |
### 开发步骤
...
...
@@ -76,78 +79,80 @@ DAC模块提供的主要接口如下所示,具体API详见//drivers/hdf_core/f
在进行DA转换之前,首先要调用DacOpen打开DAC设备,打开函数如下所示:
```
c
++
```
c
DevHandle
DacOpen
(
uint32_t
number
);
```
**表 2**
DacOpen参数和返回值描述
| 参数
| 参数描述
|
| 参数
| 参数描述
|
| --------- | ---------------- |
| number
| DAC设备号。
|
|
**返回值**
|
**返回值描述**
|
| NULL
| 打开DAC设备失败。
|
| 设备句柄
| 打开的DAC设备句柄。 |
| number
| uint32_t类型,DAC设备号。
|
|
**返回值**
|
**返回值描述**
|
| NULL
| 打开DAC设备失败。
|
| 设备句柄 | 打开的DAC设备句柄。 |
假设系统中存在2个DAC设备,编号从0到1,现在打开1号设备。
```
c
++
DevHandle
dacHandle
=
NULL
;
// DAC设备句柄
```
c
DevHandle
dacHandle
=
NULL
;
// DAC设备句柄
/
* 打开DAC设备 */
/
/ 打开DAC设备
dacHandle
=
DacOpen
(
1
);
if
(
dacHandle
==
NULL
)
{
HDF_LOGE
(
"DacOpen:
failed
\n
"
);
return
;
HDF_LOGE
(
"DacOpen:
open dac fail.
\n
"
);
return
NULL
;
}
```
#### 设置DA目标值
```
c
++
```
c
int32_t
DacWrite
(
DevHandle
handle
,
uint32_t
channel
,
uint32_t
val
);
```
**表 3**
DacWrite参数和返回值描述
| 参数
| 参数描述
|
| 参数
| 参数描述
|
| --------- | ------------ |
| handle
| DAC设备句柄。
|
| channel
| DAC设备通道号。
|
| val
| 设置DA的值。
|
| handle
| DevHandle类型,DAC设备句柄。
|
| channel
| uint32_t类型,DAC设备通道号。
|
| val
| uint32_t类型,设置DA的值。
|
|
**返回值**
|
**返回值描述**
|
|
0 | 写入成功。
|
| 负数
| 写入失败。
|
|
HDF_SUCCESS | 写入DA目标值成功
|
| 负数
| 写入DA目标值失败
|
```
c++
/* 通过DAC_CHANNEL_NUM设备通道写入目标val值 */
```
c
// 通过DAC_CHANNEL_NUM设备通道写入目标val值
int32_t
ret
;
ret
=
DacWrite
(
dacHandle
,
DAC_CHANNEL_NUM
,
val
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"
%s: tp DAC write reg fail!:%d"
,
__func__
,
ret
);
HDF_LOGE
(
"
DacWrite: tp DAC write reg fail!,ret:%d"
,
ret
);
DacClose
(
dacHandle
);
return
-
1
;
return
ret
;
}
```
#### 关闭DAC设备
DAC通信完成之后,需要关闭DAC设备,关闭函数如下所示:
```
c++
```
c
void
DacClose
(
DevHandle
handle
);
```
**表 4**
DacClose参数和返回值描述
| 参数
| 参数描述
|
| 参数
| 参数描述
|
| --------- | ------------ |
| handle
| DAC设备句柄。
|
| handle
| DAC设备句柄。
|
|
**返回值**
|
**返回值描述**
|
|
void | 无
|
|
无 | 无
|
关闭DAC设备示例:
```
c
++
DacClose
(
dacHandle
);
/* 关闭DAC设备 */
```
c
DacClose
(
dacHandle
);
// 关闭DAC设备
```
## 使用实例
...
...
@@ -155,20 +160,22 @@ DacClose(dacHandle); /* 关闭DAC设备 */
DAC设备的具体使用方式可以参考如下示例代码,示例代码步骤主要如下:
1.
根据设备号DAC_DEVICE_NUM打开DAC设备得到设备句柄。
2.
通过DAC的设备号以及设备通道设置val的值,如果写入失败则关闭设备句柄。
3.
访问完毕DAC设备后,则关闭该设备句柄。
运行结果:根据输入的val通过打印日志得到输出的结果。
```
c
++
#include "dac_if.h"
/
* DAC标准接口头文件 */
#include "hdf_log.h"
/
* 标准日志打印头文件 */
```
c
#include "dac_if.h" /
/ DAC标准接口头文件
#include "hdf_log.h" /
/ 标准日志打印头文件
/
* 设备号0,通道号1 */
/
/ 设备号0,通道号1
#define DAC_DEVICE_NUM 0
#define DAC_CHANNEL_NUM 1
/
* DAC例程总入口 */
/
/ DAC例程总入口
static
int32_t
TestCaseDac
(
void
)
{
// 设置要写入的val值
...
...
@@ -176,14 +183,14 @@ static int32_t TestCaseDac(void)
int32_t
ret
;
DevHandle
dacHandle
;
/
* 打开DAC设备 */
/
/ 打开DAC设备
dacHandle
=
DacOpen
(
DAC_DEVICE_NUM
);
if
(
dacHandle
==
NULL
)
{
HDF_LOGE
(
"%s: Open DAC%u fail!"
,
__func__
,
DAC_DEVICE_NUM
);
return
-
1
;
}
/
* 写入数据 */
/
/ 写入数据
ret
=
DacWrite
(
dacHandle
,
DAC_CHANNEL_NUM
,
val
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"%s: tp DAC write reg fail!:%d"
,
__func__
,
ret
);
...
...
@@ -191,9 +198,9 @@ static int32_t TestCaseDac(void)
return
-
1
;
}
/
* 访问完毕关闭DAC设备 */
/
/ 访问完毕关闭DAC设备
DacClose
(
dacHandle
);
HDF_LOGI
(
"%s: function tests end."
,
__func__
);
return
0
;
}
```
\ No newline at end of file
```
zh-cn/device-dev/driver/driver-platform-dac-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-gpio-des.md
浏览文件 @
d31322d7
...
...
@@ -8,10 +8,13 @@ GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO
GPIO接口定义了操作GPIO管脚的标准方法集合,包括:
-
设置管脚方向:方向可以是输入或者输出(暂不支持高阻态)。
-
读写管脚电平值:电平值可以是低电平或高电平。
-
设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式。
-
使能和禁止管脚中断:禁止或使能管脚中断。
-
设置、获取管脚方向:方向可以是输入或者输出(暂不支持高阻态)。
-
读、写管脚电平值:电平值可以是低电平或高电平。
-
设置、取消管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式。取消一个管脚的中断服务函数。
-
使能、禁止管脚中断:禁止或使能管脚中断。
### 基本概念
...
...
@@ -19,11 +22,11 @@ GPIO又俗称为I/O口,I指的是输入(in),O指的是输出(out)。
-
GPIO输入
输入是检测各个引脚上的电平状态,高电平或者低电平状态。常见的输入模式有:模拟输入、浮空输入、上拉输入、下拉输入。
输入是检测各个引脚上的电平状态,高电平或者低电平状态。常见的输入模式有:模拟输入、浮空输入、上拉输入、下拉输入。
-
GPIO输出
输出是当需要控制引脚电平的高低时需要用到输出功能。常见的输出模式有:开漏输出、推挽输出、复用开漏输出、复用推挽输出。
输出是当需要控制引脚电平的高低时需要用到输出功能。常见的输出模式有:开漏输出、推挽输出、复用开漏输出、复用推挽输出。
### 运作机制
...
...
@@ -34,7 +37,9 @@ GPIO又俗称为I/O口,I指的是输入(in),O指的是输出(out)。
GPIO模块各分层作用:
-
接口层提供操作GPIO管脚的标准方法。
-
核心层主要提供GPIO管脚资源匹配,GPIO管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互,供芯片厂家快速接入HDF框架。
-
适配层主要是将钩子函数的功能实例化,实现具体的功能。
**图 1**
GPIO统一服务模式结构图
...
...
@@ -45,36 +50,36 @@ GPIO模块各分层作用:
### 场景介绍
GPIO
仅是一个软件层面的概念,主要工作是GPIO管脚资源管理。开发者可以使用提供的GPIO操作接口,实现对管脚
控制。
GPIO
主要是对GPIO管脚资源进行管理。开发者可以使用提供的GPIO操作接口,实现对管脚控制的具体
控制。
### 接口说明
GPIO模块提供的主要接口如表1所示。
GPIO模块提供的主要接口如表1所示。
具体API详见//drivers/hdf_core/framework/include/platform/gpio_if.h。
**表1**
GPIO驱动API接口功能介绍
**表
1**
GPIO驱动API接口功能介绍
| 接口名
| 描述
|
| 接口名
| 描述
|
| ------------------------------------------------------------ | ------------------------------ |
| GpioGetByName(const char
*
gpioName) | 获取GPIO管脚ID
|
| int32_t GpioRead(uint16_t gpio, uint16_t
*
val) | 读GPIO管脚电平值
|
| int32_t GpioWrite(uint16_t gpio, uint16_t val)
| 写GPIO管脚电平值
|
| int32_t GpioGetDir(uint16_t gpio, uint16_t
*
dir) | 获取GPIO管脚方向
|
| int32_t GpioSetDir(uint16_t gpio, uint16_t dir)
| 设置GPIO管脚方向
|
| int32_t GpioUnsetIrq(uint16_t gpio, void
*
arg);
| 取消GPIO管脚对应的中断服务函数 |
| int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void
*
arg) | 设置GPIO管脚对应的中断服务函数 |
| int32_t GpioEnableIrq(uint16_t gpio)
| 使能GPIO管脚中断
|
| int32_t GpioDisableIrq(uint16_t gpio)
| 禁止GPIO管脚中断
|
| GpioGetByName(const char
\*
gpioName) | 获取GPIO管脚ID
|
| int32_t GpioRead(uint16_t gpio, uint16_t
\*
val) | 读GPIO管脚电平值
|
| int32_t GpioWrite(uint16_t gpio, uint16_t val)
| 写GPIO管脚电平值
|
| int32_t GpioGetDir(uint16_t gpio, uint16_t
\*
dir) | 获取GPIO管脚方向
|
| int32_t GpioSetDir(uint16_t gpio, uint16_t dir)
| 设置GPIO管脚方向
|
| int32_t GpioUnsetIrq(uint16_t gpio, void
\*
arg)
| 取消GPIO管脚对应的中断服务函数 |
| int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void
\
*
arg) | 设置GPIO管脚对应的中断服务函数 |
| int32_t GpioEnableIrq(uint16_t gpio)
| 使能GPIO管脚中断
|
| int32_t GpioDisableIrq(uint16_t gpio)
| 禁止GPIO管脚中断
|
>![](../public_sys-resources/icon-note.gif) **说明:**<br>
>本文涉及GPIO的所有接口,支持内核态及用户态使用。
### 开发步骤
GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如
下图
所示。
GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如
图2
所示。
**图
1
**
GPIO使用流程图
**图
2
**
GPIO使用流程图
![
image
](
figures/GPIO使用流程图.png
"GPIO使用流程图"
)
![
GPIO使用流程图
](
figures/GPIO使用流程图.png
)
#### 确定GPIO管脚号
...
...
@@ -82,31 +87,31 @@ GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流
-
根据SOC芯片规则进行计算
不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。
不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。
-
Hi3516DV300
- Hi3516DV300
控制器管理12组GPIO管脚,每组8个。
控制器管理12组GPIO管脚,每组8个。
GPIO号 = GPIO组索引 (0~11) \* 每组GPIO管脚数(8) + 组内偏移
GPIO号 = GPIO组索引 (0~11) \* 每组GPIO管脚数(8) + 组内偏移
举例:GPIO10_3的GPIO号 = 10 \* 8 + 3 = 83
举例:GPIO10_3的GPIO号 = 10 \* 8 + 3 = 83
-
Hi3518EV300
- Hi3518EV300
控制器管理10组GPIO管脚,每组10个。
控制器管理10组GPIO管脚,每组10个。
GPIO号 = GPIO组索引 (0~9) \* 每组GPIO管脚数(10) + 组内偏移
GPIO号 = GPIO组索引 (0~9) \* 每组GPIO管脚数(10) + 组内偏移
举例:GPIO7_3的GPIO管脚号 = 7 \* 10 + 3 = 73
举例:GPIO7_3的GPIO管脚号 = 7 \* 10 + 3 = 73
-
通过管脚别名获取
调用接口GpioGetByName进行获取,入参是该管脚的别名,接口返回值是管脚的全局ID。
调用接口GpioGetByName进行获取,入参是该管脚的别名,接口返回值是管脚的全局ID。
```
c
GpioGetByName
(
const
char
*
gpioName
);
```
```c
GpioGetByName(const char *gpioName);
```
#### 设置GPIO管脚方向
...
...
@@ -116,15 +121,15 @@ GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流
int32_t
GpioSetDir
(
uint16_t
gpio
,
uint16_t
dir
);
```
**表2**
GpioSetDir参数和返回值描述
**表
2**
GpioSetDir参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | ------------------ |
| gpio
|
GPIO管脚号 |
| dir
| 待设置的方向值
|
|
**返回值**
|
**返回值描述**
|
|
0 | 设置成功
|
| 负数
| 设置失败
|
| gpio
| uint16_t类型,
GPIO管脚号 |
| dir
| uint16_t类型,待设置的方向值
|
|
**返回值**
|
**返回值描述**
|
|
HDF_SUCCESS | 设置GPIO管脚方向成功
|
| 负数
| 设置GPIO管脚方向失败
|
假设需要将GPIO管脚3的方向配置为输出,其使用示例如下:
...
...
@@ -132,8 +137,8 @@ int32_t GpioSetDir(uint16_t gpio, uint16_t dir);
int32_t
ret
;
ret
=
GpioSetDir
(
3
,
GPIO_DIR_OUT
);
// 将3号GPIO管脚配置为输出
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioSetDir:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioSetDir:
gpio set dir fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
```
...
...
@@ -146,15 +151,15 @@ if (ret != 0) {
int32_t
GpioGetDir
(
uint16_t
gpio
,
uint16_t
*
dir
);
```
**表3**
GpioGetDir参数和返回值描述
**表
3**
GpioGetDir参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | ------------------ |
| gpio
|
GPIO管脚号 |
| dir
| 获取到的方向值指针
|
|
**返回值**
|
**返回值描述**
|
|
0 | 设置成功
|
| 负数
| 设置失败
|
| gpio
| uint16_t类型,
GPIO管脚号 |
| dir
| uint16_t类型指针,获取到的方向值
|
|
**返回值**
|
**返回值描述**
|
|
HDF_SUCCESS | 获取GPIO管脚方向成功
|
| 负数
| 获取GPIO管脚方向失败
|
假设需要获取GPIO管脚3的方向,其使用示例如下:
...
...
@@ -163,8 +168,8 @@ int32_t ret;
uin16_t
dir
;
ret
=
GpioGetDir
(
3
,
&
dir
);
// 获取3号GPIO管脚方向
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioGetDir:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioGetDir:
gpio get dir fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
```
...
...
@@ -177,15 +182,15 @@ if (ret != 0) {
int32_t
GpioRead
(
uint16_t
gpio
,
uint16_t
*
val
);
```
**表4**
GpioRead参数和返回值描述
**表
4**
GpioRead参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | -------------------- |
| gpio
| GPIO管脚号
|
| val
| 接收读取电平值的指针
|
|
**返回值**
|
**返回值描述**
|
|
0 | 读取成功
|
| 负数
| 读取失败
|
| gpio
| uint16_t类型,GPIO管脚号
|
| val
| uint16_t类型指针,接收读取电平值
|
|
**返回值**
|
**返回值描述**
|
|
HDF_SUCCESS | 读取GPIO管脚电平值成功
|
| 负数
| 读取GPIO管脚电平值失败
|
假设需要读取GPIO管脚3的电平值,其使用示例如下:
...
...
@@ -194,8 +199,8 @@ int32_t ret;
uint16_t
val
;
ret
=
GpioRead
(
3
,
&
val
);
// 读取3号GPIO管脚电平值
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioRead:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioRead:
gpio read fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
```
...
...
@@ -208,15 +213,15 @@ if (ret != 0) {
int32_t
GpioWrite
(
uint16_t
gpio
,
uint16_t
val
);
```
**表5**
GpioWrite参数和返回值描述
**表
5**
GpioWrite参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | ------------------ |
| gpio
|
GPIO管脚号 |
| val
| 待写入的电平值
|
|
**返回值**
|
**返回值描述**
|
|
0 | 写入成功
|
| 负数
| 写入失败
|
| gpio
| uint16_t类型,
GPIO管脚号 |
| val
| uint16_t类型,待写入的电平值
|
|
**返回值**
|
**返回值描述**
|
|
HDF_SUCCESS | 写入GPIO管脚电平值成功
|
| 负数
| 写入GPIO管脚电平值失败
|
假设需要给GPIO管脚3写入低电平值,其使用示例如下:
...
...
@@ -224,8 +229,8 @@ int32_t GpioWrite(uint16_t gpio, uint16_t val);
int32_t
ret
;
ret
=
GpioWrite
(
3
,
GPIO_VAL_LOW
);
// 给3号GPIO管脚写入低电平值
if
(
ret
!=
0
)
{
HDF_LOGE
(
"Gpio
Read: failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"Gpio
Write: gpio write fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
```
...
...
@@ -238,17 +243,17 @@ if (ret != 0) {
int32_t
GpioSetIrq
(
uint16_t
gpio
,
uint16_t
mode
,
GpioIrqFunc
func
,
void
*
arg
);
```
**表6**
GpioSetIrq参数和返回值描述
**表
6**
GpioSetIrq参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | ------------------------ |
| gpio
| GPIO管脚号
|
| mode
| 中断触发模式
|
| func
| 中断服务程序
|
| arg
|
传递给中断服务程序的入参 |
|
**返回值**
|
**返回值描述**
|
|
0 | 设置成功
|
| 负数
| 设置失败
|
| gpio
| uint16_t类型,GPIO管脚号
|
| mode
| uint16_t类型,中断触发模式
|
| func
| 函数指针,中断服务程序
|
| arg
| 无类型指针,
传递给中断服务程序的入参 |
|
**返回值**
|
**返回值描述**
|
|
HDF_SUCCESS | 设置GPIO管脚中断成功
|
| 负数
| 设置GPIO管脚中断失败
|
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**<br>
> 同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。
...
...
@@ -261,15 +266,15 @@ int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg);
int32_t
GpioUnsetIrq
(
uint16_t
gpio
,
void
*
arg
);
```
**表7**
GpioUnsetIrq参数和返回值描述
**表
7**
GpioUnsetIrq参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | -------------- |
| gpio
| GPIO管脚号
|
| arg
| GPIO中断数据
|
| gpio
| uint16_t类型,GPIO管脚号
|
| arg
| 无类型指针,GPIO中断数据
|
|
**返回值**
|
**返回值描述**
|
|
0 | 取消成功
|
| 负数
| 取消失败
|
|
HDF_SUCCESS | 取消GPIO管脚中断成功
|
| 负数
| 取消GPIO管脚中断失败
|
#### 使能GPIO管脚中断
...
...
@@ -279,14 +284,14 @@ int32_t GpioUnsetIrq(uint16_t gpio, void *arg);
int32_t
GpioEnableIrq
(
uint16_t
gpio
);
```
**表8**
GpioEnableIrq参数和返回值描述
**表
8**
GpioEnableIrq参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | -------------- |
| gpio
| GPIO管脚号
|
| gpio
| uint16_t类型,GPIO管脚号
|
|
**返回值**
|
**返回值描述**
|
|
0 | 使能成功
|
| 负数
| 使能失败
|
|
HDF_SUCCESS | 使能GPIO管脚中断成功
|
| 负数
| 使能GPIO管脚中断失败
|
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**<br>
> 必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。
...
...
@@ -298,51 +303,51 @@ int32_t GpioEnableIrq(uint16_t gpio);
```
c
int32_t
GpioDisableIrq
(
uint16_t
gpio
);
```
**表9**
GpioDisableIrq参数和返回值描述
**表
9**
GpioDisableIrq参数和返回值描述
|
**参数**
|
**参数描述**
|
|
**参数**
|
**参数描述**
|
| ---------- | -------------- |
| gpio
| GPIO管脚号
|
| gpio
| uint16_t类型,GPIO管脚号
|
|
**返回值**
|
**返回值描述**
|
|
0 | 禁止成功
|
| 负数
| 禁止失败
|
|
HDF_SUCCESS | 禁止GPIO管脚中断成功
|
| 负数
| 禁止GPIO管脚中断失败
|
中断相关操作示例:
```
c
/
* 中断服务函数*/
/
/ 中断服务函数
int32_t
MyCallBackFunc
(
uint16_t
gpio
,
void
*
data
)
{
HDF_LOGI
(
"
%s: gpio:%u interrupt service in data
\n
"
,
__func__
,
gpio
);
return
0
;
HDF_LOGI
(
"
MyCallBackFunc: gpio:%u interrupt service in data.
\n
"
,
gpio
);
return
HDF_SUCCESS
;
}
int32_t
ret
;
/
* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */
/
/ 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发
ret
=
GpioSetIrq
(
3
,
OSAL_IRQF_TRIGGER_RISING
,
MyCallBackFunc
,
NULL
);
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioSetIrq:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioSetIrq:
gpio set irq fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
/
* 使能3号GPIO管脚中断 */
/
/ 使能3号GPIO管脚中断
ret
=
GpioEnableIrq
(
3
);
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioEnableIrq:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioEnableIrq:
gpio enable irq fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
/
* 禁止3号GPIO管脚中断 */
/
/ 禁止3号GPIO管脚中断
ret
=
GpioDisableIrq
(
3
);
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioDisableIrq:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioDisableIrq:
gpio disable irqfail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
/
* 取消3号GPIO管脚中断服务程序 */
/
/ 取消3号GPIO管脚中断服务程序
ret
=
GpioUnsetIrq
(
3
,
NULL
);
if
(
ret
!=
0
)
{
HDF_LOGE
(
"GpioUnSetIrq:
failed, ret
%d
\n
"
,
ret
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"GpioUnSetIrq:
gpio unset irq fail, ret:
%d
\n
"
,
ret
);
return
ret
;
}
```
...
...
@@ -363,65 +368,66 @@ if (ret != 0) {
static
uint32_t
g_irqCnt
;
/
* 中断服务函数*/
/
/ 中断服务函数
static
int32_t
TestCaseGpioIrqHandler
(
uint16_t
gpio
,
void
*
data
)
{
HDF_LOGE
(
"
%s: irq triggered! on gpio:%u, in data"
,
__func__
,
gpio
);
g_irqCnt
++
;
/* 如果中断服务函数触发执行,则将全局中断计数加1 */
HDF_LOGE
(
"
TestCaseGpioIrqHandler: irq triggered! on gpio:%u, in data"
,
gpio
);
g_irqCnt
++
;
// 如果中断服务函数触发执行,则将全局中断计数加1
return
GpioDisableIrq
(
gpio
);
}
/
* 测试用例函数 */
/
/ 测试用例函数
static
int32_t
TestCaseGpioIrqEdge
(
void
)
{
int32_t
ret
;
uint16_t
valRead
;
uint16_t
mode
;
uint16_t
gpio
=
8
3
;
/* 待测试的GPIO管脚号 */
uint16_t
gpio
=
8
4
;
// 待测试的GPIO管脚号
uint32_t
timeout
;
/
* 将管脚方向设置为输出 */
/
/ 将管脚方向设置为输出
ret
=
GpioSetDir
(
gpio
,
GPIO_DIR_OUT
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"
%s: set dir fail! ret:%d
\n
"
,
__func__
,
ret
);
HDF_LOGE
(
"
TestCaseGpioIrqEdge: set dir fail! ret:%d
\n
"
,
ret
);
return
ret
;
}
/
* 先禁止该管脚中断 */
/
/ 先禁止该管脚中断
ret
=
GpioDisableIrq
(
gpio
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"
%s: disable irq fail! ret:%d
\n
"
,
__func__
,
ret
);
HDF_LOGE
(
"
TestCaseGpioIrqEdge: disable irq fail! ret:%d
\n
"
,
ret
);
return
ret
;
}
/
* 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发 */
/
/ 为管脚设置中断服务函数,触发模式为上升沿和下降沿共同触发
mode
=
OSAL_IRQF_TRIGGER_RISING
|
OSAL_IRQF_TRIGGER_FALLING
;
HDF_LOGE
(
"
%s: mode:%0x
\n
"
,
__func__
,
mode
);
HDF_LOGE
(
"
TestCaseGpioIrqEdge: mode:%0x
\n
"
,
mode
);
ret
=
GpioSetIrq
(
gpio
,
mode
,
TestCaseGpioIrqHandler
,
NULL
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"
%s: set irq fail! ret:%d
\n
"
,
__func__
,
ret
);
HDF_LOGE
(
"
TestCaseGpioIrqEdge: set irq fail! ret:%d
\n
"
,
ret
);
return
ret
;
}
/
* 使能此管脚中断 */
/
/ 使能此管脚中断
ret
=
GpioEnableIrq
(
gpio
);
if
(
ret
!=
HDF_SUCCESS
)
{
HDF_LOGE
(
"
%s: enable irq fail! ret:%d
\n
"
,
__func__
,
ret
);
HDF_LOGE
(
"
TestCaseGpioIrqEdge: enable irq fail! ret:%d
\n
"
,
ret
);
(
void
)
GpioUnsetIrq
(
gpio
,
NULL
);
return
ret
;
}
g_irqCnt
=
0
;
/* 清除全局计数器 */
timeout
=
0
;
/* 等待时间清零 */
/
* 等待此管脚中断服务函数触发,等待超时时间为1000毫秒 */
g_irqCnt
=
0
;
// 清除全局计数器
timeout
=
0
;
// 等待时间清零
/
/ 等待此管脚中断服务函数触发,等待超时时间为1000毫秒
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 */
HDF_LOGE
(
"
TestCaseGpioIrqEdge: wait irq timeout:%u
\n
"
,
timeout
);
OsalMDelay
(
200
);
/
/ 等待中断触发
timeout
+=
200
;
}
(
void
)
GpioUnsetIrq
(
gpio
,
NULL
);
HDF_LOGI
(
"TestCaseGpioIrqEdge: function tests end, g_irqCnt:%u"
,
g_irqCnt
);
return
(
g_irqCnt
>
0
)
?
HDF_SUCCESS
:
HDF_FAILURE
;
}
```
\ No newline at end of file
```
zh-cn/device-dev/driver/driver-platform-gpio-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-hdmi-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-hdmi-develop.md
浏览文件 @
d31322d7
# HDMI
# HDMI
## 概述
...
...
@@ -19,18 +18,25 @@ HDMI(High Definition Multimedia Interface),即高清多媒体接口,是H
-
HDCP(High-bandwidth Digital Content Protection):即高带宽数字内容保护技术,当用户对高清晰信号进行非法复制时,该技术会进行干扰,降低复制出来的影像的质量,从而对内容进行保护。
### 运作机制
在HDF框架中,HDMI的接口适配模式采用独立服务模式(如图1)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用率。
在HDF框架中,HDMI的接口适配模式拟采用独立服务模式(如图1)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用率。
HDMI模块各分层作用:
-
接口层提供打开HDMI设备、启动HDMI传输、停止HDMI传输、声音图像消隐设置、设置色彩深度、获取色彩深度、设置视频属性、获取视频属性、设置HDR属性、读取Sink端原始EDID数据、注册HDMI热插拔检测回调函数、注销HDMI热插拔检测回调函数、关闭HDMI设备的接口。
-
核心层主要提供HDMI控制器的打开、关闭及管理的能力,通过钩子函数与适配层交互。
**图 1**
HDMI独立服务模式
-
适配层主要是将钩子函数的功能实例化,实现具体的功能。
![
image1
](
figures/独立服务模式结构图.png
)
**图 1**
HDMI独立服务模式
![
HDMI独立服务模式
](
figures/独立服务模式结构图.png
)
### 约束与限制
HDMI模块当前仅支持轻量和小型系统内核(LiteOS)
。
HDMI模块当前仅支持轻量和小型系统内核(LiteOS)
,暂无实际适配驱动
。
## 开发指导
...
...
@@ -41,6 +47,7 @@ HDMI具有体积小、传输速率高、传输带宽宽、兼容性好、能同
### 接口说明
HdmiCntlrOps定义:
```
c
struct
HdmiCntlrOps
{
void
(
*
hardWareInit
)(
struct
HdmiCntlr
*
cntlr
);
...
...
@@ -80,17 +87,17 @@ struct HdmiCntlrOps {
};
```
**表1**
HdmiCntlrOps结构体成员的回调函数功能说明
**表
1**
HdmiCntlrOps结构体成员的回调函数功能说明
| 函数成员
| 入参 | 出参 | 返回值 | 功能
|
| 函数成员
| 入参 | 出参 | 返回值 | 功能
|
| ------------------------ | ------------------------------------------------------------ | -------------------------------------- | ------------------ | -------------------------------------------------- |
| hardWareInit
|
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | 无 | 初始化HDMI硬件 |
| hardWareStatusGet
|
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
|
**status**
:HDMI硬件状态 ; | 无 | 获取HDMI当前硬件状态 |
| controllerReset
|
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | 无 | 复位HDMI控制器 |
| hotPlugStateGet
|
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | bool:HDMI热插拔状态 | 获取HDMI热插拔状态 |
| hardWareInit |
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | 无 | 初始化HDMI硬件 |
| hardWareStatusGet |
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
|
**status**
:HDMI硬件状态 ; | 无 | 获取HDMI当前硬件状态 |
| controllerReset |
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | 无 | 复位HDMI控制器 |
| hotPlugStateGet |
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | bool:HDMI热插拔状态 | 获取HDMI热插拔状态 |
| hotPlugInterruptStateGet |
**cntlr**
:结构体指针,核心层HDMI控制器 | 无 | bool:HDMI热插拔中断状态 | 获取HDMI热插拔中断状态 |
| lowPowerSet
|
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**enable**
:bool,使能/去使能 | 无 | 无 | 使能/去使能低功耗 |
| tmdsModeSet
|
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**mode**
:TMDS模式 | 无 | 无 | 设置TMDS模式 |
| lowPowerSet |
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**enable**
:bool,使能/去使能 | 无 | 无 | 使能/去使能低功耗 |
| tmdsModeSet |
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**mode**
:TMDS模式 | 无 | 无 | 设置TMDS模式 |
| tmdsConfigSet |
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**mode**
:TMDS参数 | 无 | HDF_STATUS相关状态 | 配置TMDS参数 |
| infoFrameEnable |
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**infoFrameType**
:packet类型
<br
/>
**enable**
:bool,使能/去使能 | 无 | 无 | 使能/去使能infoFrame |
| infoFrameSend |
**cntlr**
:结构体指针,核心层HDMI控制器
<br
/>
**infoFrameType**
:packet类型
<br
/>
**data**
:infoFrame数据
<br
/>
**len**
:数据长度 | 无 | HDF_STATUS相关状态 | 发送infoFrame |
...
...
@@ -120,20 +127,30 @@ struct HdmiCntlrOps {
### 开发步骤
HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以及实例化HDMI控制器对象。
HDMI模块适配包含以下四个步骤:
-
实例化驱动入口
-
实例化驱动入口:
-
实例化HdfDriverEntry结构体成员。
-
调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
-
配置属性文件:
-
配置属性文件
-
在device_info.hcs文件中添加deviceNode描述。
-
【可选】添加hdmi_config.hcs器件属性文件。
-
实例化HDMI控制器对象:
-
实例化HDMI控制器对象
-
初始化HdmiCntlr成员。
-
实例化HdmiCntlr成员HdmiCntlrOps方法集合。
-
驱动调试
【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,HDMI传输等。
1.
实例化驱动入口
驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
...
...
@@ -148,16 +165,14 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
.
Bind
=
HdmiAdapterBind
,
.
Init
=
HdmiAdapterInit
,
.
Release
=
HdmiAdapterRelease
,
.
moduleName
=
"adapter_hdmi_driver"
,
//【必要】与HCS里面的名字匹配
.
moduleName
=
"adapter_hdmi_driver"
,
// 【必要且与HCS文件中里面的moduleName匹配】
};
HDF_INIT
(
g_hdmiDriverEntry
);
// 调用HDF_INIT将驱动入口注册到HDF框架中
HDF_INIT
(
g_hdmiDriverEntry
);
// 调用HDF_INIT将驱动入口注册到HDF框架中
```
2.
配置属性文件
完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在hdmi_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值对于厂商驱动的实现以及核心层HdmiCntlr相关成员的默认值或限制范围有密切关系。
从第一个节点开始配置具体HDMI控制器信息,此节点并不表示某一路HDMI控制器,而是代表一个资源性质设备,用于描述一类HDMI控制器的信息。本例只有一个HDMI控制器,如有多个控制器,则需要在device_info文件增加deviceNode信息,以及在hdmi_config文件中增加对应的器件属性。
完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在hdmi_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值对于厂商驱动的实现以及核心层HdmiCntlr相关成员的默认值或限制范围有密切关系。从第一个节点开始配置具体HDMI控制器信息,此节点并不表示某一路HDMI控制器,而是代表一个资源性质设备,用于描述一类HDMI控制器的信息。本例只有一个HDMI控制器,如有多个控制器,则需要在device_info文件增加deviceNode信息,以及在hdmi_config文件中增加对应的器件属性。
-
device_info.hcs配置参考
...
...
@@ -181,8 +196,8 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
-
hdmi_config.hcs 配置参考
```
c
root
{
platform
{
root
{
platform
{
hdmi_config
{
template
hdmi_controller
{
// 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。
match_attr
=
""
;
//【必要】需要和device_info.hcs中的deviceMatchAttr值一致。
...
...
@@ -227,7 +242,7 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
}
```
3.
实例化控制器对象
3.
实例化
HDMI
控制器对象
最后一步,完成驱动入口注册之后,要以核心层HdmiCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化HdmiCntlr成员HdmiCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
...
...
@@ -245,7 +260,6 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
uint32_t
irqNum
;
//【必要】中断号
};
/* HdmiCntlr是核心层控制器结构体,其中的成员在Init函数中被赋值。 */
struct
HdmiCntlr
{
struct
IDeviceIoService
service
;
struct
HdfDeviceObject
*
hdfDevObj
;
...
...
@@ -320,16 +334,17 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
**返回值:**
HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)
HDF_STATUS相关状态 (表2为部分展示,如需使用其他状态,可参考//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS的定义)。
**表 2**
HDF_STATUS相关状态说明
|状态(值)|状态描述|
|:-|:-|
|HDF_ERR_INVALID_OBJECT|控制器对象非法|
|HDF_ERR_INVALID_PARAM |参数非法|
|HDF_ERR_MALLOC_FAIL |内存分配失败|
|HDF_ERR_IO |I/O错误|
|HDF_SUCCESS |传输成功|
|HDF_FAILURE |传输失败|
| 状态(值) | 问题描述 |
| -------- | -------- |
| HDF_ERR_INVALID_OBJECT | 控制器对象非法 |
| HDF_ERR_MALLOC_FAIL | 内存分配失败 |
| HDF_ERR_IO | I/O
错误 |
| HDF_SUCCESS | 初始化成功 |
| HDF_FAILURE | 初始化失败 |
**函数说明:**
...
...
@@ -358,13 +373,13 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
cntlr
->
hdfDevObj
=
obj
;
//【必要】使HdfDeviceObject与HdmiCntlr可以相互转化的前提
obj
->
service
=
&
cntlr
->
service
;
//【必要】使HdfDeviceObject与HdmiCntlr可以相互转化的前提
ret
=
HdmiAdapterCntlrParse
(
cntlr
,
obj
);
//【必要】初始化cntlr,失败则goto __ERR。
...
...
...
ret
=
HdmiAdapterHostParse
(
host
,
obj
);
//【必要】初始化host对象的相关属性,失败则goto __ERR。
...
...
...
ret
=
HdmiAdapterHostInit
(
host
,
cntlr
);
// 厂商自定义的初始化,失败则goto __ERR。
...
...
...
ret
=
HdmiCntlrAdd
(
cntlr
);
// 调用核心层函数,失败则goto __ERR。
...
...
...
HDF_LOGD
(
"HdmiAdapterBind: success."
);
return
HDF_SUCCESS
;
__ERR:
...
...
@@ -416,11 +431,13 @@ HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以
static
void
HdmiAdapterRelease
(
struct
HdfDeviceObject
*
obj
)
{
struct
HdmiCntlr
*
cntlr
=
NULL
;
...
...
...
cntlr
=
(
struct
HdmiCntlr
*
)
obj
->
service
;
// 这里有HdfDeviceObject到HdmiCntlr的强制转化,通过service成员,赋值见Bind函数。
...
...
...
HimciDeleteHost
((
struct
HimciAdapterHost
*
)
cntlr
->
priv
);
// 厂商自定义的内存释放函数,这里有HdmiCntlr到HimciAdapterHost的强制转化。
}
```
4.
驱动调试
【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,HDMI传输等。
zh-cn/device-dev/driver/driver-platform-i2c-des.md
浏览文件 @
d31322d7
# I2C
## 概述
### 功能简介
...
...
@@ -16,12 +15,14 @@ I2C数据的传输必须以一个起始信号作为开始条件,以一个结
I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。
I2C接口定义了完成I2C传输的通用方法集合,包括:
-
I2C控制器管理:打开或关闭I2C控制器
-
I2C消息传输:通过消息传输结构体数组进行自定义传输
**图
1** I2C物理连线示意图
**图
1**
I2C物理连线示意图
![image](figures/I2C物理连线示意图.png "I2C物理连线示意图"
)
![
I2C物理连线示意图
](
figures/I2C物理连线示意图.png
)
## 使用指导
...
...
@@ -33,9 +34,9 @@ I2C通常用于与各类支持I2C协议的传感器、执行器或输入输出
I2C模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/framework/include/platform/i2c_if.h。
**表1**
I2C驱动API接口功能介绍
**表
1**
I2C驱动API接口功能介绍
|
接口名
| 接口描述 |
|
接口名
| 接口描述 |
| -------- | -------- |
| DevHandle I2cOpen(int16_t number) | 打开I2C控制器 |
| void I2cClose(DevHandle handle) | 关闭I2C控制器 |
...
...
@@ -45,9 +46,9 @@ I2C模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/
使用I2C设备的一般流程如下图所示。
**图2**
I2C设备使用流程图
**图
2**
I2C设备使用流程图
![
image
](
figures/I2C设备使用流程图.png
"I2C设备使用流程图"
)
![
I2C设备使用流程图
](
figures/I2C设备使用流程图.png
)
#### 打开I2C控制器
...
...
@@ -58,11 +59,11 @@ I2C模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/
DevHandle
I2cOpen
(
int16_t
number
);
```
**表
2**
I2cOpen参数和返回值描述
**表
2**
I2cOpen参数和返回值描述
|
**参数**
|
**参数描述**
|
| -------- | -------- |
| number | I2C控制器号 |
| number |
int16_t类型,
I2C控制器号 |
|
**返回值**
|
**返回值描述**
|
| NULL | 打开I2C控制器失败 |
| 设备句柄 | 打开的I2C控制器设备句柄 |
...
...
@@ -70,57 +71,55 @@ DevHandle I2cOpen(int16_t number);
假设系统中存在8个I2C控制器,编号从0到7,以下代码示例为获取3号控制器:
```
c
DevHandle
i2cHandle
=
NULL
;
/
* I2C控制器句柄 /
DevHandle
i2cHandle
=
NULL
;
/
/ I2C控制器句柄
/
* 打开I2C控制器 */
/
/ 打开I2C控制器
i2cHandle
=
I2cOpen
(
3
);
if
(
i2cHandle
==
NULL
)
{
HDF_LOGE
(
"I2cOpen:
failed
\n
"
);
return
;
HDF_LOGE
(
"I2cOpen:
i2c open fail.
\n
"
);
return
NULL
;
}
```
#### 进行I2C通信
消息传输
```
c
int32_t
I2cTransfer
(
DevHandle
handle
,
struct
I2cMsg
\
*
msgs
,
int16_t
count
);
int32_t
I2cTransfer
(
DevHandle
handle
,
struct
I2cMsg
*
msgs
,
int16_t
count
);
```
**表
3**
I2cTransfer参数和返回值描述
**表
3**
I2cTransfer参数和返回值描述
|
**参数**
|
**参数描述**
|
| -------- | -------- |
| handle | I2C控制器设备句柄 |
| msgs | 待传输数据的消息结构体数组 |
| count | 消息数组长度 |
| handle |
DevHandle类型,
I2C控制器设备句柄 |
| msgs |
结构体指针,
待传输数据的消息结构体数组 |
| count |
int16_t类型,
消息数组长度 |
|
**返回值**
|
**返回值描述**
|
| 正整数 | 成功传输的消息结构体数目 |
| 负数 | 执行失败 |
I2C传输消息类型为I2cMsg,每个传输消息结构体表示一次读或写,通过一个消息数组,可以执行若干次的读写组合操作。组合读写示例:
```
c
int32_t
ret
;
uint8_t
wbuff
[
2
]
=
{
0x12
,
0x13
};
uint8_t
rbuff
[
2
]
=
{
0
};
struct
I2cMsg
msgs
[
2
];
/* 自定义传输的消息结构体数组 */
msgs
[
0
].
buf
=
wbuff
;
/* 写入的数据 */
msgs
[
0
].
len
=
2
;
/* 写入数据长度为2 */
msgs
[
0
].
addr
=
0x5A
;
/* 写入设备地址为0x5A */
msgs
[
0
].
flags
=
0
;
/* 传输标记为0,默认为写 */
msgs
[
1
].
buf
=
rbuff
;
/* 要读取的数据 */
msgs
[
1
].
len
=
2
;
/* 读取数据长度为2 */
msgs
[
1
].
addr
=
0x5A
;
/* 读取设备地址为0x5A */
msgs
[
1
].
flags
=
I2C_FLAG_READ
/
* I2C_FLAG_READ置位 */
/
* 进行一次自定义传输,传输的消息个数为2 */
struct
I2cMsg
msgs
[
2
];
// 自定义传输的消息结构体数组
msgs
[
0
].
buf
=
wbuff
;
// 写入的数据
msgs
[
0
].
len
=
2
;
// 写入数据长度为2
msgs
[
0
].
addr
=
0x5A
;
// 写入设备地址为0x5A
msgs
[
0
].
flags
=
0
;
// 传输标记为0,默认为写
msgs
[
1
].
buf
=
rbuff
;
// 要读取的数据
msgs
[
1
].
len
=
2
;
// 读取数据长度为2
msgs
[
1
].
addr
=
0x5A
;
// 读取设备地址为0x5A
msgs
[
1
].
flags
=
I2C_FLAG_READ
/
/ I2C_FLAG_READ置位
/
/ 进行一次自定义传输,传输的消息个数为2
ret
=
I2cTransfer
(
i2cHandle
,
msgs
,
2
);
if
(
ret
!=
2
)
{
HDF_LOGE
(
"I2cTransfer:
failed, ret
%d
\n
"
,
ret
);
return
;
HDF_LOGE
(
"I2cTransfer:
i2c transfer fail, ret:
%d
\n
"
,
ret
);
return
HDF_FAILURE
;
}
```
...
...
@@ -142,19 +141,18 @@ I2C通信完成之后,需要关闭I2C控制器,关闭函数如下所述:
void
I2cClose
(
DevHandle
handle
);
```
**表
4**
I2cClose参数和返回值描述
**表
4**
I2cClose参数和返回值描述
| 参数 | 参数描述 |
| -------- | -------- |
| handle | I2C控制器设备句柄 |
| handle |
DevHandle类型,
I2C控制器设备句柄 |
关闭I2C控制器示例:
```
c
I2cClose
(
i2cHandle
);
/
* 关闭I2C控制器 */
I2cClose
(
i2cHandle
);
/
/ 关闭I2C控制器
```
### 使用示例
本例程以操作开发板上的I2C设备为例,详细展示I2C接口的完整使用流程。
...
...
zh-cn/device-dev/driver/driver-platform-i2c-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-i3c-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-i3c-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-mipicsi-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-mipicsi-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-mipidsi-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-mipidsi-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-mmc-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-pin-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-pin-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-pwm-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-pwm-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-regulator-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-regulator-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-rtc-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-rtc-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-sdio-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-sdio-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-spi-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-spi-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-uart-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-uart-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-watchdog-des.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
zh-cn/device-dev/driver/driver-platform-watchdog-develop.md
浏览文件 @
d31322d7
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录