VF50: Gpio_GetLevel returns incorrect value

Calling Gpio_SetLevel works fine.
Calling Gpio_GetLevel will return low even if the pin is actually high.

For example, I have pin # 28 (configured as GPIO ouput) connected to a speaker. If I call Gpio_SetLevel to high, the speaker makes a constant noise. If I then call Gpio_GetLevel, it indicates low, even though the pin must be high because I can hear the speaker make noise. If I then call Gpio_SetLevel with low, it will turn the speaker off.

I can replicate the same behavior using the Gpio utility. I can right-click on the level value for pin # 28, set it to 1, hear the speaker noise, but the level remains at “0” in the Gpio utility. I can then right-click set it to 0, and the speaker turns off.

I have tested this with various pins, such as 28, 71, 100.

Any suggestions?

Hi,

I tested all three pins at my end, and here are my findings:

  • SODIMM 28 AND 100: works fine by default
  • SODIMM 71: BL_ON pin by default. If you are not using any RGB/parallel display in your application then you can use this pin, or else you need to either use any other SODIMM pin for Backlight of your display or look for any other pin in software.

To disable SODIMM 71 by default you need to configure SplashScreen ConfigBlock settings for BL_ON pin.

Through bootloader use command

> set ss.bl_gpio <any other SODIMM pin than 71, or set to 0 if not using RGB/parallel display>
> save ss

After this there should not be any issue with SODIMM 71.

Below is the test code I used it to confirm all three pins are working fine.

#include <windows.h> 
#include "gpio.h"

uIo io1 = {28, ioColibriPin}; 
uIo io2 = {71, ioColibriPin};
uIo io3 = {100, ioColibriPin};
//=============================================================================
// Application Entry Point
// 
// The simple error handling using ASSERT statements is only effective when 
// the application is run as a debug version.
//=============================================================================
int wmain(int argc, _TCHAR* argv[])   
{ 
    HANDLE hGpio = NULL;            ///< handle to the GPIO library
    BOOL success;
	DWORD level;
    // === Initialize GPIO library. ===
    // We don't use registry-based  configuration, thus we can 
    // pass NULL go Gpio_Init()
    hGpio = Gpio_Init(NULL);   
    ASSERT(hGpio != 0);
    success = Gpio_Open(hGpio);
    ASSERT (success);

    //// === Io Manipulation ===
    //// Configure the pin to act as GPIO (as opposed to an Alternate function)
    //// Set it to Output,  High
    Gpio_ConfigureAsGpio(hGpio, io1);
    Gpio_SetDir         (hGpio, io1, ioOutput);
	Gpio_SetLevel       (hGpio, io1, ioLow);
	level = Gpio_GetLevel(hGpio, io1);
	printf("Pin 28, level: %d\n",level);

    Gpio_ConfigureAsGpio(hGpio, io2);
    Gpio_SetDir         (hGpio, io2, ioOutput);
	Gpio_SetLevel       (hGpio, io2, ioHigh);
	level = Gpio_GetLevel(hGpio, io2);
	printf("Pin 71, level: %d\n",level);

    Gpio_ConfigureAsGpio(hGpio, io3);
    Gpio_SetDir         (hGpio, io3, ioOutput);
	Gpio_SetLevel       (hGpio, io3, ioLow);
	level = Gpio_GetLevel(hGpio, io3);
	printf("Pin 100, level: %d\n",level);

    // === De-Initialize GPIO library ===
    success = Gpio_Close(hGpio);
    ASSERT(success);
    success = Gpio_Deinit(hGpio); 
    ASSERT(success);

    // === Application exit code ===
    printf("Press Enter to end the program\n");
    getchar();

    return(TRUE);
}

The code you provided works for me.

I was doing things slightly differently. For example, I was doing this:

  1. call Gpio_GetAltFn and if result is not gpio, then call Gpio_ConfigureAsGpio.
  2. call Gpio_GetDir and if result is not output, then call Gpio_SetDir as output.
  3. call Gpio_GetLevel and if result is not high, then call Gpio_SetLevel as high.

I removed the unnecessary getter calls and just called the setter functions and that seemed to resolve the issue. The code I mentioned above (using the getter functions) works fine using the old WinCE libraries (using the equivalent functions) with PXA modules, but not with the new Toradex CE libraries with VFxx modules.

