VIM3 Android Power Suspend by Voltage Level / GPIO?

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!

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

This does help, tremendously! I am using an Arduino Mega, alongside the VIM3, and had considered tapping into the LED, to gain a power status on the VIM3. I like your solution much better. Are you tapping the I2C SCL or SDA? Can you elaborate on the script? I am well versed in other embedded things, but Android scripting and programming escapes me. Thank for responding!

1 Like

I think both work but if I remember correctly I am using I2C SCL.
The code I am using on the VIM is this one:

#!/system/bin/sh
restart_usb=false
echo 'Starting Powermanagement Service...'
while true
do
	ignition=$( cat /sys/class/gpio/gpio431/value )
	enabled=$( cat /sys/class/gpio/gpio432/value )
	logcat > /logs/logcat_$(date +"%Y%m%d%H%M").txt
	if [ "$enabled" = 1 ]; then
		if [ "$ignition" = 0 ]; then
			shutdown_timer_run=true
			if [ -z $(dumpsys display | grep mScreenState=OFF) ]; then
				echo 'Going to sleep'
				echo 'mem' > /sys/power/state
				restart_usb=true
			fi
		else
			if [ "$restart_usb" = true ]; then
				echo 0 > /sys/bus/usb/devices/1-1.1/authorized
				sleep 1
				echo 1 > /sys/bus/usb/devices/1-1.1/authorized
				restart_usb=false
			fi
		fi
	fi
	sleep 1
done

The enabled part is just a jumper so I can test the device outside of the car.
I needed the restart usb part because my touchscreen wouldn’t work after it woke up from sleep, maybe you will not need this.

This is the important part of the code I am using for the ESP:

void loop() {
  VIM_PWR_VALUE = analogRead(ANALOG_PIN);

  if (VIM_PWR_VALUE < 500) {
    if (wake_vim_timer >= 1000) {
      Serial.print("Wake VIM\n");
      wake_up_vim();
      wake_vim_timer = 0;
    } else {
      wake_vim_timer++;
    }
  }
}

void wake_up_vim() {
  digitalWrite(VIM_WAKE_PIN, 1);
  delay(100);
  digitalWrite(VIM_WAKE_PIN, 0);
  delay(3000);
}
4 Likes

How are you running the script? Through terminal, or are you compiling that somehow?

I run it at start but I forgot exactly where I run it, but you have to make sure that it has root permissions

OK. I will try to do some homework on it. I sure do appreciate your willingness to help me out!

Hi @Terry

Could you please advice what need to be changed here to wake from deep sleep (or if this possible) in the following scenario

1/ Deep sleep - I want to wake up on signal change on signal received on I2C_M3_SDA or I2C_M3_SCL pin on GPIO 40 header. It seems that I need to register pin in

void get_wakeup_source(void *response, unsigned int suspend_from)

but it’s not clear how to do that - could you please advice (I’m planning to wake up board from external MCU signal - atmega328 based)

2/. Will any transmission on i2c-3 bus will wake system from early_suspend state or it needs driver change ?

This is an area that the VIM3 misses the boat as an embedded system. Without a way for positive control of the sleep state from an external controller, the VIM3 becomes an Android tablet without a screen.