From ec9dfab81fbd7b8e7d6dad53f6dc3f85f68e7611 Mon Sep 17 00:00:00 2001 From: zhangyalei Date: Sun, 6 Feb 2022 18:44:42 -0800 Subject: [PATCH 1/8] Added I2S document Signed-off-by: zhangyalei --- zh-cn/device-dev/driver/Readme-CN.md | 2 + zh-cn/device-dev/driver/driver-develop.md | 15 +- .../driver/driver-platform-i2s-des.md | 682 ++++++++++++++++++ .../driver/driver-platform-i2s-develop.md | 522 ++++++++++++++ zh-cn/device-dev/driver/driver-platform.md | 14 +- .../I2S-master\346\230\257controller.png" | Bin 0 -> 10879 bytes .../I2S-master\346\230\257receiver.png" | Bin 0 -> 7239 bytes .../I2S-master\346\230\257transmiter.png" | Bin 0 -> 9980 bytes ...0\346\265\201\347\250\213\345\233\276.png" | Bin 0 -> 5890 bytes 9 files changed, 1210 insertions(+), 25 deletions(-) create mode 100755 zh-cn/device-dev/driver/driver-platform-i2s-des.md create mode 100755 zh-cn/device-dev/driver/driver-platform-i2s-develop.md create mode 100755 "zh-cn/device-dev/driver/figures/I2S-master\346\230\257controller.png" create mode 100755 "zh-cn/device-dev/driver/figures/I2S-master\346\230\257receiver.png" create mode 100755 "zh-cn/device-dev/driver/figures/I2S-master\346\230\257transmiter.png" create mode 100755 "zh-cn/device-dev/driver/figures/I2S\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" diff --git a/zh-cn/device-dev/driver/Readme-CN.md b/zh-cn/device-dev/driver/Readme-CN.md index 1db6007a4f7..b021fe5cb3a 100755 --- a/zh-cn/device-dev/driver/Readme-CN.md +++ b/zh-cn/device-dev/driver/Readme-CN.md @@ -22,6 +22,7 @@ - [SPI](driver-platform-spi-develop.md) - [UART](driver-platform-uart-develop.md) - [WatchDog](driver-platform-watchdog-develop.md) + - [I2S](driver-platform-i2s-develop.md) - [平台驱动使用](driver-platform.md) - [ADC](driver-platform-adc-des.md) - [GPIO](driver-platform-gpio-des.md) @@ -36,6 +37,7 @@ - [SPI](driver-platform-spi-des.md) - [UART](driver-platform-uart-des.md) - [WATCHDOG](driver-platform-watchdog-des.md) + - [I2S](driver-platform-i2s-des.md) - [外设驱动使用](driver-peripherals.md) - [LCD](driver-peripherals-lcd-des.md) - [TOUCHSCREEN](driver-peripherals-touch-des.md) diff --git a/zh-cn/device-dev/driver/driver-develop.md b/zh-cn/device-dev/driver/driver-develop.md index e4cee0c8838..a9a1378503c 100644 --- a/zh-cn/device-dev/driver/driver-develop.md +++ b/zh-cn/device-dev/driver/driver-develop.md @@ -1,29 +1,18 @@ # 平台驱动开发 - **[ADC](driver-platform-adc-develop.md)** - - **[GPIO](driver-platform-gpio-develop.md)** - - **[HDMI](driver-platform-hdmi-develop.md)** - - **[I2C](driver-platform-i2c-develop.md)** - - **[I3C](driver-platform-i3c-develop.md)** - - **[MIPI-CSI](driver-platform-mipicsi-develop.md)** - - **[MIPI-DSI](driver-platform-mipidsi-develop.md)** - - **[MMC](driver-platform-mmc-develop.md)** - - **[PWM](driver-platform-pwm-develop.md)** - - **[RTC](driver-platform-rtc-develop.md)** - - **[SDIO](driver-platform-sdio-develop.md)** - - **[SPI](driver-platform-spi-develop.md)** - - **[UART](driver-platform-uart-develop.md)** - - **[WatchDog](driver-platform-watchdog-develop.md)** +- **[I2S](driver-platform-i2s-develop.md)** + diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-des.md b/zh-cn/device-dev/driver/driver-platform-i2s-des.md new file mode 100755 index 00000000000..8ade8c092fd --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-i2s-des.md @@ -0,0 +1,682 @@ +# I2S + +- [概述](#section193356154511) +- [接口说明](#section1325964832615) +- [使用指导](#section71363452477) + - [使用流程](#section32846814820) + - [获取I2S设备句柄](#section1927265711481) + - [设置I2S设备属性](#section541133418493) + - [获取I2S设备属性](#section7870106145010) + - [使能I2S设备](#section13324155195013) + - [失能I2S设备](#section19661632135117) + - [开启I2S设备读](#section19661632135118) + + - [关闭I2S设备读](#section19661632135119) + - [开启I2S设备写](#section19661632135120) + - [关闭I2S设备写](#section19661632135121) + - [I2S读](#section19661632135122) + - [I2S写](#section19661632135123) + - [销毁I2S设备句柄](#section19661632135124) +- [使用实例](#section06541058155120) + +## 概述 + +- I2S(Inter-IC Sound)总线, 又称集成电路内置音频总线,是飞利浦半导体公司(现为恩智浦半导体公司)针对数字音频设备之间的音频数据传输而制定的一种总线标准。该总线专门用于音频设备之间的数据传输,广泛应用于各种多媒体系统。采用了沿独立的导线传输时钟与数据信号的设计,通过将数据和时钟信号分离,避免了因时差诱发的失真。 +- I2S信号线,串行时钟SCK,也叫位时钟BCLK,对应数字音频的每一位数据。SCK的频率 = 声道数 * 采样频率 * 采样位数。字段选择信号WS,也叫LRCLK,用于切换左右声道的数据,字段选择信号WS表明了正在被传输的声道,WS为0,表示正在传输的是左声道的数据,WS为1,表示正在传输的是右声道的数据。WS的频率 = 采样频率。串行数据SD,就是用二进制补码表示的音频数据。I2S串行数据在传输的时候,由高位(MSB)到低位(LSB)依次进行传输。 +- 能够产生SCK和WS的信号端就是主设备,用MASTER表示,通信示意图如下: + +**图 1** master是transmitter时的通信示意图 + +![](figures/I2S-master是transmiter.png) + +**图 2** master是receiver时的通信示意图 + +![](figures/I2S-master是receiver.png) + +**图 3** master是controller时的通信示意图 + +![](figures/I2S-master是controller.png) + +## 接口说明 + +**表 1** I2S驱动API接口功能介绍: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能分类

+

接口名

+

描述

+

I2S设备句柄获取、释放接口

+

I2sOpen

+

获取I2S设备句柄

+

I2sClose

+

释放I2S设备句柄

+

I2S使能、失能接口

+

+

I2sEnable

+

使能I2S控制器

+

I2sDisable

+

失能I2S控制器

+

I2S开启读、写接口

+

+

I2sStartRead

+

I2S开启读

+

I2sStartWrite

+

I2S开启写

+

I2S关闭读、写接口

+

+

I2sStopRead

+

I2S关闭读

+

I2sStopWrite

+

I2S关闭写

+

I2S读写接口

+

+

I2sRead

+

I2S读

+

I2sWrite

+

I2S写

+

I2S获取/设置设备属性

+

+

I2sGetCfg

+

I2S获取设备属性

+

I2sSetCfg

+

I2S设置设备属性

+
+ +>![](../public_sys-resources/icon-note.gif) **说明:** +>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 + +## 使用指导 + +### 使用流程 + +使用I2S的一般流程如[图4](#fig1586912310348)所示。 + +**图 4** I2S使用流程图 +![](figures/I2S使用流程图.png) + +### 获取I2S设备句柄 + +在使用I2S进行通信时,首先要调用I2sOpen获取I2S设备句柄,该函数会返回指定编号的I2S设备句柄。 + +DevHandle I2sOpen(int16_t number); + +**表 2** I2sOpen参数和返回值描述 + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

number

+

I2S设备编号

+

返回值

+

返回值描述

+

NULL

+

获取I2S设备句柄失败

+

设备句柄

+

对应的I2S设备句柄

+
+ +假设系统中存在8个I2S控制器,编号从0到7,获取3号控制器设备句柄示例如下: + +```c +DevHandle i2sHandle = NULL; /* I2C控制器句柄 */ +/* 打开I2C控制器 */ +i2sHandle = I2sOpen(3); +if (i2sHandle == NULL) { + HDF_LOGE("I2sOpen: failed\n"); + return; +} +``` + +### 设置[I2S]()设备属性 + +在使用I2S进行通信前,需要调用I2sSetCfg设置I2S设备属性。设置I2S设备属性函数如下: + +void I2sSetCfg(DevHandle handle, struct I2sCfg *cfg); + +**表 3** I2sSetCfg参数和返回值描述 + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+

cfg

+

I2S设备配置参数

+

返回值

+

返回值描述

+

0

+

获取配置成功

+

负数

+

获取配置失败

+
+ +```c +struct I2sCfg cfg; + cfg.sampleRate = test->sampleRate; + cfg.type = test->type; + cfg.channelMode = test->channelMode; + cfg.samplePrecision = test->samplePrecision; + cfg.channelIfMode = test->channelIfMode; + cfg.mclk = test->mclk; + cfg.bclk = test->bclk; + cfg.writeChannel = test->writeChannel; + cfg.i2slFsSel = test->i2slFsSel; + cfg.width = I2S_WORDWIDTH_16BIT; + I2sSetCfg(test->handle, &cfg); +``` + +### 获取I2S设备属性 + +设置I2S属性成功后,可以通过获取设备属性接口查看I2S设备属性。获取I2S设备属性的函数如下所示: + +void I2sGetCfg(DevHandle handle, struct I2sCfg *cfg); + +**表 4** I2sGetCfg参数和返回值描述 + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+

cfg

+

I2S设备配置参数

