Pengutronix - GPIO Input

Titus Breidung
Is it possible to set an GPIO Input over the /sys filesystem?

After creating f.e. GPIO 165 by echoing 165 to /sys/class/export the
direction is declared as "in", the edge as "none". The value is always "0"
even if there is an input of 3.2V - 3.3V.

If i set the edge to "rising", "falling" or "both" the value always is "1",
not respecting the input signal.

Is this caused by using the filesystem instead the library or what i am
doing wrong?

Thanks in advance,

Titus

davef
I only verified that the GPIO Usage example (8.4.1) worked.

If you don't set edge does the input work as expected?

Titus Breidung
Hi Dave,

no, if edge has the default value of "none" the value is always "0".

How much amperes are expected by the GPIO as input? On the side of my
circuit it is limited this time to about 30 mikroA. (3.2V and 100 kOhm).

davef
Titus,

If you are connecting a 100K resistor to gpio165 and then to 3.2V the input
will be pulled high permanently.

Following 8.4.1 when you export gpio165 do you find a directory
/sys/class/gpio/gpio165

and in that directory

active_low
direction
edge
subsystem
uevent
value

That example is for setting a GPIO up as an output, so you will need to
modify.

Have you been able to follow the complete example 8.4.1 and turn the port
on and off (as an output)?

Titus Breidung
Yes, as an output the ports are working as expected for on and off and
switching an external opto-coupler. This is the thing confusing me. So i
thought there is maybe a minimum amount of current needed for triggering
the input. I'll try to search for a failure in my connection from circuit
to board now...

I want to pullup the port when there is a input of 3.2V and pulldown the
port if the input is nearly 0V. Is the value "none" for edge the right
choice or have i set it to "both" or another value?

Titus Breidung
I found another problem...

Input signal of constantly 3.2V DC is connected over a 100 kOhm resistor to
GPIO input.

Before the resistor the power stays 3.2V. Between resistor and GPIO the
power amounts a few hundred mV.

Why that??? What is the input impedance of the GPIO inputs?

Thanks, Titus

davef
> Why that??? What is the input impedance of the GPIO inputs?

If you are using a digital multimeter (say 10MegaOhms input or higher) it
should not affect the reading at the junction of the resistor and the GPIO.

I'd guess the port is configured as an output low, so the voltage gets
dropped to almost zero.

A test . . . place a LED and a 1K resistor from to 3.2V to the GPIO and see
if it lights.  LED has to be the correct polarity.

Input impedance of the GPIO is quite high. Guess up to MegaOhms.  

Also, setting the edge parameter I believe is only needed if you want to
use that GPIO as an interrupt source.  edge = none for interrupt on level
change. edge  = raising, falling or both for interrupt on the respective
changes.

> I want to pullup the port when there is a input of 3.2V and pulldown the
> port if the input is nearly 0V. Is the value "none" for edge the right
> choice or have i set it to "both" or another value?

Re-word this to . . . I want my software to indicate a HIGH when I put 3.2V
on the GPIO and a LOW when I put 0V on the GPIO.

All I do in my application using a GPIO as an input port is to just export
it:

echo 193 > /sys/class/gpio/export

This (by default) sets the port to input and internal pull-up resistor
disabled.  If you put a multimeter on this port you will see the voltage
changing or floating, ie it can read anything between 0V and 3.2V.

If you want to define the input level either you enable the internal pullup
resistor OR place an external resistor (ie 100K) either to 3.2V (for
external pull-up) or to 0V (for external pull-down).

davef
I am not sure about edge = none.  According to the datasheet it looks like
an interrupt can be generated on going to a low level or going to a high
level.  Also, I do not know what they mean by "active_low" or the keywords
to set it with respect to a GPIO.

From the datasheet

EXTERNAL INTERRUPT CONTROL REGISTER
The 24 external interrupts are requested by various signaling methods. The
EXTINT register configures the signaling
method among the low level trigger, high level trigger, falling edge
trigger, rising edge trigger, and both edge trigger
for the external interrupt request

Ah, in the kernel documentation and gpio.txt near the last page both
"none" and "active_low" are explained.

