• 20150223 IMX257 LED驱动程序实现


    20150223 IMX257 LED驱动程序实现

    2015-02-23 李海沿

    由于昨天对IMX257的地址分配不了解,所以前面只能用s3c24xx的驱动程序来了解ioremap等对IO端口的工作原理。

    但是经过昨晚对IMX257芯片的细细梳理,今天早上起来又把IMX257的芯片资料看了一遍,终于成功看懂了,下面意义给大家道来。

    我们此处使用ERR_LED 也就是GPIO3_23引脚

    一、IMX257 芯片资料分析

    1.确定相关寄存器基址

    确定IOMUX地址

    GPIO3的地址

     

    2.确定相关寄存器的偏移地址

    IOMUX的相关的模式配置寄存器,配置为ALT5模式

    偏移地址:

    寄存器描述:

     

    接下来就是配置GPIO的相关信息,上拉,CMOS输入输出,等信息

    偏移地址:

    寄存器描述:

     

    这个是有关ERR_LED的引脚的一些信息

     

    GPIO寄存器的偏移地址

    因为每个GPIO上最大只有32位,刚刚好上面的DR寄存器每一位就是表示单独一个引脚的电平

     

    二、IMX257 代码分析

    1.定义一些寄存器

    //寄存器基址;

    static unsigned long mem_iomux;

    static unsigned long mem_gpio3;

    static unsigned long base_iomux;     //iomux基址 0X 43FA C000 - 0X 43FA FFFF

    static unsigned long base_gpio3;    //gpio3     0X 53FA 4000 - 0X 53FA 7FFF

    // MUX_CTL模式选择 配置寄存器

    #define MUX_CTL (*(volatile unsigned long *)(base_iomux + 0x0060))

    // PAD_CTL GPIO常用功能设置

    #define PAD_CTL (*(volatile unsigned long *)(base_iomux + 0x0270))

    // GPIO DR 数据寄存器 DR

    #define DR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0000))

    // GPIO GDIR 方向控制寄存器 GDIR

    #define GDIR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0004))

    如图所示:

     

    2.在init函数中初始化寄存器,及做相应的配置

     

    IO端口申请:

    配置引脚为ALT5 GPIO模式

     

    配置引脚的电平,1.8v, CMOS输出,都是配置为0

     

    配置为端口引脚为输出模式,并且初始化电平

     

    打印各个寄存器的地址信息

     

    将LED灯1秒间隔闪烁

     

     

    3.在exit函数中释放IO端口

     

     

    4.编译测试

     

    硬件:

    如图所示ERR_LED灯点亮

     

    ERR_LED等熄灭

     

     

     

    好了,大功告成:

    附上驱动程序代码:

     

      1 #include<linux/cdev.h>
      2 #include<linux/module.h>
      3 #include<linux/types.h>
      4 #include<linux/fs.h>
      5 #include<linux/errno.h>
      6 #include<linux/mm.h>
      7 #include<linux/sched.h>
      8 #include<linux/init.h>
      9 #include<asm/io.h>
     10 #include<asm/system.h>
     11 #include<asm/uaccess.h>
     12 #include<linux/device.h>
     13 #include <linux/delay.h>
     14 
     15 #define Driver_NAME "err_led_dev"
     16 #define DEVICE_NAME "err_led_dev"
     17 
     18 static int major = 0;
     19 
     20 //auto to create device node
     21 static struct class *drv_class = NULL;
     22 static struct class_device *drv_class_dev = NULL;
     23 
     24 //寄存器基址;
     25 static unsigned long mem_iomux;
     26 static unsigned long mem_gpio3;
     27 static unsigned long base_iomux;      //iomux基址 0X 43FA C000 -  0X 43FA FFFF
     28 static unsigned long base_gpio3;    //gpio3      0X 53FA 4000 -  0X 53FA 7FFF
     29 // MUX_CTL模式选择  配置寄存器
     30 #define MUX_CTL  (*(volatile unsigned long *)(base_iomux + 0x0060))
     31 // PAD_CTL GPIO常用功能设置
     32 #define PAD_CTL  (*(volatile unsigned long *)(base_iomux + 0x0270))
     33 // GPIO DR   数据寄存器  DR
     34 #define DR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0000))
     35 // GPIO GDIR 方向控制寄存器  GDIR
     36 #define GDIR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0004))
     37 
     38 
     39 static int key_open(struct inode *inode, struct file *file)
     40 {
     41     printk("<0>function open!
    
    ");
     42     return 0;
     43 }
     44 
     45 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
     46 {
     47     return 0;
     48 }
     49 
     50 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
     51 {
     52     printk("<0>function write!
    
    ");
     53     return 1;
     54 }
     55 
     56 static int  key_release(struct inode *inode, struct file *filp)
     57 {
     58     printk("<0>function write!
    
    ");
     59     return 0;
     60 }
     61 
     62 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
     63 {
     64     printk("<0>function ioctl!
    
    ");
     65     return 0;
     66 }
     67 static struct file_operations key_fops = {
     68     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
     69     .open   =   key_open,
     70     .read   =   key_read,
     71     .write  =   key_write,
     72     .release=   key_release,
     73     .ioctl  =   key_ioctl,
     74 };
     75 
     76 void gpio_addr(void){
     77     printk("<0>addr base_iomux : %x 
    ",base_iomux);
     78     printk("<0>addr base_gpio3 : %x 
    ",base_gpio3);
     79     printk("<0>addr MUX_CTL : %x 
    ",&MUX_CTL);
     80     printk("<0>addr PAD_CTL : %x 
    ",&PAD_CTL);
     81     printk("<0>addr GDIR_GPIO3 : %x 
    ",&GDIR_GPIO3);
     82     printk("<0>addr DR_GPIO3 : %x 
    ",&DR_GPIO3);
     83 }
     84 
     85 void led_on_off(void){
     86     ssleep(1);
     87     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
     88     ssleep(1);
     89     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
     90     ssleep(1);
     91     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
     92     ssleep(1);
     93     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
     94     ssleep(1);
     95     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
     96     ssleep(1);
     97     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
     98     ssleep(1);
     99     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
    100     ssleep(1);
    101     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
    102     ssleep(1);
    103     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
    104 }
    105 
    106 static int __init  key_irq_init(void)
    107 {
    108     printk("<0>
    Hello,this is %s module!
    
    ",Driver_NAME);
    109     //register and mknod
    110     major = register_chrdev(0,Driver_NAME,&key_fops);
    111     drv_class = class_create(THIS_MODULE,Driver_NAME);
    112     drv_class_dev = device_create(drv_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME);  /*/dev/key_query*/
    113     
    114     //IO端口申请 ioremap  可以直接通过指针来访问这些地址
    115     base_iomux = ioremap(0x43FAC000,0xFFF);
    116     base_gpio3 = ioremap(0x53FA4000,0xFFF);
    117 
    118     //MUX_CTL
    119     MUX_CTL &= ~(0x07 << 0);    
    120     MUX_CTL |= (0X05 << 0);    //设置为ALT5  GPIO3_23 ERR_LED
    121     //PAD_CTL
    122     PAD_CTL &= ~(0x01<<13 | 0x01<<3 | 0x03<<1 | 0x01<<0);   //1.8v 不需要上拉下拉  CMOS输出 slew rate
    123     //GDIR_GPIO3    配置为输出模式
    124     GDIR_GPIO3 &= ~(0x01 << 23);    
    125     GDIR_GPIO3 |= (0x01 << 23);    //配置为输出模式    
    126 
    127     //DR_GPIO3        配置为输出0 点亮ERR_LED
    128     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
    129     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
    130     gpio_addr();
    131     led_on_off();
    132     return 0; 
    133 }
    134                      
    135 static void __exit key_irq_exit(void)
    136 {
    137     gpio_addr();
    138     printk("<0>
    Goodbye,%s!
    
    ",Driver_NAME);
    139     led_on_off();
    140 
    141        unregister_chrdev(major,Driver_NAME);
    142     device_unregister(drv_class_dev);
    143     class_destroy(drv_class);
    144     
    145     //释放IO端口
    146     iounmap(base_iomux);
    147     iounmap(base_gpio3);
    148 }
    149 
    150 
    151 /* 这两行指定驱动程序的初始化函数和卸载函数 */
    152 module_init(key_irq_init);
    153 module_exit(key_irq_exit);
    154 
    155 /* 描述驱动程序的一些信息,不是必须的 */
    156 MODULE_AUTHOR("Lover雪儿");
    157 MODULE_VERSION("0.1.0");
    158 MODULE_DESCRIPTION("IMX257 key Driver");
    159 MODULE_LICENSE("GPL");
    View Code
  • 相关阅读:
    博客园培训团队工作进度通报
    ASP.NET 2.0打造购物车和支付系统之二
    vs2005视频教程系列 之 MasterPage创建使用 [视频]
    今天过节,我给自己放假一天,不发布教程!
    Visual Studio 2005入门 之 Table [视频]
    vs2005入门 之 GridView使用基础 [视频]
    存放视频文件的服务器出问题了,所有视频暂时打不开!
    加入博客园培训团队须知
    请关心这个系列教程命运的朋友请进来讨论下!
    未来一周将不能发布教程!
  • 原文地址:https://www.cnblogs.com/lihaiyan/p/4297923.html
Copyright © 2020-2023  润新知