+
+ +```c +struct I2sCfg cfg; +I2sGetCfg(test->handle, &cfg); +HDF_LOGE("%s:sampleRate[%u], type[%u], channelMode[%u], samplePrecision[%u],\ + channelIfMode[%u], mclk[%u], bclk[%u], writeChannel[%u], i2slFsSel[%u]", __func__, + test->sampleRate, test->type, test->channelMode, test->samplePrecision, + test->channelIfMode, test->mclk, test->bclk, test->writeChannel, test->i2slFsSel); +``` + +### 使能I2S设备 + +- 在使用I2S进行通信前必须使能I2S设备,通过调用I2sEnable使能I2S设备。使能I2S设备的函数如下所示: + +void I2sEnable(DevHandle handle); + +**表 5** I2sEnable参数和返回值描述 + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +```c +if (test == NULL || test->handle == NULL || test->wbuf == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } +I2sEnable(test->handle); +``` + +### 失能I2S设备 + +需要禁用I2S设备时可以通过调用I2sDisable来实现。失能I2S设备的函数如下所示: + +void I2sDisable(DevHandle handle) ; + +**表 6** I2sDisable参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +```c +if (test == NULL || test->handle == NULL || test->wbuf == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } +I2sDisable(test->handle); +``` + +### 开启I2S设备读 + +在进行读I2S从设备之前需要调用函数I2sStartRead向I2S从设备发送开启读命令来开启读的功能。开启I2S设备的函数如下所示: + +void I2sStartRead(DevHandle handle); + +**表 7** I2sStartRead参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +```c +if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } +HDF_LOGI("%s: rbuf[%p] wbuf[%p]\n", __func__, test->rbuf, test->wbuf); +I2sStartRead(test->handle); +``` + +### 关闭I2S读功能 + +在读取从设备结束之前需要调用I2sStopRead函数发送停止读的命令来关闭读功能。关闭I2S设备的函数如下所示: + +void I2sStopRead(DevHandle handle); + +**表 8** I2sStopRead参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +```c +if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } +HDF_LOGI("%s: rbuf[%p] wbuf[%p]\n", __func__, test->rbuf, test->wbuf); +I2sStopRead(test->handle); +``` + +### 开启I2S写功能 + +在进行写I2S从设备之前需要调用函数I2sStartWrite向I2S从设备发送开启写命令来开启写功能。开启I2S写功能的函数如下所示: + +void I2sStartWrite(DevHandle handle); + +**表 9** I2sStartWrite参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +```c +if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } +I2sStartWrite(test->handle); +``` + +### 关闭I2S写功能 + +在写从设备结束之前需要调用函数I2sStopWrite向I2S从设备发送关闭写的命令来关闭写功能。关闭I2S写功能的函数如下所示: + +void I2sStopWrite(DevHandle handle); + +**表 10** I2sStopWrite参数描述 + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +```c +if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } +I2sStopWrite(test->handle); +``` + +### I2S读 + +通过调用函数I2sRead读取I2S从设备的数据,I2S读函数如下所示: + +int32_t I2sRead(DevHandle handle, uint8_t *buf, uint32_t len, uint32_t *pRlen) ; + +**表 11** I2sRead参数描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+

buf

+

接收读取数据的指针

+

len

+

读buffers的长度

+

pRlen

+

每次实际读的长度

+

返回值

+

返回值描述

+

HDF_SUCCESS

+

表示读取成功

+

HDF_FAILURE

+

表示读取失败

+
+ +```c +if (I2sRead(test->handle, test->rbuf, test->len, &test->len) != HDF_SUCCESS) { + HDF_LOGE("%s: I2sRead error \n", __func__); + return HDF_FAILURE; + } +``` + +### I2S写 + +通过调用函数I2sWrite向I2S从设备写数据,I2S写的函数如下所示: + +int32_t I2sWrite(DevHandle handle, uint8_t *buf, uint32_t len, uint32_t *pWlen) ; + +**表 12** I2sWrite参数描述 + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+

buf

+

写数据的指针

+

len

+

写buffers的长度

+

pWlen

+

每次实际写的长度

+

返回值

+

返回值描述

+

HDF_SUCCESS

+

表示写成功

+

HDF_FAILURE

+

表示写失败

+
+ +```c +if (I2sWrite(test->handle, test->wbuf, test->len, &test->len) != HDF_SUCCESS) { + HDF_LOGE("%s: I2sWriteTest error \n", __func__); + return HDF_FAILURE; + } +``` + +### 销毁I2S设备句柄 + +在使用I2S通信结束后需要调用函数I2sClose销毁I2S设备句柄,销毁I2S设备句柄的函数如下所示: + +void I2sClose(DevHandle handle); + +**表 13** I2sClose参数描述 + + + + + + + + +

参数

+

参数描述

+

handle

+

I2S设备句柄

+
+ +``` +I2sClose(test->handle); +``` + +## 使用实例 + +I2S设备完整的使用实例如下,首先需要获取I2S设备句柄,接着设置I2S设备属性、使能I2S设备,开启I2S读、写功能,进行I2S读、写,关闭I2S读、写功能,失能I2S设备,销毁I2S设备句柄。 + +```c +#include "hdf_log.h" +#include "i2s_if.h" +void I2sTestSample(void) +{ + int32_t ret; + int32_t i; + int16_t number; + DevHandle handle = NULL; + uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; + uint8_t rbuff[5] = { 0 }; + uint32_t wlen = 0; + uint32_t pRlen = 0; + struct I2sCfg cfg; + cfg.sampleRate = I2S_SAMPLE_RATE_44_1K; /* I2S采样速率,这里设置的是44.1k速率采样 */ + cfg.type = I2S_PROTOCOL_I2S_MSB; /* I2S 协议传输类型 ,这里设置的协议类型是msb,先传输高字节后传输低字节 */ + cfg.channelMode = I2S_CHANNEL_MODE_STEREO; /* I2S通道模式,这里设置的是立体声通道模式 */ + cfg.samplePrecision = 8; /* I2S采样精度,这里设置的是8bit,位数越高声音的保真度越高 */ + cfg.channelIfMode = I2S_CHANNEL_IF_MODE_I2S; /* I2S协议时序模式,这里设置的是I2S协议时序 */ + cfg.mclk = 256; /* I2S同步时钟频率,这里设置的是256khz */ + cfg.bclk = 32768; /* I2S串行时钟频率,这里设置的是32768hz */ + cfg.writeChannel = I2S_WRITE_CHANNEL_AUDIO; /* I2S 写通道,这里设置的是音频通道 */ + cfg.i2slFsSel = I2SL_FS_SEL_1024_FS /* I2S采样频率设置,这里设置的采样频率是1024hz */; + cfg.width = I2S_WORDWIDTH_16BIT; /* I2S传输的位宽,这里设置的是16bit */ + number = 0; /* I2S设备号,要填写实际平台上的设备号 */ + handle = I2sOpen(number); /* 获取I2S设备句柄 */ + if (handle == NULL) { + HDF_LOGE("I2sOpen: failed!\n"); + return; + } + /* 设置I2S设备属性 */ + ret = I2sSetCfg(handle, &cfg); + if (ret != 0) { + HDF_LOGE("I2sSetCfg: failed, ret %d\n", ret); + goto _ERR; + } + /* 使能I2S设备 */ + I2sEnable(handle); + /* 开启I2S写功能 */ + I2sStartWrite(handle); + /* 向I2S设备写5字节的数据 */ + ret = I2sWrite(handle, wbuff, 5, &wlen); + if (ret < 0) { + HDF_LOGE("I2sWrite: failed, ret %d\n", ret); + goto _ERR; + } + /* 关闭I2S写功能 */ + I2sStopWrite(handle); + /* 开启I2S读功能 */ + I2sStartRead(handle); + /* 从I2S设备读5字节的数据 */ + ret = I2sRead(handle, rbuff, 5, &pRlen); + if (ret < 0) { + HDF_LOGE("I2sRead: failed, ret %d\n", ret); + goto _ERR; + } + /* 关闭I2S读功能 */ + I2sStopRead(handle); + for (i = 0; i < 5; i++) { + HDF_LOGE("%s: rbuff[%d] = 0x%x", __func__, i, rbuff[i]); + } +_ERR: + /* 销毁I2S设备句柄 */ + I2sClose(handle); +} +``` + diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md new file mode 100755 index 00000000000..b239d91e0e7 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -0,0 +1,522 @@ +# I2S + +- [概述](#section84922229152909) +- [接口说明](#section752964871810) +- [开发步骤](#section799667984152909) +- [开发实例](#section956157227152909) + +## 概述 + +I2S(Inter—IC Sound)总线, 又称集成电路内置音频总线,在HDF框架中,I2S的接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 + +**图 1** I2S独立服务模式结构图 +![](figures/独立服务模式结构图.png) + +## 接口说明 + +I2sCntlrMethod定义: + +```c +struct I2sCntlrMethod { + int32_t (*GetCfg)(struct I2sCntlr *, struct I2sCfg *); + int32_t (*SetCfg)(struct I2sCntlr *, struct I2sCfg *); + int32_t (*Transfer)(struct I2sCntlr *, struct I2sMsg *); + int32_t (*Open)(struct I2sCntlr *); + int32_t (*Close)(struct I2sCntlr *); + int32_t (*Enable)(struct I2sCntlr *); + int32_t (*Disable)(struct I2sCntlr *); + int32_t (*StartWrite)(struct I2sCntlr *); + int32_t (*StopWrite)(struct I2sCntlr *); + int32_t (*StartRead)(struct I2sCntlr *); + int32_t (*StopRead)(struct I2sCntlr *); +}; +``` + +**表 1** I2sCntlrMethod结构体成员的回调函数功能说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

成员函数

+

入参

+

出参

+

返回值

+

功能

+

GetCfg

+

Cntlr:结构体指针,核心层i2s控制器;

+

Cfg:结构体指针,传出的属性值(见i2s_if.h中I2sCfg定义)

+

HDF_STATUS相关状态

+

获取属性值

+

SetCfg

+

Cfg:结构体指针,传入的属性值(见i2s_if.h中I2sCfg定义)

