EmbeddedRelated.com
Forums
Memfault Beyond the Launch

GPIO interrupt edge triggering

Started by James Li July 23, 2009
Hi friends,

I have a question regarding "gpio_irq_type" in linux2.6.28 kernel.

I would like to trigger an interrupt on the falling edge of a GPIO pin
(PC3) on at91sam9261ek. I have my own driver ready but it fails when
request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, "myInt",
NULL) is called. However if I changed code to

request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING, "myInt", NULL), the irq is requested successfully.

I checked source code, it failed at gpio_set_type(...).

The following is gpio_irq_type function

static int gpio_irq_type(unsigned pin, unsigned type)

{

switch (type) {

case IRQ_TYPE_NONE:

case IRQ_TYPE_EDGE_BOTH:

return 0;

default:

return -EINVAL;

}

}

It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
IRQF_TRIGGER_FALLING, what should I do?

Thanks a lot,

James
Hai,
can you just make sure that AT91_PIN_PC3 is not used by any other device
etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check if
your request_irq succeeds.
Regards
T.V.R.Prasad

On Thu, Jul 23, 2009 at 10:54 PM, James Li wrote:

> Hi friends,
>
> I have a question regarding gpio_irq_type in linux2.6.28 kernel.
>
> I would like to trigger an interrupt on the falling edge of a GPIO pin
> (PC3) on at91sam9261ek. I have my own driver ready but it fails when
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, myInt,
> NULL) is called. However if I changed code to
>
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
> IRQF_TRIGGER_RISING, myInt, NULL), the irq is requested successfully.
>
> I checked source code, it failed at gpio_set_type().
>
> The following is gpio_irq_type function
>
> static int gpio_irq_type(unsigned pin, unsigned type)
>
> {
>
> switch (type) {
>
> case IRQ_TYPE_NONE:
>
> case IRQ_TYPE_EDGE_BOTH:
>
> return 0;
>
> default:
>
> return -EINVAL;
>
> }
>
> }
>
> It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
> IRQF_TRIGGER_FALLING, what should I do?
>
> Thanks a lot,
>
> James
>
>
Thank you for your reply.

I have tried and it failed since set_irq_type will eventually call
gpio_irq_type because of this

static struct irq_chip gpio_irqchip = {

.name = "GPIO",

.mask = gpio_irq_mask,

.unmask = gpio_irq_unmask,

.set_type = gpio_irq_type,

.set_wake = gpio_irq_set_wake,

};

It seems that ISR (Interrupt Status Register) is set whenever there is
an input change (either rising edge or falling edge) on GPIO pin and if
the corresponding bit in IMR (Interrupt Mask Register) is set, an
interrupt will be triggered.

My workaround is in the interrupt_isr, I read the current GPIO value. If
it is high, meaning rising edge, I ignore the interrupt and if it is
low, meaning falling edge, I process the interrupt.

Any advice?

James

________________________________

From: A... [mailto:A...] On Behalf
Of vishnu Tadepalli
Sent: Thursday, July 23, 2009 5:41 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Hai,
can you just make sure that AT91_PIN_PC3 is not used by any other device
etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check
if your request_irq succeeds.
Regards
T.V.R.Prasad

On Thu, Jul 23, 2009 at 10:54 PM, James Li > wrote:

Hi friends,

I have a question regarding "gpio_irq_type" in linux2.6.28 kernel.

I would like to trigger an interrupt on the falling edge of a GPIO pin
(PC3) on at91sam9261ek. I have my own driver ready but it fails when
request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, "myInt",
NULL) is called. However if I changed code to

request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING, "myInt", NULL), the irq is requested successfully.

I checked source code, it failed at gpio_set_type(...).

The following is gpio_irq_type function

static int gpio_irq_type(unsigned pin, unsigned type)

{

switch (type) {

case IRQ_TYPE_NONE:

case IRQ_TYPE_EDGE_BOTH:

return 0;

default:

return -EINVAL;

}

}

It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
IRQF_TRIGGER_FALLING, what should I do?

Thanks a lot,

James
Your "workaround" is the correct way to do it. There is no way to interrupt
only on the rising or falling edge, just changes, despite some confusing
documentation that might lead you to believe otherwise.

Steve
On Thu, Jul 23, 2009 at 6:02 PM, James Li wrote:

