I have a GPIO (PTE8 - Pin Nr. 113) exported via the /sys/class/gpio device tree and configured as OUTPUT direction.
From my C-Code I do the following
int fd = open ("/sys/class/gpio/gpio113/value", O_WRONLY);
write (fd, "1", 1);
write (fd, "0", 1);
The problem is, that write() does not work every time. It seems as if the value is not written into the Port-Register of the processor. I did measurements with a scope directly on the processor pin and the value showed 1 after the second write statement in line 11, but it should be 0. In the same step I checked in shell with "cat /sys/class/gpio/gpio113/value" and here the value is also shown as 0. When I then typed "echo 0 > /sys/class/gpio/gpio113/value" in the shell the pin went to 0. I also tried to modify the driver strength in IOMUX to 25Ohm, 50Ohm and 150Ohm and explicitely set OBE to high, but the behaviour is the same - sometimes it work - sometimes not!
Do you have an advice for me?
Thanks in advance,
What Kernel version do you exactly use? The Mainline GPIO/Pinctrl driver behaves slightly different then the 3.0/3.13 Timesys one. Also, how do you debug exactly? At least on current kernels, it looks like the value write could sleep. Do you break the code execution after the write?
What polarity do you use? (see active_low file). However, I don't think this is the issue since you do not change it and hence it should be the same issue when using sysfs from the shell.
Linux version 3.0.15-ts-armv7l
gcc version 4.8.3 (Timesys 20140811) )
In this case I didn't have to debug, it was enough to write a shell script, which toggles the pin and verified it with an oscilloscope. The result on the scope was that the pin did not toggle every time as expected, but it stay for one complete period low or high.
ACTIVE_LOW is 0.
In the initial post you stated that it worked in Bash. So it does not work when using a loop in a bash script? How do you know whether it toggled the pin or whether it just had a glitch timewise (latency)? We recently used a Python script on one of our modules and got a pretty decent square wave, however we run it on a newer kernel.org Linux kernel:
in my initial post I mentioned that I just used the shell to check the status of the the GPIO file parallel to the C-Program. Let me explain again in detail:
1. Set GPIO to low in C-Program: write (gpio_fd, "0", 1);
2. Checked with scope: the pin is still HIGH!
3. Checked File-Status in shell: "cat /sys/class/gpio/gpio113/value" - returns "0", so even linux thinks that the pin is low, but it is actually high, because the scope doesn't lie! :smileywink:
4. Tried to explicitely set the pin to LOW: "echo 0 > /sys/class/gpio/gpio113/value" - suddenly the pin goes to LOW.
But this behaviour is not really reproducable, it happens stochastic.
In my second post I tried to set the GPIO from shell only and did this in a loop. Also here it happens, so it is not related to the C code.
I tried the loop with different intervals (100ms/500ms) which are quite long, so I could easily measure it with a scope.
The reason the kernel does not see the value of the outside world is that the Input buffer is explicitly disabled in the old 3.0 kernel, when direction is "output":
The driver upstream kernel driver explicitly does not change the input buffer, but leaves it up to the initial pinmux configuration whether the input buffer should be on or not (in our device trees we enable the input buffers for GPIO's):
However, this does not explain the stochastic behavior. Honestly, I currently don't know how why this happens.
thanks for your answer! Maybe I can modify the driver to be able to read the input buffer, so that I can set the output as long as the correct value is available, but this is just a workaround.
@Timesys Support: Can you check this issue and give feedback?
Our apologies for the delay in replying; our ping notifications have been silently bouncing on our end.
Our Vybrid kernel maintainers are reviewing, but as we have moved our Vybrid support to a 3.13 kernel, futher developments on the 3.0 kernel would need to be addressed as an engineering engagement.
Unfortunately it is currently not possible to build a 3.13 Kernel for "PHYTEC phyCORE Vybrid Development Kit/pcm052" in your build factory. It is no problem for us to switch to a newer kernel!
We understand that Phytec is working to update their kernel support to the 3.13 release; until they have validated the kernel support, we will only be able to provide the 3.0 kernel. If you have a pressing need for this kernel release, we would suggest contacting Phytec to determine their roadmap.