OpenCores
no use no use 1/1 no use no use
PCI DAS, PLX 9052
by sujan5614 on Feb 10, 2013
sujan5614
Posts: 1
Joined: Jan 24, 2013
Last seen: Mar 13, 2013
Platform :: OpenSUSE 11.0 2.6.34
Core :: PLX 9052
Vendor :: ESA

I am working on a project where i am writing a Linux Driver to interface ESA PCI DAS card. I have been able to interface the ADC and get data from it in polled mode, but i am not able to do the same using interrupt.

As per the datasheet of PLX 9052, it is instructed to access the INTCSR register and the CNTRL register to enable the interrupt, I have used the api of resource_start() to get the base address of my local configuration registers, and added offset with it.

ret = pci_request_region(priv_dev->sys_dev,1,"esa_pci_device");

priv_dev->BAR= pci_resource_start(pdev,BADR);
priv_dev->bar_length = pci_resource_len(pdev,BADR);

priv_dev->BAR1= pci_resource_start(pdev,1);
priv_dev->bar_length1 = pci_resource_len(pdev,1);

I have added the offset to this base address using ::
#define COMMAND_INTCSR(a,val) (outl(val, a+0x4c))

COMMAND_INTCSR(priv_dev->BAR1,0Xff); //referred from the datasheet of PLX 9052

This is my private structure:
typedef struct esa_pcidev {
struct kobject mykobj;
struct list_head list;
struct pci_esadas_device *next;
struct cdev cdev;
const char *device_name;
struct pci_dev *sys_dev;
struct device *device;
unsigned int owner;
unsigned long index;
unsigned long int BAR;
unsigned long int bar_length; /* range of mapped I/O port region */
unsigned long int BAR0;
unsigned long int bar_length0; /* range of mapped memory mapped region */
unsigned long int BAR1;
unsigned long int bar_length1; /* range of mapped io mapped region */
unsigned int irq;
wait_queue_head_t read_queue;
struct kfifo read_kfifo;
unsigned char * read_buff;
u16 adc_read;
}ESA_PCI_PRIV;


I have used ioctl methods to get the data from the ADC register.
Here is my ISR

irqreturn_t esa_pci_isr (int irq_no, void *pdev)
{
dump_stack();
u8 bytes;
ESA_PCI_PRIV *priv_dev = (ESA_PCI_PRIV *)pdev;
irqreturn_t irq_r_flag=0;

irq_r_flag |=IRQ_NONE;

/*
gadc_val is a global value, for sending the adc output to the user space using ioctl, value is updated in the ISR
and the same is sent to the user space, hence gadc_val is a global parameter
*/
gadc_val = inb(priv_dev->BAR + DATA_HIGH_REG); //higher byte read
gadc_val = ((priv_dev->adc_read BAR + DATA_LOW_REG)); //lower byte d

bytes = kfifo_in(&priv_dev->read_kfifo,&gadc_val,2);
printk(KERN_INFO "The no. of bytes written to kfifo is %d",bytes);

irq_r_flag |=IRQ_HANDLED;
return irq_r_flag;
}


And here is the ioctl method i ahev defined:
case _ADC_DATA_READ_INTR :
if(wait_event_interruptible(priv_dev->read_queue,(kfifo_len(&priv_dev->read_kfifo))!=0));
return -ERESTARTSYS;
return gadc_val;
break;

When i run my user sapce application, it gets blcoked in my _ADC_DATA_READ_INTR(as seen by using dmesg), it waits for the ISR to update the read_kfifo. So what i could conclude is that my ISR is not getting invoked.

Please guide me on how to solve this problem,
Thanks in advance

no use no use 1/1 no use no use
© copyright 1999-2022 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.