20150223 IMX257 LED驱动程序实现
发布日期:2021-06-29 14:55:58 浏览次数:2 分类:技术文章

本文共 5652 字,大约阅读时间需要 18 分钟。

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
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
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!\n\n"); 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!\n\n"); 53 return 1; 54 } 55 56 static int key_release(struct inode *inode, struct file *filp) 57 { 58 printk("<0>function write!\n\n"); 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!\n\n"); 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 \n",base_iomux); 78 printk("<0>addr base_gpio3 : %x \n",base_gpio3); 79 printk("<0>addr MUX_CTL : %x \n",&MUX_CTL); 80 printk("<0>addr PAD_CTL : %x \n",&PAD_CTL); 81 printk("<0>addr GDIR_GPIO3 : %x \n",&GDIR_GPIO3); 82 printk("<0>addr DR_GPIO3 : %x \n",&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置1100 ssleep(1);101 DR_GPIO3 &= ~(0x01 << 23); //将GPIO2_23清零102 ssleep(1);103 DR_GPIO3 |= (0x01 << 23); //将GPIO2_23置1104 }105 106 static int __init key_irq_init(void)107 {108 printk("<0>\nHello,this is %s module!\n\n",Driver_NAME);109 //register and mknod110 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_CTL119 MUX_CTL &= ~(0x07 << 0); 120 MUX_CTL |= (0X05 << 0); //设置为ALT5 GPIO3_23 ERR_LED121 //PAD_CTL122 PAD_CTL &= ~(0x01<<13 | 0x01<<3 | 0x03<<1 | 0x01<<0); //1.8v 不需要上拉下拉 CMOS输出 slew rate123 //GDIR_GPIO3 配置为输出模式124 GDIR_GPIO3 &= ~(0x01 << 23); 125 GDIR_GPIO3 |= (0x01 << 23); //配置为输出模式 126 127 //DR_GPIO3 配置为输出0 点亮ERR_LED128 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>\nGoodbye,%s!\n\n",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

 

转载地址:https://ciellee.blog.csdn.net/article/details/82599457 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Ajax_iframe文件上传
下一篇:深入浅出JSONP--解决ajax跨域问题

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月05日 00时46分33秒