收藏本站| 欢迎收藏LED之家,LED之家是国内LED行业信息最全面的门户网站之一。
首页
登录免费注册一个新账号
我的账号
广州国际照明展览会(光亚展)
首页 》LED之家 》LED驱动 》SOC8200下LED驱动 点击:975    LED知识讨论发表新主题
LED之家   永久地址:www.ledjia.com

  LED驱动  原理图  ICE  控制  问题  引脚  原理  解释  实现  LED

SOC8200下LED驱动

LED之家  于2012-01-30 15:57:31  http://www.ledjia.com/ledhangye/viewarticle.php?id=7990

文章摘要: 虽然linux新内核下GPIO包括LED驱动有笼统接口架构。而选择自己实现。原本认为可以轻松搞定,但是这是可选择的为了能去理解LED这个驱动中的helloworld还是选择绕过linux复杂的架构。没想到还是呈现了一些小问题记录一下。硬件平台是天漠的SOC8200CPUam3517cortexa8找到LED对应的引脚。首先看硬件原理图。  可以看到LED2受HLED引脚控制。高电平时亮,当低电平时灭。继续跟踪HLED一直发现是引脚SYS_BOOT0这时去am3517硬件手册

 虽然linux新内核下GPIO包括LED驱动有笼统接口架构。而选择自己实现。原本认为可以轻松搞定,但是这是可选择的为了能去理解LED这个驱动中的helloworld还是选择绕过linux复杂的架构。没想到还是呈现了一些小问题记录一下。硬件平台是天漠的SOC8200CPUam3517cortexa8
找到LED对应的引脚。首先看硬件原理图。
 可以看到LED2受HLED引脚控制。高电平时亮,当低电平时灭。继续跟踪HLED一直发现是引脚SYS_BOOT0
这时去am3517硬件手册查一下sys_boot0发现如下:
分别叫做GPIO1-6每组里32个gpio脚,32位寄存器的每一位都控制一个脚,所以gpio_2实际上是GPIO1,am3517下将gpio分为6个组。 可以看到sys_boot0其实也是gpio_2这里解释一下。而LED需要gpio驱动的所以我首先利用CONPCL_PA DCONF_SYS_NRESWA RM[31:16]这个寄存器配置成mode4具体见手册).
下面就应该是操作gpio寄存器了有几个对我目的比较重要。GPIO_DA TA OUT,GPIO_OE.GPIO_CLEA RDA TA OUT,GPIO_SETDA TA OUT
 GPIO_OE使能输出的所以我第二步就是将gpio_2设为输出使能。
 第三步就是对GPIO_DA TA OUT对应该gpio_2位写1或者0就相应的输出了低电平和高电平。
 这时会有人问那后两个寄存器有什么用?这个问题其实仔细看一下数据手册就知道了当时就是由于看的不仔细。置位,结果在这里浪费好多时间其实这两个寄存器是间接设置GPIO_DA TA 相应位的GPIO_CLEA RDA TA OUT相当于对该位置0GPIO_SETDA TA OUT相当于对该位置1而GPIO_DA TA OUT就是用顺序直接对该位写0或写1用间接设置寄存器一条指令就可以对特定位置0或1而直接写需要多条指令(先读取保存。再写入)
写的很粗糙也没有改。下面是驱动源码。
#includ<linux/module.h>
#includ<linux/kernel.h>
#includ<linux/init.h>
#includ<asm/delay.h>
#includ<asm/uaccess.h>
#includ<asm/io.h>
#includ<linux/types.h>
#includ<linux/cdev.h>
#includ<linux/fs.h>
#definGPIO1_BA SE  0x48310000        //这是GPIO1基址
下同 #definGPIO_OE     0x0034            //寄存器相对基址偏移量。
#definGPIO_DA TA OUT0x003C
#definGPIO_SETDA TA OUT0x0094
#definGPIO_CLEA RDA TA OUT0x0090
#definPA D_CONF    0x48002A 08        //这是用来将sys_boot0设成gpio_2寄存器
structcdev*dev;
intled_major;
structfile*filpintled_openstructinod*inode.{
 
 filp->private_data=inode->i_cdev;
 return0;
}
structfile*filpintled_releasstructinod*inode.{
 return0;
}
ssize_tled_writstructfile*filp.size_tcount,constchar__user*buff.loff_t*offp{
 
 u32l=0;
 unsigncharvalue;
 void __iomem*base;  //因为用了MMU所以要ioremap
 void__iomem*pad;
4096 bas=ioremapGPIO1_BA SE.;
256 pad=ioremapPA D_CONF.;
 ifcopy_from_user&value.1buff.{
  return-EFA ULT;
 }
//设成mode4
 l=__raw_readlpad;
 l=l|1<<18;
 l=l&~1<<17;
 l=l&~1<<16;
pad __raw_writell.;
 
//使能输出
 l=__raw_readlbase+GPIO_OE;
 l=l&~1<<2;
base+GPIO_OE __raw_writell.;
//向gpio_2写0或1控制LED亮灭
 l=__raw_readlbase+GPIO_DA TA OUT;
 ifvalu=='1'{
  l=l|1<<2;
base+GPIO_DA TA OUT __raw_writell.;
base+GPIO_SETDA TA OUT;可以看出来。用这个方法一条指令就够了 //或者直接用__raw_writel1<<2.>
 }els{
  l=l&~1<<2;
base+GPIO_DA TA OUT __raw_writell.;
base+GPIO_CLEA RDA TA OUT //或者iowrite321<<2.;
 }
 
 return1;
}
structfile_operled_fops={
.own=THIS_MODULE.>
.write=led_write.>
.open=led_open.>
.releas=led_release.>
};
statintled_initvoid{
 
 dev_tdevno;
 interr;
 
 ifalloc_chrdev_region&devno.1,0."led-zj"<0{
  return-1;
 }
 led_major=MA JORdevno;
 dev=cdev_alloc;
&led_fop cdev_initdev.;
 dev->op=&led_fops;
 dev->own=THIS_MODULE;
 err=cdev_adddev.1devno.;
 iferr<0
 printkKERN_NOTICE"Error";
 return1;
}
staticvoidled_exitvoid{
 
 cdev_deldev;
 unregister_chrdev_regionMKDEVled_major.10.;
}
module_initled_init;
module_exitled_exit;
MODULE_LICENSE"DualBSD/GPL";
 
遇到问题和总结:
对物理地址的读写用ioremap后才以用(如果启用了MMU
读写寄存器命令即可以用__raw_write8系列也可以用iowrite8系列函数(实际iowrit就是__raw_writ
查找硬件手册和原理图时要善用搜索功能(2700多页看手册说明仔细一些,免的走回头路。
LED之家小提示:若文章图片无法显示,又急需查看图片,请将需求文章的网址发往邮箱:wantled@163.com ,本站将尽快将相关图片回复到您的邮箱。



相关词语:  LED驱动  原理图  ICE  控制  问题  引脚  原理  解释  实现  LED

LED之家永久地址:www.ledjia.com
首页 -- 联系我们 -- 使用帮助 -- 收藏本站 -- 设为首页

Copyright ? 2008~2024 www.ledjia.com. All Rights Reserved.  [ 粤ICP备05006808号 ]  版权所有: LED之家.