> Thank you for your reply.
>
> I have tried and it failed since set_irq_type will eventually call
> gpio_irq_type because of this
>
> static struct irq_chip gpio_irqchip = {
>
> .name = "GPIO",
>
> .mask = gpio_irq_mask,
>
> .unmask = gpio_irq_unmask,
>
> .set_type = gpio_irq_type,
>
> .set_wake = gpio_irq_set_wake,
>
> };
>
> It seems that ISR (Interrupt Status Register) is set whenever there is an
> input change (either rising edge or falling edge) on GPIO pin and if the
> corresponding bit in IMR (Interrupt Mask Register) is set, an interrupt will
> be triggered.
>
> My workaround is in the interrupt_isr, I read the current GPIO value. If it
> is high, meaning rising edge, I ignore the interrupt and if it is low,
> meaning falling edge, I process the interrupt.
>
> Any advice?
>
> James
> ------------------------------
>
> *From:* A... [mailto:A...] *On
> Behalf Of *vishnu Tadepalli
> *Sent:* Thursday, July 23, 2009 5:41 PM
> *To:* A...
> *Subject:* Re: [AT91SAM] GPIO interrupt edge triggering
>
> Hai,
> can you just make sure that AT91_PIN_PC3 is not used by any other device
> etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check if
> your request_irq succeeds.
> Regards
> T.V.R.Prasad
>
> On Thu, Jul 23, 2009 at 10:54 PM, James Li wrote:
>
> Hi friends,
>
> I have a question regarding gpio_irq_type in linux2.6.28 kernel.
>
> I would like to trigger an interrupt on the falling edge of a GPIO pin
> (PC3) on at91sam9261ek. I have my own driver ready but it fails when
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, myInt,
> NULL) is called. However if I changed code to
>
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
> IRQF_TRIGGER_RISING, myInt, NULL), the irq is requested successfully.
>
> I checked source code, it failed at gpio_set_type().
>
> The following is gpio_irq_type function
>
> static int gpio_irq_type(unsigned pin, unsigned type)
>
> {
>
> switch (type) {
>
> case IRQ_TYPE_NONE:
>
> case IRQ_TYPE_EDGE_BOTH:
>
> return 0;
>
> default:
>
> return -EINVAL;
>
> }
>
> }
>
> It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
> IRQF_TRIGGER_FALLING, what should I do?
>
> Thanks a lot,
>
> James
>
>

--
******************************
Steve Manion
S...@Metrozet.com
(626) 507-8025
(626) 437-6905

WWW.METROZET.COM
******************************
Thanks Steve.

________________________________

From: A... [mailto:A...] On Behalf
Of Stephen Manion
Sent: Thursday, July 23, 2009 9:11 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Your "workaround" is the correct way to do it. There is no way to
interrupt only on the rising or falling edge, just changes, despite some
confusing documentation that might lead you to believe otherwise.

Steve

On Thu, Jul 23, 2009 at 6:02 PM, James Li > wrote:

Thank you for your reply.

I have tried and it failed since set_irq_type will eventually call
gpio_irq_type because of this

static struct irq_chip gpio_irqchip = {

.name = "GPIO",

.mask = gpio_irq_mask,

.unmask = gpio_irq_unmask,

.set_type = gpio_irq_type,

.set_wake = gpio_irq_set_wake,

};

It seems that ISR (Interrupt Status Register) is set whenever there is
an input change (either rising edge or falling edge) on GPIO pin and if
the corresponding bit in IMR (Interrupt Mask Register) is set, an
interrupt will be triggered.

My workaround is in the interrupt_isr, I read the current GPIO value. If
it is high, meaning rising edge, I ignore the interrupt and if it is
low, meaning falling edge, I process the interrupt.

Any advice?

James

________________________________

From: A...
[mailto:A... ] On
Behalf Of vishnu Tadepalli
Sent: Thursday, July 23, 2009 5:41 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Hai,
can you just make sure that AT91_PIN_PC3 is not used by any other device
etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check
if your request_irq succeeds.
Regards
T.V.R.Prasad

On Thu, Jul 23, 2009 at 10:54 PM, James Li > wrote:

Hi friends,

I have a question regarding "gpio_irq_type" in linux2.6.28 kernel.

I would like to trigger an interrupt on the falling edge of a GPIO pin
(PC3) on at91sam9261ek. I have my own driver ready but it fails when
request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, "myInt",
NULL) is called. However if I changed code to

