• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# PIN
2
3## 概述<a name="section1"></a>
4
5### 功能简介<a name="section2"></a>
6
7PIN即管脚控制器,用于统一管理各SoC的管脚资源,对外提供管脚复用功能:包括管脚推拉方式、管脚推拉强度以及管脚功能。
8
9PIN接口定义了操作PIN管脚的通用方法集合,包括:
10
11- 获取/释放管脚描述句柄:传入管脚名与链表中每个控制器下管脚名进行匹配,匹配则会获取一个管脚描述句柄,操作完PIN管脚后释放该管脚描述句柄。
12- 设置/获取管脚推拉方式:推拉方式可以是上拉、下拉以及悬空。
13- 设置/获取管脚推拉强度:用户可根据实际设置管脚推拉强度大小。
14- 设置/获取管脚功能:通过管脚功能名设置/获取管脚功能,实现管脚复用。
15
16### 基本概念<a name="section3"></a>
17
18PIN是一个软件层面的概念,目的是为了统一各SoC的PIN管脚管理,对外提供管脚复用功能,配置PIN管脚的电气特性。
19
20- SoC(System on Chip)
21
22  系统级芯片,也有称作片上系统,通常是面向特定用途将微处理器、模拟IP核、数字IP核和存储器集成在单一芯片的标准产品。
23
24- 管脚复用
25
26  由于芯片自身的引脚数量有限,无法满足日益增多的外接需求。此时可以通过软件层面的寄存器设置,让引脚工作在不同的状态,从而实现相同引脚完成不同功能的目的。
27
28### 运作机制<a name="section4"></a>
29
30在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。PIN模块接口适配模式采用统一服务模式。
31
32在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。
33
34PIN模块各分层作用:
35
36- 接口层提供获取PIN管脚、设置PIN管脚推拉方式、获取PIN管脚推拉方式、设置PIN管脚推拉强度、获取PIN管脚推拉强度、设置PIN管脚功能、获取PIN管脚功能、释放PIN管脚的接口。
37- 核心层主要提供PIN管脚资源匹配,PIN管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。
38- 适配层主要是将钩子函数的功能实例化,实现具体的功能。
39
40**图 1**  PIN统一服务模式
41![PIN统一服务模式](figures/统一服务模式结构图.png "统一服务模式")
42
43### 约束与限制<a name="section5"></a>
44
45PIN模块目前只支持小型系统LiteOS-A内核。
46
47## 使用指导<a name="section6"></a>
48
49### 场景介绍<a name="section7"></a>
50
51PIN模块仅是一个软件层面的概念,主要工作是管脚资源管理。使用复用管脚时,通过设置管脚功能、设置管脚推拉方式、设置管脚推拉强度来适配指定场景的需求。
52
53### 接口说明<a name="section8"></a>
54
55PIN模块提供的主要接口如表1所示,更多关于接口的介绍请参考对应的API接口文档。
56
57**表 1**  PIN驱动API接口功能介绍
58<a name="table1"></a>
59
60| **接口名**                                                   | **描述**         |
61| ------------------------------------------------------------ | ---------------- |
62| DevHandle PinGet(const char *pinName)                       | 获取管脚描述句柄 |
63| void PinPut(DevHandle handle)                               | 释放管脚描述句柄 |
64| int32_t PinSetPull(DevHandle handle, enum PinPullType pullType) | 设置管脚推拉方式 |
65| int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType) | 获取管脚推拉方式 |
66| int32_t PinSetStrength(DevHandle handle, uint32_t strength) | 设置管脚推拉强度 |
67| int32_t PinGetStrength(DevHandle handle, uint32_t *strength) | 获取管脚推拉强度 |
68| int32_t PinSetFunc(DevHandle handle, const char *funcName)  | 设置管脚功能 |
69| int32_t PinGetFunc(DevHandle handle, const char **funcName) | 获取管脚功能 |
70
71>![](../public_sys-resources/icon-note.gif) **说明:**<br>
72>本文涉及PIN的所有接口,支持内核态及用户态使用。
73
74### 开发步骤<a name="section9"></a>
75
76使用PIN设备的一般流程如图2所示。
77
78 **图 2**  PIN使用流程图<a name="fig2"></a>
79![](figures/PIN使用流程图.png "PIN使用流程图")
80
81#### 获取PIN管脚描述句柄
82
83在使用PIN进行管脚操作时,首先要调用PinGet获取管脚描述句柄,该函数会返回匹配传入管脚名的管脚描述句柄。
84
85```c
86DevHandle PinGet(const char *pinName);
87```
88
89**表 2**  PinGet参数和描述
90
91<a name="table2"></a>
92
93| 参数       | 描述                |
94| ---------- | ----------------------- |
95| pinName    | 管脚名                  |
96| **返回值** | **描述**          |
97| NULL       | 获取PIN管脚描述句柄失败 |
98| handle     | PIN管脚描述句柄         |
99
100假设PIN需要操作的管脚名为P18,获取其管脚描述句柄的示例如下:
101
102```c
103DevHandle handle = NULL;    // PIN管脚描述句柄
104
105char pinName = "P18";       // PIN管脚名
106handle = PinGet(pinName);
107if (handle == NULL) {
108    HDF_LOGE("PinGet: get handle failed!\n");
109    return;
110}
111```
112
113#### PIN设置管脚推拉方式
114
115PIN设置管脚推拉方式的函数如下所示:
116
117```c
118int32_t PinSetPull(DevHandle handle, enum PinPullType pullType);
119```
120
121**表 3**  参数和描述
122
123<a name="table3"></a>
124
125| 参数       | 描述                |
126| ---------- | ----------------------- |
127| handle     | PIN管脚描述句柄         |
128| pullType   | PIN管脚推拉方式         |
129| **返回值** | **描述**          |
130| 0          | PIN设置管脚推拉方式成功 |
131| 负数       | PIN设置管脚推拉方式失败 |
132
133假设PIN要设置的管脚推拉方式为上拉,其实例如下:
134
135```c
136int32_t ret;
137enum PinPullType pullTypeNum;
138
139/* PIN设置管脚推拉方式 */
140pullTypeNum = 1;
141ret = PinSetPull(handle, pullTypeNum);
142if (ret != HDF_SUCCESS) {
143    HDF_LOGE("PinSetPull: failed, ret %d\n", ret);
144    return ret;
145}
146```
147
148#### PIN获取管脚推拉方式
149
150PIN获取管脚推拉方式的函数如下所示:
151
152```c
153int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType);
154```
155
156**表 4**  PinGetPull参数和描述
157
158<a name="table4"></a>
159
160| 参数       | 描述                  |
161| ---------- | ------------------------- |
162| handle     | PIN管脚描述句柄           |
163| pullType   | 接收PIN管脚推拉方式的指针 |
164| **返回值** | **描述**            |
165| 0          | PIN获取管脚推拉方式成功   |
166| 负数       | PIN获取管脚推拉方式失败   |
167
168PIN获取管脚推拉方式的实例如下:
169
170```c
171int32_t ret;
172enum PinPullType pullTypeNum;
173
174/* PIN获取管脚推拉方式 */
175ret = PinGetPull(handle, &pullTypeNum);
176if (ret != HDF_SUCCESS) {
177    HDF_LOGE("PinGetPull: failed, ret %d\n", ret);
178    return ret;
179}
180```
181
182#### PIN设置管脚推拉强度
183
184PIN设置管脚推拉强度函数如下所示:
185
186```c
187int32_t PinSetStrength(DevHandle handle, uint32_t strength);
188```
189
190**表 5**  PinSetStrength参数和描述
191
192<a name="table5"></a>
193
194| 参数       | 描述                |
195| ---------- | ----------------------- |
196| handle     | 管脚描述句柄            |
197| strength   | PIN管脚推拉强度         |
198| **返回值** | **描述**          |
199| 0          | PIN设置管脚推拉强度成功 |
200| 负数       | PIN设置管脚推拉强度失败 |
201
202假设PIN要设置的管脚推拉强度为2,其实例如下:
203
204```c
205int32_t ret;
206uint32_t strengthNum;
207/* PIN设置管脚推拉强度 */
208strengthNum = 2;
209ret = PinSetStrength(handle, strengthNum);
210if (ret != HDF_SUCCESS) {
211    HDF_LOGE("PinSetStrength: failed, ret %d\n", ret);
212    return ret;
213}
214```
215
216#### PIN获取管脚推拉强度
217
218PIN设置管脚推拉强度后,可以通过PIN获取管脚推拉强度接口来查看PIN管脚推拉强度,PIN获取管脚推拉强度的函数如下所示:
219
220```c
221int32_t PinGetStrength(DevHandle handle, uint32_t *strength);
222```
223
224**表 6**  PinGetStrength参数和描述
225
226<a name="table6"></a>
227
228| 参数       | 描述                  |
229| ---------- | ------------------------- |
230| handle     | 管脚描述句柄              |
231| strength   | 接收PIN管脚推拉强度的指针 |
232| **返回值** | **描述**            |
233| 0          | PIN获取管脚推拉强度成功   |
234| 负数       | PIN获取管脚推拉强度失败   |
235
236PIN获取管脚推拉强度的实例如下:
237
238```c
239int32_t ret;
240uint32_t strengthNum;
241
242/* PIN获取管脚推拉强度 */
243ret = PinGetStrength(handle, &strengthNum);
244if (ret != HDF_SUCCESS) {
245    HDF_LOGE("PinGetStrength: failed, ret %d\n", ret);
246    return ret;
247}
248```
249
250#### PIN设置管脚功能
251
252管脚功能特指的是管脚复用的功能,每个管脚功能都不相同,管脚功能名详细可以参考//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs253
254PIN设置管脚功能函数如下所示:
255
256```c
257int32_t PinSetFunc(DevHandle handle, const char *funcName);
258```
259
260**表 7**  PinSetFunc参数和描述
261
262<a name="table7"></a>
263
264| 参数       | 描述            |
265| ---------- | ------------------- |
266| handle     | 管脚描述句柄        |
267| funcName   | PIN管脚功能名       |
268| **返回值** | **描述**      |
269| 0          | PIN设置管脚功能成功 |
270| 负数       | PIN设置管脚功能失败 |
271
272假设PIN需要设置的管脚功能为LSADC_CH1(ADC通道1),其实例如下:
273
274```c
275int32_t ret;
276char funcName = "LSADC_CH1";
277
278/* PIN设置管脚功能 */
279ret = PinSetFunc(handle, funcName);
280if (ret != HDF_SUCCESS) {
281    HDF_LOGE("PinSetFunc: failed, ret %d\n", ret);
282    return ret;
283}
284```
285
286#### PIN获取管脚功能
287
288PIN设置管脚功能后,可以通过PIN获取管脚功能接口来查看PIN管脚功能,PIN获取管脚功能的函数如下所示:
289
290```c
291int32_t PinGetFunc(DevHandle handle, const char **funcName);
292```
293
294**表 8**  PinGetFunc参数和描述
295
296<a name="table8"></a>
297
298| 参数       | 描述              |
299| ---------- | --------------------- |
300| handle     | 管脚描述句柄          |
301| funcName   | 接收PIN管脚功能名指针 |
302| **返回值** | **描述**        |
303| 0          | PIN获取管脚功能成功   |
304| 负数       | PIN获取管脚功能失败   |
305
306PIN获取管脚功能的实例如下:
307
308```c
309int32_t ret;
310char *funcName = NULL;
311
312/* PIN获取管脚功能 */
313ret = PinGetFunc(handle, &funcName);
314if (ret != HDF_SUCCESS) {
315    HDF_LOGE("PinGetFunc: failed, ret %d\n", ret);
316    return ret;
317}
318```
319
320####  释放PIN管脚描述句柄
321
322PIN不再进行任何操作后,需要释放PIN管脚描述管脚句柄,函数如下所示:
323
324```c
325void PinPut(DevHandle handle);
326```
327
328**表 9**  PinPut参数和描述
329
330<a name="table9"></a>
331
332| 参数       | 描述       |
333| ---------- | -------------- |
334| handle     | 管脚描述句柄   |
335| **返回值** | **描述** |
336| NA         | 无返回值       |
337
338PIN销毁管脚描述句柄实例如下:
339
340```c
341PinPut(handle);
342```
343
344## 使用实例<a name="section10"></a>
345
346下面将基于Hi3516DV300开发板展示使用PIN设置管脚相关属性完整操作,步骤主要如下:
347
3481. 传入要设置的管脚名,获取PIN管脚描述句柄。
3492. 通过PIN管脚描述句柄以及推拉方式pullTypeNum设置管脚推拉方式,如果操作失败则释放PIN管脚描述句柄。
3503. 通过PIN管脚描述句柄,并用pullTypeNum承接获取的管脚推拉方式,如果操作失败则释放PIN管脚描述句柄。
3514. 通过PIN管脚描述句柄以及推拉强度strengthNum设置管脚推拉强度,如果操作失败则释放PIN管脚描述句柄。
3525. 通过PIN管脚描述句柄,并用strengthNum承接获取的管脚推拉强度,如果操作失败则释放PIN管脚描述句柄。
3535. 通过PIN管脚描述句柄以及管脚功能名funName设置管脚功能,如果操作失败则释放PIN管脚描述句柄。
3546. 通过PIN管脚描述句柄,并用funName承接获取的管脚功能名,如果操作失败则释放PIN管脚描述句柄。
3557. 使用完PIN后,不再对管脚进行操作,释放PIN管脚描述句柄。
356
357```c
358#include "hdf_log.h"                              /* 标准日志打印头文件 */
359#include "pin_if.h"                               /* PIN标准接口头文件 */
360
361int32_t PinTestSample(void)
362{
363    int32_t ret;
364    uint32_t strengthNum;
365    enum PinPullType pullTypeNum;
366    char pinName;
367    char *funName;
368    DevHandle handle = NULL;
369
370    /* PIN管脚名,要填写实际要设置的管脚名 */
371    pinName = "P18";
372    /* PIN获取管脚描述句柄 */
373    handle = PinGet(pinName);
374    if (handle == NULL) {
375        HDF_LOGE("PinGet: pin get failed!\n");
376        return;
377    }
378    /* PIN设置管脚推拉方式为上拉 */
379    pullTypeNum = 1;
380    ret = PinSetPull(handle, pullTypeNum);
381    if (ret != HDF_SUCCESS) {
382        HDF_LOGE("PinSetPull: failed, ret %d\n", ret);
383        goto ERR;
384    }
385    /* PIN获取管脚推拉方式 */
386    ret = PinGetPull(handle, &pullTypeNum);
387    if (ret != HDF_SUCCESS) {
388        HDF_LOGE("PinGetPull: failed, ret %d\n", ret);
389        goto ERR;
390    }
391    /* PIN设置管脚推拉强度为2 */
392    strengthNum = 2;
393    ret = PinSetStrength(handle, strengthNum);
394    if (ret != HDF_SUCCESS) {
395        HDF_LOGE("PinSetStrength: failed, ret %d\n", ret);
396        goto ERR;
397    }
398    /* PIN获取管脚推拉强度 */
399    ret = PinGetStrength(handle, &strengthNum);
400    if (ret != HDF_SUCCESS) {
401        HDF_LOGE("PinGetStrength: failed, ret %d\n", ret);
402        goto ERR;
403    }
404    /* PIN设置管脚功能为LSADC_CH1 */
405    funName = "LSADC_CH1";
406    ret = PinSetFunc(handle, funName);
407    if (ret != HDF_SUCCESS) {
408        HDF_LOGE("PinSetFunc: failed, ret %d\n", ret);
409        goto ERR;
410    }
411    /* PIN获取管脚功能 */
412    ret = PinGetFunc(handle, &funcName);
413    if (ret != HDF_SUCCESS) {
414        HDF_LOGE("PinGetFunc: failed, ret %d\n", ret);
415        goto ERR;
416    }
417ERR:
418    /* 释放PIN管脚描述句柄 */
419    PinPut(handle);
420    return ret;
421}
422```
423