From 74f2552c29b0eb2a2b31c3dced0a475182cb6bb6 Mon Sep 17 00:00:00 2001 From: GenesiaW <74142392+GenesiaW@users.noreply.github.com> Date: Wed, 28 Jan 2026 17:39:08 +0800 Subject: [PATCH 1/3] feat: holding back button while booting, boots to home screen as a mean of escaping boot loop --- USER_GUIDE.md | 13 +++++++++++++ src/main.cpp | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 06973c92..deeb2e9d 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/main.cpp b/src/main.cpp index 2308f0a2..2456f96e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -311,7 +311,7 @@ void setup() { APP_STATE.loadFromFile(); RECENT_BOOKS.loadFromFile(); - if (APP_STATE.openEpubPath.empty()) { + if (APP_STATE.openEpubPath.empty() || mappedInputManager.isPressed(MappedInputManager::Button::Back)) { onGoHome(); } else { // Clear app state to avoid getting into a boot loop if the epub doesn't load From 7f9b5787c110523be877539243b1e3e393a620f3 Mon Sep 17 00:00:00 2001 From: GenesiaW <74142392+GenesiaW@users.noreply.github.com> Date: Wed, 28 Jan 2026 19:57:19 +0800 Subject: [PATCH 2/3] feat: add automatic bootloop recovery --- 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 ++++- 6 files changed, 17 insertions(+), 2 deletions(-) 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 58668c68..9cfc1e0b 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 e9303de3..8cfd6eed 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -89,6 +89,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 f579abcd..5aef68c5 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -69,6 +69,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 2456f96e..c1ac6b1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -311,13 +311,16 @@ void setup() { APP_STATE.loadFromFile(); RECENT_BOOKS.loadFromFile(); - if (APP_STATE.openEpubPath.empty() || mappedInputManager.isPressed(MappedInputManager::Button::Back)) { + // 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 > 2) { 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.lastSleepImage = 0; + APP_STATE.readerActivityLoadCount++; APP_STATE.saveToFile(); onGoToReader(path, MyLibraryActivity::Tab::Recent); } From cf04ae4a35570d13458755c3d06c540262ea2762 Mon Sep 17 00:00:00 2001 From: GenesiaW <74142392+GenesiaW@users.noreply.github.com> Date: Tue, 3 Feb 2026 21:51:05 +0800 Subject: [PATCH 3/3] Update src/main.cpp Co-authored-by: Arthur Tazhitdinov --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index c1ac6b1d..9b20f27d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -313,7 +313,7 @@ void setup() { // 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 > 2) { + APP_STATE.readerActivityLoadCount > 0) { onGoHome(); } else { // Clear app state to avoid getting into a boot loop if the epub doesn't load