request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING, "myInt", NULL), the irq is requested successfully.

I checked source code, it failed at gpio_set_type(...).

The following is gpio_irq_type function

static int gpio_irq_type(unsigned pin, unsigned type)

{

switch (type) {

case IRQ_TYPE_NONE:

case IRQ_TYPE_EDGE_BOTH:

return 0;

default:

return -EINVAL;

}

}

It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
IRQF_TRIGGER_FALLING, what should I do?

Thanks a lot,

James

--
******************************
Steve Manion
S...@Metrozet.com
(626) 507-8025
(626) 437-6905

WWW.METROZET.COM
******************************
Hi ,

I was just going through the AT91SAM9260 datasheet.The PIO user interface
doesn't provide an option on configuring the type of interrupt.

As there is nothing in the hardware giving you that option there is nothing
the linux kernel can do about it.

A PIO on AT91SAM9260 can be configured as interrupt but its polarity,edge
cannot be configured.
Regards
T.V.R.Prasad

On Fri, Jul 24, 2009 at 10:02 PM, James Li wrote:

> Thanks Steve.
> ------------------------------
>
> *From:* A... [mailto:A...] *On
> Behalf Of *Stephen Manion
> *Sent:* Thursday, July 23, 2009 9:11 PM
>
> *To:* A...
> *Subject:* Re: [AT91SAM] GPIO interrupt edge triggering
>
> Your "workaround" is the correct way to do it. There is no way to
> interrupt only on the rising or falling edge, just changes, despite some
> confusing documentation that might lead you to believe otherwise.
>
> Steve
>
> On Thu, Jul 23, 2009 at 6:02 PM, James Li wrote:
>
> Thank you for your reply.
>
> I have tried and it failed since set_irq_type will eventually call
> gpio_irq_type because of this
>
> static struct irq_chip gpio_irqchip = {
>
> .name = "GPIO",
>
> .mask = gpio_irq_mask,
>
> .unmask = gpio_irq_unmask,
>
> .set_type = gpio_irq_type,
>
> .set_wake = gpio_irq_set_wake,
>
> };
>
> It seems that ISR (Interrupt Status Register) is set whenever there is an
> input change (either rising edge or falling edge) on GPIO pin and if the
> corresponding bit in IMR (Interrupt Mask Register) is set, an interrupt will
> be triggered.
>
> My workaround is in the interrupt_isr, I read the current GPIO value. If it
> is high, meaning rising edge, I ignore the interrupt and if it is low,
> meaning falling edge, I process the interrupt.
>
> Any advice?
>
> James
> ------------------------------
>
> *From:* A... [mailto:A...] *On
> Behalf Of *vishnu Tadepalli
> *Sent:* Thursday, July 23, 2009 5:41 PM
> *To:* A...
> *Subject:* Re: [AT91SAM] GPIO interrupt edge triggering
>
> Hai,
> can you just make sure that AT91_PIN_PC3 is not used by any other device
> etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check if
> your request_irq succeeds.
> Regards
> T.V.R.Prasad
>
> On Thu, Jul 23, 2009 at 10:54 PM, James Li wrote:
>
> Hi friends,
>
> I have a question regarding gpio_irq_type in linux2.6.28 kernel.
>
> I would like to trigger an interrupt on the falling edge of a GPIO pin
> (PC3) on at91sam9261ek. I have my own driver ready but it fails when
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, myInt,
> NULL) is called. However if I changed code to
>
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
> IRQF_TRIGGER_RISING, myInt, NULL), the irq is requested successfully.
>
> I checked source code, it failed at gpio_set_type().
>
> The following is gpio_irq_type function
>
> static int gpio_irq_type(unsigned pin, unsigned type)
>
> {
>
> switch (type) {
>
> case IRQ_TYPE_NONE:
>
> case IRQ_TYPE_EDGE_BOTH:
>
> return 0;
>
> default:
>
> return -EINVAL;
>
> }
>
> }
>
> It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
> IRQF_TRIGGER_FALLING, what should I do?
>
> Thanks a lot,
>
> James
> --
> ******************************
> Steve Manion
> S...@Metrozet.com
> (626) 507-8025
> (626) 437-6905
>
> WWW.METROZET.COM
> ******************************
>
>
Yes. That's what I figured out two.

