ltib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Ltib] RE: P1 interrupt issue


From: Kevin Wells
Subject: [Ltib] RE: P1 interrupt issue
Date: Wed, 13 Oct 2010 00:45:44 +0200

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
Sent: Tuesday, October 12, 2010 3:14 PM
To: Kevin Wells; address@hidden
Cc: Peter von Konigsmark
Subject: RE: P1 interrupt issue

 

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
Sent: Wednesday, 13 October 2010 3:18 AM
To: Amit Hergass; address@hidden
Cc: Peter von Konigsmark
Subject: RE: P1 interrupt issue

 

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
Sent: Monday, October 11, 2010 8:08 PM
To: address@hidden; Kevin Wells
Cc: Peter von Konigsmark
Subject: P1 interrupt issue

 

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

 

 

 

 

 

 

 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]