Hello all.
I want to use a GPIO as an input counter on an iMX28 board. I'm using kernel 2.6.35 from the Freescale BSP.
For testing I connected a digital output of my board to a digital input. The good news first. When reading the value of the GPIO everything seems okay. It changes whenever I switch my digital output.
The bad news: I'm observing three problems.
1. Despite configuring for rising or falling edges I'm seeing the interrupt counter increasing everytime I do switch the digital output. I expected that there isn't any rising edge when switching from 1 to 0. Or did I misunderstood the meaning of rising edge?
2. I'm not able to configure the trigger to detect "both" edges. Why?
root@iMX28:/# echo both > /sys/class/gpio/gpio116/edge
[ 642.890000] setting trigger mode 3 for irq 244 failed (mxs_gpio_set_irq_type+0x0/0x58)
3. For one event the interrupt counter increases by a higher value depending on the utilization of the system (up to 9). I would expect it to increase by one for one event. I even looked at the signal with an oscillator but couldn't observe any strange things with the ramps.
Log:
# detect rising edges
root@iMX28:/# echo rising > /sys/class/gpio/gpio116/edge
# print gpio configuration for gpio 116
root@iMX28:/# cat /sys/kernel/debug/gpio | grep 116
gpio-116 (Digital Input 1 ) in hi irq-244 edge-falling
# show interrupt counter
root@iMX28:/# cat /proc/interrupts |grep gpio
244: 1 - gpiolib
# switch to 1
root@iMX28:/# echo 1 > /sys/class/gpio/gpio74/value
# show interrupt counter again
root@iMX28:/# cat /proc/interrupts |grep gpio
244: 5 - gpiolib
# switch to 0
root@iMX28:/# echo 0 > /sys/class/gpio/gpio74/value
# show interrupt counter
root@iMX28:/# cat /proc/interrupts |grep gpio
244: 14 - gpiolib
I also tried with an external signal generator but the problem persists. Now the question:
Hardware problem? Kernel problem? pebcak?
Any help is appreciated.
Regards
Oliver
We solved the problem somehow. It depends on the source generating the impulses. If we use a discrete impulse generator the IRQ counter works as supposed. It doesn't if we use a relais for generating impulses...
Thanks for your answers.
It is good to know your issue was solved. Relay chattering is a classic case - you may try to insert parallel capacitor to eliminate (or reduce) chattering.
By the way, would you change this topic status to "solved"?
We are using external pullups for the digital inputs.
For "both" edge issue, it is not supported by iMX28 architecture. You can see only "rising" and "falling" are supported as HW_PINCTRL_IRQPOL register description in the reference manual. Also function mx28_gpio_set_irq_type() in Kernel source arch/arm/mach-mx28/gpio.c will help understand. There is Kernel API for "both" edge, but iMX28 gpio driver does not accept "both" setting.
I tested gpio IRQ on my iMX280 board (a silex SX-580). "rising" and "falling" seems working on my case. Interrupt counts up one by one, each time when I press the button (falling) or release the button (rising). I'm sorry this is wont' help your problem, but at least I can say it is not native to iMX28 chip hardware or Linux GPIO implementation.
Hi.
Thank you for your answer. I looked up the mentioned function and agree with you that "both" edges are not supported. Triggering on a level is also not feasible because the system hangs counting IRQs...
To clarify: If you setup your trigger to rising edge you only see rising edges or do you see interrupts for both edges?
Output from /sys/kernel/debug/gpio:
gpio-116 (Digital Input 1 ) in hi irq-244 edge-rising
I soldered out a capacitor in my digital input line so the edges should be stronger. Now I'm loosing some interrupts independendly of the trigger frequency. But the others are counted multiple times as before. Very miraculous... :-)
Some numbers from /proc/interrupts after 100 times of switching on and off:
with capacitor in input lines:
208: 1044 - gpiolib
209: 3150 - gpiolib
210: 1352 - gpiolib
211: 4111 - gpiolib
without capacitor in input lines:
244: 175 - gpiolib
245: 497 - gpiolib
246: 124 - gpiolib
247: 468 - gpiolib
Now I will try a different relay to switch my digital inputs and see if it has an effect on my interrupt count.
Regards
Oliver
Hi Oliver,
Just as Sasaki says, it should be expected to see bouncing and chattering on input lines that are switched low/high with push button like switches. Causes for this are mostly imperfections on mechanical contacts (opens and closes repeatedly until settled) and oscillations generated by the disturbance (electrical impulse) applied to input circuitry. Depending on design and geometry, cooper lines behave like transmission lines or inductive loads, leading in some cases to resonant L-C circuits due to parasitic capacitances.
For reducing (but unfortunately not completely eliminating) both effects it is useful to couple switched input lines with R-C low-pass filters. This "slows" down input signal edges and therefore reduces glitches amplitude.
Depending on pulses source (and sources count, of course) it could be a good solution to pass inputs through isolated buffers with hysteresis. I used this with success couple of years ago for an industrial machine controller reading standard 24V NPN reflective-type object presence/absense sensors and for reading signals from several mechanical relays (used free-contacts to know when they changed state).
Oliver,
I've configured both "falling" and "rising" configurations. I confirmed IRQ counter only up only when I press the button / with irq polarity="falling", or counts up only when I release the button with irq polarity="falling".
I've tested GPIO IRQ with connected push button, so I could not repeat numerous times - only less than 10 times or so. As long as I saw, I didn't see suspicious multiple countup. It is simple mechanical push switch directly connected to GPIO00 without capacitor. I expected chattering / bouncing, but for some reason, IRQ counter increased one-by-one as I push or release the button. I didn't check the waveform.