查看: 4662|回复: 5

[原创] RIoTboard连载五 RIoTboard GPIO相关函数和宏定义简介

[复制链接]

15

主题

4

好友

903

积分

举人

Rank: 4

  • TA的每日心情
    开心
    2016-9-29 15:49
  • 签到天数: 113 天

    [LV.6]常住居民II

    爱板会员勋章 活跃会员勋章

    发表于 2014-5-10 17:35:52 |显示全部楼层
    最近几天忙于做LCD显示驱动板的原理图和PCB,终于板子投了,大概周一能够收到就可以焊接调试了。
    这几天也算是有时间看下驱动相关的东西,先总最简单的GPIO开始说起吧。首先分析下linux下操作imx6s芯片的大概过程和主要函数与宏定义。
    不管uboot中还是linux下imx6的GPIO配置都要区分IOMUX和GPIO的配置,首先通过配置IOMUX寄存器,设置芯片的pad管脚为GPIO功能,然后通过GPIO寄存器来设置GPIO功能。
    那么我们看下linux下和IOMUX配置相关的几个函数和宏定义:

    在看这个之前要先看一个对引脚配置非常关键的64位的数据定义:
    typedef u64 iomux_v3_cfg_t 64bit的数据定义
    这个就是关于IOMUX/PAD的bit为的定义的组合,iomux_v3_cfg_t的数据域分布如下:
    MUX_CTRL_OFS:         0..11 (12)
    Mux控制寄存器地址偏移量,占用12bit,分布为iomux_v3_cfg_t的第0-11bit
    PAD_CTRL_OFS:          12..23 (12)
    Pad控制寄存器地址偏移占用12bit,分布为iomux_v3_cfg_t的第12-23bit
    SEL_INPUT_OFS:         24..35 (12)
    Select input地址偏移量,占用12bit,分布为iomux_v3_cfg_t的第24-35bit
    MUX_MODE + SION:           36..40  (5)
    Mux模式和Software Input On Field.寄存器的设置,占据5位,其中mux mode占用3bitSION占用两个bit,分布为iomux_v3_cfg_t36-40bit
    PAD_CTRL + NO_PAD_CTRL: 41..58 (18)
    Pad_ctrl寄存器配置占用18bit,分布为iomux_v3_cfg_t41-58bit
    SEL_INP:              59..62 (4)
    SEL_INP占用4bit,分布为iomux_v3_cfg_t59-62bit
    reserved:               63   (1)
    这个iomux_v3_cfg_t 是后面几乎所有关于GPIO配置的地方都要用到的一个数据。好了,那下面我们先分析几个函数和宏定义
    1.
    IOMUX_PAD(PAD Control Offset, MUX ControlOffset, MUX Mode, Select Input Offset, Select Input, Pad Control)
    IOMUX_PAD后面几个参数的定义做如下分析:
    PAD Control Offsetpad control register的地址偏移,这个寄存器主要配置引脚物理和电气特性,类似接口形式,上下拉,驱动能力,速度等。
    1.JPG

    MUX Control OffsetMUX control register的地址偏移,这个寄存器主要是配置引脚的输入路径和引脚的模式选择 ALT0-ALT7.
    2.JPG
    MUX ModeMUX mode数据,在MUX controlregisters中定义。000-111对应alt0-alt7
    3.JPG
    Select Input OffsetMUX control register地址偏移,主要配置功能见上述表格。
    Select InputSelect Input data,在select inputregisters定义。
    Pad ControlPad Control data,在Pad controlregisters中定义。
    后面我们看看IOMUX_PAD的定义如下:
    #define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _sel_input_ofs, \
                    _sel_input, _pad_ctrl)                                        \
            (((iomux_v3_cfg_t)(_mux_ctrl_ofs) << MUX_CTRL_OFS_SHIFT) |        \
                    ((iomux_v3_cfg_t)(_mux_mode) << MUX_MODE_SHIFT) |        \
                    ((iomux_v3_cfg_t)(_pad_ctrl_ofs) << MUX_PAD_CTRL_OFS_SHIFT) | \
                    ((iomux_v3_cfg_t)(_pad_ctrl) << MUX_PAD_CTRL_SHIFT) |        \
                    ((iomux_v3_cfg_t)(_sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT) | \
                    ((iomux_v3_cfg_t)(_sel_input) << MUX_SEL_INPUT_SHIFT))
    通过IOMUX_PAD的定义可以看出,这个就是一个宏定义,是一个用来生成iomux_v3_cfg_t 这个数据的方法的定义。
    括号里的参数都是按照iomux_v3_cfg_t 的数据域进行不同位数的移位然后相或,来产生iomux_v3_cfg_t 。
    那我们看代码中的如下定义:
    #define MX6DL_PAD_EIM_A25__GPIO_5_2 IOMUX_PAD(0x0504, 0x0134, 5, 0x0000, 0, NO_PAD_CTRL)

    其实这个定义就是针对EIM_A25生成一个iomux_v3_cfg_t数据。
    以上只是生成了IOMUX/PAD的相关数据,那么怎么配置IOMUX和GPIO呢,那就继续看下面一个函数
    2.int mxc_iomux_v3_setup_pad(iomux_v3_cfg_tpad)
    {
             u32mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
             u32mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
             u32sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >>MUX_SEL_INPUT_OFS_SHIFT;
             u32sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
             u32pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >>MUX_PAD_CTRL_OFS_SHIFT;
             u32pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
             if(mux_ctrl_ofs)
                       __raw_writel(mux_mode,base + mux_ctrl_ofs);
             if(sel_input_ofs)
                       __raw_writel(sel_input,base + sel_input_ofs);
             if(!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
                       __raw_writel(pad_ctrl,base + pad_ctrl_ofs);
             return0;
    }
    这个函数呢也还是围绕着iomux_v3_cfg_t这个64位的数据做文章,大家也都可以看到,基本就是从iomux_v3_cfg_t  中取出和实际引脚对应的mux_mode等实际值,然后通过__raw_writel ()函数来完成引脚功能的实际初始化。
    好了到现在我们可以配置IOMUX了,但是如何操作GPIO呢,其实在这个源代码里面没有看见类似直接操作寄存器来操作GPIO输出的函数,因为毕竟到了linux下面直接访问寄存器已经不向uboot或者裸机操作那么简单了,那么我们如何操作GPIO呢,下面就来看下linux的GPIO number的导出。
    在imx6下面有GPIO1-7组GPIO,在uboot和GPIO初始化时候可以使用寄存器基地址或者 iomux_v3_cfg_t 这个数据来操作GPIO,但是到了linux就要将GPIO1-7组的GPIO统一编号到linux下,那么如何进行编号呢,可能大家都看到了,在board_mx6q_riot.c文件中有很多类似#define RIOT_USER_LED                IMX_GPIO_NR(5, 2)的定义,那么这个IMX_GPIO_NR又是什么呢,我们看看它的定义如下
    #define IMX_GPIO_NR(bank, nr)                (((bank) - 1) * 32 + (nr))
    由此可见这是个将不同组的GPIO统一到linux下的GPIO number的计算公式,即:<GPIO Instance – 1> × 32 + <GPIO Port number>
    比如说RIOT板子的用户LED这个GPIO的转换,IMX_GPIO_NR(5,2),就是说在imx6芯片中控制LED的引脚是GPIO5_2,那么转换到linux就是GPIO ((5-1)*32+2)=130,即linux的GPIO数是GPIO-130。
    关于linux的GPIO操作我们可以在linux命令行中路径/sys/class/gpio/export中导出GPIO number,然后对GPIO进行操作,来控制GPIO输入和输出,比如刚才分析我们的LED控制引脚在linux下是GPIO-130,那我们就可以进行如下操作:
    echo 130 > /sys/class/gpio/export
    设置输出命令:
    echo out > /sys/class/gpio/gpio30/direction
    设置输出1和输出0:
    echo 1 > /sys/class/gpio/gpio130/value
    echo 0 > /sys/class/gpio/gpio130/value
    但是在我们系统中,GPIO-130已经由系统注册为platform设备,所以使用GPIO export会提示资源繁忙无法配置,那在后续的文章中我们就继续分析如何在linux源码中进行GPIO的控制。



    回复

    使用道具 举报

    78

    主题

    21

    好友

    6227

    积分

    状元

    Rank: 6Rank: 6

  • TA的每日心情
    奋斗
    2016-7-29 22:00
  • 签到天数: 726 天

    [LV.9]以坛为家II

    爱板会员勋章 活跃会员勋章 发帖机器勋章

    发表于 2014-5-10 20:51:12 |显示全部楼层
    分析得非常好,读得很畅快,期待继续。
    回复

    使用道具 举报

    33

    主题

    10

    好友

    2412

    积分

    进士

    Rank: 5Rank: 5

  • TA的每日心情
    无聊
    2016-11-9 20:46
  • 签到天数: 229 天

    [LV.7]常住居民III

    发表于 2014-5-11 23:09:57 |显示全部楼层
    紧跟楼主脚步!
    回复

    使用道具 举报

    15

    主题

    3

    好友

    1361

    积分

    进士

    Rank: 5Rank: 5

  • TA的每日心情
    奋斗
    8 小时前
  • 签到天数: 413 天

    [LV.9]以坛为家II

    爱板会员勋章

    发表于 2014-5-24 14:35:16 |显示全部楼层
    问一下,你GPIO关于寄存器的pdf文档时什么名字的,我怎么没找到寄存器的说明啊
    回复

    使用道具 举报

    15

    主题

    4

    好友

    903

    积分

    举人

    Rank: 4

  • TA的每日心情
    开心
    2016-9-29 15:49
  • 签到天数: 113 天

    [LV.6]常住居民II

    爱板会员勋章 活跃会员勋章

    发表于 2014-5-24 23:20:24 |显示全部楼层
    哦,寄存器的说明在imx6的用户手册文档中,文档名字是IMX6SDLRM.pdf,那个50多M的,在freescale官网下载就行
    回复

    使用道具 举报

    15

    主题

    3

    好友

    1361

    积分

    进士

    Rank: 5Rank: 5

  • TA的每日心情
    奋斗
    8 小时前
  • 签到天数: 413 天

    [LV.9]以坛为家II

    爱板会员勋章

    发表于 2014-5-24 23:36:49 |显示全部楼层
    哦 好的 知道了
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /6 下一条


    手机版|爱板网 |网站地图  

    GMT+8, 2016-12-7 18:35 , Processed in 0.138453 second(s), 15 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部