But I have another question regarding PIO_ISR.

On page 328 of at81sam9261 datasheet, it says that when an input change
is detected on an I/O line, the corresponding bit in PIO_ISR (Interrupt
Status Register) is set.

My question is if my GPIO pin is configured as a general purpose pin,
does the processor still detect the input change and update PIO_ISR?

The reason I am asking this question is that I am working on a driver
interfacing a Credit Card Controller (CCC). The interface between
processor and CCC is just two wires. One is the STROBE and the other is
DATA. The STROBE is input to the CCC and is controlled as a GPIO pin.
However DATA has several usages. When resetting the CCC, processor
configures DATA as GPIO output and sends a predefined pattern of 1s and
0s to reset the CCC. After that, DATA should be configured as input,
waiting for the interrupts from CCC. The first falling edge interrupt is
Card Present and the second edge interrupt is Data Ready. When the
processor receives Data Ready, it will configure DATA line to GPIO input
and read serial data on it from CCC.

In my _init function, I do the following:

static int __init ccr_init(void)

{

...

at91_set_GPIO_periph(CCR_DATA, 1);

ccr_reset();

at91_set_B_periph(CCR_DATA, 1);

request_irq(CCR_DATA, ccr_interrupt, IRQ_TYPE_EDGE_BOTH,
"ccr", NULL);

...

}

Then right away the interrupt_isr is called just when request_irq() is
called since an input change is detected by the processor. But I
couldn't understand why the processor detects the input change when the
interrupt is not enabled yet?

Could someone clarify it?

Thanks,

James

________________________________

From: A... [mailto:A...] On Behalf
Of vishnu Tadepalli
Sent: Friday, July 24, 2009 9:48 AM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Hi ,

I was just going through the AT91SAM9260 datasheet.The PIO user
interface doesn't provide an option on configuring the type of
interrupt.

As there is nothing in the hardware giving you that option there is
nothing the linux kernel can do about it.

A PIO on AT91SAM9260 can be configured as interrupt but its
polarity,edge cannot be configured.
Regards
T.V.R.Prasad

On Fri, Jul 24, 2009 at 10:02 PM, James Li > wrote:

Thanks Steve.

________________________________

From: A...
[mailto:A... ] On
Behalf Of Stephen Manion
Sent: Thursday, July 23, 2009 9:11 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Your "workaround" is the correct way to do it. There is no way to
interrupt only on the rising or falling edge, just changes, despite some
confusing documentation that might lead you to believe otherwise.

Steve

On Thu, Jul 23, 2009 at 6:02 PM, James Li > wrote:

Thank you for your reply.

I have tried and it failed since set_irq_type will eventually call
gpio_irq_type because of this

static struct irq_chip gpio_irqchip = {

.name = "GPIO",

.mask = gpio_irq_mask,

.unmask = gpio_irq_unmask,

.set_type = gpio_irq_type,

.set_wake = gpio_irq_set_wake,

};

It seems that ISR (Interrupt Status Register) is set whenever there is
an input change (either rising edge or falling edge) on GPIO pin and if
the corresponding bit in IMR (Interrupt Mask Register) is set, an
interrupt will be triggered.

My workaround is in the interrupt_isr, I read the current GPIO value. If
it is high, meaning rising edge, I ignore the interrupt and if it is
low, meaning falling edge, I process the interrupt.

Any advice?

James

________________________________

From: A...
[mailto:A... ] On
Behalf Of vishnu Tadepalli
Sent: Thursday, July 23, 2009 5:41 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Hai,
can you just make sure that AT91_PIN_PC3 is not used by any other device
etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check
if your request_irq succeeds.
Regards
T.V.R.Prasad

On Thu, Jul 23, 2009 at 10:54 PM, James Li > wrote:

Hi friends,

I have a question regarding "gpio_irq_type" in linux2.6.28 kernel.

I would like to trigger an interrupt on the falling edge of a GPIO pin
(PC3) on at91sam9261ek. I have my own driver ready but it fails when
request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, "myInt",
NULL) is called. However if I changed code to

request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING, "myInt", NULL), the irq is requested successfully.

I checked source code, it failed at gpio_set_type(...).

The following is gpio_irq_type function

static int gpio_irq_type(unsigned pin, unsigned type)

