|
From: | Amit Hergass |
Subject: | [Ltib] RE: P1 interrupt issue |
Date: | Wed, 13 Oct 2010 10:45:52 +1100 |
Hi Kevin, I have implemented the code you
suggested, but still having problems using the interrupts. I have also implemented a
separate ISR for each IRQ the printk its identity. Once the module is inserted, it
complains for not being able to request for two of the IRQs, A3 and B1 "request_irq ZERO A3
Crossing failed! " "request_irq ZERO B1
Crossing failed! " Then it immediately prints the
B2 from the ISR and seems to hang there, and losses the connection to the NFS. Other interrupts are not
received. It clearly looks like the
interrupt still hitting, and should be cleared somehow. Thanks, Amit
retp=request_irq(ZERO_X_INT_A1
,P0_P1_GPIO_ISR1,0,"P0_P1_GPIO_ISR",NULL);
if(retp<0)
printk("request_irq ZERO A1 Crossing failed! \n"); else
lpc32xx_unmask_irq(ZERO_X_INT_A1);
retp=request_irq(ZERO_X_INT_A2
,P0_P1_GPIO_ISR2,0,"P0_P1_GPIO_ISR",NULL);
if(retp<0)
printk("request_irq ZERO A2 Crossing failed! \n"); else
lpc32xx_unmask_irq(ZERO_X_INT_A2); retp=request_irq(ZERO_X_INT_A3
,P0_P1_GPIO_ISR3,0,"P0_P1_GPIO_ISR",NULL);
if(retp<0)
printk("request_irq ZERO A3 Crossing failed! \n"); else
lpc32xx_unmask_irq(ZERO_X_INT_A3);
retp=request_irq(ZERO_X_INT_B1 ,P0_P1_GPIO_ISR4,0,"P0_P1_GPIO_ISR",NULL);
if(retp<0)
printk("request_irq ZERO B1 Crossing failed! \n"); else
lpc32xx_unmask_irq(ZERO_X_INT_B1);
retp=request_irq(ZERO_X_INT_B2
,P0_P1_GPIO_ISR5,0,"P0_P1_GPIO_ISR",NULL);
if(retp<0)
printk("request_irq ZERO B2 Crossing failed! \n"); else
lpc32xx_unmask_irq(ZERO_X_INT_B2);
retp=request_irq(ZERO_X_INT_B3
,P0_P1_GPIO_ISR6,0,"P0_P1_GPIO_ISR",NULL);
if(retp<0)
printk("request_irq ZERO B3 Crossing failed! \n"); else lpc32xx_unmask_irq(ZERO_X_INT_B3); static irqreturn_t
P0_P1_GPIO_ISR1(int irq, void *dummy) {
printk("\nzero x A1 "); return IRQ_HANDLED; } . . . From: Kevin Wells
[mailto:address@hidden Hi Amit, That or’ed P0/P1 interrupt
shouldn’t be used. It should work, but you’ll still need to clear the ‘other’
interrupts that make it work correctly. What’s probably happening is the interrupt is firing and
latching and the OR’d state only fires once because the P0x interrupt that makes one of
it’s OR’ed conditions isn’t clearing. Have you tried just setting the
IRQ type for just the GPIOs you are using and then doing a request_irq for each one
routing them to the same IRQ handler? Each individual interrupt will clear
normally using this approach… So something like this, but with
better error handling..
set_irq_type(ZERO_X_INT_A1 ,IRQ_TYPE_EDGE_FALLING);
set_irq_type(ZERO_X_INT_A2 ,IRQ_TYPE_EDGE_FALLING);
set_irq_type(ZERO_X_INT_A3 ,IRQ_TYPE_EDGE_FALLING);
set_irq_type(ZERO_X_INT_B1 ,IRQ_TYPE_EDGE_FALLING); set_irq_type(ZERO_X_INT_B2 ,IRQ_TYPE_EDGE_FALLING);
set_irq_type(ZERO_X_INT_B3 ,IRQ_TYPE_EDGE_FALLING);
retp=request_irq(ZERO_X_INT_A1 ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL);
retp=request_irq(ZERO_X_INT_A2 ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL); retp=request_irq(ZERO_X_INT_A3 ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL);
retp=request_irq(ZERO_X_INT_B1 ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL);
retp=request_irq(ZERO_X_INT_B2 ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL);
retp=request_irq(ZERO_X_INT_B3 ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL); You could even replace that NULL
argument in request_irq with the GPIO number if you want to know which GPIO
triggered the IRQ in your handler. >
__raw_writel(0xE0000000, P0_INTR_ER_IO ); // Enabling the three first
interrupts only You don’t need to touch
the start enables for normal IRQ usage (this has nothing to do qith IRQs). If you’re
trying to setup automatic system wakeup from suspend with this, this won’t work (without
additional changes to the IRQ driver). Kevin From: Amit Hergass
[mailto:address@hidden Hi Kevin, Thanks for the quick response. I am using kernel 2.6.34. The code is running in a kernel
module. A snippet of the Probe routine
is shown below as well. static irqreturn_t
P0_P1_GPIO_ISR(int irq, void *dummy) { static int blink=0; uint32_t intDef;
blink = 1 - blink;
if (blink == 0) {
//Send Sync pulse
gpio_set_value(DGEM_SYNC_PULSE, (int) 1); }
else {
gpio_set_value(DGEM_SYNC_PULSE, (int) 0); } return
IRQ_HANDLED; } From the module probe routine: static int __devinit
DGM_spi_probe(struct spi_device *spi) { . . #define
ZERO_X_INT_A1
LPC32XX_GPIO(LPC32XX_GPIO_P1_GRP, 23) #define
ZERO_X_INT_A2
LPC32XX_GPIO(LPC32XX_GPIO_P1_GRP, 22) #define
ZERO_X_INT_A3
LPC32XX_GPIO(LPC32XX_GPIO_P1_GRP, 21) #define
ZERO_X_INT_B1
LPC32XX_GPIO(LPC32XX_GPIO_P1_GRP, 20) #define
ZERO_X_INT_B2
LPC32XX_GPIO(LPC32XX_GPIO_P1_GRP,
19) #define
ZERO_X_INT_B3
LPC32XX_GPIO(LPC32XX_GPIO_P1_GRP, 18) #define NPOWER_FAIL
LPC32XX_GPIO(LPC32XX_GPIO_P0_GRP, 5) // #define
DGEM_SYNC_PULSE
LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 18) //Allocate
Interrupts input pins for zero crossing on P1 pins 18-23 if (gpio_request(ZERO_X_INT_A1,
"Meter 1 Zero cross Int"))
printk(KERN_ERR "Error requesting gpio %u", ZERO_X_INT_A1);
else if (gpio_direction_input(ZERO_X_INT_A1))
printk(KERN_ERR "Error setting gpio %u to output",ZERO_X_INT_A1);
if (gpio_request(ZERO_X_INT_A2, "Meter 2 Zero cross Int"))
printk(KERN_ERR "Error requesting gpio %u",ZERO_X_INT_A2);
else if (gpio_direction_input(ZERO_X_INT_A2))
printk(KERN_ERR "Error setting gpio %u to output",ZERO_X_INT_A2); if
(gpio_request(ZERO_X_INT_A3, "Meter 3 Zero cross Int"))
printk(KERN_ERR "Error requesting gpio %u",ZERO_X_INT_A3);
else if (gpio_direction_input(ZERO_X_INT_A3))
printk(KERN_ERR "Error setting gpio %u to output",ZERO_X_INT_A3);
if (gpio_request(ZERO_X_INT_B1,
"Meter 4 Zero cross Int"))
printk(KERN_ERR "Error requesting gpio %u",
ZERO_X_INT_B1);
else if (gpio_direction_input(ZERO_X_INT_B1))
printk(KERN_ERR "Error setting gpio %u to
output", ZERO_X_INT_B1);
if (gpio_request(ZERO_X_INT_B2, "Meter 5 Zero cross Int"))
printk(KERN_ERR "Error requesting gpio %u",
ZERO_X_INT_B2);
else if (gpio_direction_input(ZERO_X_INT_B2))
printk(KERN_ERR "Error setting gpio %u to
output", ZERO_X_INT_B2); if
(gpio_request(ZERO_X_INT_B3, "Meter 6 Zero cross Int"))
printk(KERN_ERR "Error requesting gpio %u",ZERO_X_INT_B3);
else if (gpio_direction_input(ZERO_X_INT_B3))
printk(KERN_ERR "Error setting gpio %u to output",ZERO_X_INT_B3);
if
(gpio_request(NPOWER_FAIL, "Mains power fail Int"))
printk(KERN_ERR "Error requesting gpio %u", NPOWER_FAIL);
else if (gpio_direction_input(NPOWER_FAIL))
printk(KERN_ERR "Error setting gpio %u to output",NPOWER_FAIL); . . . . // set int polarity
of pn pins to rising or falling edge:
set_irq_type(IRQ_P0_P1_IRQ,IRQ_TYPE_EDGE_FALLING); // Enable
ZERO_X_INT from all channels // __raw_writel(0xFC000020,
P0_INTR_ER_IO ); // This is the correct configuration but it does not work
__raw_writel(0xE0000000, P0_INTR_ER_IO ); // Enabling the three first
interrupts only
retp=request_irq(IRQ_P0_P1_IRQ,P0_P1_GPIO_ISR,0,"P0_P1_GPIO_ISR",NULL);
// chapter 5, section 4.3 page 90 bit 8 user manual if(retp<0)
printk("request_irq ZERO Crossing failed! \n"); else
lpc32xx_unmask_irq(IRQ_P0_P1_IRQ); . . } Thanks, Amit From: Kevin Wells
[mailto:address@hidden Hi Amit, Please post or send over the
code snippet for setting up and handling the IRQs. Also, which version of the kernel are
you using? Kevin From: Amit Hergass
[mailto:address@hidden Hi Kevin, I am working on handling six interrupts
sourced by Port-1 pins 18-23. The interrupts are configured as Falling
Edge. The interrupts are generated by a 50% duty
cycle square wave signals on those pins. These signals starts one after the other
and have the same frequency (they never occur at the same time). I can control the generation of these
signals. The interrupt is successfully triggered if
I generate the wave on a single channel (P1.23) , but when I add a wave on
another pin (P1.22), no interrupt triggered at all. I have configured the correct activity type
using “set_irq_type” API, and verified it in the registers. Blow are some of the
registers configuration read from the MCU: Reg Address | Value 40008000 -> 3015a203 40010000 -> 02000100 40008004 -> 00080000 40010004 -> 607b66c4 4000800c -> 3ff0efe0 4001000c -> 821810c0 40008010 -> 00000000 40010010 -> 02000100 40008014 -> c0000000 40010014 -> 00000000 40028138
-> 00ff8000 Thanks, Amit Hergass Senior Software Engineer Genesys Electronics Design Unit 5, 33 Ryde Rd, Pymble NSW 2073, AUSTRALIA Office: +61 2 9496 8925 Mobile: +61 413 667 809 Fax: +61 2 9496 8999 |
[Prev in Thread] | Current Thread | [Next in Thread] |