[iMX28] Using a GPIO as an input counter

cancel
Showing results for 
Search instead for 
Did you mean: 

[iMX28] Using a GPIO as an input counter

3,500 Views
olistudent
Contributor I

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

Labels (1)
0 Kudos
8 Replies

164 Views
Rooney
Contributor III

Is the pullup activated on the relevant GPIO?

Maybe this could cause your problem as well...

0 Kudos

164 Views
olistudent
Contributor I

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.

0 Kudos

164 Views
YS
Contributor IV

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"?

0 Kudos

164 Views
olistudent
Contributor I

We are using external pullups for the digital inputs.

0 Kudos

164 Views
YS
Contributor IV

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.

164 Views
olistudent
Contributor I

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

0 Kudos

164 Views
VictorLorenzo
Contributor IV

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).

0 Kudos

164 Views
YS
Contributor IV

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.

0 Kudos