对于所有的处理器,pad 一般可以分为两大类:IO(输入输出)、Power(VDD 和
GDD)。
类似摄像头 IO、以太网 IO、PWM 的 IO 等等,都可以统称为 IO。一个 IO,有可能能够
被配置为多种功能。
GPIO 是 IO 的一种,GPIO 就是普通输入输出的意思,当需要实现高低电平输入输出、中
断功能的时候,都需要将其设置为 GPIO 模式。
本文档以 GPIO 为例,介绍如何配置 iTOP-4418 和 iTOP-6818 的 IO。iTOP-4418 和
iTOP-6818 的完全兼容,适用于 Android、Ubuntu 和 QtE 等各种文件系统。
1 IO 和 GPIO 部分 datasheet 阅读指导
本小节带大家阅读 datasheet 的相关内容,如果要分析 GPIO 的 datasheet,6818 的
datasheet 主要理解 datasheet 的 2.4 小节和 16.5 小节;4418 的 datasheet 主要理解 2.3.2
小节,15.4 小节。
通过 2.3.2 或者 2.4 小节了解 IO 复用也就是 alternate func
tion 功能,通过 15.4 或者
16.5 了解 GPIO 各种寄存器。当然,这些寄存器不需要我们一个一个配置,在接下来的一节
中所有寄存器都有对应的内核代码以及对一个的宏,可以通过配置内核代码中的宏来实现 IO
的初始化。
本文档以 4418 为例来分析,6818 的分析类似。
1.1 IO 的 alternate function 功能
datasheet 的 2.3.2 小节,如下图所示,。
表格中的 Ball 对应个每一个 pad(类似 BGA 封装的芯片,有些会用 Ball 来表示 pad),
pad 是编号是唯一;
Name 表示每一个 pad 对应的名字,这个名字是唯一的;
Type 表示 IO 的类型,S 表示是信号管脚,P 表示
电源管脚,G 表示接地管脚;
alternate function[0-4],表示这个 pad 可以被设置的功能,下表中的每个管脚似乎都是
只能设置为一种功能。
如下图所示,红色框中的是 GPIOB18(这个管脚是后面我们要分析 IO),可以看到这个
IO 可以被设置为三种功能,如果我们要将其配置为 GPIO,那么这个管脚要在这里要被设置为
alternate function3。
1.2 GPIO 的寄存器分析
datasheet 上的 15.4 小节目录,如下图所示。
似乎 4418 和 6818 的 GPIO 设计的比较整齐划一,每一个 bank 都是 32 个 GPIO,所以
datasheet 上的介绍很笼统,不过并不影响 datasheet 的使用。
现在我们来分析,每一类寄存器的作用。
GPIOxOUT:在 GPIO 被设置为输出模式的时候,寄存器被设置为 1,则输出高电平,设
置为 0,则输出低电平;
GPIOxOUTEND:输入和输出模式的使能,输出和输入要二选一;
GPIOxDETMODE[0:1]:设置 GPIO 的中断模式,3 个比特设置一个 IO,其中两个 bit 在
这两个寄存器中,剩余的 1 个 bit 位在 GPIOxDETMODEEX 寄存器中;
GPIOxINTENB:中断使能寄存器;
GPIOxDET:中断触发之后,可用于清除中断;
GPIOxPAD:在 GPIO 被设置为输入模式的时候,读取这个寄存器就是对应 GPIO 输入的
电平值;
GPIOxALTFN[0:1]:用于设置 IO 的 alternate function,前面介绍的 IO 管脚多功能配
置,这个是对应的寄存器;
GPIOxDETMODEEX:用于中断模式,结合 GPIOxDETMODE[0:1]寄存器来设置中断 IO
输入模式,是高电平触发、低电平触发等等;
GPIOxDETENB:在输入模式下,寄存器用于设置使能;
GPIOx_SLEW:设置 GPIO 检测速度,也就是 GPIO 翻转速度;
GPIOx_SLEW_DISABLE_DEFAULT:用于配置 GPIO 的翻转速度是否使用默认的设置;
GPIOx_DRV0 和 GPIOx_DRV1:设置 GPIO 的驱动能力;
GPIOx_DRV0_DISABLE_DEFAULT 和 GPIOx_DRV1_DISABLE_DEFAULT:用于配置
GPIO 的驱动能力是否使用默认的设置;
GPIOx_PULLSEL_DISABLE_DEFAULT:用于设置 GPIO 输出能力使用默认配置还是使用
GPIOx_PULLSEL 寄存器配置的值;
GPIOx_PULLSEL:用于设置 GPIO 内部上拉和下拉;
GPIOx_PULLSELENB:GPIO 内部上来和下拉的使能;
GPIOx_PULLSELENB_DISABLE_DEFAULT:GPIO 内部上拉和下拉的使能的配置寄存
器。
2 内核 IO 初始化配置分析
本小节介绍 IO 初始化宏定义和配置文件,并和 datasheet 结合来理解。
2.1 初始化文件分析
内核代码最好 Windows 上的 source insight 和 Ubuntu 上的 vim 工具结合起来阅读。
4418 的内核 IO 配置文件是“arch/arm/plat-s5p4418/topeet/include/cfg_gpio.h”;
6818 的内核 IO 配置文件是“arch/arm/plat-s5p6818/topeet/include/cfg_gpio.h”。
所有的 IO 都是在这个文件下配置基本功能的。
这里以 GPIOB18 为例,在内核 IO 文件 cfg_gpio.h 中搜索“GPIOB18”,如下图所示。
这部分 source insight 下查看,如下图所示。作者的 source insight 中的代码比较旧,
和上面一张截图有一点区别,不过并不影响使用。
如上图所示,4412 的 BSP 文件 cfg_gpio.h 中,PAD_GPIOB18 使用了 5 个宏通过或运
算来实现初始化配置。
我们先来分析这 5 个宏分别对应什么参数,在 cfg_gpio.h 文件靠前位置,可以看到如
下。
如上图所示,这 5 个宏对应配置如下:
第一个:PAD_MOD_XXX,用于设置 GPIO 被配置为对应模式;
第二个:PAD_FUNC_ALT[0:3],用于设置 GPIO 被配置为对应模式,PAD_FUNC_ALT
可以和 PAD_MOD_XXX 结合起来使用;
第三个:PAD_LEVEL_XXX,用于 GPIO 电平输出或者输出,对应输出高电平或者低电平或
者中断模式下的中断模式设置;
第四个:PAD_PULL_XX,用于输入模式的内部上拉或者下拉。例如 GPIO 被设置为输入
模式,这里设置为上拉模式,那么 GPIO 在悬空状态下检测到的就是高电平;
第五个:PAD_STRENGTH_0,1,2,3,用于设置 GPIO 输出能力设置。
这里对应前一小节中,GPIO 寄存器,不过在软件上纯粹的设置,就比较容易了。
另外在 linux 内核驱动中,还提供了一部分函数接口,例如:设置输入模式和输出模式、
读取输入值,设置输出值,设置中断口,设置独立中断 IO 的中断模式等等。
作者在 4418 和 6818 的 GPIO 函数接口中,没有找到输入模式下的上拉和下拉函数,后
面我们就在这个文件中设置一下,然后让 GPIO 悬空,通过读取输入值就可以判断设置是否生
效。如果 pull up 模式下,GPIO 悬空状态读取的值应该 1;pull down 模式下,GPIO 悬空状
态读取的值就是 0。
2.2 常用 GPIO 宏介绍
第一个宏介绍:
通过 source insight 可以找到宏定义,定义的位置。例如“PAD_MODE_ALT”,如下图
所示。
如上图可知,如果设置为 PAD_MODE_ALT,那么要结合第二个宏来设置管脚功能,不过
这样似乎还要结合 datasheet 来对照。
作者发现 4418 和 6818 所有的 GPIOXXX 都可以作为 OUT、IN 和 INT 这三种模式,可
以直接将其设置为输出模式,不用管第二个宏定义,如果要严谨一点应该也没问题,用户可以
自己测试。
PAD_MODE_ALT:IO 的功能设置,结合第二个宏来使用
PAD_MODE_IN:直接设置为输入模式;
PAD_MODE_OUT:直接设置为输出模式;
PAD_MODE_INT:至二级设置为中断模式。
第二个宏介绍:
如下图所示,可以有以下选择。
这个宏要结合 datasheet 来使用,不是很建议在 GPIO 设置中使用,如下图所示,例如
要设置 GPIOB18 功能,那么第一个宏要设置为 PAD_MODE_ALT,第二个宏设置为
PAD_FUNC_ALT2,然后在驱动中设置是输入、输出还是中断模式。当然如果要简单,可以直
接将第一个宏设置为 PAD_MODE_IN,这样就是输入模式了。
PAD_FUNC_ALT[0:3],表示将 IO 设置为 datasheet 上对应的功能。
第三个宏介绍:
如下图所示,可以有以下选择。
上图中的介绍,主要是中断部分,表示中断触发模式,分别对应高电平触发、低电平触
发,下降沿触发等等,这不可以参考独立中断的例程。
不过这部分在驱动中通过内核函数接口都是可以设置的,初始化的状态可以修改。
第四个宏介绍:
如下图所示,可以有以下选择。
这个比较好理解,在输入模式下有上拉和下拉,悬空状态下可以通过读取 GPIO 的值来实
现。
第五个宏介绍:
如下图所示,可以有以下选择。
这里用于设置 GPIO 驱动能力,0-3 和第二个宏的 0-3 对应。
至此,GPIO 部分所有配置的宏都分析完毕,另外还有其它宏定义,用于设置特殊的功
能,这部分用户可以自行去理解,分析方法和思路都是一样的。
2.3 GPIOB18 的配置
这里回到 GPIOB18 这个管脚,我们在初始状态中,可以将其设置为输入模式或者 GPIO
模式,这样在内核中,我们可以有以下两种配置,如下图所示。
#define PAD_GPIOB18 (PAD_MODE_IN | PAD_FUNC_ALT0 | PAD_LEVEL_HIGH | PAD_PULL_DN |
PAD_STRENGTH_0)
或者
#define PAD_GPIOB18 (PAD_MODE_ALT | PAD_FUNC_ALT2 | PAD_LEVEL_HIGH | PAD_PULL_DN
| PAD_STRENGTH_0)
如上配置代码,PAD_PULL_DN 这第四个宏可以将其设置为下拉模式,这样在管脚悬空
状态下,就可以读取的管脚值为 0;
如果将其替换为 PAD_PULL_UP,则将其设置为上拉模式,在管脚悬空状态下,读取的管
脚值为 1;
3 GPIO 例程-pull up 和 pull down 测试
这里的例程在独立文档“iTOP-4418 和 6818-驱动-GPIO 输入输出和例程_V1.0”基础上
做,所以不做重复分析,直接用这个例程即可。
如下图所示,在内核“arch/arm/plat-s5p4418/topeet/include/cfg_gpio.h”文件下,
默认是设置为输出模式(输入输出模式是可以在内核中修改的,这里也可以不用修改第一个
宏,直接设置为 PAD_MODE_OUT 也是一样的)。默认状态下是 PAD_PULL_UP,那么悬空
状态下读取出的值是 1(在独立文档“iTOP-4418 和 6818-驱动-GPIO 输入输出和例程
_V1.0”测试中将 GPIOB18 悬空,读到的值是 1,就是因为这里设置为 PAD_PULL_UP)。
如果将上图中的 PAD_PULL_UP 修改为 PAD_PULL_DN,其它参数不用修改,则可以实
现,在 GPIOB18 悬空状态,读到的值是 0。
具体操作和驱动代码请参考“iTOP-4418 和 6818-驱动-GPIO 输入输出和例程_V1.0”文
档。
至此,GPIO 寄存器配置和初始化配置分析完毕。