InfiniTimeOrg / InfiniTime

Firmware for Pinetime smartwatch written in C++ and based on FreeRTOS
GNU General Public License v3.0
2.75k stars 942 forks source link

"storage"/"Off" mode #341

Closed blaueente closed 1 year ago

blaueente commented 3 years ago

Is there any possibility to turn it "off", i.e. in a state where it deactivates anything it can, to save most power it can, such that it can only be woken by (long-)pressing the button, and then it boots again?

Originally posted by @blaueente in https://github.com/JF002/InfiniTime/issues/201#issuecomment-839925903

pfeerick commented 3 years ago

This nicely overlaps with #101, as I mentioned there... would be great to see reboot and power off (halt CPU) facilty ;)

JF002 commented 3 years ago

It's not possible to completely cut the power, as there is no hardware reset or power off button on the device. However, it might be possible to halt the CPU, but ensure that it's configured correctly to reset on a push on the button.

A mode where we disable everything (ble, sensors,...) and where the system task run as slowly as possible (but fast enough to refresh the watchdog) is indeed possible.

moriel5 commented 3 years ago

Agreed, this is also important to me, since I need to turn my unit off on a weekly basis, as well as before some of my religion's holidays, to conserve battery, since I cannot use it for religious reasons.

geekbozu commented 3 years ago

I wonder if we should be extending the long press (7 second) action to popup a menu instead of just hard reset the way it currently is. This could implement this and #101 at the same time.

JF002 commented 3 years ago

The long press is directly connected to the watchdog : the watchdog is not refreshed as long as the button is pressed. This ensure that there's very little chance of a bug on the watchdog handling and that the user will be able to reset the watch in most cases. IIRC, the watchdog is already set to the highest value, so we won't be able to increase the timeout. However, it should be possible to display the popup a bit sooner (3-4s ?) so that we can display info to the user before the watchdog resets the watch.

moriel5 commented 3 years ago

@geekbozu Also a power state, as @JF002 had mentioned it's possible, could be labeled as "Poweroff", or"Hibernate", or something that better describes it.

Riksu9000 commented 3 years ago

480 can already open separate apps on button double click, long press 400ms and longer press 2000ms. The last one was added for a power menu or similar.

geekbozu commented 3 years ago

Perfect Ill give that PR a review soon so if its ready we can get it merged so we can build on it! Awesome work like always riksu!

danielgjackson commented 2 years ago

Has anyone got an existing plan for supporting an "off"/"shipping"/"storage" (very low power) mode? How do Pine64 ship the devices while retaining battery charge?

Perhaps it might be best done in the bootloader but, failing that, I think it could be done as just a low-power delay in starting the application, waiting for a button press and/or to be (re-)connected to power:

  1. Have a setting to represent that the device should be in shipping mode. Perhaps as a "noinit" item in RAM (alternatively, a setting written to flash memory). Long-press in the application can bring up a "power menu" (options for "Off", "Reboot", "Cancel"). If turning off, the setting is written (e.g. to noinit RAM) and the device restarted.

  2. Rearrange peripheral code so that everything is set to its lowest power state at the start of main(), and before the task scheduler is started. So, for example, the display should be off, SPI bus off, external memory off, motor off, accelerometer in its lowest power mode, heart rate monitor in standby. The button and connected/charging status must be correctly configured as inputs. I think there should also be some additional checking that this firmware build is definitely for the hardware its currently running on (i.e. all the peripherals behave as expected) -- otherwise the low-power loop cannot be exited if the button/charging state are not actually on the correct I/O pins!

  3. If the "off" setting is enabled (and, perhaps, also if the battery is very low on power or it was detected that the device restarted from a brown-out condition?):

    • clear the "off" setting, so that any subsequent restart will run the main app
    • adjust any remaining I/O pins and peripherals to lowest power settings
    • set up a low power and low frequency timer at interval (e.g. 500 msec)
    • bool was_connected = true;
    • int button_count = 0;
    • unsigned int elapsed_ticks = 0;
    • loop forever:
      • sleep the processor until a timer interrupt
      • elapsed_ticks++;
      • connected = whether the device is charging/connected
      • if (!was_connected && connected) break; -- run application when transitioning from not-connected to connected (stay asleep when remaining connected from the start).
      • was_connected = connected;
      • if button pressed:
      • button_count++;
      • else:
      • reset the watchdog timer
      • if (button_count >= 2) break; -- run application if the button was held then released over a medium amount of time. This allows a very long press to fire the watchdog interrupt to reset without starting the main app.
      • button_count = 0;
    • stop the low-power timer
    • update the system clock based on the missed time: elapsed_ticks * interval plus any remaining timer value.
    • restore any needed I/O pins

...hopefully the main app can then just continue (alternatively, the device could just reset).

Spagett1 commented 1 year ago

Id just like to say that this would be super helpful from a user viewpoint, if i could turn it "off"/sleep at night (assuming im not using the alarm) that would increase the time between charges and just be really handy.

Just posting this to show there is interest in this feature.

Avamander commented 1 year ago

The current sleep mode that exists - without a connection, advertising or wakeup methods enabled - is about as best as we can get. I think this feature practically exists and I'm closing the issue.

moriel5 commented 1 year ago

@Avamander Do you mean when the screen is off, or what was recommended here (especially for shipping)?

Since a mode where the device does not respond to any input (except for a long-press of the power button) and practically has nothing running (with the CPU being at it's lowest possible sleep state) is necessary, not only to preserve battery (such as when shipping) but also for times when response to input is unwanted (such as what I had earlier mentioned regarding Saturdays and certain holidays in my religion).

Avamander commented 1 year ago

Do you mean when the screen is off, or what was recommended here (especially for shipping)?

Yes. Turning the screen off basically achieves the desired power savings. There is no hardware watchdog circuit to be able to reach anything significantly better.

but also for times when response to input is unwanted

You can turn off that wakeup method from the settings.

moriel5 commented 1 year ago

Ah, on terms of power savings, I would be inclined to agree, based upon all of the conversations revolving around this subject here (and some regarding ESP32 watches).

But regarding unwanted only, it is not enough, since short single presses of the power button are also unwanted in such scenarios.

moriel5 commented 1 year ago

@Avamander I'm sorry about the double post, but just in case you did not see it due to not being notified anymore of this issue, my previous reply is of note.

Riksu9000 commented 1 year ago

I find it unlikely that the button would be accidentally pressed.

moriel5 commented 1 year ago

@Riksu9000 Actually, it is extremely common for that to happen, especially if the watch is not worn on the wrist at the time (which is also very common, such as when affixing it to a backpack, for example).