{

switch (type) {

case IRQ_TYPE_NONE:

case IRQ_TYPE_EDGE_BOTH:

return 0;

default:

return -EINVAL;

}

}

It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
IRQF_TRIGGER_FALLING, what should I do?

Thanks a lot,

James

--
******************************
Steve Manion
S...@Metrozet.com
(626) 507-8025
(626) 437-6905

WWW.METROZET.COM
******************************
James,

Looks like you are trying to implement the ISO 7816 protocol,is it correct?

Look at Atmel website where you can download the ISO7816 source code and the
corresponding application note,which should be helpful for you.
I have also implemented the ISO 7816 on an ARM7,but the protocol is very
time sensitive so I used the FIQ in ARM to keep track of the time a bit is
to be read.The interrupt latency in linux can sometimes be in the tune of
hundreds of microseconds.
Regards
T.V.R.Prasad

On Sat, Jul 25, 2009 at 3:16 AM, James Li wrote:

> Yes. Thats what I figured out two.
>
> But I have another question regarding PIO_ISR.
>
> On page 328 of at81sam9261 datasheet, it says that when an input change is
> detected on an I/O line, the corresponding bit in PIO_ISR (Interrupt Status
> Register) is set.
>
> My question is if my GPIO pin is configured as a general purpose pin, does
> the processor still detect the input change and update PIO_ISR?
>
> The reason I am asking this question is that I am working on a driver
> interfacing a Credit Card Controller (CCC). The interface between processor
> and CCC is just two wires. One is the STROBE and the other is DATA. The
> STROBE is input to the CCC and is controlled as a GPIO pin. However DATA has
> several usages. When resetting the CCC, processor configures DATA as GPIO
> output and sends a predefined pattern of 1s and 0s to reset the CCC. After
> that, DATA should be configured as input, waiting for the interrupts from
> CCC. The first falling edge interrupt is Card Present and the second edge
> interrupt is Data Ready. When the processor receives Data Ready, it will
> configure DATA line to GPIO input and read serial data on it from CCC.
>
> In my _*init function, I do the following:*
>
> *static int __init ccr_init(void)*
>
> *{*
>
> * *
>
> * at91_set_GPIO_periph(CCR_DATA, 1);*
>
> * ccr_reset();*
>
> * at91_set_B_periph(CCR_DATA, 1);*
>
> * request_irq(CCR_DATA, ccr_interrupt, IRQ_TYPE_EDGE_BOTH,
> "ccr", NULL);*
>
> * *
>
> *}*
>
> * *
>
> Then right away the interrupt_isr is called just when request_irq() is
> called since an input change is detected by the processor. But I couldnt
> understand why the processor detects the input change when the interrupt is
> not enabled yet?
>
> Could someone clarify it?
>
> Thanks,
>
> James
> ------------------------------
>
> *From:* A... [mailto:A...] *On
> Behalf Of *vishnu Tadepalli
> *Sent:* Friday, July 24, 2009 9:48 AM
>
> *To:* A...
> *Subject:* Re: [AT91SAM] GPIO interrupt edge triggering
>
> Hi ,
>
> I was just going through the AT91SAM9260 datasheet.The PIO user interface
> doesn't provide an option on configuring the type of interrupt.
>
> As there is nothing in the hardware giving you that option there is nothing
> the linux kernel can do about it.
>
> A PIO on AT91SAM9260 can be configured as interrupt but its polarity,edge
> cannot be configured.
> Regards
> T.V.R.Prasad
>
> On Fri, Jul 24, 2009 at 10:02 PM, James Li wrote:
>
> Thanks Steve.
> ------------------------------
>
> *From:* A... [mailto:A...] *On
> Behalf Of *Stephen Manion
> *Sent:* Thursday, July 23, 2009 9:11 PM
> *To:* A...
> *Subject:* Re: [AT91SAM] GPIO interrupt edge triggering
>
> Your "workaround" is the correct way to do it. There is no way to
> interrupt only on the rising or falling edge, just changes, despite some
> confusing documentation that might lead you to believe otherwise.
>
> Steve
>
> On Thu, Jul 23, 2009 at 6:02 PM, James Li wrote:
>
> Thank you for your reply.
>
> I have tried and it failed since set_irq_type will eventually call
> gpio_irq_type because of this
>
> static struct irq_chip gpio_irqchip = {
>
> .name = "GPIO",
>
> .mask = gpio_irq_mask,
>
> .unmask = gpio_irq_unmask,
>
> .set_type = gpio_irq_type,
>
> .set_wake = gpio_irq_set_wake,
>
> };
>
> It seems that ISR (Interrupt Status Register) is set whenever there is an
> input change (either rising edge or falling edge) on GPIO pin and if the
> corresponding bit in IMR (Interrupt Mask Register) is set, an interrupt will
> be triggered.
>
> My workaround is in the interrupt_isr, I read the current GPIO value. If it
> is high, meaning rising edge, I ignore the interrupt and if it is low,
> meaning falling edge, I process the interrupt.
>
> Any advice?
>
> James
> ------------------------------
>
> *From:* A... [mailto:A...] *On
> Behalf Of *vishnu Tadepalli
> *Sent:* Thursday, July 23, 2009 5:41 PM
> *To:* A...
> *Subject:* Re: [AT91SAM] GPIO interrupt edge triggering
>
> Hai,
> can you just make sure that AT91_PIN_PC3 is not used by any other device
> etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check if
> your request_irq succeeds.
> Regards
> T.V.R.Prasad
>
> On Thu, Jul 23, 2009 at 10:54 PM, James Li wrote:
>
> Hi friends,
>
> I have a question regarding gpio_irq_type in linux2.6.28 kernel.
>
> I would like to trigger an interrupt on the falling edge of a GPIO pin
> (PC3) on at91sam9261ek. I have my own driver ready but it fails when
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, myInt,
> NULL) is called. However if I changed code to
>
> request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
> IRQF_TRIGGER_RISING, myInt, NULL), the irq is requested successfully.
>
> I checked source code, it failed at gpio_set_type().
>
> The following is gpio_irq_type function
>
> static int gpio_irq_type(unsigned pin, unsigned type)
>
> {
>
> switch (type) {
>
> case IRQ_TYPE_NONE:
>
> case IRQ_TYPE_EDGE_BOTH:
>
> return 0;
>
> default:
>
> return -EINVAL;
>
> }
>
> }
>
> It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
> IRQF_TRIGGER_FALLING, what should I do?
>
> Thanks a lot,
>
> James
> --
> ******************************
> Steve Manion
> S...@Metrozet.com
> (626) 507-8025
> (626) 437-6905
>
> WWW.METROZET.COM
> ******************************
>
>
Thank you very much Prasad.

