MP2 gpioset/gpioget are either not or badly working
Hello,
I’m using an Karo SOM module (MP257) on a custom board with SFP module.
The SFP module is powered with the main 3.3V regulator. It has a TX_DISABLE input (0=ON, 1=OFF). This input :
- Is TTL
- Has an internal pull-up R (around 10k)
- Has an external pull-down R (10k)
- In connected to PE2
This makes a voltage divider : without driving the TX_DISABLE line, the voltage is something like 3.3V / 2 (1.8V to be precise)
Some simple tests to confirm that :
- SFP module unplugged => voltage is driven only by the pull down R => 0V
- A source meter on the TX_DISABLE confirms the presence and value of the internal RPU.
Now let’s play with the MP2. Is this processor able to blink a led ? Don’t laugh, nothing could be further from the truth.
After linux boot :
gpioinfo shows PE2 is input. It should logically be driven by the driver, but for an obscure reason, this is not the case. At least we can do things manually…
Set it to 0 ?
gpioset -b disabled -d push-pull PE2=0
=> Voltage is still 1.8V
Ok, bad. Try to 1 ?
gpioset -b disabled -d push-pull PE2=1
=> Voltage is still 1.8V
ok, very bad. Add a bias R to the R divider ?
gpioset -b pull-down -d push-pull PE2=0
=> Voltage is still 1.8V
I’m checking the voltage with gpioset running.
Remove the external RPD : line is 3.3V, ok, but gpioget returns “inactive”. Same for another line (PE5), on 2 different boards. It's pretty unlikely that both PCBs have the same soldering issue. Probing directly on the SOM module pins show the same voltage : if the issue is hardware, it’s on the SOM module itself (at BGA level).
Finally, replacing the external 10k RPD by a 100ohm RPD pulls the line at 0V => SFP module is on => fiber link is set up. This is functionally working, but it would be nice to be able to drive a gpio…
At this point I can’t be 100% sure the problem is hw or sw.
I have 3 other simple outputs GPIO. Working fine, but showing the gpio driver is poorly implemented or, worse, poorly designed.
For example :
gpioset PD6=0
- Set PD6 = 0, working fine. This function is blocking.
- After exiting this function, PD6 is still 0.
- gpioinfo : PD6 = active, ok
- gpioget PD6 = active. But the port is now 0. Reading the port make it going back to 0.
- gpioget PD6 = active => still active although the last command clearly reset it !
Reading an output port sometime make sense. The driver forbids that. This is basically what we can do 30 years ago using a PIC16*84 with a single step instruction… But impossible with a MP2 and a full featured OS.
Then, please, remove the --active-low options. Digital 0 is 0, 1 is 1. Hardware and software engineer can deel with inverted logic, adding a level of abstraction just make the things more ambiguous.
Finally, WTF (sorry !) the gpioset is blocking, since the GPIO keeps it direction and value once exited ?
ok, I’ve just read this on gpioset --help :
“The line output state is maintained until the process exits, but after that is not guaranteed.”
=> Not guaranteed ? Something is writing random values at random time on random free ports ? And gpioget still reads the original value ?
So, let’s redo it cleanly with a background task :
gpioset -d open-drain PD6=1 &
gpioget PD6
gpioget: unable to request lines: Device or resource busy
A good gpio driver shouldn’t behave that way.
Any help appreciated :)
Any update of the gpio driver appreciated, too.
