UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer fd9750
Observer
7,932 Views
Registered: ‎06-13-2014

Question on Polling a Gpio pin

Jump to solution

Hi,

 

I have a few bits of code running on a mircozed board that I use to

 

    a) set up gpio pin 0  to trigger  interrupts on a rising edge.

    b) monitor the condition of gpio0 using the linux poll function.

    c) when the interrupt occurs: do something and wait till the next interrupt occurs.

 

This is the code to set up the gpio pin:

 

static int GpioPin = FPGA_GPIO_PIN;
static int GpioFileDescriptor=0;
static int PollResult;
static int poll_nr_fds = 1;
static struct pollfd GpioPoll[1];

int AllocateGpio( void )
{
   char buf[MAX_GPIO_BUF];

   if ( gpio_export ( GpioPin ) < 0 )
   {
      GpioPin = -1;
      return ( -1 );
   }
   else
   {
      gpio_set_dir( GpioPin, GpioInput );                // set as input
      gpio_set_edge( GpioPin, "rising" );                // set as rising edge interrupt
      GpioFileDescriptor = gpio_fd_open( GpioPin );      // open the GPIO "file"
      if ( GpioFileDescriptor < 0 )
      {
         GpioFileDescriptor = 0;
         return ( -1 );
      }
      else
      {
         memset( (void*)GpioPoll, 0, sizeof( GpioPoll ) );  // erase the poll structure
         GpioPoll[0].fd = GpioFileDescriptor;               // setup the poll structure (file descriptor)
         GpioPoll[0].events = POLLPRI;                      // setup the poll structure (event flags)
         read( GpioPoll[0].fd, buf, MAX_GPIO_BUF);          // initial read to prevent false interrupt report
      }
   }
   return ( 0 );
}

 

That bit of code is called once and works just fine. I have checked the cretaed "files" using the command shell and everything works.

 

This is the bit of code I use to monitor the condition and wait for an interrupt to occur:

 

int GpioWaitForInterrupt( void )
{
   int timeout = GPIO_POLL_TIMEOUT;
   char buf[MAX_GPIO_BUF];

   read( GpioPoll[0].fd, buf, MAX_GPIO_BUF);                      // read again to clear pending interrupt report
   NetworkScanTrigger = OFF;                                      // clear to prevent pending trigger
   while ( !sInterupted )
   {
      if ( (GpioPin >= 0) && GpioFileDescriptor )
      {
         PollResult = poll( GpioPoll, poll_nr_fds, timeout );
         if (PollResult < 0 ) return (GPIO_WAIT_ERROR);
         if (!PollResult)
         { // timeout !
            if (NetworkScanTrigger)    // trigger via network ?
            {
               NetworkScanTrigger = OFF;
               return ( GPIO_WAIT_TRIGGER );
            }
         }
         else
         {
            if (GpioPoll[0].revents & POLLPRI)     // check for interrupt
            {
               read( GpioPoll[0].fd, buf, MAX_GPIO_BUF);          // read again to clear interrupt report
               return ( GPIO_WAIT_END);
            }
         }
      }
      else
      {
         return (GPIO_WAIT_ERROR);
      }
   }
   return (GPIO_WAIT_STOP);
}

 The problem I have is that the first time I call the second bit of code it correctly waits for the interrupt to occur, returns GPIO_WAIT_END so that I know the exit cause is an interrupt and I can do whatever is necessary.

When I call the wait function again it exits with the same return value although I am sure there was no edge signal change on that input in the mean time.

 

Originally I always had an initial interrupt after setting up the gpio pin but I cured that by adding a "read" function to prevent it from happening. I thought the extra "read" functions Would prevent spurious or false interrupts but it seems I am missing something as once the first interrupt occurs I keep getting them continuously while the gpio pin never changes again.

 

Anyone have any suggestions or ideas as to what I am doing wrong ?

 

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
Xilinx Employee
Xilinx Employee
13,394 Views
Registered: ‎09-10-2008

Re: Question on Polling a Gpio pin

Jump to solution

Hi,

 

I can't say I've done what you're trying to do, but was interested in it. I didn't see you doing this below but I might have missed it.

 

Have you reviewed https://www.kernel.org/doc/Documentation/gpio/sysfs.txt as it shows the need to seek or close and reopen the file after an event?

 

Thanks

John

 

After
		poll(2) returns, either lseek(2) to the beginning of the sysfs
		file and read the new value or close the file and re-open it
		to read the value.
0 Kudos
3 Replies
Xilinx Employee
Xilinx Employee
13,395 Views
Registered: ‎09-10-2008

Re: Question on Polling a Gpio pin

Jump to solution

Hi,

 

I can't say I've done what you're trying to do, but was interested in it. I didn't see you doing this below but I might have missed it.

 

Have you reviewed https://www.kernel.org/doc/Documentation/gpio/sysfs.txt as it shows the need to seek or close and reopen the file after an event?

 

Thanks

John

 

After
		poll(2) returns, either lseek(2) to the beginning of the sysfs
		file and read the new value or close the file and re-open it
		to read the value.
0 Kudos
Observer fd9750
Observer
7,918 Views
Registered: ‎06-13-2014

Re: Question on Polling a Gpio pin

Jump to solution

Hi,

 

I am definitely not doing the lseek anywhere so that looks very promising. It might expalin why the initial read works while the others don't . I will try it tomorrow morning and post any results I find.

 

Thanks a lot.

0 Kudos
Observer fd9750
Observer
7,899 Views
Registered: ‎06-13-2014

Re: Question on Polling a Gpio pin

Jump to solution

Hi linnj,

 

Your suggestion was right on the mark. As soon as I added the approriate lseek instructions it works just great. I knew I was doing something wrong and sure enough: I overlooked the piece of info on the lseek function. Thanks a lot for pointing it out.

0 Kudos