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.

2 Likes

Thank you SO MUCH! Really appreciated!