Chinaunix首页 | 论坛 | 博客
  • 博客访问: 290967
  • 博文数量: 95
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 714
  • 用 户 组: 普通用户
  • 注册时间: 2018-10-15 14:13
个人简介

搭建一个和linux开发者知识共享和学习的平台

文章分类

全部博文(95)

文章存档

2024年(9)

2023年(24)

2022年(27)

2019年(8)

2018年(27)

分类: LINUX

2022-10-21 14:36:26

一.参考文档:
    1.linux gpio模拟i2c的使用/用GPIO模拟I2C总线-1:
        http://blog.163.com/ac952_hmz/blog/static/94791513201281133230840/
    2.基于S3C2440的嵌入式Linux驱动——AT24C02(EEPROM I2C接口)驱动解读:
        http://blog.csdn.net/yj4231/article/details/18182775


二.Linux内核支持的I2C总线形式:
    1.使用芯片上有I2C总线控制器:
        可以直接将I2C设备挂载在对应的总线上。
    2.不使用芯片上I2C总线控制器,通过模拟I2C总线时序:
        通过使用普通的GPIO口,自己去控制GPIO引脚电平,延时时长,模拟出I2C时序,以此来和I2C设备通信。
    3.不使用芯片上I2C总线控制器,使用Linux内核自带的i2c-gpio驱动:
        只需要指定要使用的GPIO口,延时时长,由i2c-gpio驱动去管理如何跟I2C设备通信,相当是一个I2C控制器,这是Linux内核提供的。


    由于当前工作中的硬件设计需求,本文主要阐述第3种实现方式。


三.开启内核i2c-gpio功能:
    如下图在内核配置中打开I2C_GPIO功能:
        ──────────────────────────────────────────────────────────────────────────────
        ┌───────────────────────── I2C Hardware Bus support ─────────────────────────┐
        │  Arrow keys navigate the menu.  selects submenus --->.             │  
        │  Highlighted letters are hotkeys.  Pressing includes, excludes,    │  
        │  modularizes features.  Press to exit, for Help,     │  
        │  for Search.  Legend: [*] built-in  [ ] excluded  module  < > module   │  
        │ ┌────^(-)────────────────────────────────────────────────────────────────┐ │  
        │ │    < > SiS 96x                                                         │ │  
        │ │    < > VIA VT82C586B                                                   │ │  
        │ │    < > VIA VT82C596/82C686/82xx and CX700/VX8xx                        │ │  
        │ │        *** I2C system bus drivers (mostly embedded / system-on-chip) **│ │  
        │ │    < > Synopsys DesignWare                                             │ │  
        │ │    <*> GPIO-based bitbanging I2C                                       │ │  
        │ │    <*> IMX I2C interface                                               │ │  
        │ │    < > Intel Moorestown/Medfield Platform I2C controller               │ │  
        │ │    < > OpenCores I2C Controller                                        │ │  
        │ │    < > PCA9564/PCA9665 as platform device                              │ │  
        │ │    < > Simtec Generic I2C interface                                    │ │  
        │ │    < > Xilinx I2C Controller                                           │ │  
        │ └────v(+)────────────────────────────────────────────────────────────────┘ │  
        ├────────────────────────────────────────────────────────────────────────────┤  
        │                          < Exit >    < Help >                      │  
        └────────────────────────────────────────────────────────────────────────────┘  
    2. AT24Cxx系列的驱动内核源代码:drivers/misc/eeprom/at24.c


五.GPIO IO配置:
    ......
    /* IMX6DL no i2c4 */
    /**
     *MX6DL_PAD_ENET_TX_EN__I2C4_SCL,
     *MX6DL_PAD_ENET_TXD1__I2C4_SDA,
     */
    MX6DL_PAD_ENET_TX_EN__GPIO_1_28,
    MX6DL_PAD_ENET_TXD1__GPIO_1_29,
    ......


六.板级文件移植代码:
    ......
    #include                 //添加i2c-gpio头文件
    #include                 //添加头文件
    ......
    /**
     * 指定2个GPIO用于I2C总线的SDA、SCL线
     */
    #define SABRESD_I2C4_SDA_GPIO    IMX_GPIO_NR(1, 29)
    #define SABRESD_I2C4_SCL_GPIO    IMX_GPIO_NR(1, 28)
    ......
    static struct i2c_gpio_platform_data i2c_bus_gpio_data = {  
        .sda_pin = SABRESD_I2C4_SDA_GPIO,  
        .scl_pin = SABRESD_I2C4_SCL_GPIO,  
        .udelay  = 5,                   //100Khz
        .timeout = 500,  
        //.sda_is_open_drain = 1,       //在当前板子上不能加
        //.scl_is_open_drain = 1,       //在当前板子上不能加
    }; 
    static struct platform_device i2c_bus_gpio_device = {  
        //这个名字是必须这样,主要是为了和i2c-gpio驱动对应
        .name  = "i2c-gpio",  
        //由于主板已经用掉了0,1,2号,这里使用3
        .id  = 3, /* bus have 0,1,2, so start at 3 */  
        .dev = {  
            .platform_data = &i2c_bus_gpio_data,  
        }  
    };  
    static struct i2c_board_info __initdata gpio_i2c_devices[] = {  
        {  
            /**
             * 24c02:与at24.c驱动中对应的at24c02驱动名对应
             * 0x50:为对应I2C设备的地址,也就我们at24c02设备的地址
             */
            I2C_BOARD_INFO("24c02", 0x50),  
        },  
    }; 
    ......
    static void __init mx6_sabresd_board_init(void)
    {
        ......    
        /**
         * register gpio i2c bus                            write by zengjf
         * 注册i2c-gpio设备,相当于注册一个I2C控制器
         */
        platform_device_register(&i2c_bus_gpio_device);  
        ......
        /**
         * register gpio i2c device                         write by zengjf
         * 在I2C控制器3上注册I2C设备,这里的控制器3就是前面注册的I2C控制器,
         * 主要是因为前面注册的I2C控制器的id是3
         */
        i2c_register_board_info(3, gpio_i2c_devices, ARRAY_SIZE(gpio_i2c_devices));
        ......
    }
    ......


七.eeprom写保护问题:
    当你发现能够从eeprom中读出数据,但是无法往eeprom中写数据时,请检查eeprom芯片的wp(write protect)
阅读(467) | 评论(0) | 转发(0) |
0

上一篇:linux内核启动流程

下一篇:imx6ull下adc接口

给主人留下些什么吧!~~