+

Cntlr:结构体指针,核心层i2s控制器,传出的值

+

HDF_STATUS相关状态

+

设置控制器属性

+

Transfer

+

cntlr:结构体指针,核心层i2s控制器;

+

Msgs:结构体指针,传出的消息值(见i2s_if.h中I2sMsg定义)

+

HDF_STATUS相关状态

+

传递消息,此处是读取i2s设备数据

+

Transfer

+

Cntlr:结构体指针,核心层i2s控制器;Msgs:结构体指针,传入的消息值

+

+

HDF_STATUS相关状态

+

传递消息,此处是向i2s设备写数据

+

Open

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

打开I2S

+

Close

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

关闭I2S

+

Enable

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

使能I2S设备

+

Disable

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

失能I2S设备

+

StartWrite

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

开启写

+

StopWrite

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

关闭写

+

StartRead

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

开启读

+

StopRead

+

cntlr:结构体指针,核心层i2s控制器;

+

+

HDF_STATUS相关状态

+

关闭读

+
+ +## 开发步骤 + +I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动入口,以及实例化核心层接口函数。 + +1. **实例化驱动入口:** + - 实例化HdfDriverEntry结构体成员。 + - 调用HDF\_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 + +2. **配置属性文件:** + - 在device\_info.hcs文件中添加deviceNode描述。 + - 【可选】添加i2s\_config.hcs器件属性文件。 + +3. **实例化I2S控制器对象:** + + - 初始化I2sCntlr成员。 +- 实例化I2sCntlr成员I2sCntlrMethod。 + + >![](../public_sys-resources/icon-note.gif) **说明:** + >实例化I2sCntlr成员I2sCntlrMethod,其定义和成员说明见[接口说明](#section752964871810)。 + + +4. **驱动调试:** + + 【可选】针对新增驱动程序,建议验证驱动基本功能,例如设置I2S属性,获取I2S属性等。 + + +## 开发实例 + +下方将以i2s_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 + +1. 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf\_device\_desc.h 中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 + + 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + + I2S驱动入口参考: + + ```c + struct HdfDriverEntry g_hdfI2sDevice = { + .moduleVersion = 1, + .moduleName = "HDF_PLATFORM_I2S",//【必要且与 HCS 里面的名字匹配】 + .Bind = HdfI2sDeviceBind,//见Bind参考 + .Init = HdfI2sDeviceInit, //见Init参考 + .Release = HdfI2sDeviceRelease, //见Release参考 + }; + //调用HDF_INIT将驱动入口注册到HDF框架中 + HDF_INIT(g_hdfI2sDevice); + ``` + +2. 完成驱动入口注册之后,下一步请在device\_info.hcs文件中添加deviceNode信息,并在 i2s_config.hcs 中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层I2sCntlr成员的默认值或限制范围有密切关系。 + + 本例只有一个I2S控制器,如有多个器件信息,则需要在device\_info文件增加deviceNode信息,以及在i2s_config文件中增加对应的器件属性。 + + - device\_info.hcs 配置参考。 + + ``` + root { + device_info { + match_attr = "hdf_manager"; + platform :: host { + hostName = "platform_host"; + priority = 50; + device_i2s :: device { + device0 :: deviceNode { + policy = 1; + priority = 60; + permission = 0644; + moduleName = "HDF_PLATFORM_I2S"; + serviceName = "HDF_PLATFORM_I2S_0"; + deviceMatchAttr = "hisilicon_hi35xx_i2s_0"; + } + } + + } + } + } + ``` + + - i2s_config.hcs 配置参考。 + + ``` + root { + platform { + i2s_config {//每一个I2S控制器配置私有数据 + template i2s_controller {//模板公共参数, 继承该模板的节点如果使用模板中的默认值, 则节点字段可以缺省 + serviceName = ""; + match_attr = ""; + busNum = 0; // 总线号 + i2s_pad_enable = 1; + audio_enable = 0; + regBase = 0x113B0000;// 地址映射需要 + PERI_CRG103 = 0xa; + MCLK = 12288; /* KHZ */ + aiao_srst_req = 1; /* 1 reset-->RX0 channel reset */ + aiao_cken = 0; /* 0 close MCLK/BCLK/WS clk gate */ + BCLK = 3072; /* KHZ */ + i2sl_fs_sel = 0x1a; /* MCLK=256fs */ + irqNum = 0; // 中断号 + } + + controller_0x113b0000 :: i2s_controller { + busNum = 0; //【必要】总线号 + regBase = 0x113B0000; // 地址映射需要 + match_attr = "hisilicon_hi35xx_i2s_0"; + irqNum = 87; // 中断号 + } + ... + // 【可选】可新增,但需要在 device_info.hcs 添加对应的节点 + } + } + } + ``` + +3. 完成驱动入口注册之后,最后一步就是以核心层I2sCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化I2sCntlr成员I2sCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 + - 自定义结构体参考。 + + 从驱动的角度看,自定义结构体是参数和数据的载体,而且i2s_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象,例如设备号、总线号等。 + + ```c + struct I2sConfigInfo {//对应于hcs中的参数 + uint8_t i2sPadEnable; + uint8_t audioEnable; + uint32_t PERICRG103; + uint32_t I2sCfgCfg000; + uint32_t mclk; /**< KHZ */ + uint32_t bclk; /**< KHZ */ + struct I2sCfgCfg100 regCfg100; + struct RxIfAttr1Info regRxIfAttr1; + volatile unsigned char *phyBase; + volatile unsigned char *regBase; + enum I2sWriteChannel writeChannel; + enum I2sSampleRate sampleRate; + enum I2sWordWidth width; + enum I2sChannelIfMode channelIfMode; + enum I2sChannelMode channelMode; + enum I2sProtocolType type; + uint8_t samplePrecision; + uint16_t i2slFsSel; + DMA_ADDR_T rxData; + uint8_t *rxVirData; + uint32_t rxWptr; + uint32_t rxRptr; + uint32_t rxSize; + uint32_t rxTransSize; + DMA_ADDR_T txData; + uint8_t *txVirData; + uint32_t txWptr; + uint32_t txRptr; + uint32_t txSize; + uint32_t txTransSize; + volatile unsigned char *codecAddr; + volatile unsigned char *crg103Addr; + bool isplay; + bool txEn; + }; + + //I2sCntlr 是核心层控制器结构体,其中的成员在Init函数中会被赋值 + struct I2sCntlr { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + uint32_t busNum; + uint32_t irqNum; + struct OsalMutex lock; + struct I2sCntlrMethod *method; + void *priv; // private data + }; + ``` + + - I2sCntlr 成员回调函数结构体I2sCntlrMethod的实例化,其他成员在Init函数中初始化。 + + ```c + struct I2sCntlrMethod g_i2sCntlrMethod = {// i2s_hi35xx.c 中的示例:钩子函数的实例化 + .GetCfg = Hi35xxI2sGetCfg, + .SetCfg = Hi35xxI2sSetCfg, + .Transfer = Hi35xxI2sTransfer, + .Open = Hi35xxI2sOpen, + .Close = Hi35xxI2sClose, + .Enable = Hi35xxI2sEnable, + .Disable = Hi35xxI2sDisable, + .StartWrite = Hi35xxI2sStartWrite, + .StopWrite = Hi35xxI2sStopWrite, + .StartRead = Hi35xxI2sStartRead, + .StopRead = Hi35xxI2sStopRead, + }; + ``` + ``` + + - Bind 函数参考 + + 入参: + + HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 + + **返回值:** + + HDF\_STATUS相关状态。 + + 函数说明: + + 将 I2sCntlr 对象同 HdfDeviceObject 进行了关联。 + + ```c + static int32_t HdfI2sDeviceBind(struct HdfDeviceObject *device) + { + if (device == NULL) { + I2S_PRINT_LOG_ERR("%s: device NULL", __func__); + return HDF_ERR_INVALID_OBJECT; + } + return (I2sCntlrCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS; + } + struct I2sCntlr *I2sCntlrCreate(struct HdfDeviceObject *device) + { + struct I2sCntlr *cntlr = NULL; + ... + cntlr = (struct I2sCntlr *)OsalMemCalloc(sizeof(*cntlr)); + if (cntlr == NULL) { + HDF_LOGE("%s: OsalMemCalloc error", __func__); + return NULL; + } + ... + cntlr->device = device; + device->service = &(cntlr->service); + (void)OsalMutexInit(&cntlr->lock); + cntlr->priv = NULL; + cntlr->method = NULL; + return cntlr; + } + ``` + + - Init函数参考 + + 入参: + + HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 + + 返回值: + + HDF\_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见/drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS 定义)。 + + **表 2** init函数入参和返回值 + + + + + + + + + + + + + + + + + + + + + + + + + +

状态(值)

+

问题描述

+

HDF_ERR_INVALID_OBJECT

+

控制器对象非法

+

HDF_ERR_MALLOC_FAIL

+

内存分配失败

+

HDF_ERR_INVALID_PARAM

+

参数非法

+

HDF_ERR_IO

+

I/O 错误

+

HDF_SUCCESS

+

初始化成功

+

HDF_FAILURE

+

初始化失败

