ts-7000
[Top] [All Lists]

[ts-7000] Re: TS-ADC16

To:
Subject: [ts-7000] Re: TS-ADC16
From: "beetle.chus" <>
Date: Tue, 14 Apr 2009 15:10:13 -0000
Hi,
Thank you very much for the code. I am testing it now. I will let you know any 
change i will make in the driver.

Pablo

--- In  "dan" <> wrote:
>
> Hello,
> 
> Below the driver source and header file.
> to make it work:
> 
> 1. compile it
> 2. enable PC104 bus
> 3. load driver
> 4. create filesystem node acording to major/minor number
> 5. build an user land application to send basic IOCTLs to the board(also 
> check board ID)
> 
> For sure the driver can be improved and I would be happy with any 
> sugestions/fixes for it.
> In case of trouble I'll try to respond to your 
> 
> I don't have any better ideea to post it, than listing below the files:
> adc_drv.c
> 
> #include <linux/module.h>
> #include <linux/init.h>
> #include <linux/kernel.h>
> #include <linux/fs.h>
> #include <linux/cdev.h>
> #include <linux/string.h>
> #include <asm/uaccess.h>
> //#include <asm/arch/regmap.h>
> #include <linux/proc_fs.h>
> #include <asm/io.h>
> #include "/usr/src/linux/include/linux/ioport.h"
> #include </usr/src/linux/include/linux/ioport.h>
> #include <linux/interrupt.h>
> 
> #include "adc_drv.h"
> 
> MODULE_DESCRIPTION("ADC character dev");
> MODULE_AUTHOR("Dan Lupu");
> MODULE_LICENSE("GPL");
> 
> #define LOG_LEVEL     KERN_DEBUG
> 
> struct my_adc_data {
>     struct cdev cdev;
>     /* my data starts here */
>       int size;
>       int* buffer;            // buffer to store FIFO data
>       volatile char* ptr;     /* board addr from k*/
>       unsigned int irq7Show;  
> };
> 
> irqreturn_t adc_irqHnd(int irq_no, void *dev_id)
> {
>     struct my_adc_data *my_data = (struct my_adc_data *) dev_id;
>  
>       printk("ADC IRQ Hnd called\n");
> 
>       if(irq_no==0x07)
>       {
>        my_data->irq7Show = my_data->irq7Show + 1;     
>        return IRQ_HANDLED;
>       }       
> 
>     return IRQ_NONE;
> }
> 
> struct my_adc_data my_adc;
> 
> static int my_open(struct inode *inode, struct file *file);
> static int my_read(struct file *file, char __user *user_buffer, 
>                                 size_t size, loff_t *offset);
> 
> static int my_write (struct file *file, const char __user * user_buffer,
>                       size_t size, loff_t *offset);
> static int adc_ioctl (struct inode *inode,struct file *file,unsigned int cmd, 
> unsigned long arg);
> static int my_release (struct inode *inode, struct file *file);
> 
> 
> struct file_operations my_fops = {
>     .owner = THIS_MODULE,
>     .open = my_open,
>     .read = my_read,
>     .write = my_write,
>     .release = my_release,
>     .ioctl = adc_ioctl
> };
> 
> 
> static int my_init(void)
> {
>         int err;
>       //printk(LOG_LEVEL "Init ADC module\n");
>       // offset adaugat isa_regbase.  
>       my_adc.size=0;  
>       my_adc.ptr = NULL;      
>       my_adc.irq7Show=0;
>       err = register_chrdev_region(MKDEV(MY_MAJOR, MY_MINOR),1,MODULE_NAME);
> 
>       if (err != 0) {
>               /* report error */
>               return err;
>       }
>    
>       /* initialize my_dev fields */
>         cdev_init(&my_adc.cdev, &my_fops);
>         cdev_add(&my_adc.cdev, MKDEV(MY_MAJOR, MY_MINOR), 1);
> 
>       //printk(LOG_LEVEL "Open ADC device\n");
> 
>       if(check_mem_region(ADC_BASE,8))
>       {
>        printk("ADC_BASE space in use!");
>        return -EBUSY; 
>       }
> 
>       request_mem_region(ADC_BASE,0x1E,"adc_drv");
>       my_adc.ptr=__ioremap(ADC_BASE,0x1E,0);  
> 
>       if(my_adc.ptr == NULL)
>       {
>        printk("no IOREMAP success!\n");
>       }
>       // board ID     
>       if(0x3e!=readb(my_adc.ptr))
>       { 
>        printk("no ID from board 1"); 
>        if(0x3e!=inb(my_adc.ptr))
>        { 
>         printk("no ID from board 2"); 
>         return -EBUSY;
>        }
>       }
> 
>       // request IRQs 
>       if ((err = request_irq(MY_IRQ1, adc_irqHnd, IRQF_SAMPLE_RANDOM | 
> IRQF_SHARED,
>                        "adc", &my_adc))) {
>           /* handle error*/
>            printk("alocate IRQ7 not possible"); 
>           return err;
>       }
> 
>       //allocate mem for ADC FIFO
>       my_adc.buffer=kmalloc(BUFFER_SIZE * sizeof(unsigned int),GFP_KERNEL);
> 
>       return 0;
> }
> 
> static void my_exit(void)
> {
>       //printk(LOG_LEVEL "Exit\n");
> 
>       release_mem_region(ADC_BASE,0x1E);
>       __iounmap(my_adc.ptr);  
> 
>       free_irq(MY_IRQ1, &my_adc);
>     
>         cdev_del(&my_adc.cdev);
>       kfree(my_adc.buffer);
> 
>         unregister_chrdev_region(MKDEV(MY_MAJOR, MY_MINOR), 1);
> }
> 
> static int my_open(struct inode *inode, struct file *file)
> {
>       struct my_adc_data *my_adc;
>       //printk(LOG_LEVEL "Open DIO device\n");
>       my_adc = container_of(inode->i_cdev, struct my_adc_data, cdev);
>       file->private_data = my_adc;
>       my_adc->size=0;
> //    writeb(0x00,my_adc->ptr+DDR);
>       return 0;
> }
> 
> static int my_read(struct file *file, char __user *user_buffer, 
>                                 size_t size, loff_t *offset)
> {
>       struct my_adc_data *my_data =
>              (struct my_adc_data*) file->private_data;
>       size_t toberead;
>       unsigned int ind;
> 
>       if(size >= BUFFER_SIZE)
>               return 0;
>       if(*offset >= BUFFER_SIZE)
>               return 0;
>       //printk(LOG_LEVEL "[my_read] Trying to read %d bytes\n", size);
>       
>       // first read in the buffer
>       for(ind=0;ind<size;ind++){
>        my_data->buffer[ind]=readw(my_data->ptr+ADCFIFO);
>       }
>       // toberead = (size < my_data->size - *offset) ? size : my_data->size - 
> *offset;
>       if(copy_to_user(user_buffer, my_data->buffer, size))
>               return -EFAULT;
>               
>       return size;
> }
> 
> 
> static int my_write (struct file *file, const char __user * user_buffer,
>                       size_t size, loff_t *offset)
> {
> //        struct my_adc_data *my_adc = (struct my_adc_data*) 
> file->private_data;
>       size_t tobewritten;
> 
>       return tobewritten;
> }
> 
> static int adc_ioctl (struct inode *inode, struct file *file,
>                       unsigned int cmd, unsigned long arg)
> {
>   unsigned int adccfg,adcstat,count,temp;
>   unsigned int retval=0;
>         struct my_adc_data *my_adc = (struct my_adc_data*) file->private_data;
> 
>       switch(cmd) {
>       case ADC_BID_IOCTL:
>               retval=ioread16(my_adc->ptr);
>               break;
>       case ADC_CFG_IOCTL:
>               //printk(LOG_LEVEL "set ADCCFG %d\n",arg);
>               iowrite16(0x167, my_adc->ptr+ADCCFG);
>               //writeb(0x67, my_adc->ptr+ADCCFG+1);
>               break;
>       case ADC_GETCFG_IOCTL:
>               //get by pointer.
>               // cal this from user space 
> ioctl(fd,ADC_GETCFG_IOCTL,&adccfg);uint adccfg;
>               adccfg = ioread16( my_adc->ptr+ADCCFG);
>               retval = put_user(adccfg, (int __user *)arg);
>               //printk(LOG_LEVEL "get ADCCFG W %d\n",adccfg);
>               //printk(LOG_LEVEL "get ADCCFG MSB %d\n",ioread8( my_adc->ptr + 
> ADCCFG ));
>               //printk(LOG_LEVEL "get ADCCFG LSB %d\n",ioread8( my_adc->ptr + 
> ADCCFG+1 ));
>               break;
>       case ADC_DLYLSW_IOCTL:
>               iowrite16(arg, my_adc->ptr + ADC_DLY_LSW);
>               break;
>       case ADC_DLYLSWR_IOCTL:
>               temp =ioread16(my_adc->ptr + ADC_DLY_LSW);
>               retval = __put_user(temp, (int __user *)arg);
>               break;
>       case ADC_DLYMSW_IOCTL:
>               writew(arg, my_adc->ptr + ADC_DLY_MSW);
>               break;
>       case ADC_STAT_IOCTL:
>               writew(arg, my_adc->ptr +  ADCSTAT);
>               break;
>       case ADC_GETSTAT_IOCTL:
>               adcstat=readw(my_adc->ptr +  ADCSTAT);
>               retval = __put_user(adcstat, (int __user *)arg);
>               break;
> 
>       case ADC_DACCFG_IOCTL:
>               //printk(LOG_LEVEL "[my_ioctl] [MY_IOCTL_PRINT] Hello ioctl 
> DDRB SET\n");
>               writew(arg, my_adc->ptr + DACCFG);
>               break;
> 
>       case ADC_DACCMDR_IOCTL:
>               //printk(LOG_LEVEL "[my_ioctl] [MY_IOCTL_PRINT] Hello ioctl 
> DDRB SET\n");
>               retval=readw(my_adc->ptr + DACCMD);
>               break;
>       case ADC_DACCMDRP_IOCTL:
>               //printk(LOG_LEVEL "[my_ioctl] [MY_IOCTL_PRINT] Hello ioctl 
> DDRB SET\n");
>               temp=readw(my_adc->ptr + DACCMD);
>               retval=__put_user(temp, (int __user *)arg);             
>               break;
>       case ADC_DACCMD_IOCTL:
>               //printk(LOG_LEVEL "[my_ioctl] [MY_IOCTL_PRINT] Hello ioctl 
> DDRB SET\n");
>               writew(arg, my_adc->ptr + DACCMD);
>               break;
>       case ADC_DACSTART_IOCTL:
>               writeb((unsigned char)arg, my_adc->ptr + DACCMD+1);
>               break;
> 
>       // count 0-3
>       case ADC_COUNT0_IOCTL:
>               count=readw(my_adc->ptr +  COUNT0);
>               retval = __put_user(count, (int __user *)arg);
>               break;
>       case ADC_COUNT1_IOCTL:
>               count=readw(my_adc->ptr +  COUNT1);
>               retval = __put_user(count, (int __user *)arg);
>               break;
>       case ADC_COUNT2_IOCTL:
>               count=readw( my_adc->ptr +  COUNT2);
>               retval = __put_user(count, (int __user *)arg);
>               break;
>       case ADC_COUNT3_IOCTL:
>               count=readw( my_adc->ptr +  COUNT3);
>               retval = __put_user(count, (int __user *)arg);
>               break;
> 
>       case ADC_DIGIO_IOCTL:
>               writew(arg, my_adc->ptr +  DIGIO);
>               break;
> 
> 
>       }//switch
>     
>       return retval;
> }
> 
> 
> static int my_release (struct inode *inode, struct file *file)
> 
> {
>       //printk(LOG_LEVEL "[my_release] Device released.\n");
>       return 0;
> }
> 
> 
> module_init(my_init);
> module_exit(my_exit);
> 
> 
> 
> adc_drv.h
> 
> #define MY_MAJOR              43 
> #define MY_MINOR              0
> #define MODULE_NAME           "adc"
> 
> #define ISAREGSBASE (0xE8000000)
> #define ISABASE     (0xEE000000)
> #define IOPOFFSET 0x120 // JP1-ON JP2-OFF
>       
> #define ADCCFG                0x02
> #define ADC_DLY_MSW   0x04
> #define ADC_DLY_LSW   0x06
> #define ADCSTAT               0x08
> #define ADCFIFO               0x0A
> #define DACCFG                0x0C
> #define DACCMD                0x0E
> #define COUNT0                0x10
> #define COUNT1                0x12
> #define COUNT2                0x14
> #define COUNT3                0x16
> #define DIGIO         0x18
> 
> 
> #define EXTRIG_BIT 0x09
> #define SEDIF_BIT 0x08
> 
>       
> // isa base + 0x120. JP1=on,JP2=off
> #define ADC_BASE (0xEE000120)
> #define BUFFER_SIZE           512
>       
> //#define BOARD_ID ((volatile char*)(my_data->ptr))
> //#define RO1 ((volatile char*)(my_data->ptr+1))
> 
> #define BOARD_ID 0
> 
> #define ADC_DRV_IOC_MAGIC 141
> 
> #define ADC_CFG_IOCTL         _IOWR (ADC_DRV_IOC_MAGIC, 1, int)
> #define ADC_DLYMSW_IOCTL      _IOW (ADC_DRV_IOC_MAGIC, 2, int)
> #define ADC_DLYLSW_IOCTL      _IOW (ADC_DRV_IOC_MAGIC, 3, int)
> #define ADC_STAT_IOCTL                _IOWR (ADC_DRV_IOC_MAGIC, 4, int)
> #define ADC_FIFO_IOCTL                _IOR (ADC_DRV_IOC_MAGIC, 5, int)
> #define ADC_DACCFG_IOCTL      _IOR (ADC_DRV_IOC_MAGIC, 6, int)
> #define ADC_DACCMD_IOCTL      _IOW (ADC_DRV_IOC_MAGIC, 7, int)
> #define ADC_COUNT0_IOCTL      _IOR (ADC_DRV_IOC_MAGIC, 8, int)
> #define ADC_COUNT1_IOCTL      _IOR (ADC_DRV_IOC_MAGIC, 9, int)
> #define ADC_COUNT2_IOCTL      _IOR (ADC_DRV_IOC_MAGIC, 10, int)
> #define ADC_COUNT3_IOCTL      _IOR (ADC_DRV_IOC_MAGIC, 11, int)
> #define ADC_DIGIO_IOCTL               _IOWR (ADC_DRV_IOC_MAGIC, 12, int)
> #define ADC_BOARD_IOCTL               _IOR (ADC_DRV_IOC_MAGIC, 13, int)
> #define ADC_GETCFG_IOCTL      _IOR (ADC_DRV_IOC_MAGIC, 14, int)
> #define ADC_GETSTAT_IOCTL     _IOR (ADC_DRV_IOC_MAGIC, 15, int)
> #define ADC_BID_IOCTL         _IOR (ADC_DRV_IOC_MAGIC, 16, int)
> #define ADC_DACCMDR_IOCTL     _IOR (ADC_DRV_IOC_MAGIC, 17, int)
> #define ADC_DACCMDRP_IOCTL    _IOR (ADC_DRV_IOC_MAGIC, 18, int)
> #define ADC_DLYLSWR_IOCTL     _IOR (ADC_DRV_IOC_MAGIC, 19, int)
> #define ADC_DACSTART_IOCTL    _IOW (ADC_DRV_IOC_MAGIC, 20, unsigned char)
> #define MY_IRQ1       7
>




------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU