VIM3 Android Power Suspend by Voltage Level / GPIO?

I am using the VIM3 in a place, where I don’t have a good way of monitoring when the device sleeps or wakes up. I currently have a separate controller pulsing the PWR button line, to put the VIM3 to sleep, and wake it up when it is needed. This works OK, but occasionally, the two systems get out of sync with each other, and the VIM3 is either awake when it needs to be suspended, or vice versa. Given this, it would be much more reliable to have a way to wake it, and make it sleep by setting a voltage level on a pin. For instance, if the voltage is low, the VIM3 will go to sleep. If it is high, the VIM3 will wake up, and stay awake, until the voltage goes low again. I was running a Udoo x86 prior to the VIM3, and this is how it operated. Is there a way to do the same with the VIM3?

Anyone? Khadas? Really hoping for a good solution to this problem.

@nemiro I read your description over and over again, but I didn’t understand it, so I couldn’t give any advice. Maybe you can use graphics and text to describe more clearly. It’s better to describe the whole project so as to give reliable opinions.

This is a project where the VIM3 is used to run a dashboard in a car, running Android. I need the unit to come in and out of suspend by whatever the state of the ignition switch is in. Pulsing the VIM3’s power button has proven to be unreliable, as I currently do not have a positive way to confirm that the VIM3 is either in suspend or awake. I have thought about soldering a wire to one of the LEDs, and closing the loop that way, but that requires more wires, more code, and is not an elegant way of handling it. I have looked at the various methods people have used with relays, etc. I am already handling it in a similar way with an external microcontroller. It works, but it is certainly not 100% reliable.

What would be “better” is if there was a way to trigger the VIM3’s wake/suspend state by setting a pin (or the PWR_Key) to a logic high or low. ie, 0 volts will put it in suspend, and 3.3v will keep it awake. If the 3.3v drops to 0v, then the VIM3 will suspend until it comes back up to 3.3v.

The push button method works fine, when there is a human in the loop. If a push does not register, or gets pushed too many times, the human will respond and push again, if necessary. When the VIM3 is embedded, you don’t always have that luxury.

BTW, I think doing something like this will solve not only my problem, but make the VIM3 much more capable of being embedded in a larger system. It will certainly solve the problem for all the people using the VIM3 in their vehicles as a CarPC, for sure.

@nemiro Your real need is to light up the car, wake up the machine, turn off the car, and put the machine into sleep, right?

The car has a 12 volt control lead called acc. You need to design a small board to convert this lead to a GPIO port. Of course, there may be such a small board in the market. You can read the GPIO port status to determine whether you need to wake up or sleep. As for the current state of the machine, it can be judged by reading the brightness of the screen backlight: 0 is the sleep state, and greater than 1 is the wake-up state.

cat /sys/class/backlight/aml-bl/brightness

I can certainly feed a 0 or 1 to GPIO. Can you help me understand the rest? Unfortunately, I’m not much of a wiz at doing the programming of the VIM3 (or any Android, for that matter). Which GPIO pin do I need to use?

Sorry, I can’t give the specific code, it takes time to write, debug and verify. But give the direction of the strategy, you according to this direction through online research and learning.

Normal GPIO port is OK. Set the GPIO port as interrupt, and register the interrupt function for this.

I understand. Can the interrupt be read while the VIM3 is in suspend? I can see how it can be put to sleep, but waking it?

Register an interrupt with wake-up function. When the level changes, the thread will wake up automatically, and you can do the work you want in the interrupt function.

OK. Thank you for the advice!

Author: goenjoy <goenjoy@khadas.com>
Date:   Fri Mar 27 12:33:37 2020 +0800

    TP: Add touch screen touch wake-up system

+extern void rk_send_power_key(int state);
 static s8 gtp_i2c_test(struct i2c_client *client);
 void gtp_reset_guitar(struct i2c_client *client, s32 ms);
 s32 gtp_send_cfg(struct i2c_client *client);
@@ -1063,7 +1063,12 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
     gtp_irq_disable(ts);
 
     queue_work(goodix_wq, &ts->work);
-    
+       if(ts->gtp_is_suspend){
+               ts->gtp_is_suspend = 0;
+               //printk("hlm xx irq\n");
+               rk_send_power_key(1); 
+               rk_send_power_key(0);
+       }
     return IRQ_HANDLED;
 }

@@ -2351,6 +2356,8 @@ static void gtp_parse_dt(struct device *dev)
        gtp_int_gpio = of_get_named_gpio(np, "goodix,irq-gpio", 0);
        gtp_rst_gpio = of_get_named_gpio(np, "goodix,rst-gpio", 0);
        //printk("GTP gtp_parse_dt\n");
+       enable_irq_wake(gpio_to_irq(gtp_int_gpio));
+       device_init_wakeup(dev,1);
 }

The above is an example, adding wake-up function to the interrupt pin of TP. The last two lines add code to let the interrupt pin register wake-up function.

3 Likes

Thank you SO MUCH! Really appreciated!

I have worked on this off and on over the last few days. I’m just not much of an Android programmer, but need this function. I am attempting to use GPIOH_4. My need is simple. If that line goes HIGH (3.3v), I need the VIM3 to be awake. If it goes LOW (0v/GND), I need it to command the VIM3 to Sleep/Suspend. I need this to run as a background service at all times (ie, as soon as the tablet starts, this starts automatically, and runs all the way until a hard shutdown).

I am WILLING TO PAY someone to write me some code to do this :slight_smile: I am running Android Studio 4.1.1, and can set this up as Java or Kotlin, or do this another way, entirely. I would really like to have source code for this (that can be openly published here for other people to benefit from!). Any takers?

Someone surely wants to make a few bucks?

Did you want to wake up the system when the device go into deep sleep? Not early suspend?

  • On deep sleep mode

    • You need to modify the file on u-boot
  • On early suspend
    • You need to add driver support on kernel

I am using the VIM3 to drive a vehicle dashboard. It all works - except this portion. I need it to wake up quickly (which it does). I need it to go into the lowest power savings mode that is practical for Android, which will allow a quick wake up (~ 3-5 seconds). The pulsing of the PWR pin just is not foolproof enough in this application.

So, I need a logic level to give a constant VIM3 WAKE state, and a constant SLEEP/SUSPEND whatever state. I don’t know if I need deep sleep or suspend. Typically, just what happens when you push the PWR button quickly. Whatever state that is. That’s probably all I need.

This is a customized requirement. I can only provide you with some ideas. You can follow the method I provide you and try it yourself.
Thanks!

I suppose it is, but you can surely see that this would make embedding the VIM3 much more practical for many applications. I am willing to pay Khadas or anyone else to get a function like this working.

I don’t know if it helps you but I got my VIM3 working in my car using the power button approach with a script and the help of an esp8266.

VIM3 is connected to the cars battery.
ESP is connected to the ignition.

When the ESP is turned on it check if the VIM3 is on or off and if it is off it wakes it up with the power button (it waits some seconds and tries again if it hasn’t woke up but that is only for savety). This is done with by checking the ADC Pin of the ESP which is connected to the VIM3s I2C pin (this pin changes its voltage depending on the vim state)

On the VIM3 is a script which checks if the ESP is turned on by connecting a 3V3 pin from the ESP to the GPIO of the VIM3. So if we turn off the car the esp turns off and the vim3 goes to sleep.

I am using this command to put the vim into deep sleep

echo ‘mem’ > /sys/power/state

Should be fool proof hadn’t any problems yet.
Regards

5 Likes