+
+ + 函数说明: + + 初始化自定义结构体对象,初始化I2sCntlr 成员。 + + ```c + static int32_t HdfI2sDeviceInit(struct HdfDeviceObject *device) + { + struct I2sCntlr *cntlr = NULL; + ... + cntlr = I2sCntlrFromDevice(device); + ... + int32_t ret = I2sInit(cntlr, device); + ... + return ret; + } + ``` + + - Release函数参考 + + 入参: + + HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 + + 返回值: + + 无。 + + 函数说明: + + 释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给 Release 接口, 当HDF框架调用Init函数初始化驱动失败时,可以调用 Release 释放驱动资源。所有强制转换获取相应对象的操作**前提**是在Init函数中具备对应赋值的操作。 + + ```c + static void HdfI2sDeviceRelease(struct HdfDeviceObject *device) + { + struct I2sCntlr *cntlr = NULL; + ... + cntlr = I2sCntlrFromDevice(device); + ... + if (cntlr->priv != NULL) { + struct I2sConfigInfo *configInfo = cntlr->priv; + if (configInfo->regBase != 0) { + OsalIoUnmap((void *)configInfo->regBase); + } + if (configInfo->codecAddr != 0) { + OsalIoUnmap((void *)configInfo->codecAddr); + } + if (configInfo->crg103Addr != 0) { + OsalIoUnmap((void *)configInfo->crg103Addr); + } + OsalMemFree(cntlr->priv); + } + I2sCntlrDestroy(cntlr);//释放cntlr对象 + } + ``` + + + diff --git a/zh-cn/device-dev/driver/driver-platform.md b/zh-cn/device-dev/driver/driver-platform.md index 01fc51f6cd1..5b24fb41bf1 100644 --- a/zh-cn/device-dev/driver/driver-platform.md +++ b/zh-cn/device-dev/driver/driver-platform.md @@ -1,27 +1,17 @@ # 平台驱动使用 - **[ADC](driver-platform-adc-des.md)** - - **[GPIO](driver-platform-gpio-des.md)** - - **[HDMI](driver-platform-hdmi-des.md)** - - **[I2C](driver-platform-i2c-des.md)** - - **[I3C](driver-platform-i3c-des.md)** - - **[MIPI-CSI](driver-platform-mipicsi-des.md)** - - **[MIPI-DSI](driver-platform-mipidsi-des.md)** - - **[PWM](driver-platform-pwm-des.md)** - - **[RTC](driver-platform-rtc-des.md)** - - **[SDIO](driver-platform-sdio-des.md)** - - **[SPI](driver-platform-spi-des.md)** - - **[UART](driver-platform-uart-des.md)** - - **[WATCHDOG](driver-platform-watchdog-des.md)** +- **[I2S](driver-platform-i2s-des.md)** + diff --git "a/zh-cn/device-dev/driver/figures/I2S-master\346\230\257controller.png" "b/zh-cn/device-dev/driver/figures/I2S-master\346\230\257controller.png" new file mode 100755 index 0000000000000000000000000000000000000000..c3684f735f8a68a198c3ced8a243b6674760272d GIT binary patch literal 10879 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 KrdrM-_`d=5=~*rS literal 0 HcmV?d00001 diff --git "a/zh-cn/device-dev/driver/figures/I2S-master\346\230\257receiver.png" "b/zh-cn/device-dev/driver/figures/I2S-master\346\230\257receiver.png" new file mode 100755 index 0000000000000000000000000000000000000000..056e2b9178b380023228d9a9747d8fd4f02b14d8 GIT binary patch literal 7239 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 PAfTqCtym%d`on(!vZN8g literal 0 HcmV?d00001 diff --git "a/zh-cn/device-dev/driver/figures/I2S-master\346\230\257transmiter.png" "b/zh-cn/device-dev/driver/figures/I2S-master\346\230\257transmiter.png" new file mode 100755 index 0000000000000000000000000000000000000000..889c0c0ba5a11880ea41fdbbd8a00b5c2bd61e5e GIT binary patch literal 9980 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 Date: Sun, 6 Feb 2022 19:58:20 -0800 Subject: [PATCH 2/8] Added I2S document Signed-off-by: zhangyalei --- .../driver/driver-platform-i2s-develop.md | 238 ++++++++---------- 1 file changed, 105 insertions(+), 133 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md index b239d91e0e7..6be486bdfd2 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -296,7 +296,7 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 ``` 3. 完成驱动入口注册之后,最后一步就是以核心层I2sCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化I2sCntlr成员I2sCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 - - 自定义结构体参考。 + - 自定义结构体参考 从驱动的角度看,自定义结构体是参数和数据的载体,而且i2s_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象,例如设备号、总线号等。 @@ -352,37 +352,36 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 - I2sCntlr 成员回调函数结构体I2sCntlrMethod的实例化,其他成员在Init函数中初始化。 - ```c - struct I2sCntlrMethod g_i2sCntlrMethod = {// i2s_hi35xx.c 中的示例:钩子函数的实例化 - .GetCfg = Hi35xxI2sGetCfg, - .SetCfg = Hi35xxI2sSetCfg, - .Transfer = Hi35xxI2sTransfer, - .Open = Hi35xxI2sOpen, - .Close = Hi35xxI2sClose, - .Enable = Hi35xxI2sEnable, - .Disable = Hi35xxI2sDisable, - .StartWrite = Hi35xxI2sStartWrite, - .StopWrite = Hi35xxI2sStopWrite, - .StartRead = Hi35xxI2sStartRead, - .StopRead = Hi35xxI2sStopRead, - }; - ``` - ``` - + ```c + struct I2sCntlrMethod g_i2sCntlrMethod = {// i2s_hi35xx.c 中的示例:钩子函数的实例化 + .GetCfg = Hi35xxI2sGetCfg, + .SetCfg = Hi35xxI2sSetCfg, + .Transfer = Hi35xxI2sTransfer, + .Open = Hi35xxI2sOpen, + .Close = Hi35xxI2sClose, + .Enable = Hi35xxI2sEnable, + .Disable = Hi35xxI2sDisable, + .StartWrite = Hi35xxI2sStartWrite, + .StopWrite = Hi35xxI2sStopWrite, + .StartRead = Hi35xxI2sStartRead, + .StopRead = Hi35xxI2sStopRead, + }; + ``` + - Bind 函数参考 入参: - + HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 - - **返回值:** - + + 返回值: + HDF\_STATUS相关状态。 - + 函数说明: - + 将 I2sCntlr 对象同 HdfDeviceObject 进行了关联。 - + ```c static int32_t HdfI2sDeviceBind(struct HdfDeviceObject *device) { @@ -392,7 +391,7 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 } return (I2sCntlrCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS; } - struct I2sCntlr *I2sCntlrCreate(struct HdfDeviceObject *device) + struct I2sCntlr *I2sCntlrCreate(struct HdfDeviceObject *device) { struct I2sCntlr *cntlr = NULL; ... @@ -401,7 +400,7 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 HDF_LOGE("%s: OsalMemCalloc error", __func__); return NULL; } - ... + ... cntlr->device = device; device->service = &(cntlr->service); (void)OsalMutexInit(&cntlr->lock); @@ -409,114 +408,87 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 cntlr->method = NULL; return cntlr; } - ``` - - - Init函数参考 - - 入参: - - HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 - - 返回值: - - HDF\_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见/drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS 定义)。 - - **表 2** init函数入参和返回值 - - - - - - - - - - - - - - - - - - - - - - - - - -

状态(值)

-

问题描述

-

HDF_ERR_INVALID_OBJECT

-

控制器对象非法

-

HDF_ERR_MALLOC_FAIL

-

内存分配失败

-

HDF_ERR_INVALID_PARAM

-

参数非法

-

HDF_ERR_IO

-

I/O 错误

-

HDF_SUCCESS

-

初始化成功

-

HDF_FAILURE

-

初始化失败

