S3C2440驱动篇之ADC驱动分析

发布者:WanderlustGaze最新更新时间:2024-06-14 来源: elecfans关键字:S3C2440  ADC驱动  触摸屏 手机看文章 扫描二维码
随时随地手机看文章

一.硬件简介

       Linux-2.6.32.2内核没有提供S3C2440的ADC驱动程序,ADC驱动属于字符设备驱动,下面就讲解驱动实现的过程。

       在2440中,AD和触摸屏使用共同的A/D转换器,如下图所示,具体见2440芯片手册16章。
           

二.驱动实现:

       驱动源码如下:

  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. #include    

  15. #include    

  16. #include    

  17. #include    

  18. #include    

  19. #include    

  20. #include    

  21.   

  22. #define DEVICE_NAME 'adc'   

  23.   

  24. static void __iomem *base_addr;  //定义用来保存经虚拟映射的内存地址   

  25.   

  26. typedef struct  

  27. {  

  28.     wait_queue_head_t wait;  

  29.     int channel;  

  30.     int prescale;  

  31. }ADC_DEV;  

  32.   

  33. DECLARE_MUTEX(ADC_LOCK);    //信号量ADC_LOCK,AD、触摸屏互斥访问   

  34.   

  35. static int ownADC = 0;  

  36.   

  37. static ADC_DEV adcdev;  

  38. static volatile int ev_adc = 0;  

  39. static int adc_data;  

  40.   

  41. static struct clk *adc_clk;   //ADC所需时钟   

  42.   

  43. //启动AD转换的宏www.linuxidc.com   

  44. #define START_ADC_AIN(ch,prescale)   

  45. do{  

  46.     iowrite32(S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(prescale)|S3C2410_ADCCON_SELMUX(ch),  

  47.         base_addr+S3C2410_ADCCON);  

  48.     iowrite32(ioread32(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);  

  49. }while(0)  

  50.   

  51. static irqreturn_t adc_handler(int irq,void *dev_id)  

  52. {  

  53.     if(ownADC)  

  54.     {  

  55.         adc_data = ioread32(base_addr+S3C2410_ADCDAT0)&0x3ff;  

  56.   

  57.         ev_adc = 1;   //表示有数据可读,唤醒等待队列   

  58.         wake_up_interruptible(&adcdev.wait);  

  59.     }  

  60.     return IRQ_HANDLED;  

  61. }  

  62.   

  63. static int s3c2440_adc_open(struct inode *inode,struct file *filp)  

  64. {  

  65.     init_waitqueue_head(&adcdev.wait);  //初始化队列   

  66.   

  67.     adcdev.channel = 0;  

  68.     adcdev.prescale = 0xff;  

  69.   

  70.     return 0;  

  71. }  

  72.   

  73. static int s3c2440_adc_close(struct inode *inode,struct file *filp)  

  74. {  

  75.     return 0;  

  76. }  

  77.   

  78. static ssize_t s3c2440_adc_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)  

  79. {  

  80.     int ret;      

  81.       

  82.     if(down_trylock(&ADC_LOCK))   //尝试获取信号量   

  83.     {  

  84.         return -EBUSY;  

  85.     }  

  86.       

  87.     ownADC =1;  

  88.     START_ADC_AIN(adcdev.channel,adcdev.prescale);  

  89.     wait_event_interruptible(adcdev.wait,ev_adc);   //等待有数据可读,中断处理中将唤醒此处   

  90.   

  91.     ev_adc = 0;  

  92.   

  93.     ret=copy_to_user(buffer,(char *)&adc_data,sizeof(adc_data));  

  94.       

  95.     ownADC = 0;  

  96.     up(&ADC_LOCK);   //释放信号量   

  97.   

  98.     return sizeof(adc_data);  

  99. }  

  100.   

  101. static struct file_operations dev_fops=  

  102. {  

  103.     .owner = THIS_MODULE,  

  104.     .open = s3c2440_adc_open,  

  105.     .read = s3c2440_adc_read,  

  106.     .release = s3c2440_adc_close,  

  107. };  

  108.   

  109. static struct miscdevice misc=  

  110. {  

  111.     .minor = MISC_DYNAMIC_MINOR,  // MISC_DYNAMIC_MINOR定义在include/linux/miscdevice.h      

  112.     .name = DEVICE_NAME,  

  113.     .fops = &dev_fops,  

  114. };  

  115.   

  116. static int __init dev_init(void)  

  117. {  

  118.     int ret;  

  119.     /*将ADC的IO端口占用的这段IO空间映射到内存的虚拟地址, S3C2410_PA_ADC是ADC控制器的基地址, 

  120.              定义在arch/arm/mach-s3c2410/include/mach/map.h*/  

  121.     base_addr = ioremap(S3C2410_PA_ADC,0x20);  

  122.     if(base_addr==NULL)  

  123.     {  

  124.         printk(KERN_ERR 'Failed to remap registern');  

  125.         return -ENOMEM;  

  126.     }  

  127.   

  128.     /*从平台时钟队列中获取ADC的时钟,ADC的转换频率跟时钟有关www.linuxidc.com。定义在arch/arm/plat-s3c24xx/s3c2410-clock.c中*/  

  129.     adc_clk = clk_get(NULL,'adc');  

  130.     if(!adc_clk)  

  131.     {  

  132.         printk(KERN_ERR 'Failed to get adc clkn');  

  133.         return -ENOENT;  

  134.     }  

  135.   

  136.     clk_enable(adc_clk);  

  137.   

  138.     iowrite32(0,base_addr+S3C2410_ADCTSC);  

  139.   

  140.     /*申请ADC中断,使用的是共享中断:IRQF_SHARED,为什么要使用共享中断,因为在触摸屏驱动中也使用了这个中断号。 

  141.              中断服务程序为:adc_irq在下面实现,IRQ_ADC是ADC的中断号。共享中断最后一个参数不能为NULL*/  

  142.     ret = request_irq(IRQ_ADC,adc_handler,IRQF_SHARED,DEVICE_NAME,&adcdev);  

  143.     if(ret)  

  144.     {  

  145.         iounmap(base_addr);  

  146.         return ret;  

  147.     }  

  148.   

  149.     ret = misc_register(&misc);  //ADC注册为misc设备   

  150.   

  151.     printk(KERN_INFO 'initializedn');  

  152.     return ret;  

  153. }  

  154.   

  155. static void __exit dev_exit(void)  

  156. {  

  157.     free_irq(IRQ_ADC,&adcdev);  

  158.     iounmap(base_addr);  

  159.   

  160.     if(adc_clk)  

  161.     {  

  162.         clk_disable(adc_clk);  

  163.         clk_put(adc_clk);  

  164.         adc_clk = NULL;  

  165.     }  

  166.   

  167.     misc_deregister(&misc);  

  168. }  

  169.   

  170. EXPORT_SYMBOL(ADC_LOCK);    //导出信号量ADC_LOCK,触摸屏驱动使用   

  171. module_init(dev_init);  

  172. module_exit(dev_exit);  

  173. MODULE_LICENSE('GPL');  

  174. MODULE_AUTHOR('Zechin Liao');  