I am actually implementing ISO 7811 protocol. I have done it on the
PXA320 WinCE based product and it worked fine. Now I am porting it to
at91sam9261 Linux based product. This new credit card controller has a
local buffer to store the data. So when it finishes reading the data, it
will generate an interrupt to the processor and the processor will
retrieve the data from CCR. The previous one I used before did not have
a local buffer. Therefore all the data has to be retrieved one bit at a
time and it was really time sensitive.

Thanks again for your help,

James

________________________________

From: A... [mailto:A...] On Behalf
Of vishnu Tadepalli
Sent: Friday, July 24, 2009 5:27 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

James,

Looks like you are trying to implement the ISO 7816 protocol,is it
correct?

Look at Atmel website where you can download the ISO7816 source code and
the corresponding application note,which should be helpful for you.
I have also implemented the ISO 7816 on an ARM7,but the protocol is very
time sensitive so I used the FIQ in ARM to keep track of the time a bit
is to be read.The interrupt latency in linux can sometimes be in the
tune of hundreds of microseconds.
Regards
T.V.R.Prasad

On Sat, Jul 25, 2009 at 3:16 AM, James Li > wrote:

Yes. That's what I figured out two.

But I have another question regarding PIO_ISR.

On page 328 of at81sam9261 datasheet, it says that when an input change
is detected on an I/O line, the corresponding bit in PIO_ISR (Interrupt
Status Register) is set.

My question is if my GPIO pin is configured as a general purpose pin,
does the processor still detect the input change and update PIO_ISR?

The reason I am asking this question is that I am working on a driver
interfacing a Credit Card Controller (CCC). The interface between
processor and CCC is just two wires. One is the STROBE and the other is
DATA. The STROBE is input to the CCC and is controlled as a GPIO pin.
However DATA has several usages. When resetting the CCC, processor
configures DATA as GPIO output and sends a predefined pattern of 1s and
0s to reset the CCC. After that, DATA should be configured as input,
waiting for the interrupts from CCC. The first falling edge interrupt is
Card Present and the second edge interrupt is Data Ready. When the
processor receives Data Ready, it will configure DATA line to GPIO input
and read serial data on it from CCC.

