FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6359 Discussions

PIO Interrupts PCIe

Altera_Forum
Honored Contributor II
1,540 Views

Hello, 

 

i'm a student from germany and new in this forum. I have found many answers to my questions, but i stuck on a problem. 

 

i have the 

 

Cyclone IV GX Transceiver Starter Kit  

 

 

and i'm trying to implement some simple PCIe Designs first, to get close with the PCIe and Driver writing stuff. I have implemented an PIO ( Output ) for the four LEDs on the Board and write a little Driver to access the LEDs, that worked fine. Next i integrated an PIO ( INPUT ) for the two switches on board. In the SOPC Builder i select "Synchronously Capture - Falling Edge - Enable bit-clearing for edge capture register" and "Generate IRQ - Edge", so i think i'm getting an IRQ on every switch push ( LOW Active ). I connected the irq line with the RxmIrq of the PCIe Compiler. 

 

My driver requests the Interrupt (request_irq as IRQF_SHARED) and is connected to a small IRQ Handler, which only counts the IRQs and returns IRQ_HANDLED, is see in /proc/interrupts my drivername. But there always stand 0, so no Interrupt comes across, and my Counter also not increments, so i think there really comes no IRQ. 

 

On the FPGA i set the AVL_IRQ Bit in the CRA ( 0x50) to activate the IRQs. 

 

In the description of the PIO there are some registers (interruptmask), to activate the IRQ to the corresponding bit, but if i write to this register i only read 0s back, so i think i can't access this Register. Perhaps its just because the SOPC Builder hard wired these Bits? I looked in the PIO VHDL File generated by SOPC an on reset the mask is written to "00". I changed it to "11", so IRQs are default activated. If i do, i press a button and get many Interrupts. It seems that i must clear a bit in the edgecapture register, but it doesn't work. The interrupts still comes across. Only clearing the AVL_IRQ bit stops the flood of IRQs. 

 

But i think there is another problem with my design, because this can't be the solution? I can read out the data register from my PIO and there always are the right values. But the other registers doesn't exists? Is there another options i must probably turn on in SOPC builder?  

 

 

I also have a question of the register width. In the Datasheet stands the register length 1 to (n-1), does this mean every register has a width of ( in my Example) 2 bits or only the first? In the description stands " controlled by four 32 bit registers ", but it seems there are six registers? I'm a little confused :confused:  

 

 

Thanks for reading, 

ringo 

 

Ps: Sorry for my horrible english :oops:
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
457 Views

Hi ringo, 

 

a lot of questions from your side. I will try to give you some answers. First of all you can take a look in the documentation of the PIO Core which is part of the "Embedded peripherals user guide". I extracted the PIO Core so you don´t have to work through the whole documentation. On Page 9-6 you will find the registermap of the PIO Core and which of them are R/W. 

With "Enable bit-clearing for edge capture register" your handling of the interrupt is clear. If you generate an Interrupt i.e. on Input two, you have to clear the edge capture bit by writing 0x02 to the edgecapture register. 

I hope this helps you out a little bit! 

 

JacoL
0 Kudos
Altera_Forum
Honored Contributor II
457 Views

Hi JacoL, 

 

thanks for your reply! Thanks for your PIO Core PDF, but i already looked into the "Embedded peripherals user guide" and thought i understand everything. I know that i must clear the bit by writing to them. My Problem is where is the register? Because my PIO have a width of 2 bit, but in documentation there stands 32bit? 

 

"An Avalon-MM master peripheral, such as a CPU, controls and communicates with 

the PIO core via the four 32-bit registers, shown in Table 9–2. The table assumes that 

the PIO core's I/O ports are configured to a width of n bits." 

 

So for example my PIO is on adress 0x4000. 

 

interruptmask is on 0x4008 

edgecapture is on 0x400C 

 

In Table 9-2 in looks like the register only have the width of 2 in my example. I think that's my main understanding problem.  

 

Thanks,  

ringo 

 

Ps: JacoL are you german?
0 Kudos
Altera_Forum
Honored Contributor II
457 Views

Hi again, 

 

ah ok. The registers are always 32 bits wide. You have a problem with the comment "n-1" in the register map. In your case you only use the two least significant bits of each register. The 30 most significant bits are not used if you define only two inputs in sopc. But they are also present. The Address map will not change. If you take a look on the PIO Core pdf again you will find the line "Each PIO core can provide up to 32 I/O ports." 

So if you define 32 Inputs in the SOPC, all bits of the register are used. Which of the 6 registers are necessary for you and must be handeled in software is depending on your settings. (i.e. "Enable bit-clearing for edge capture register")
0 Kudos
Altera_Forum
Honored Contributor II
457 Views

Hi Ringo 97, 

 

Can we share together. I am also student from gemany and have to deal with Altera Cyclone IV GX. 

So have you solve this pb with PIO?  

 

Regards,
0 Kudos
Altera_Forum
Honored Contributor II
457 Views

Hello alterahenry, 

 

yeah write me a PM with your icq number, i can't send because i have not so many posts. 

 

I havn't fixed the PIO Problem. I think i can't access the register to control the PIO interrupt stuff. Writing to edgecapture or interruptmask has no effect. Reading back always returns zeros. I'm currently working on another project but i think next week i make a new design. Is there a cleanup function to delete all files generated from SOPC Builder? I didn't find one.  

 

Greetings 

ringo
0 Kudos
Altera_Forum
Honored Contributor II
457 Views

Hello, 

 

me again. 

 

I made a new Design with PCIe + PIO. This time i configured the PIO as Bidirectional (tristate) ports. I tried to write the direction register in the PIO regiser map but when i read back i always read zeros and the IO are still Inputs. It seems i can't access the registers, only the data register works. I'm clueless. 

 

Here my codesnippets from the driver: arg = 0xf; 

 

unsigned long adr; adr = (unsigned long) device->baseAdress; // Base adress of PCI MEMRegion adr += (unsigned long)device->startAdress; // Start Adress PIO adr += (unsigned long)4; // second 32Bit Register printk(KERN_DEBUG "Schreibe %8lx an %8lx \n", arg, adr); iowrite32(arg,(void*)(adr)); wmb(); ret = ioread32((void*)(adr)); printk(KERN_DEBUG "PIO_DIR AFTER : %8lx \n", ret); and here the output: 

 

--- Quote Start ---  

 

[ 4062.810750] Schreibe 7 an f88c4044  

[ 4062.810757] PIO_DIR AFTER : 0  

 

--- Quote End ---  

any idea?  

 

Thanks for reading.
0 Kudos
Altera_Forum
Honored Contributor II
457 Views

Hello Ringo87, 

 

 

I am also have the same problem, but instead of PIO I'm using one timer to generate the interruptions. I just can read and write on one register and i can't see any interruptions on PC side. 

so have you solve this problem with PIO ? 

 

Best regards 

L.Lessa
0 Kudos
Reply