【OK210试用体验】之adc驱动动 - 在线问答 - 电子技术论坛 - 最好最受欢迎电子论坛!

【OK210试用体验】之adc驱动动

罗崇军 ( 楼主 ) 2015-8-18 17:07:19  只看该作者 倒序浏览
电子设计大赛终于结束了,那俩天我也是累得不行,今天做了adc的实验,在这里与大家分享。
版本说明:
               平台:OK210;
                os :Linux2.6.35.7
                驱动类型:adc


驱动程序如下
  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. #define ADC_REL                (0x10012)
  21. #define ADC_INPUT_PIN        (0x10013)

  22. struct s5pv210_adc_regs {
  23.         unsigned long tsadccon0;
  24.         unsigned long tscon0;
  25.         unsigned long tsdly0;
  26.         unsigned long tsdatx0;
  27.         unsigned long tstaty0;
  28.         unsigned long tspenstat0;
  29.         unsigned long clrintadc0;
  30.         unsigned long adcmux;
  31.         unsigned long clrintpen0;
  32.         unsigned long tsadccon1;
  33.         unsigned long tscon1;
  34.         unsigned long tsdly1;
  35.         unsigned long tsdatx1;
  36.         unsigned long tsdaty1;
  37.         unsigned long tspenstat1;
  38.         unsigned long clrintadc1;
  39.         unsigned long clrintpen1;
  40. };

  41. static struct s5pv210_adc_regs *adc_regs;
  42. static int port;
  43. static int nbit;
  44. static int EndConvered;

  45. static DECLARE_WAIT_QUEUE_HEAD(adc_waitq);

  46. static int s5pv210_adc_open(struct inode *inode, struct file *file)
  47. {
  48.         return 0;
  49. }

  50. static int s5pv210_adc_close(struct inode *inode, struct file *file)
  51. {
  52.         return 0;
  53. }  input_event

  54. static ssize_t s5pv210_adc_read(struct file *file, char __user *buf, size_t count, loff_t *ffops)
  55. {
  56.         unsigned long data;

  57.         adc_regs->tsadccon0 |= (1 << 0);

  58.         udelay(500);

  59.         wait_event_interruptible(adc_waitq, EndConvered);
  60.         EndConvered = 0;
  61.        
  62.         if(nbit == 12)
  63.                 data = adc_regs->tsdatx0 & 0xfff;
  64.         else
  65.                 data = adc_regs->tsdatx0 & 0x3ff;

  66.         copy_to_user(buf, &data, sizeof(data));

  67.         return count;
  68. }

  69. static int s5pv210_adc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  70. {
  71.         switch(cmd) {
  72.                 case ADC_INPUT_PIN:
  73.                         copy_from_user(&port, (int *)arg, 4);
  74.                         adc_regs->adcmux &= ~0xf;
  75.                         adc_regs->adcmux |= port;
  76.                         break;
  77.                 case ADC_REL:
  78.                         copy_from_user(&nbit, (int *)arg, 4);
  79.                         if(nbit == 12)
  80.                                 adc_regs->tsadccon0 |= (1 << 16);
  81.                         else
  82.                                 adc_regs->tsadccon0 &= ~(1 << 16);
  83.                         break;
  84.         }
  85.         return 0;
  86. }

  87. static struct file_operations s5pv210_adc_fops = {
  88.         .open                                 = s5pv210_adc_open,
  89.         .release                          = s5pv210_adc_close,
  90.         .read                                = s5pv210_adc_read,
  91.         .ioctl                = s5pv210_adc_ioctl,
  92. };

  93. static irqreturn_t adc_irq(int irq, void *dev_id)
  94. {
  95.         EndConvered = 1;
  96.         wake_up_interruptible(&adc_waitq);
  97.        
  98.         adc_regs->clrintadc0 = 0;
  99.         return IRQ_HANDLED;
  100. }

  101. static struct miscdevice s5pv210_adc_drv = {
  102.         .minor         = 132,
  103.         .name        = "adc",
  104.         .fops        = &s5pv210_adc_fops,
  105. };
  106. static int adc_drv_init(void)
  107. {
  108.         struct clk *clk;
  109.        
  110.            misc_register(&s5pv210_adc_drv);

  111.         clk = clk_get(NULL, "adc");
  112.         clk_enable(clk);

  113.         adc_regs = ioremap(0xe1700000, sizeof(struct s5pv210_adc_regs));

  114.         /* ADCCON[16] = 1 (12bit)*/
  115.         /* ADCCON[14] = 1 (enable prescaler)*/
  116.         /* ADCCON[13:6] = 13 (prescaler value)*/
  117.         adc_regs->tsadccon0         = (1 << 16) | (1 << 14) | (13 << 6);
  118.         adc_regs->tsdly0        = 10000;

  119.         request_irq(IRQ_ADC, adc_irq, 0, "adc_irq", NULL);
  120.        
  121.         return 0;
  122. }

  123. static void adc_drv_exit(void)
  124. {
  125.         free_irq(IRQ_ADC, NULL);
  126.         misc_deregister(&s5pv210_adc_drv);
  127. }

  128. module_init(adc_drv_init);
  129. module_exit(adc_drv_exit);
  130. MODULE_LICENSE("GPL");
复制代码
makefile文件如下
  1. all:
  2.         make -C $(SRC_PATH)/kernel M=`pwd` modules
  3.         cp adc_drv.ko $(SRC_PATH)/system/modules/
  4. clean:
  5.         make -C $(SRC_PATH)/kernel M=`pwd` modules clean
  6.         rm -rf modules.order *.ko *.o *.mod.* Module*

  7. obj-m        += adc_drv.o
复制代码
测试程序如下
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include

  8. #define ADC_RESOL       0x10012
  9. #define ADC_INPUT_PIN   0x10013

  10. int main(int argc, char *argv[])
  11. {
  12.     int fd;
  13.     unsigned int voltage;
  14.     double AdcInfo;
  15.     char  tmp[10];
  16.     int nbit;
  17.     int port;

  18.     memset(tmp, 0, sizeof(tmp));
  19.    
  20.     if (argc != 3) {
  21.         printf("usage:n%s n", argv[0]);
  22.         return -1;
  23.     }
  24.    
  25.     nbit = strtoul(argv[1], NULL, 10);
  26.     port = strtoul(argv[2], NULL, 10);

  27.     fd = open("/dev/s5pv210_adc", O_RDWR);

  28.     ioctl(fd, ADC_RESOL, &nbit);
  29.     ioctl(fd, ADC_INPUT_PIN, &port);

  30.     while (1) {
  31.         read(fd, &voltage, sizeof(voltage));
  32.         AdcInfo =  (float)voltage / (1 << nbit) * 3.3;
  33.         sprintf(tmp, "%.1f", AdcInfo);
  34.         AdcInfo = atof(tmp);
  35.         printf("vol = %fn", AdcInfo);
  36.         usleep(300000);
  37.     }

  38.     close(fd);
  39.     return 0;
  40. }
复制代码
特别说明一下,这个驱动程序是改的以前在smart210上的驱动,我测试是可以用的,但是,由于测试次数之测了一次,难免有错误,如果需要使用,请一定要仔细检查。




0个回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

站长推荐上一条 /6 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 湘ICP备2023018690号 )

GMT+8, 2024-4-20 04:22 , Processed in 0.532446 second(s), Total 63, Slave 46 queries .

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表