However, there is still a bug in the Gpio utility. If I run it after a cold boot, then it doesn’t show the correct level values after changing them. If I cold boot, run the code you provided, then run Gpio utility, the Gpio utility works properly.

Hi,

If I run it after a cold boot, then it doesn’t show the correct level values after changing them.

Can you please be more specific like on which pins you have teste, this is what I tested at my end

coldboot → run GPIO tool → SODIMM 45, 105 set to output → checked pin level it worked and same status was there on tool also.


If I cold boot, run the code you provided, then run Gpio utility, the Gpio utility works properly.

Yes, it should but it should work in both the cases not just one.

Can you please tell me how you did testing so that I can replicate at my end too.


I created a screen capture video (includes audio) that walks through the process.

https://drive.google.com/file/d/0Bxm1ZyqFfnn5MC1YVkFyOElSYzg/view?usp=sharing

Hi,

I also did exactly what you did but at my end, all worked well.

My hardware setup:

  • VF50 1.1A
  • Colibri Eval v3.1

Software:

  • Image WEC 7, 1.3Beta 4

  • Libraries v1.6

  • GPIO Tool v1.2 (last week we launched new version, try on this also)

Only one thing I noticed, if you have ColdBoot (RESET) your device then by default SODIMM 28 should be configured to GPIO INPUT LOW, but in your video @00:20 it is showing GPIO OUTPUT LOW, this do not seem to be correct.

Also, can you try latest GPIO Tool v1.2, I tested on same application version.

Here is my video: https://share.toradex.com/kzt9lcyigeskirl

Power ON module → open GPIO TOOL → configured PIN 28 to OUTPUT LOW /HIGH → checked pin level using multimeter : all seemed OK

Run Test application (same I have posted on community) → tested GPIO tool : all seemed OK

I can visualize only one possibility which is hardware end.

Try one of the following:

  1. If you have Toradex Colibri Evaluation Board, try to do the same test on it, remove JUMPERS and test it using multimeter and GPIO tool.
  2. If you do not have, then disconnect your speakers, just check the pin level directly coming out from SODDIMM, using multimeter and GPIO tool.

Also, can you try latest GPIO Tool v1.2, I tested on same application version.

Yes, same issue.

I have done some more investigation. The issue seems to happen when I setup some pins in the config block GPIO. However, the pins I’m setting up in the config block isn’t the pin I’m having trouble with in the GPIO utility.

I have setup pin 146/GPIO 111 and pin 100/GPIO 92 in the config block as ouput high, like this:

  • set gpio.XX.ctrl=1
  • set gpio.XX.obe=1
  • set gpio.XX.dse=1
  • set gpio.XX.state=1

Cold boot, launch Vybrid GPIO Utility v1.2, change pin 28 from low to high, the GPIO Utility still shows pin as low but the pin is high (verified with beeper sound on custom base board, and verified with volt meter on Eval board).

If I zero out the config block GPIO, it works fine.

Not sure why, but setting pins 146 and 100 in config block GPIO prevents the GPIO Utility from showing the correct level when I change pin 28.

So in summary, there is still a bug in the GPIO Utility that doesn’t properly show the gpio level if other pins have been configured in the config block.

If you have Toradex Colibri Evaluation
Board, try to do the same test on it,
remove JUMPERS and test it using
multimeter and GPIO tool.

I tried this. I put the module in the Eval board, removed jumper labelled sodimm 28 and connected a volt meter. Cold boot, launch GPIO Utility, change pin 28 to high, and the volt meter goes from 0v to ~3.2v, but GPIO Utility still shows “0”.

Only one thing I noticed, if you have
ColdBoot (RESET) your device then by
default SODIMM 28 should be configured
to GPIO INPUT LOW, but in your video
@00:20 it is showing GPIO OUTPUT LOW,
this do not seem to be correct.

Pin 28 by default is GPIO output, not input, at least that is what I am seeing. I have not configured pin 28 in the config block, so that is what its defaulting to for me. Is that a problem?

This is very interesting finding, I need to investigate further, allow me some time will get back to you.

I have done everything at my end, same you did and got correct results at my end.

Download this video for reference: https://share.toradex.com/74z0j7c9kbt3r4l

One last testing, can you reflash your module with latest image 1.3Beta4 completely including bootloader and then try to do the same steps.

As of now I cannot find any specific reason why at your end SODIMM 28 is not behaving correctly, there is no relation with SODIMM 100 and SODIMM 146 you configured in the bootloader.

Also, please let me know if I missed something.