静态编译:

      1.将上面s3c2440_adc.c文件拷贝至drivers/char目录;

      2.打开drivers/char/Makefile添加相应内容:

                obj-$(CONFIG_JS_RTC) += js-rtc.o

                js-rtc-y = rtc.o

                obj-$(CONFIG_S3C2440_ADC) += s3c2440_adc.o

       3.打开drivers/char/Kconfig添加:

                config DEVKMEM

[1] [2]
关键字:S3C2440  ADC驱动  触摸屏 引用地址:S3C2440驱动篇之ADC驱动分析

上一篇:porting minicom移植 to S3C2440
下一篇:S3C2440驱动篇之触摸屏驱动分析

推荐阅读最新更新时间:2024-11-10 11:27

S3C2440⑤ | S3C2440时钟体系架构及实验
1.时钟架构 简化一下如图所示: 1.1.时钟源的选择 S3C2440的时钟源来源有两种: 外部晶振(OSC) 外部时钟信号(EXTCLK) 选择哪一路作为S3C2440的时钟源由模式控制引脚OM3和OM2引脚(的电平)决定,如何选择见下图: 以JZ2440开发板为例,其使用的是12Mhz外部晶振, 硬件电路如下: 其OM3和OM2选择引脚设置如下,选择第一种方式: 1.2.MPLL改变主时钟FCLK的控制时序(上电复位时序) 2.实验 —— LED闪烁(为了后续对比) 2.1.实验目的 使用C语言控制LED闪烁。 2.2.实验代码 启动文件与之前相同; C程序添加延时函数delay修改后如下:
[单片机]
<font color='red'>S3C2440</font>⑤ | <font color='red'>S3C2440</font>时钟体系架构及实验
未来已来 柔性显示、曲面屏、可折叠屏幕引动产业商机
随着智能手机、平板电脑、车载移动终端及商业化信息查询系统等智能终端产品的推广普及,触摸屏的市场需求量呈井喷式增长。今年,触摸屏技术取得非常大的突破,柔性显示、全面屏、曲面屏、甚至可折叠屏幕产品开始出现。   为此,上海励扩展览有限公司计划于2018年11月22-24日在深圳会展中心举办2018国际全触与显示展,并与昨日(6月20日)在深圳星河丽思卡尔酒店顿召开了新闻发布会。   本次发布会旨在通过发挥行业媒体和协会的力量,进一步提升行业上下游企业的展会参与度以及行业各界人士的关注,探索发掘更多下游创新应用,以及展示生产技术和材料的最新成果,从而使得新一届展会能够更准确地反映显示行业的发展趋势和热点。   励展博览集团大中华区副总
[家用电子]
Hello全触摸屏 致终将消逝的“按键”
1 不止“高颜值”,还玩“高科技” 自特斯拉开始,依靠一块17英寸触控屏替代一堆传统的物理按钮,掀起了车机系统进入新时代的序曲。众多车企争相采用越来越大尺寸的中控触摸屏来当作产品亮点,如造车新势力拜腾推出了令人咂舌的48英寸中控超大屏幕,相当于把“智能电视”搬进了汽车内。 不过,依旧有大部分车型坚持自我,为多媒体中控屏继续配置物理旋钮和按键。一边是对颜值、高科技的追求,一边是对传统的坚持。消灭“按键”,到底是颠覆式创新还是少数人的狂欢? 30秒灵魂拷问: 没有人能拒绝娱乐性的科技产物? 现有触控屏能否让你“一声尖叫”? 触摸大屏永远不懂按键的“爽”? 何种盲操可媲美实体按键的体验? ■不止“高颜值”,
[汽车电子]
Hello全<font color='red'>触摸屏</font> 致终将消逝的“按键”
S3C2440的中断
中断源发生中断,此信号自动被挂起PEND,自动被屏蔽 MASK S3C2440一共有60个中断源,其中有15个子中断源,它们与SUBSRCPND寄存器中的每一位相对应,其他45个中断源与SRCPND中的每一位相对应。要注意的是EINT4~7对应的是同一位SRCPND ,而EINT8~23对应的也是SRCPND 一位。 1 S3C2440的中断寄存器 中断分两大类:外部中断和内部中断。 1.1 外部中断寄存器 24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用这些脚做中断输入,则必须配置引脚为中断,并且不要上拉。具体可参考datesheet
[单片机]
<font color='red'>S3C2440</font>的中断
S3C2440 Linux驱动移植——SPI
1. 配置内核 首先,修改arch/arm/plat-s3c24xx/Kconfig,这一步的目的是为了可以在内核中使能SPI0的配置函数。 修改后的内容如下: config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 bool S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 help SPI GPIO configuration code for BUS0 when connected to GPE11, GPE12 and GPE13. 接着配置内核,首先打开S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13选项,这样编译的时候会将 ar
[单片机]
<font color='red'>S3C2440</font> Linux<font color='red'>驱动</font>移植——SPI
S3C2440开发板裸机程序系列07—NAND FLASH存储器
1. 概述 我的TQ2440开发板上安装有2M的NOR FLASH和512M的NAND FLASH。 NOR FLASH 的特点是芯片内执行(XIP, eXecute In Place),应用程序可以直接在 NOR FLASH 里运行,不必再把代码读到系统RAM中(可以节约SRAM的成本)。NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能。 NAND FLASH的特点是有很高的存储密度,并且写入和擦除速度也很快,但是无法直接寻址运行程序,接口上需要专门的控制器。另外NAND FLASH 非常容易出现坏区,所以需要有校验的算法。 因此,NOR FLASH一
[单片机]
<font color='red'>S3C2440</font>开发板裸机程序系列07—NAND FLASH存储器
记录1--s3c2440 GPIO && UART的控制
一.初始化对应的UART void Uart_Init(int pclk, int baud) { if(pclk == 0) pclk = PCLK; if(UartNum==0) //判断是否使用UART0 { rGPHCON = rGPHCON & (~(0xffff)); //UART0: RXD0 == GPH3 TXD0 == GPH2 rGPHCON = rGPHCON | (0xaaa0) ; //设置GPH端口为UART口 rGPHUP = 0x0; //使能上拉功能 rUFCON0=0x0; // 不使用FIFO rUMCON
[单片机]
平板电脑市场份额将在2020年下跌至低于75%
Strategy Analytics的平板电脑和触摸屏战略(TTS)服务最新发布的研究报告《2010-2020平板电脑出货量,市场存量和渗透率预测(按国家划分):2016年Q4更新》指出,随着平板电脑在娱乐和生产力方面成为具有高性价比的计算设备,在经历两年的衰退后,平板电脑市场正在出现改善迹象。平板电脑出货量预计在2017年同比下降仅1%,之后随着大家对2-in-1、Windows平板电脑和企业销量的需求反弹,平板电脑市场规模将会适度的增长。 Strategy Analytics平板电脑和触摸屏战略服务总监Peter King表示,“2-in-1平板电脑和高配平板电脑在发展中市场是电脑的替代品;2016年下半年,我们看到了这类平板
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved