2008-10-17 15:15:09     Registering a GPIO IRQ on the PPI port?

Document created by Aaronwu Employee on Aug 8, 2013
Version 1Show Document
  • View in full screen mode

2008-10-17 15:15:09     Registering a GPIO IRQ on the PPI port?

Frank Van Hooft (CANADA)

Message: 63864   

 

I'm receiving data into the BF537 PPI port using 2 framesyncs (FS1 & FS2) under 2008R1.5. This is all going nicely.

 

However, I also need to monitor the status of the FS2 pin via kernel software. The BF537 permits this - you can read GPIO pins when they're being used as alternate functions simply by setting the appropriate PORTxIO_INEN bit.

 

So in my case I have the PPI port configured as follows:

 

u16 camera_ppi_req[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0,\

     P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, P_PPI0_D6,\

     P_PPI0_D7, P_PPI0_D8, P_PPI0_D9, 0};

 

    if (peripheral_request_list(camera_ppi_req, "Auto_Cam")) {

        printk("Error: peripheral PPI request failed\n");

        return -EFAULT;

    }

 

which works fine and I'm using the PPI port in the normal manner. NOW, what I need to do is configure an interrupt on the FS2 pin, so that when the FS2 pin is high, I get the IRQ & can respond accordingly.

 

On the BF537, PPI FS2 is the GPIO PF8 pin.

 

By some experiments I've proven there's no problem polling the PF8 pin - I can read the PORTFIO data register and see bit 8 (PF8) go high & low while the PPI port is running. As per the BF537-HRM. But in my code I need that as an interrupt - not polling.

 

I tried to register an interrupt handler to PF8 as follows:

 

        if ( request_irq (IRQ_PF8, camera_fs2high_irq, IRQF_TRIGGER_NONE, "PPI-FS2 IRQ", 0) )

            printk("ERROR - unable to register PPI FS2 IRQ handler\n");

 

Note the use of the IRQF_TRIGGER_NONE flag in the above. This produced the following output when run:

 

bfin-gpio: GPIO 8 is already reserved as Peripheral by Auto_Cam !

Hardware Trace:

   0 Target : <0x00003868> { _dump_stack + 0x0 }

     Source : <0x000051a6> { _gpio_request + 0xbe }

   1 Target : <0x000051a6> { _gpio_request + 0xbe }

     Source : <0x0000cd8a> { _printk + 0x16 }

   2 Target : <0x0000cd86> { _printk + 0x12 }

   <snip>

 

 

 

Clearly the kernel is seeing that PF8 is already reserved by the PPI port, and is refusing to allow use of it as a GPIO, even with the TRIGGER_NONE flag.

 

So my question is, how can I do this? The BF537 hardware specifically allows you to read the value of a GPIO pin while it's being used as an alternate function. But the kernel appears to not like this idea at all. At least, not the way I'm doing it. How do I register an IRQ on this pin?

 

Many thanks.

QuoteReplyEditDelete

 

 

2008-10-17 16:12:34     Re: Registering a GPIO IRQ on the PPI port?

Mike Frysinger (UNITED STATES)

Message: 63866   

 

there is no discrepancy between the hardware and software.  the HRM clearly states that you can sense the value of the pin using the GPIO registers (so you can use the gpio get/set functions), but that is different from actually using the pin as both a GPIO and a peripheral simultaneously.  either you us PF8 as a GPIO interrupt source, or you use it as a PPI FS2 peripheral pin.  the hardware does not allow you to do both.

QuoteReplyEditDelete

 

 

2008-10-17 17:46:59     Re: Registering a GPIO IRQ on the PPI port?

Frank Van Hooft (CANADA)

Message: 63870   

 

Perhaps I didn't state what I'm doing clearly enough - it is a little difficult for me to explain.

 

Take the BF537 PPI. The FS2 pin is physically also the PF8 pin.

 

I am using the PPI port, with the FS2 pin configured as a PPI input pin.

 

The BF537-HRM states:

 

When the control bit in the function enable registers (PORTx_FER) is set, the pin is set to its peripheral functionality and is no longer controlled by the GPIO module. However, the GPIO module can still sense the state of the pin.

 

and, when reading the status of the pin in the PORTxIO register...

 

...the returned value reflects the state of the input pin only if the proper input enable bit in the PORTxIO_INEN register is set. Note that GPIOs can still sense the state of the pin when the function enable bits in the PORTx_FER registers are set.

 

So in my case, the FS2 pin is no longer controlled by the GPIO module. However FS2 can still be read by the GPIO module, and the GPIO module can generate interrupts based upon the state of the pin.

 

As I'd mentioned in the original post, I can read the state of the FS2 / PF8 pin. I had previously been doing that by directly reading the PORTFIO register - thanks for the pointer to the gpio_get function.

 

My question is: how to get the kernel to accept an interrupt from the state of the FS2 / PF8 pin?  The hardware *does* allow you to do this, but how to get the kernel to accept it?

 

 

 

I'll confess that I'm doing it now, but in an ugly, hack-ish kind of way which I really hate to admit to. What I've done is remove P_PPI0_FS2 from the camera_ppi_req[] structure. Then I set bit 8 in the PORTF_FER register myself (normally this would be done by the peripheral_request function, but of course I've just removed that pin from its list). In this way FS2 is attached to the PPI port from a BF537 hardware perspective, but the kernel doesn't know about it.

 

Then the request_irq (IRQ_PF8...) works, as does the interrupt handler, etc. Because the kernel believes PF8 is free, it allows it.

 

Note that FS2 *is* functioning as part of the PPI port. That bit in the PORTF_FER register is set. It's just that the kernel is unaware of that, so the kernel allows me to attach an interrupt handler to the state of the pin.

 

Is there a better way? This sure is a teeny weeny bit ugly.   <grin>

 

Many thanks.

QuoteReplyEditDelete

 

 

2008-10-17 18:39:57     Re: Registering a GPIO IRQ on the PPI port?

Mike Frysinger (UNITED STATES)

Message: 63872   

 

the crux of the matter is this statement:

So in my case, the FS2 pin is no longer controlled by the GPIO module. However FS2 can still be read by the GPIO module, and the GPIO module can generate interrupts based upon the state of the pin.

 

where in the HRM do you see this ?  i only see the part where you can read the state of the pin.

 

if what you say is true, there is no way currently in the kernel to do what you want.  your little MMR hackery is your best bet until we extend the relevant frameworks ...

QuoteReplyEditDelete

 

 

2008-10-17 20:01:01     Re: Registering a GPIO IRQ on the PPI port?

Frank Van Hooft (CANADA)

Message: 63876   

 

Thanks Mike. Agreed, it doesn't explicitly say that in the HRM. The HRM describes how the pin can be read. It then goes on to show how GPIO interrupts are generated. Figure 14-5 shows that interrupts diagram, and the diagram shows no particular dependencies upon the PORTx_FER register (for example). So the way I read it, optimistically, the diagram implies that you can generate interrupts.

 

<grin>

 

Anyway, obviously I tried it with my hackery, and it appears to work. Although I'll post here again if I prove myself wrong.

QuoteReplyEditDelete

 

 

2008-11-10 08:55:08     Re: Registering a GPIO IRQ on the PPI port?

Mike Frysinger (UNITED STATES)

Message: 64928   

 

after talking to design, i'm afraid the answer isnt the good one.  it may work, it may not ... there is no guarantee.

QuoteReplyEditDelete

 

 

2008-11-10 10:28:07     Re: Registering a GPIO IRQ on the PPI port?

Frank Van Hooft (CANADA)

Message: 64945   

 

Hi Mike,

 

That's kind that you would go and ask. Although it appears to work (at the moment anyway), I certainly don't like this hackery. Our plan is to run this signal to a free GPIO on the next PCB rev, so then we can generate an interrupt in a more normal manner and this messing around will no longer be required.

 

Thanks!

Attachments

    Outcomes