In my _init function, I do the following:

static int __init ccr_init(void)

{

...

at91_set_GPIO_periph(CCR_DATA, 1);

ccr_reset();

at91_set_B_periph(CCR_DATA, 1);

request_irq(CCR_DATA, ccr_interrupt, IRQ_TYPE_EDGE_BOTH,
"ccr", NULL);

...

}

Then right away the interrupt_isr is called just when request_irq() is
called since an input change is detected by the processor. But I
couldn't understand why the processor detects the input change when the
interrupt is not enabled yet?

Could someone clarify it?

Thanks,

James

________________________________

From: A...
[mailto:A... ] On
Behalf Of vishnu Tadepalli
Sent: Friday, July 24, 2009 9:48 AM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Hi ,

I was just going through the AT91SAM9260 datasheet.The PIO user
interface doesn't provide an option on configuring the type of
interrupt.

As there is nothing in the hardware giving you that option there is
nothing the linux kernel can do about it.

A PIO on AT91SAM9260 can be configured as interrupt but its
polarity,edge cannot be configured.
Regards
T.V.R.Prasad

On Fri, Jul 24, 2009 at 10:02 PM, James Li > wrote:

Thanks Steve.

________________________________

From: A...
[mailto:A... ] On
Behalf Of Stephen Manion
Sent: Thursday, July 23, 2009 9:11 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Your "workaround" is the correct way to do it. There is no way to
interrupt only on the rising or falling edge, just changes, despite some
confusing documentation that might lead you to believe otherwise.

Steve

On Thu, Jul 23, 2009 at 6:02 PM, James Li > wrote:

Thank you for your reply.

I have tried and it failed since set_irq_type will eventually call
gpio_irq_type because of this

static struct irq_chip gpio_irqchip = {

.name = "GPIO",

.mask = gpio_irq_mask,

.unmask = gpio_irq_unmask,

.set_type = gpio_irq_type,

.set_wake = gpio_irq_set_wake,

};

It seems that ISR (Interrupt Status Register) is set whenever there is
an input change (either rising edge or falling edge) on GPIO pin and if
the corresponding bit in IMR (Interrupt Mask Register) is set, an
interrupt will be triggered.

My workaround is in the interrupt_isr, I read the current GPIO value. If
it is high, meaning rising edge, I ignore the interrupt and if it is
low, meaning falling edge, I process the interrupt.

Any advice?

James

________________________________

From: A...
[mailto:A... ] On
Behalf Of vishnu Tadepalli
Sent: Thursday, July 23, 2009 5:41 PM
To: A...
Subject: Re: [AT91SAM] GPIO interrupt edge triggering

Hai,
can you just make sure that AT91_PIN_PC3 is not used by any other device
etc.Also just call set_irq_type(irqnum,IRQF_TRIGGER_FALLING) and check
if your request_irq succeeds.
Regards
T.V.R.Prasad

On Thu, Jul 23, 2009 at 10:54 PM, James Li > wrote:

Hi friends,

I have a question regarding "gpio_irq_type" in linux2.6.28 kernel.

I would like to trigger an interrupt on the falling edge of a GPIO pin
(PC3) on at91sam9261ek. I have my own driver ready but it fails when
request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING, "myInt",
NULL) is called. However if I changed code to

request_irq(AT91_PIN_PC3, interrupt_isr, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING, "myInt", NULL), the irq is requested successfully.

I checked source code, it failed at gpio_set_type(...).

The following is gpio_irq_type function

static int gpio_irq_type(unsigned pin, unsigned type)

{

switch (type) {

case IRQ_TYPE_NONE:

case IRQ_TYPE_EDGE_BOTH:

return 0;

default:

return -EINVAL;

}

}

It only allows IRQ_TYPE_NONE and IRQ_TYPE_EDGE_BOTH. But if I want only
IRQF_TRIGGER_FALLING, what should I do?

Thanks a lot,

James

--
******************************
Steve Manion
S...@Metrozet.com
(626) 507-8025
(626) 437-6905

WWW.METROZET.COM
******************************

Memfault Beyond the Launch