eclipse / mraa

Linux Library for low speed IO Communication in C with bindings for C++, Python, Node.js & Java. Supports generic io platforms, as well as Intel Edison, Intel Joule, Raspberry Pi and many more.
http://mraa.io
MIT License
1.37k stars 613 forks source link

gpio isr on pin2 & 3 on galileo gen1 is unreliable #42

Closed arfoll closed 9 years ago

arfoll commented 9 years ago

After a few minutes, stops registering ISRs. Reported by William Penner.

arfoll commented 9 years ago

I ran the following code whilst with mraa v0.5.2-49-gabd538d. I used pin 2 as the interupt pin and pin 4 as the trigger pin with a jumper between those pins.

#!/usr/bin/env python

import mraa as m
import time

DELAY=0.01
TESTLENGTH=1000

class Counter:
  count = 0

interuptCount = Counter()
twiddles = 0

def isrCount(args):
  interuptCount.count+=1

# isr pin
x = m.Gpio(2)
x.dir(m.DIR_IN)

# trigger pin
t = m.Gpio(4)
t.dir(m.DIR_OUT)
# start high
t.write(1)

x.isr(m.EDGE_BOTH, isrCount, isrCount)

while twiddles < TESTLENGTH:
  t.write(0)
  twiddles+=1
  time.sleep(DELAY)
  t.write(1)
  twiddles+=1
  time.sleep(DELAY)

print(str(interuptCount.count) + " vs " + str(twiddles))

from what I can see the counts always match

arfoll commented 9 years ago

It ran for 21minutes with TESTLENGTH=100000 and got the correct answer.

bpenner commented 9 years ago

Thanks for running this test. I am leaning toward an i2c issue on my board. My configuration uses the sparkfun weather board plus an additional BMP180 sensor attached to a gen 1 board. When I generate lots of interrupts (either by using a shorting lead or by connecting up an anemometer) the interrupts stop after 100 or so interrupts. After the interrupts stop, I can still correctly read the interrupt inputs and everything seems to be working fine (other than no interrupts). I can stop my app, and restart it, and everything is fine for a few minutes and again interrupts stop.

I moved this configuration to a gen 2 board and it works perfectly for many 1000's of interrupts.

My theory is that the loading on my i2c bus is resulting in corrupting the clearing of the interrupts to the cy8c9540a. Since I have seen other cases of i2c corruption, I think we can close this issue for now. I took your suggestion to get a usb LA and I'll check this out over this next weekend.

arfoll commented 9 years ago

Yes the cy8c9540a sounds like the likely culprit, I left my i2c bus entirely clear but it's possible you might miss interupts that way or crash the expander. Not really sure what to suggest, it's surprising the kernel ringbuffer (dmesg) stays quiet if that is the case.

Closing for now then, feel free to reopen if you have any more insights, if there is a possible workaround I'm more than happy to add something.