From c8683340ab9ee1dc00a8faaf4127b1ea0f3d4903 Mon Sep 17 00:00:00 2001 From: GenesiaW <74142392+GenesiaW@users.noreply.github.com> Date: Thu, 5 Feb 2026 19:45:09 +0800 Subject: [PATCH] feat: holding back button while booting, boots to home screen as a mean of escaping boot loop (#587) ## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) - Allows back button to be held to escape boot loops when reader activity crashes and device attempts to boot to previous state - Reduces the need of removing SD card and access to another device to delete the `/.crosspoint/state.bin` * **What changes are included?** - Back button can be held while booting to boot to home screen - Update of User Guide section to include this feature ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**NO**_ --------- Co-authored-by: Arthur Tazhitdinov --- USER_GUIDE.md | 13 +++++++++++++ src/CrossPointState.cpp | 7 ++++++- src/CrossPointState.h | 1 + src/activities/reader/EpubReaderActivity.cpp | 2 ++ src/activities/reader/TxtReaderActivity.cpp | 2 ++ src/activities/reader/XtcReaderActivity.cpp | 2 ++ src/main.cpp | 5 ++++- 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index e4d72b0c..f46ddd07 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -21,6 +21,7 @@ Welcome to the **CrossPoint** firmware. This guide outlines the hardware control - [System Navigation](#system-navigation) - [5. Chapter Selection Screen](#5-chapter-selection-screen) - [6. Current Limitations \& Roadmap](#6-current-limitations--roadmap) + - [7. Troubleshooting Issues \& Escaping Bootloop](#7-troubleshooting-issues--escaping-bootloop) ## 1. Hardware Overview @@ -220,3 +221,15 @@ Accessible by pressing **Confirm** while inside a book. Please note that this firmware is currently in active development. The following features are **not yet supported** but are planned for future updates: * **Images:** Embedded images in e-books will not render. + +--- + +## 7. Troubleshooting Issues & Escaping Bootloop + +If an issue or crash is encountered while using Crosspoint, feel free to raise an issue ticket and attach the serial monitor logs. The logs can be obtained by connecting the device to a computer and starting a serial monitor. Either [Serial Monitor](https://www.serialmonitor.org/) or the following command can be used: + +``` +pio device monitor +``` + +If the device is stuck in a bootloop, press and release the Reset button. Then, press and hold on to the configured Back button and the Power Button to boot to the Home Screen. diff --git a/src/CrossPointState.cpp b/src/CrossPointState.cpp index 91aa2536..d578945c 100644 --- a/src/CrossPointState.cpp +++ b/src/CrossPointState.cpp @@ -5,7 +5,7 @@ #include namespace { -constexpr uint8_t STATE_FILE_VERSION = 2; +constexpr uint8_t STATE_FILE_VERSION = 3; constexpr char STATE_FILE[] = "/.crosspoint/state.bin"; } // namespace @@ -20,6 +20,7 @@ bool CrossPointState::saveToFile() const { serialization::writePod(outputFile, STATE_FILE_VERSION); serialization::writeString(outputFile, openEpubPath); serialization::writePod(outputFile, lastSleepImage); + serialization::writePod(outputFile, readerActivityLoadCount); outputFile.close(); return true; } @@ -45,6 +46,10 @@ bool CrossPointState::loadFromFile() { lastSleepImage = 0; } + if (version >= 3) { + serialization::readPod(inputFile, readerActivityLoadCount); + } + inputFile.close(); return true; } diff --git a/src/CrossPointState.h b/src/CrossPointState.h index 87ce4e96..e8c65c10 100644 --- a/src/CrossPointState.h +++ b/src/CrossPointState.h @@ -9,6 +9,7 @@ class CrossPointState { public: std::string openEpubPath; uint8_t lastSleepImage; + uint8_t readerActivityLoadCount = 0; ~CrossPointState() = default; // Get singleton instance diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index cefd69f9..94195b6e 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -112,6 +112,8 @@ void EpubReaderActivity::onExit() { } vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; + APP_STATE.readerActivityLoadCount = 0; + APP_STATE.saveToFile(); section.reset(); epub.reset(); } diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index 4de12d18..799b90a1 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -91,6 +91,8 @@ void TxtReaderActivity::onExit() { renderingMutex = nullptr; pageOffsets.clear(); currentPageLines.clear(); + APP_STATE.readerActivityLoadCount = 0; + APP_STATE.saveToFile(); txt.reset(); } diff --git a/src/activities/reader/XtcReaderActivity.cpp b/src/activities/reader/XtcReaderActivity.cpp index a7350c16..c143d2c5 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -70,6 +70,8 @@ void XtcReaderActivity::onExit() { } vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; + APP_STATE.readerActivityLoadCount = 0; + APP_STATE.saveToFile(); xtc.reset(); } diff --git a/src/main.cpp b/src/main.cpp index 5b118fad..03ed0b18 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -331,12 +331,15 @@ void setup() { APP_STATE.loadFromFile(); RECENT_BOOKS.loadFromFile(); - if (APP_STATE.openEpubPath.empty()) { + // Boot to home screen directly when back button is held or when reader activity crashes 3 times + if (APP_STATE.openEpubPath.empty() || mappedInputManager.isPressed(MappedInputManager::Button::Back) || + APP_STATE.readerActivityLoadCount > 0) { onGoHome(); } else { // Clear app state to avoid getting into a boot loop if the epub doesn't load const auto path = APP_STATE.openEpubPath; APP_STATE.openEpubPath = ""; + APP_STATE.readerActivityLoadCount++; APP_STATE.saveToFile(); onGoToReader(path); }