Titus Breidung
Hi Dave,

thank you for your answer and sorry for my bad and misunderstandable
English.

Usage as output works perfectly.

But when i configure as input by echo 165 > /sys/class/gpio/export and
connect a voltage of 3.2V it was dropped down in the following way:

                            -------
---------x-----]           [-----x----------( GPIO Input
                            -------
   3.2V                100 kOhm            0.3V

It acts like an voltage divider between the resistor and the input. So it
is normal that the input is low with 0.3V. But i do not understand why the
voltage drops down.

Titus Breidung
Aaaaah... the to lines of the resistor were not correctly formatted :-(


3.2V ------x---- 100kOhm -----x-- 0.3V -----( GPIO INPUT

davef
If the GPIO is really configured as an input with the internal pull-up
resistor either enabled or disabled AND you connect a 100K resistor from
3.2V to that input . . . the GPIO pin should be at 3.2V.

Remove the 100K resistor and tell me what you read.

davef
Note:

GPAxx are only outputs
GPFx and GPGxx can be configured to use interrupts.  "edge" should have no
effect on the other (non-interrupt capable) ports.

I can work it out, but you tell me which GPxxxx is 165.

Titus Breidung
165 is assigned to GPF5. 

I want to use GPF3, GPF5 and GPF6 as inputs.

If there is no need to configure edge for reading voltage on and off from
the ports it would be fine.

I am not at home this moment, so i test the inputs without the 100kOhm
resistor if there would be no harm to destroy the chip with too much
current.

GPG1 / 193 is not wired to the connector on my micro2440. The micro2440 has
only a 20 pin connector for GPIO and ADC and a 20 pin connector for the
camera. GPG1 isn't available on the camera port too.

What do you mean with "internal pull-up resistor either enabled or
disabled" ? How can i enable the internal pull-up resistor? Are there more
steps necessary than echoing the ports number to /sys/class/export?

Thank you for your help!

davef
OK, GPF5.  It can be either an input or an output AND can be used as an
interrupt port.

> If there is no need to configure edge for reading voltage on and off from
> the ports it would be fine.

I would expect the default would to be have the port as a non-interrupt
port, so don't worry about configuring the "edge" value.  

> . . . so i test the inputs without the 100kOhm
> resistor if there would be no harm to destroy the chip with too much
> current.

How would any current flow without the 100KOhm resistor?  Even if you
connect an INPUT port up to 3.2V only microamperes will flow.

However, if the port is configured as an OUTPUT LOW and you connect it to
3.2V then you might damage it.  Likewise, configuring a port as OUTPUT HIGH
and then connecting it to ground you might damage it.  Maybe, the chip has
good internal current limiting for these conditions but I would not rely on
it.

Read about the "sink" and "sourcing" capabilities on I/O port and whether
or not they are protected from damage.

Also, read about "bus contention"

> What do you mean with "internal pull-up resistor either enabled or
> disabled" ? How can i enable the internal pull-up resistor? Are there
> more steps necessary than echoing the ports number to /sys/class/export?

According to 8.4.1 you can set the "direction" (input or output), "value"
(high or low for an output port).  According to the kernel doc referred to
above you can set the "edge" (none, rising, falling or both).  I think
"edge" by default must be set to a condition which makes the port act like
an non-interrupt port.  As soon as you set "edge" to one of the 4
parameters then it must start behaving as an interrupt port.

> How can i enable the internal pull-up resistor?

I have looked through the docs and can't find the answer.  I suspect that
when the GPIO is configured as input then "value" will turn the internal
pull-up on and off.

Yikes, just read "Note that requesting a GPIO does NOT cause it to be
configured in any way"

Probably, best to explicitly set the "direction" to "in" and the pull-up to
the "value" you want (if that is the correct term to use).

"The harder you look the more there is to it".

davef
Doing:

echo 193 > /sys/class/gpio/export
echo low > /sys/class/gpio/gpio193/direction

sets the port to output low, see kernel docs (gpio.txt)

Then the docs say, "and using 'value' If the GPIO is configured as an
output, this value may be written . . ."

(echo out > /sys/class/gpio/gpio193/direction)
echo 1 /sys/class/gpio/gpio193/value

makes this output port high.

Likewise,

(echo out > /sys/class/gpio/gpio193/direction)
echo 0 /sys/class/gpio/gpio193/value

makes this output port low.

Now, for input ports

echo in > /sys/class/gpio193/direction

should set it to an input port.

When it is set up as an input port you can (only) read the "value".

By default it appears that the pull-up is enabled as I read 3.3V steady on
the pin and a 10K resistor drops the voltage to about 1.7Volts.  Therefore,
I conclude that the internal pull-up resistor is close to 10K.

Looking in mach-mini2440.c I see some lines like:

/* remove pullup on optional PWM backlight - - */
s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);

I don't see information which suggests you can disable the pull-up from
userspace (sysfs).

I am sure a some stage I saw my inputs floating to indeterminate values,
indicating no pull-ups enabled, but not today!

Several reasons I do all my IO and peripherals using a ATmega32U4 board and
talk to it via USB!!

Titus Breidung
Hi Dave,

thank you for your detailed explanations.

Today i soldered a 560Ohm resistor parallel to the 100KOhm. At the input
were only about 1000mV. With a 10KOhm it is about 700mV. This will be the
same if i switch off the board and measure connected to the powerless
board.

Strange behavior!

So i tested it with another, newer micro2440 Board and got 1.5V over the
100kOhm resistor at the powerless board.

Oh my goodness, i fear the other board has broken GPIO inputs. As an output
they are working as expected but as input they have too low resistance and
drop down the voltage :-(((

All other IO are working including ADC and linux system is running stable.

Very strange, but i have no other answer on it as changing the board.

So sorry for causing the confusion here and your wonderful help!

Titus

davef
> By default it appears that the pull-up is enabled as I read 3.3V steady
> on the pin and a 10K resistor drops the voltage to about 1.7Volts.
> Therefore, I conclude that the internal pull-up resistor is close to 10K.

I should clarify this statement:

I am connecting the 10K resistor from the input pin to GROUND and measuring
the voltage at the junction.  BTW, this seems a low value for an internal
pull-up, I expected more like 100K.

Tonight I'll verify what happens when a I connect various series resistors
from 3.3V to the input pin.
 
I would not be doing any tests without power on the board and trying to
draw a conclusion about whether or not the port "would work".

Does the newer micro2440 board's GPIO work properly?

Titus Breidung
Hi Dave,

i just tested with the powerless board because the probably broken one
pulls down the power too in powerless state. If the other one works
properly i will test when back at home. This times i stay at Ibiza to test
the generally function of my project, prepare the location and do some
other organizations with my friend here for it.

At end of the week i will be back in Germany and then i test the effects
with the other board. I am frightened the i maybe damaged the inputs with
my circuit by putting power to them before they are configured (by
/sys/class/gpio/export).

I have not enough equipment here to do saver tests.

Thank you for your help!

I'll report when i am back at home.

davef
Configuring an GPIO should not make any difference to its ability to
withstand damage.

It will be just as fragile configured or not!

Still couldn't find out what values the pull-up resistors are.

I see I said I would do some testing, which will have to wait a few days as
I am away from home.

Rob
In the S3C2440 datasheet there is a table which lists details for each pin
one of which is "I/O Type". GPFX pins have I/O type "t8" which is described
in another table as:

"Bi-directional pad, LVCMOS schmitt-trigger, 100k pull-up resistor with
control, tri-state, Io = 8mA"

Also, the GPF5 on the mini2440 already has a 10K pull-up connected to it.

If you are pulling down a 10K resistor I can think of 3 possibilities.

1) The pin is configured as an output.
2) There is something else connected to this pin pulling it down.
3) The I/O circuitry for the pin is damaged.

Regards,
Rob

davef
Rob,

I now see that a lot of the GPIO have external 10K resistors pulling them
up to 3V3!!  That explains my test results.

> If you are pulling down a 10K resistor I can think of 3 possibilities.

May, I add a few words:

If you are pulling a port with an external 10K resistor to 3V3 down close
to ground . . . 
  
Thanks for the clarification.

Titus, have you got this sorted yet?