-
- - 函数说明: - - 初始化自定义结构体对象,初始化I2sCntlr 成员。 - - ```c - static int32_t HdfI2sDeviceInit(struct HdfDeviceObject *device) - { - struct I2sCntlr *cntlr = NULL; - ... - cntlr = I2sCntlrFromDevice(device); - ... - int32_t ret = I2sInit(cntlr, device); - ... - return ret; - } - ``` - - - Release函数参考 - - 入参: - - HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 - - 返回值: - - 无。 - - 函数说明: + ``` + + - Init函数参考 - 释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给 Release 接口, 当HDF框架调用Init函数初始化驱动失败时,可以调用 Release 释放驱动资源。所有强制转换获取相应对象的操作**前提**是在Init函数中具备对应赋值的操作。 + 入参: + + HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 + + 返回值: + + HDF\_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见/drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS 定义)。 + + **表 2** init函数入参和返回值 + + + + | 状态(值) | 问题描述 | + | ---------------------- | -------------- | + | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | + | HDF_ERR_MALLOC_FAIL | 内存分配失败 | + | HDF_ERR_INVALID_PARAM | 参数非法 | + | HDF_ERR_IO | I/O 错误 | + | HDF_SUCCESS | 初始化成功 | + | HDF_FAILURE | 初始化失败 | + + 函数说明: + + 初始化自定义结构体对象,初始化I2sCntlr 成员。 + + ```c + static int32_t HdfI2sDeviceInit(struct HdfDeviceObject *device) + { + struct I2sCntlr *cntlr = NULL; + ... + cntlr = I2sCntlrFromDevice(device); + ... + int32_t ret = I2sInit(cntlr, device); + ... + return ret; + } + ``` + + - Release函数参考 - ```c - static void HdfI2sDeviceRelease(struct HdfDeviceObject *device) - { - struct I2sCntlr *cntlr = NULL; - ... - cntlr = I2sCntlrFromDevice(device); - ... - if (cntlr->priv != NULL) { - struct I2sConfigInfo *configInfo = cntlr->priv; - if (configInfo->regBase != 0) { - OsalIoUnmap((void *)configInfo->regBase); - } - if (configInfo->codecAddr != 0) { - OsalIoUnmap((void *)configInfo->codecAddr); - } - if (configInfo->crg103Addr != 0) { - OsalIoUnmap((void *)configInfo->crg103Addr); - } - OsalMemFree(cntlr->priv); - } - I2sCntlrDestroy(cntlr);//释放cntlr对象 - } - ``` + 入参: + + HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 + + 返回值: + + 无。 + + 函数说明: + + 释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给 Release 接口, 当HDF框架调用Init函数初始化驱动失败时,可以调用 Release 释放驱动资源。所有强制转换获取相应对象的操作**前提**是在Init函数中具备对应赋值的操作。 + + ```c + static void HdfI2sDeviceRelease(struct HdfDeviceObject *device) + { + struct I2sCntlr *cntlr = NULL; + ... + cntlr = I2sCntlrFromDevice(device); + ... + if (cntlr->priv != NULL) { + struct I2sConfigInfo *configInfo = cntlr->priv; + if (configInfo->regBase != 0) { + OsalIoUnmap((void *)configInfo->regBase); + } + if (configInfo->codecAddr != 0) { + OsalIoUnmap((void *)configInfo->codecAddr); + } + if (configInfo->crg103Addr != 0) { + OsalIoUnmap((void *)configInfo->crg103Addr); + } + OsalMemFree(cntlr->priv); + } + I2sCntlrDestroy(cntlr);//释放cntlr对象 + } + ``` + +​ -- Gitee From c88e821937eeab19b2bc622f6c8339ef59fcabb5 Mon Sep 17 00:00:00 2001 From: zhangyalei Date: Sun, 6 Feb 2022 22:20:46 -0800 Subject: [PATCH 3/8] Added I2S document Signed-off-by: zhangyalei --- zh-cn/device-dev/driver/driver-platform-i2s-develop.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md index 6be486bdfd2..82b96eed646 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -198,10 +198,10 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 3. **实例化I2S控制器对象:** - 初始化I2sCntlr成员。 -- 实例化I2sCntlr成员I2sCntlrMethod。 - - >![](../public_sys-resources/icon-note.gif) **说明:** - >实例化I2sCntlr成员I2sCntlrMethod,其定义和成员说明见[接口说明](#section752964871810)。 + - 实例化I2sCntlr成员I2sCntlrMethod。 + +>​ ![](../public_sys-resources/icon-note.gif) **说明:** +>​ 实例化I2sCntlr成员I2sCntlrMethod,其定义和成员说明见[接口说明](#section752964871810)。 4. **驱动调试:** -- Gitee From 8d03916a917740c4311716c367fa809ef1d6777a Mon Sep 17 00:00:00 2001 From: zhangyalei Date: Sun, 6 Feb 2022 23:52:46 -0800 Subject: [PATCH 4/8] Added i2s documentation Signed-off-by: zhangyalei --- zh-cn/device-dev/driver/driver-develop.md | 15 ++++++++++++++- zh-cn/device-dev/driver/driver-platform.md | 14 +++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-develop.md b/zh-cn/device-dev/driver/driver-develop.md index a9a1378503c..6162a4129fe 100644 --- a/zh-cn/device-dev/driver/driver-develop.md +++ b/zh-cn/device-dev/driver/driver-develop.md @@ -1,18 +1,31 @@ # 平台驱动开发 - **[ADC](driver-platform-adc-develop.md)** + - **[GPIO](driver-platform-gpio-develop.md)** + - **[HDMI](driver-platform-hdmi-develop.md)** + - **[I2C](driver-platform-i2c-develop.md)** + - **[I3C](driver-platform-i3c-develop.md)** + - **[MIPI-CSI](driver-platform-mipicsi-develop.md)** + - **[MIPI-DSI](driver-platform-mipidsi-develop.md)** + - **[MMC](driver-platform-mmc-develop.md)** + - **[PWM](driver-platform-pwm-develop.md)** + - **[RTC](driver-platform-rtc-develop.md)** + - **[SDIO](driver-platform-sdio-develop.md)** + - **[SPI](driver-platform-spi-develop.md)** + - **[UART](driver-platform-uart-develop.md)** + - **[WatchDog](driver-platform-watchdog-develop.md)** -- **[I2S](driver-platform-i2s-develop.md)** +- **[I2S](driver-platform-i2s-develop.md)** diff --git a/zh-cn/device-dev/driver/driver-platform.md b/zh-cn/device-dev/driver/driver-platform.md index 5b24fb41bf1..b26773496a4 100644 --- a/zh-cn/device-dev/driver/driver-platform.md +++ b/zh-cn/device-dev/driver/driver-platform.md @@ -1,17 +1,29 @@ # 平台驱动使用 - **[ADC](driver-platform-adc-des.md)** + - **[GPIO](driver-platform-gpio-des.md)** + - **[HDMI](driver-platform-hdmi-des.md)** + - **[I2C](driver-platform-i2c-des.md)** + - **[I3C](driver-platform-i3c-des.md)** + - **[MIPI-CSI](driver-platform-mipicsi-des.md)** + - **[MIPI-DSI](driver-platform-mipidsi-des.md)** + - **[PWM](driver-platform-pwm-des.md)** + - **[RTC](driver-platform-rtc-des.md)** + - **[SDIO](driver-platform-sdio-des.md)** + - **[SPI](driver-platform-spi-des.md)** + - **[UART](driver-platform-uart-des.md)** + - **[WATCHDOG](driver-platform-watchdog-des.md)** -- **[I2S](driver-platform-i2s-des.md)** +- **[I2S](driver-platform-i2s-des.md)** -- Gitee From 2230c762057c1273c9b7f7ab7cf8b32f50d50ed3 Mon Sep 17 00:00:00 2001 From: zhangyalei Date: Mon, 7 Feb 2022 00:01:04 -0800 Subject: [PATCH 5/8] Added i2s documentation Signed-off-by: zhangyalei --- zh-cn/device-dev/driver/driver-platform-i2s-develop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md index 82b96eed646..82bb1adcae1 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -354,7 +354,7 @@ I2S模块适配HDF框架的三个环节是配置属性文件,实例化驱动 ```c struct I2sCntlrMethod g_i2sCntlrMethod = {// i2s_hi35xx.c 中的示例:钩子函数的实例化 - .GetCfg = Hi35xxI2sGetCfg, + .GetCfg = Hi35xxI2sGetCfg, .SetCfg = Hi35xxI2sSetCfg, .Transfer = Hi35xxI2sTransfer, .Open = Hi35xxI2sOpen, -- Gitee From 1e996b67a171ee8b62b12dc78ee02695f2661495 Mon Sep 17 00:00:00 2001 From: zhangyalei Date: Tue, 8 Feb 2022 19:50:12 -0800 Subject: [PATCH 6/8] i2s documentation Signed-off-by: zhangyalei --- .../driver/driver-platform-i2s-des.md | 44 +++++++++---------- .../driver/driver-platform-i2s-develop.md | 8 ++-- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-des.md b/zh-cn/device-dev/driver/driver-platform-i2s-des.md index 8ade8c092fd..16ee0cc28c6 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-des.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-des.md @@ -9,11 +9,11 @@ - [获取I2S设备属性](#section7870106145010) - [使能I2S设备](#section13324155195013) - [失能I2S设备](#section19661632135117) - - [开启I2S设备读](#section19661632135118) + - [开始I2S设备读](#section19661632135118) - - [关闭I2S设备读](#section19661632135119) - - [开启I2S设备写](#section19661632135120) - - [关闭I2S设备写](#section19661632135121) + - [停止I2S设备读](#section19661632135119) + - [开始I2S设备写](#section19661632135120) + - [停止I2S设备写](#section19661632135121) - [I2S读](#section19661632135122) - [I2S写](#section19661632135123) - [销毁I2S设备句柄](#section19661632135124) @@ -76,30 +76,30 @@

失能I2S控制器

-

I2S开启读、写接口

+

I2S开始读、写接口

I2sStartRead

-

I2S开启读

+

I2S开始读

I2sStartWrite

-

I2S开启写

+

I2S开始写

-

I2S关闭读、写接口

+

I2S停止读、写接口

I2sStopRead

-

I2S关闭读

+

I2S停止读

I2sStopWrite

-

I2S关闭写

+

I2S停止写

I2S读写接口

@@ -346,9 +346,9 @@ if (test == NULL || test->handle == NULL || test->wbuf == NULL) { I2sDisable(test->handle); ``` -### 开启I2S设备读 +### 开始I2S读功能 -在进行读I2S从设备之前需要调用函数I2sStartRead向I2S从设备发送开启读命令来开启读的功能。开启I2S设备的函数如下所示: +在进行读I2S从设备之前需要调用函数I2sStartRead向I2S从设备发送开始读命令来开始读的功能。开始I2S设备读的函数如下所示: void I2sStartRead(DevHandle handle); @@ -378,9 +378,9 @@ HDF_LOGI("%s: rbuf[%p] wbuf[%p]\n", __func__, test->rbuf, test->wbuf); I2sStartRead(test->handle); ``` -### 关闭I2S读功能 +### 停止I2S读功能 -在读取从设备结束之前需要调用I2sStopRead函数发送停止读的命令来关闭读功能。关闭I2S设备的函数如下所示: +在读取从设备结束之前需要调用I2sStopRead函数发送停止读的命令来停止读功能。停止I2S设备读的函数如下所示: void I2sStopRead(DevHandle handle); @@ -410,9 +410,9 @@ HDF_LOGI("%s: rbuf[%p] wbuf[%p]\n", __func__, test->rbuf, test->wbuf); I2sStopRead(test->handle); ``` -### 开启I2S写功能 +### 开始I2S写功能 -在进行写I2S从设备之前需要调用函数I2sStartWrite向I2S从设备发送开启写命令来开启写功能。开启I2S写功能的函数如下所示: +在进行写I2S从设备之前需要调用函数I2sStartWrite向I2S从设备发送开始写命令来开始写功能。开始I2S写功能的函数如下所示: void I2sStartWrite(DevHandle handle); @@ -443,7 +443,7 @@ I2sStartWrite(test->handle); ### 关闭I2S写功能 -在写从设备结束之前需要调用函数I2sStopWrite向I2S从设备发送关闭写的命令来关闭写功能。关闭I2S写功能的函数如下所示: +在写从设备结束之前需要调用函数I2sStopWrite向I2S从设备发送停止写的命令来停止写功能。停止I2S写功能的函数如下所示: void I2sStopWrite(DevHandle handle); @@ -611,7 +611,7 @@ I2sClose(test->handle); ## 使用实例 -I2S设备完整的使用实例如下,首先需要获取I2S设备句柄,接着设置I2S设备属性、使能I2S设备,开启I2S读、写功能,进行I2S读、写,关闭I2S读、写功能,失能I2S设备,销毁I2S设备句柄。 +I2S设备完整的使用实例如下,首先需要获取I2S设备句柄,接着设置I2S设备属性、使能I2S设备,开始I2S读、写功能,进行I2S读、写,停止I2S读、写功能,失能I2S设备,销毁I2S设备句柄。 ```c #include "hdf_log.h" @@ -651,7 +651,7 @@ void I2sTestSample(void) } /* 使能I2S设备 */ I2sEnable(handle); - /* 开启I2S写功能 */ + /* 开始I2S写功能 */ I2sStartWrite(handle); /* 向I2S设备写5字节的数据 */ ret = I2sWrite(handle, wbuff, 5, &wlen); @@ -659,9 +659,9 @@ void I2sTestSample(void) HDF_LOGE("I2sWrite: failed, ret %d\n", ret); goto _ERR; } - /* 关闭I2S写功能 */ + /* 停止I2S写功能 */ I2sStopWrite(handle); - /* 开启I2S读功能 */ + /* 开始I2S读功能 */ I2sStartRead(handle); /* 从I2S设备读5字节的数据 */ ret = I2sRead(handle, rbuff, 5, &pRlen); @@ -669,7 +669,7 @@ void I2sTestSample(void) HDF_LOGE("I2sRead: failed, ret %d\n", ret); goto _ERR; } - /* 关闭I2S读功能 */ + /* 停止I2S读功能 */ I2sStopRead(handle); for (i = 0; i < 5; i++) { HDF_LOGE("%s: rbuff[%d] = 0x%x", __func__, i, rbuff[i]); diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md index 82bb1adcae1..a5283865748 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -144,7 +144,7 @@ struct I2sCntlrMethod {

HDF_STATUS相关状态

-

开启写

+

开始写

StopWrite

@@ -155,7 +155,7 @@ struct I2sCntlrMethod {

HDF_STATUS相关状态

-

关闭写

+

停止写

StartRead

@@ -166,7 +166,7 @@ struct I2sCntlrMethod {

HDF_STATUS相关状态

-

开启读

+

开始读

StopRead

@@ -177,7 +177,7 @@ struct I2sCntlrMethod {

HDF_STATUS相关状态

-

关闭读

+

停止读

-- Gitee From 5aca4c17a54cff91139d27ef08998fb9ca1b6a7e Mon Sep 17 00:00:00 2001 From: zhangyalei Date: Tue, 8 Feb 2022 23:39:50 -0800 Subject: [PATCH 7/8] i2s documentation Signed-off-by: zhangyalei --- .../driver/driver-platform-i2s-des.md | 16 +++++++++------- .../driver/driver-platform-i2s-develop.md | 2 +- ...0\346\265\201\347\250\213\345\233\276.png" | Bin 5890 -> 12577 bytes 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-des.md b/zh-cn/device-dev/driver/driver-platform-i2s-des.md index 16ee0cc28c6..57d64d4832f 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-des.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-des.md @@ -8,7 +8,7 @@ - [设置I2S设备属性](#section541133418493) - [获取I2S设备属性](#section7870106145010) - [使能I2S设备](#section13324155195013) - - [失能I2S设备](#section19661632135117) + - [禁用I2S设备](#section19661632135117) - [开始I2S设备读](#section19661632135118) - [停止I2S设备读](#section19661632135119) @@ -63,17 +63,17 @@

释放I2S设备句柄

-

I2S使能、失能接口

+

I2S使能、禁用接口

I2sEnable

-

使能I2S控制器

+

使能I2S设备

I2sDisable

-

失能I2S控制器

+

禁用I2S设备

I2S开始读、写接口

@@ -315,9 +315,9 @@ if (test == NULL || test->handle == NULL || test->wbuf == NULL) { I2sEnable(test->handle); ``` -### 失能I2S设备 +### 禁用I2S设备 -需要禁用I2S设备时可以通过调用I2sDisable来实现。失能I2S设备的函数如下所示: +需要禁用I2S设备时可以通过调用I2sDisable来实现。禁用I2S设备的函数如下所示: void I2sDisable(DevHandle handle) ; @@ -611,7 +611,7 @@ I2sClose(test->handle); ## 使用实例 -I2S设备完整的使用实例如下,首先需要获取I2S设备句柄,接着设置I2S设备属性、使能I2S设备,开始I2S读、写功能,进行I2S读、写,停止I2S读、写功能,失能I2S设备,销毁I2S设备句柄。 +I2S设备完整的使用实例如下,首先需要获取I2S设备句柄,接着设置I2S设备属性、使能I2S设备,开始I2S读、写功能,进行I2S读、写,停止I2S读、写功能,禁用I2S设备,销毁I2S设备句柄。 ```c #include "hdf_log.h" @@ -674,6 +674,8 @@ void I2sTestSample(void) for (i = 0; i < 5; i++) { HDF_LOGE("%s: rbuff[%d] = 0x%x", __func__, i, rbuff[i]); } + /* 禁用I2S设备 */ + I2sDisable(handle); _ERR: /* 销毁I2S设备句柄 */ I2sClose(handle); diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md index a5283865748..d0c98bf2a8d 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -133,7 +133,7 @@ struct I2sCntlrMethod {

HDF_STATUS相关状态

-

失能I2S设备

+

禁用I2S设备

StartWrite

diff --git "a/zh-cn/device-dev/driver/figures/I2S\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" "b/zh-cn/device-dev/driver/figures/I2S\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" index f45a7ed7adfc7b73b13fdb26ac4179f30a5796ea..92013eb57c9c4c5fa3bbbde4edd109cc441295e0 100755 GIT binary patch literal 12577 zcmeIYXHb(}*ES3m5Tyu+^d?O}nl$NxNN-X@M?w)|i1ZpzQ3R<1(wp>-w1gfNNTl~r zLQ#tJPG|x0#_PK8=Y5{*^`80uyffd-_wAV^`%E(Dx%RQvI`-ac9}xz6>J-H4OG`k3YfKt z@8-Nx`Ly2TxAwv&hneEmR#9md^VJ_#!~{G3ZeQgOk2~kT(bC_DlKl5~FNy8S|LY%7 zL_msv|6q580rc-a5!V;M<$qr=5F?rX-T!h;^fw@XH?^15zj67iiC+3|kD&g)^N80& z$fp$>RG>b-mzs}f;u=tP0Lw$7=l z&j5O|q>Y)xgN80{UA@~1p)c;8mndA7J2$e!u+D~7`QQ`*ik4uJN>cb?TE=(_rm>F1v&oy62Gz_>HL*VkxzvY z;dDwc3aw9t9^vhZ#g{ccveawJf1}B-l$*a~UqjOR7=zlBvTG4m?9_CZ{a!qA+gTtP z;5j7`-l6dRra}c8Am_W4&nv+*;ko=e{&3TLvtzWUOQ!zZQ|s*ThC1?>G3#8H`J?av z|IHkXB6H|(I~Y(8dQOrU%7gSIF9h5K(m_GU=Xi&uSCZOL^dPdpbzw@@ZtR^p*SiNB zp|UTHyPl+XaNSd0YvK~--~|m@mP1E@=V2mGP{+55mZ-qc!a>vMUB{9|6TVJOFipE= z=lW--8MoFh)=TAa4iO)K(LAd9>yl_DI+v@KJ(KYCTGLluWF^e*ZH~Gs8LMx0nG!a! zPv|}F-5vvQ=dvuYEaPqhE2P_KoDYx1z>|$y&gR0y?poHU5){k)XR0+KLmqW7P3-3@ zCF?N_FH_2uA?}Ami%NadYC2VWnO@%6--7hFE=nkuHxKm&ql3S&-bRZ4?bJQ;7Jd1o$Tr^A zx=?S?+%xo4m6ERVHo}$&QxX0>^`)WlP1uaM6~6rRNJ88!|Kf~N3^^5a&o}B_=62?Z z(ftf&Bn(BQL~Zn}I4eGu^=a<$r1xOyrVJP+Ryn(l5a*NWc*;&79<6^6kNpOai#=Z6 zSz1pzEUxQvFG5!<$Ae^mVb0*f>YP%>+^n0pP!#RaT}?^gi?UWaW2cWMA82JamaZZ> zFns62yCUh}^xCF}(LdJ1tVD#qNfPtl@uFH1jHnU5E#ubQukZzObToKgGBTgRJk+%0 zG3RSRMP?-z$-3}r*;1)!5GY$F^eogeEAJOBOFqcs1#?Qk#$Q5)D9WXE2wkI0BSC94v_WR-xYLYObT{;vM+1v8}X zMRrAFt;NH7$Jdi;;HOk$sW0udq~K-zSG7S8`&8wlh1AP|83#dvP_4XG5v|BIxyq*% zRU;VM%hPTG;T`tsDO|w^%n(;*F|~XPr&vL>=UDgR&38}((l~*CuzNa`-7#wJ`-cot z&R}I1-gE(3B>~-)p%dkH(JAH^y1iHZk_9x}j7~E8=?-N~4Uln~F_Kp~11wNclBqV& zST$udJ@(R!s2_jnza`H1NrbE-{h10dRo3OBXa0qvS(Xo@R^*HGlpLB@8%kSA(Z}G& zSbuLArT4jpHMX@|y0Je@Mvvt-LOwHCi&Sw%mOV@nDF)b?;I7Iwt8xO@EqBJhP-Cw@gGAqZe6fYm#z| zBpt!>fr^~14#5w{`#otd>xt3xFDzb1Nn)Fq%obeDq%?vg)yUv2cttTPAe`Ts(oOo5 z(c^ySLHX!iiT5{BTuu7)yrPA^WS}14Po&byy#z|X9<}xvfr9a%brriPmk7ckP*#JvgL0$G3YxHIbf(e6xKd2zZV;R&tVIU^{bxp{8mMm!}6+4z}Wd-$Ne z_`Jg1E}z``kS&8(r4rL$MvYqFH)V5OpK}t3?)frC>Vh~ru>CWeidHpOM>zYcfpH*T z6-LSyQ@RNlx$nX8>p#Q?guN`bByAP|N@w66ut;cmcwvhb>3-}{_#;CQ#RB3c@EZm& z;^sKX;CbhOOpE7}hswHIs=`p4!)WpbF4_DQJagkF$+hub!`%>{vcs>e3Di5+#Om4J zT~9$m4kgL=sUHJx&@M4J%gwDaf@)DQqM)-BnC_I=+*M))Ym2eQtWI8Bm7;i!X=oQG zB`$}O!^C5hclVlhT+>$gjqom}gWDkXGGrPPYW-CsBOcx-pKwP;(=Ygk@{)S=sMfL$ z7@6^|+@rkx+R#XV+tsm@>t1|y0c{SMIS{9DK+S^65FZ{RLYXA5Qo+&^T=10yY{KJwwpz@vrk z6o&#e->VA=%QwOM=#34AOydB7C)qE!7Hhv;X~O_8Yq)?u3((5y=K9rkGMcTyIcj3d zBfs#^vZ{jXhu-#w&UKs~9J`XYv;VSH&jo3bKS9k~uJ12d7wq#g#ePq0@^B07sl9w3 zYuj_MQu6)3V09V=nu5VtNAuD-Bd`yKOKs}O`PYaw>9AmMeaaP3vLEbLY9BQkT0fQz zrHnlX=^4h>j~-FQL`trJx1e5|F;ad^GVi;Hr;L(s1N)Y)3O(NYw5NTe;|HdIQBI`e zg7q8qGQfy7x5!%osC!gw_#undQcD6`JGL<|>{V0srtSl#Y|+$k^M2VKgvoj_soWRu zfVZGaI>8|;11nJGz1Fm6JYsWHraIQz=fX0Uy5XhOZ^J#JYBM2albz1xkE2+h_8(8y z19?=E`&232C)6`!4MI!M9hRr{VqGmNov}LEM-a5NyzHHPC5UF-QZ*%3+E243CT(-l zq>8#rOtDDO$)(IP`$isS%0tfWH2u?g>MGUr1F0*F=~E%Ru?K-|(s1uOkpL?Qii&f$ z2se|IUkRFdlg|d)-^^A(uuhHD`l?`_Fpg+unLr`~wbe5URe7NXYr7mBQ|dEqWu8wS zcSd)MP`1(4L0YO7y2{xlBb3{+wPUTxMK4g1rVly*`(q!e*I%LJh^r-F+)rZMVf(CEc2TYyto)rZ zqRwY4;Bk_SQrcbNc0iKFufrNMw0|mOn%)DHc|-^7PG6qS4<7OaU+f*~z~^Kh}Fj=SnX_${@amK~!j3YGVo_>W>mu zYuWF(IV-*iMZ$p1dr+CeQ}xBt?AsGB?P_wz%tC?`3NYhu!7yX<2 zT;U6@QG)xu080*^H!=(AFl)TcN=+)jh~=;vx;HkT=c{O96?|T5O`{eiyTWG0Tp>+L zjoDf>UhS~%y2W%E92?{C@^;|o`!XI@S*o8W5$TQ>#E$f^&A94UMXd?2PjKtBa7oni z+%(>Bx9^<@2JtO*DW%>?9;(cx=2|@gn*F|vv3CuIcH}8i9`%}zcuzk^EmjN8G=SlA zHUdyLC~w^AJJQ2#){gh}a$CWl8cr|+w;(pGQk5AHd{o#>BQ~?DusWwd1miLW=_<}!Ql8+=-6O`}&1y$3RK0(3<^_Klg+2V)v4)$*wB8_)N^ zD)RQqGd#*KlMRh@+t}m`(piAZgQ6>J&=#wk6v3@S37eyM^t=gTyoO9k=-U`Y>1~bH zCv}fWi@re-d*-zw0U=>m5-1)*&Nr@is#SVFHWR4 z;{S!ZL=)%KJ_YY|{7qNT4KdiP*wRpITKa zwXto~itIQ`_L2OF>uwob(fAC72&nTrF!Y;~84zoBf7;jbB%(}lyr2Pt%4K5L3bc(W zVfyvH*|H3#P=D9rR9!jir^})36d6BjwKcw+d*j_k*=&_-YvXAtlbw_KIAjcUOgnBT zT5Z4Cm^>#Oyu45U9t83Ke0=dXd2=|J7o$}0_Vju8xxYBm2Onb)2C4@4FW3j;c(-@7 zKnvfa>&Z`Z0J}T$AhSqY#OBZWx#>d<_idx9$%3Z@YJe&pG$1w@H&EWez5Z(oSf32o zhlV<_BIk>#u~Tryn(x5qM0J%Ac6j(5i{oFZV)3@xv`yB&qq*ui*IoT3%dc7mR3-a0 z#5wTICoL|6s-glfM^AJ50^fp;o*i{mN8Jj`O=V20QOAYrC z3LNhGf4ddjJe2xII6XqL^XXkG1zf=Hwvu<-F@5^G_v{K6@2#i$H@pV}6{BYrWD4s3x zz1OZfK!x4}v14VP*Cl(jHJ`qZ!NvE&ryL^g@rL*o)9u!LWdNqp-G0LT)yQ+d6wN?|8n&nkGkid`hD?JUW9#9>xe z^gMBOeCpas)Z|Az3;h&IAr(WcoCltrB~#2JE}X1dbN&~ zO1Fa$S{aL`4V7)4SwJ_&IB73hrpP{SjW%hWo;A5r+tqxoLnbO!-)xgzz(=rWsvS(s zE~G~@`l2Guf8Me%K^xJPTPeELX#2qojr-l$sMdWhDKRKg)gru?>;jrwas zEbygzCe20b^+UD*>oV+c%o_d9gk*)Ex7{FA?YDEwet2!2Y~<1hFo7eURzL@7c6Ykd zw{MMyER@V=m-!tpQe_FwHl?Y>6kxj53g8URYiCImoVLxD=yd%Xyj9P-_%bd`cJ<{g zXkGjX`+bX{ikwn0cgk{_zErK7-`4b)N_Mo8Xd9@L{gAW?S7bk%IG3!8Z2-K1?9~?Y zpy#po;i@Y&D#t;njW0^MBJ1&3wa_k}x&sq-jumdmm#s~S@zp|rKX9+3aU z!b2>kgT}=>1FH~K#}mF;SVa+cwCsxrp#MvrP)AKCRUqv9!;&T)5?d@cD#y9Im@XKq zVe6WZmh`I4;uB2C&S5tG`^s0Rjm25RXvqW)e`zl7ilZW9ix_L$-ZF59e1e`(ElP5R zyje6xNRd70m*kkQqTyLtOq*vs&?6vZlH2d*XCTVELCm|93Bk8zDj;iHGTYW zm(}FsbZ(VSHGA;TeK|B48zqGb^0uQJ45x}wnaBsEDD87pG$(<6_g(HJWiC2L`Oac5%ZkKB#Gd ztm5u4F%X>0zs!(P`CAnKF_|Y zMWoG->5xDF~-X{+AFvyi6z6IMtg-VrZDr;SSMHN~CHh^$P4?nml6 z)qYI%!K>2i@hydv?Jo&m@LM;V%gOm>L#R`G3>TA+2EX{}c>WNJe}VH?(0-UwL1|@gs6XrYIV8Ng5V7671|h-W zh}+1I`(Cy@37~yNBNP#pEfXKue({;R+9)F33Y)0vS_Yddjx-!X2xY_P*k9@$j#jTo zvzKMES4V_C_;sAvwlC6#t=p25o|`$!^kmuh16FKTh8sp7?1@?vb)*T|3ZE z8+!u|#mmg-pPfi&3)?_F@frQbhtx5lf7jkw(vev~tGWtYztYm#@3vhGI=23<*f(x1 z;ERu!EQ232>oq2BXCQLtjE`gSi)`ngr$I^=wc;Hm` zH;y;tBQF{sx#jI_U2KBY{;o=wJat9r7>|&hL`oQI>SElji z=hJrP&OJHrY%L23RcdEkgKHi1#_m_k5KWLlw-RopRrW*j#m}^Kwn2D)SI>*ZzPEe! zEUQWmxBIqd-IWnRKd2CUZ-Tk7>f1r34az+Dz2jGw2;B4CWFwwdbJc$uY1(l@{XdciHNIzE5CxH&KZ0>N%TA(d|$X`gi!}b za|V0^ggW@+qeBc@j>4ED@z^E4n9`QzQ=Cs|El5g9oke*#TrK3{bl?^OyQ*F*uouNg zU$l)_h4aOZRLIMHyRfAC))SV@mgvj9FZ(H(*eg=gi8c}`{@iuW1yS$7ahWEyF(FXb z(l9ScBAazQBYG%W%f`61t8r&6GfNjpE7^))6Q>=0Avhj9?`#r}$IdrdvdORQWvy?| zbS{u8`D`xkPPn>8Bnix4lMLvt4Wj& ze3Q-s56UKj4~RF7>MO7)|5SUm49FTQhFVWIRV{ z=zKL(lVs++Do_Z^(s^lGR$I*+9_k`L=X@zfL2;?ka8F8AjP_!CJnNn?BG@|#=q6sT z%09OAR88L-Jur++6Q_~~zos8*lGJ={-##dTcAditjo{E&=C)I*%}*j*K98f`e%b_3 z@pn#{(9!Q5T17w0aIC`UkTeY8q|HZ^QObO0*L7T6V55|ytk>rG9 z#mo!|0ddO3KG6L~KeCDrA>0|Ql&)dP%2|E$Ng8{MX}4|&Wmlc+jY$}U`aqex!p)!m z#v&$P4ZRsVxnY!?$_Yuk4=FMviwNrVt&~kJ!Ao6WLJEJREEu_kCP;(uzc!ZzAu1UQ zDd&Yrs6lj3SbvViFhCq3gx4p`LM6=V<882H|( zk2Q~RIn*Bm_vJ8}IQZ1nRb(aPN9U`BI1jE{=sh2Ay8a27hO>&jP_tg?%AwNYWV_PH zaQYEvGu^sTc$VAn-#IlB$;}zp@sQ?<=B@6V>T$9%&y3kf&fnQK7H21O!8g9&OTAw^ z{t9AHK2b{C$_5Ff9TwiOn@QeC3`Q}6exW~5ho$97e~3t)2IVViV@)y@^4E}QJhD%i zjjP^&)$D6w0S0yN=Po8aXuQb-A2!Kz&jKDYipeT6eOs6IPD|N7U{uKK&FP+8XX z+P}tVAqI+bEF77^3UN7%yhVnfvCWL*=Xii&( zn0eEj7l7;2q74_yC4o+iZ+%X(tM@x}7*jbDmgns3m(-Us`XGj1aj7DE@7MDPR662Z zXBUaVNk2Po@egfj6cAbD`*`x zgICW>p}ue(#qF$_G3R^7Yt48TmV|0vc*FUHtx~1P*>p8jd5&Zah(52~%qlY+@tru1 zV>H?89n4wVQuMX{Wlji#3bCJeQDN4%G+u-xDzn!a%U|1zYR8{{jFd&hTjoMfK7L+Q z{I*M-%NHf7kyP)h!{q0mG=+0((4SilS;Ch2=+Y8aa?1>o0*^j#D;(AYC#1Ku>SpPW zbZ&TaTwa0^f7Yc54!wcbsyX60Mn2XL$eZA^hq1>fh1Oxsym>1fq@yRos}$2Hdyl zBf;z$zVlWb5P`sF$eLoIVm#^Mc1wkI_c^iiW!o2?F9=6<+EvzL5Nf(Sa~q$XDa(r+ zN->j%5Z{=if#v&RMs9N(jmCTh&FBJM2xOr7uh1bZi0uwX4m5p+h{BjasAzqq`>HB5Q%L zi_*j_Z62)o`x9~BmS#p!VMg&l7ltMs@hqm`loqClnW8h%LykI9Rom-2xy~M*FW33+ zplqQv4F_u&A6@C%jqFYBHF~u)WZDm}<<&rzVPUC*8fP0In4P}X_BXq{r=xn^%pd?) z)(+u3SGy*5L>-g;_j;{d6S$|7GS|AGvimii?e134iibgs@NbeqML_1G!}v@LZ)iaJtrU2IH+eGn{-}nVD*{MEH}D0+d-H2V34v)oP6ryG zCgp=Q4?D{R`667|eMz#!gqMzFL&PLr?PiUvntKLajKzx3A#&z-N0b8Eu!mCYBP_Ke z&I+1R?nPKW-stIh)BA|DP9{}*Sbf&>eal(DnkL^gs$GiVTsfPA(D5bH2MSz+w|vW& zhG)?!O=ajvi229*en6nv+pqP~N`SNeWszI-HrK?dSd6x_g9Qs++Yhq_F063Tl3&yG zXA`)VE84w`jQhm>FP0V2lu*HEqc;>750u5`mHn3bd=JtgRZmXFq}eD3s@?!_*Zgn( zoq&=qI)&?V!@D{uQom;);BawAk$gJvZtb`-nCLkT6W-+celD@x3OsZdNuK_`+B8k! zPC>@=MB4Cx4|CZdRW>@`GhUZnR>J~4%e9$Lv`UkvGMpn$ubd~NG^2riyC;M#$QouQ z?Ea(}geRgNUzrzgIn>vGvlOLXa=sfo^&q)4 zk-rFzcpu{H5n{a3p)pogIq*3&X;Ko(E-5Z>DV`20+?;^t|1PHJDenZx8ug|J;}72E zoaziHMls4ViH%Q1wHV9n{Z&gxe~u*_=Mj`Sg|u-I%xoB9okm?>NzY1>`;TMPfUJuz zqMm9D+cr<#Hcm5>E=x(h)H+ZVN30oC8WowuAFK8*EQqU=kre~36R zYrxlCN}ANUMZM9IxVS!a>V5krY>Pr+jNV{T2oZP;P&;t3v*lT_g4?>BtsTdJ`c&=a z@c=1GDT*l@cu|Mb@YUHOwl$udw!^n_1H0P3$?Pz*oDeb%+OX-y%Z#)T{Nn(c zeh;98Fo2+F$xJ{`dYJM2rvJ5k@fng#kkG^@ssoAF8?+|ob(q_cOhE8och?}je{c2x zbY`-lMGgn{xkc>mq1LM3SEH{p6;N_m|KkJ`_AAA1Pd|X5$}j@zc6irF*BTpIi^0@n znwU3RDDThT3kK?vBU(S}`+T*Vw$6UENxvDe?Qa7|e*6BDp}m+HZg3M!*5#%wqojNX& z&@szB@<_M7Vp^MJkM-jsZbcfs(dHjjzc(I~OCh#t=vcwTtU`%mP}3d2=z;@k#o9~v zlEPYNj%jL}?aMVU3yT%^?N6C74@60d<~&&=8vdt>2NXrdi_a&_fi=PY%8b$#hF0U8 zRiEgLz>raX&auZv0w3QMB(Km_co!`Rv3;ET2C!84Jy=NvP@fr46Q#ejMDhz}03kKX zQfn1Qlhg1;r+fi`uKqDJEq{k5_^&i&e_2VhIn$e5Av?6T7^#dFR81uY;!9kvyXfPZ z6rVDV=&J^rrb4-l9{1SpgGqrx;NNNBx;rG=6eNyblxthQ3J}*tdCdTfLb3zeLjOZF z`P>uxx|l6-ZO90TO!H?g?|r%3*pBH-P0hWlVoG+Z1}(&o!qc6t*PGrtl1o7GHP>n+ zDC%6x8881d-ULnF>;Pz|v&4vn&yb7be0QSiVSb*Y1cij$Y%;4~l)Qdz9M2!Kd5XMdthIJWZ&A$WOJ^-pH6 zPr2lNWJr7wDf&@Eetu5r*-WsPdf>c>ihRB8L?rqNO~n)n2_34L6VNy~pAe)0r;dT{ zy(HlLX0P?AX$brb-4T)C?;qgl+dfTg>qye+Z}Z1df+7g9TTUn)ErHAVsZDxCcrI<% zC?hSBpS@!Q&093b!r%Mk!J3Zcz0SoMW8Me9%$oz`;SnSMMs#+U+2ZMX#HO8Ze*v0KE{MjKdRWyo`vY@yzyLu zbHWC1f!}c!1v?Ygtij9VKp_`GAh_l4R;*2g2tJehiA-At=PZ>eMhhwn{5q&xZRwNz zBahXKRliaH`L;{Rkq~?p)lTFUB}L|82EhyO_&NP?96()8DlsoawW+P$Cesbhcfbu* z@9Ra9)TE4{Q{`-$Dkzf(Gbn7;UWTe>y!iG1DTKth0`19w(OpWd1b&79g&edNf0Zwp z)?FU@n$yA5@YH`_%_NA}NR~%KC4@s6U0HpTFbtm#2REtl)3)=6lWry~-UD|N!Yn1X zpsknc;^Ar(e^BM2nP_z`G!qD+6)1R@TmMh`;=h*)@OmU6?uY+Bspa+Uz12;_V-keZ z`qXRv521B0E7#ljfG$Q`sKH(Sj~P3xN^fb(^4~*j`4bzpyUU-lKUH|MLI$LW=OK-5 z1m+tUipVUKQC;ULxJ1ya2d=O`B?zs(K3A&|?))zayUNZ|;;rsa1q89Y*4}S1KcR74 zvDMT3#A4CJ0RG>q`9<>omk8qjFKO=WqUs|%@ud6oCB-9)UGU#HXg=0ctyHml{l5Uy C7+B!| literal 5890 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 Date: Tue, 15 Feb 2022 23:00:43 -0800 Subject: [PATCH 8/8] i2s documentation Signed-off-by: zhangyalei --- .../device-dev/driver/driver-platform-i2s-des.md | 10 +++++----- .../driver/driver-platform-i2s-develop.md | 15 ++------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-des.md b/zh-cn/device-dev/driver/driver-platform-i2s-des.md index 57d64d4832f..39863601e3d 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-des.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-des.md @@ -9,11 +9,11 @@ - [获取I2S设备属性](#section7870106145010) - [使能I2S设备](#section13324155195013) - [禁用I2S设备](#section19661632135117) - - [开始I2S设备读](#section19661632135118) + - [开始I2S设备读功能](#section19661632135118) - - [停止I2S设备读](#section19661632135119) - - [开始I2S设备写](#section19661632135120) - - [停止I2S设备写](#section19661632135121) + - [停止I2S设备读功能](#section19661632135119) + - [开始I2S设备写功能](#section19661632135120) + - [停止I2S设备写功能](#section19661632135121) - [I2S读](#section19661632135122) - [I2S写](#section19661632135123) - [销毁I2S设备句柄](#section19661632135124) @@ -441,7 +441,7 @@ if (test == NULL || test->handle == NULL) { I2sStartWrite(test->handle); ``` -### 关闭I2S写功能 +### 停止I2S写功能 在写从设备结束之前需要调用函数I2sStopWrite向I2S从设备发送停止写的命令来停止写功能。停止I2S写功能的函数如下所示: diff --git a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md index d0c98bf2a8d..ea1d8e85de9 100755 --- a/zh-cn/device-dev/driver/driver-platform-i2s-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-i2s-develop.md @@ -70,26 +70,15 @@ struct I2sCntlrMethod {

设置控制器属性

-

Transfer

- -

cntlr:结构体指针,核心层i2s控制器;

- -

Msgs:结构体指针,传出的消息值(见i2s_if.h中I2sMsg定义)

- -

HDF_STATUS相关状态

- -

传递消息,此处是读取i2s设备数据

- -

Transfer

-

Cntlr:结构体指针,核心层i2s控制器;Msgs:结构体指针,传入的消息值

+

Cntlr:结构体指针,核心层i2s控制器;Msgs:消息结构体指针

HDF_STATUS相关状态

-

传递消息,此处是向i2s设备写数据

+

i2s数据传输

Open

-- Gitee