Commit Graph
538 Commits
Author SHA1 Message Date
Justin Mitchell 02398c8a96 Add memory profiling for EPUB and heap diagnostics
Adds residentBytes() and cssRuleCount() methods to track EPUB memory usage including parsed CSS. Enhances memory audit logging with EPUB heap usage, max allocatable block size, and CSS rule count. Implements one-shot heap block map dump on first settled audit to identify fragmentation and long-lived allocations.
2026-07-14 13:21:15 -04:00
Justin Mitchell ba92cb902e Add heap memory reporting for fonts and sections
Implements reportMemory() methods across SdCardFont, SdCardFontManager, and Section classes to track resident heap usage. Adds heap audit logging in EpubReaderActivity to attribute memory to fonts, framebuffer, section data, and other components for measurement-driven optimization.
2026-07-14 12:08:29 -04:00
Justin Mitchell 4d19d38152 Add idle-time glyph prewarming for next page
Preload glyphs for the next page during idle time to reduce page-turn latency. After a 400ms debounce period, scan the next page in FCM scan mode (no pixels drawn) to cache missing glyphs from SD card, avoiding ~100ms of SD reads during the actual page turn. Prewarm is deferred when rendering is active, heap is low, or during rapid page-flipping.
2026-07-14 11:26:07 -04:00
Justin Mitchell 302c0771dd Batch file list responses to reduce TCP segments
Buffer JSON file list entries into ~1.4KB batches before sending to avoid one TCP segment per file. This eliminates client delayed ACK delays that were causing large directory listings to take tens of seconds. Falls back to per-entry sends if buffer allocation fails.
2026-07-14 05:15:00 -04:00
Justin Mitchell c1a396c1ba Stop BLE before initializing WiFi in activities
Explicitly stop the BLE stack before bringing up WiFi in CrossPointWebServerActivity, FontDownloadActivity, and OtaUpdateActivity. On ESP32-C3, the shared radio and heap between BLE and WiFi stacks causes WiFi to be permanently starved if initialized while NimBLE's ~50KB is still resident, as the WiFi driver sizes its RX/TX buffer pools at init time.
2026-07-14 05:04:22 -04:00
Justin Mitchell 078d9ef535 Update status bar immediately on BLE connect/disconnect
Previously the status bar showed 'BT connecting' until the next page turn. Now monitors connection state in loop() and redraws the status bar immediately when connection completes or disconnects, restoring the chapter/book title. The connecting message now takes over the entire title slot instead of prepending to it.
2026-07-14 04:47:48 -04:00
Justin Mitchell 17e4230068 Add async display refresh to overlap CPU work
Introduces non-blocking display refresh methods that allow CPU work (like grayscale rendering) to overlap with the e-ink panel's refresh time. The async path starts the waveform and returns immediately, with the caller responsible for waiting via waitRefreshComplete(). Falls back to blocking refresh when fadingFix is enabled or the panel lacks deferral support.
2026-07-14 04:42:27 -04:00
Justin Mitchell 34e7ed249b Merge remote-tracking branch 'origin/develop' into feat-bluetooth 2026-07-14 04:20:50 -04:00
Justin Mitchell c5787d1cc1 fix: Use HALF_REFRESH for sleep and boot instead of FULL (#2588)
Changes all sleep screen display refreshes and boot screens from
FULL_REFRESH to HALF_REFRESH to match OEM firmware behavior. The stock
firmware uses a single-pass 0xD7 waveform for sleep screens, not the
multi-flash GC waveform (0xF7) that FULL_REFRESH triggers. For grayscale
mode, HALF_REFRESH is required because the gray nudge LUT is calibrated
against the pixel charge state left by the single-pass waveform; using
FULL_REFRESH causes blotchy noise in gray areas. Also adds X3 wb_gc
passive byte (the one-byte 0x54 to 0x00, matching stock's passive WB
table in the gc nudge bank): Every X3 grayscale render, reader AA,
covers, and the sleep-cover nudge, gets it.
2026-07-13 17:06:09 -04:00
Mr.Catfood bfa1d706b1 feat: Hidden wifi ssid support (#2360) 2026-07-13 02:33:48 -04:00
Jacob Latonis 73ab9ab20d feat: implement captive portal redirects for auto-loading the management page on hotspot mode (#2550) 2026-07-13 00:10:23 -04:00
Nick Perez 3a97f3e63e feat: Send optional document metadata with KOSync progress uploads (#1820) 2026-07-12 23:50:38 -04:00
Matthías Páll Gissurarson 39ea4b045f feat: render placeholders while waiting for images to render (#1003) 2026-07-12 21:40:07 +03:00
Justin Mitchell 444d87de82 fix: Add framebuffer release/realloc and improved lazy indexing (#2563) 2026-07-12 13:16:48 -04:00
Alexander Hoff ❍andAlexander Hoffer 5202bbf911 feat: auto-connect saved Wi-Fi networks (#2189)
Co-authored-by: Alexander Hoffer <git@alexanderhoffer.com>
2026-07-11 22:47:26 -04:00
Justin Mitchell 3e627112f6 fix: oom exceptions for OPDS, KOSync, and OTA via wolfssl (#2475) 2026-07-12 01:53:26 +03:00
4fb843ef92 perf: skip redundant progress writes when position is unchanged (#2436)
Co-authored-by: Erica Jensen <erica@mailershaven.com>
Co-authored-by: Uri Tauber <uritaube@gmail.com>
2026-07-10 10:37:43 +03:00
Justin Mitchell cecdbefa0e Normalize whitespace in comments and includes
Standardize spacing in inline comments and remove extra blank line in include statement for consistency
2026-07-09 00:21:25 -04:00
Justin Mitchell 4c5fd653c0 Add Bluetooth status icon to reader status bar
Display a Bluetooth icon in the status bar when BLE is connected. Also optimize memory management by lending the framebuffer instead of immediately tearing down BLE when heap is low, allowing BLE to remain active during rendering.
2026-07-09 00:13:54 -04:00
Justin Mitchell 05c1e9aa46 Add framebuffer lending for memory-intensive builds
Temporarily release framebuffer memory during section pagination to reduce heap pressure. The framebuffer can be released before memory-intensive operations and restored afterward, allowing BLE stack startup threshold to be lowered from 80KB to 70KB. Implements RAII-style FrameBufferBuildLoan class to ensure proper cleanup and automatic restart on restoration failure.
2026-07-09 00:04:11 -04:00
Justin Mitchell f3da5e4f06 Merge branch 'develop' of https://github.com/crosspoint-reader/crosspoint-reader into feat-bluetooth 2026-07-08 22:13:16 -04:00
Uri Tauber 7ec07b4d9d fix: show "Failed to index" when failing to parse epub (#2556) 2026-07-08 21:22:35 +03:00
Uri Tauber c2c1badc7e chore: Refactor stores to use PersistableStore CRTP template (#2464) 2026-07-08 12:44:52 +03:00
Pietro Campagnano 3c5c5e8aa7 feat: preview image files inline in web file browser (#2429) 2026-07-06 16:45:22 -04:00
Justin Mitchell 6f0707e83c Suppress cppcheck warnings for CI compatibility
Add missingInclude suppression to prevent false positives on fresh CI checkouts where include paths are unresolved. Add inline suppression for constVariableReference warning where cppcheck cannot detect mutations without full include path resolution.
2026-07-06 08:55:24 -04:00
Justin Mitchell 7b6df60a54 Shrink NimBLE footprint to prevent stack overflow
Reduce BLE stack memory usage from ~68KB to ~52KB by disabling unused NimBLE roles (peripheral, broadcaster), limiting connections to 1, and reducing buffer counts for ACL, HCI events, and ATT entries. Remove unused cloud components (esp_insights, esp_rainmaker) that require unavailable server certificates. These changes prevent stack collision with the render shed, eliminating restart flaps on the reader device.
2026-07-06 08:48:44 -04:00
Justin Mitchell 1c13913713 Implement keep-if-fits buffer reuse to reduce heap fragmentation
Replace per-page buffer free+realloc pattern with capacity tracking that only reallocates when needed size exceeds current capacity. This prevents heap fragmentation from non-coalescing holes that occurred when each page's freed block rarely fit the next page's allocation. After a few page turns, capacities converge on the book's maximum and page turns stop touching the allocator entirely.
2026-07-06 08:30:17 -04:00
Justin Mitchell 613371b716 Add heap pressure management for BLE and rendering
Prevent OOM aborts by shedding BLE stack when free heap drops below 24KB before rendering. Lower BLE start threshold from 100KB to 80KB to match steady-state heap levels (~84KB). Reserve vector capacity upfront in page parsing to avoid reallocation crashes on fragmented heaps. Gate background section builds on heap availability.
2026-07-06 08:12:11 -04:00
Justin Mitchell 0d7a84e3c5 Rename variable count to scanCount for clarity
Improves code readability by using a more descriptive variable name that better indicates the variable holds the device count from a BLE scan.
2026-07-06 02:23:04 -04:00
Justin Mitchell 4c93950771 Merge branch 'pr-2527' into feat-bluetooth
# Conflicts:
#	src/activities/reader/EpubReaderActivity.cpp
2026-07-06 02:10:55 -04:00
Justin Mitchell 1d01eebf55 Reformat Bluetooth scan log statement 2026-07-06 02:06:25 -04:00
Justin Mitchell 9bf6e5f43c Merge remote-tracking branch 'origin/develop' into feat-bluetooth
# Conflicts:
#	.gitmodules
#	freeink-sdk
#	platformio.ini
#	src/activities/reader/EpubReaderActivity.cpp
2026-07-06 02:04:38 -04:00
Jacob Latonis ca1b833126 fix: follow spec for zxing qr code generation (#2540) 2026-07-06 00:33:34 +03:00
Tom-Inge Larsen 3e1dd31e53 feat(reader): End of Book next-book suggestions (#2499) (#2532) 2026-07-04 23:12:59 +03:00
685d4e88f9 feat: Lazy incremental EPUB section indexing (#2452)
Co-authored-by: Uri Tauber <uritaube@gmail.com>
Co-authored-by: Julia Nguyen <julia@uxj.io>
2026-07-04 21:21:24 +03:00
Jakub Sypiański 79b4d63ee2 fix: settings persist on font clear, reserve() before push_back, minor (#2519) 2026-07-03 18:58:24 +03:00
Nick ad3138983b fix: clear the BT-paused popup with an immediate redraw (toast semantics)
The popup lingered until the next page turn. E-ink has no free timers --
clearing costs a refresh whenever it happens -- so request the redraw
right away: the popup shows for the ~2 s page re-render, then clears.
2026-07-02 17:25:34 -05:00
Nick 793685e76b feat: user path to resume BT from low-memory pause via reader menu toggle
Field session: after a recovery teardown the heap settles at ~72 KB --
below the 100 KB start floor -- and never recovers on its own (the
defrag silent-restart only fires when a build FAILS, and builds succeed
now). BT stayed paused forever, the menu toggle claimed ON, and toggling
off/on changed nothing.

- Menu label tells the truth: ON / PAUSED (enabled but stack down) / OFF
  (new STR_STATE_PAUSED string)
- Toggling BT on below the heap floor silent-restarts into the current
  book: the fresh boot's ~118 KB passes the gate and BT auto-starts on
  resume. Explicit user intent is the right trigger for the defrag.
- Hoist the floor to bleinput::kStartMinFreeHeap, shared by the
  lifecycle gate and the toggle
2026-07-02 17:25:34 -05:00
Nick 551d29744a fix: stop BLE lifecycle oscillation after build recovery
The 70 KB restart floor was arithmetic nonsense: NimBLE takes ~57 KB, so
a restart at 70 KB free left ~13 KB -- below the 40 KB build pre-flight
-- so the next chapter build instantly re-entered recovery and tore BLE
back down. Field symptom: endless 'BT Connecting...' popup + redraw loop.

- Single conservative floor: 100 KB (57 KB stack + 40 KB build headroom)
- 30 s cool-down after any recovery teardown before the lifecycle may
  restart BLE, so a marginal heap can never flap; the 'BT paused (low
  memory)' popup shows instead and reading continues without the remote
2026-07-02 17:25:10 -05:00
Nick 74a0969cc6 fix: pre-flight heap floor before section builds; no inline BLE restart
Layout code (line-break DP arrays, CSS lookups, glyph buffers) allocates
via std::vector/std::string and abort()s on OOM under -fno-exceptions --
it cannot fail cleanly mid-build. Field crashes (X4, BLE resident):
builds entered at ~11 KB free and aborted in ParsedText::
computeLineBreaks; an inline BLE restart after recovery re-starved the
render and abort()ed in FontCacheManager's scanText_.reserve at ~8 KB.

- BUILD_MIN_FREE_HEAP (40 KB): pre-flight before the build; below the
  floor go straight to recovery instead of attempting a doomed build
- Recovery no longer restarts NimBLE inline; the lifecycle stays paused
  until the render completes (scoped unpause guard), then the main-loop
  lifecycle restarts BLE behind its own heap gate
2026-07-02 17:24:29 -05:00
Nick 06aa1ac2f7 feat: silent-restart defrag on section-build double failure + BLE debug flags
- EpubReaderActivity: when a section build fails even after the BLE
  teardown/retry, silentRestartToReader() as last-resort heap defrag,
  guarded by bootWasSilentRestart() to prevent reboot loops
- main/SilentRestart.h: expose bootWasSilentRestart()
- platformio.ini: enable FREEINK_BLE_HID_REPORT_DEBUG in env:default
2026-07-02 17:20:51 -05:00
Rahat Ahmed 5c86bfe1fd feat(network): add device serial number to web UI (#2506) 2026-07-02 00:53:55 +03:00
Justin Mitchell c463da994e Add BLE lifecycle pause mechanism for memory mgmt
Introduces a global pause flag to temporarily block BLE stack auto-start during large memory allocations (e.g., in EPUB rendering). Also adds auto-restart logic for BLE scanning when device list is empty, and extensive debug logging for BLE scan lifecycle troubleshooting.
2026-06-30 16:31:54 -04:00
Tom-Inge LarsenandClaude Opus 4.8 e4d3981469 fix(reader): correct slider side-button direction and legend on X3 (#2402) (#2428)
## Summary

* **What is the goal of this PR?** Fixes #2402. On the X3, the "Time to
Sleep"
picker's 5-minute side buttons were inverted (left increased, right
decreased)
  and the on-screen legend didn't match the physical buttons.
* **What changes are included?**
  * Flip the large-step (±5 min) direction on X3 so the left side button
decreases and the right increases, matching the layout. X4 is unchanged.
* Add a device-specific step-hint string
(`STR_SLEEP_TIMER_STEP_HINT_X3`)
selected via `gpio.deviceIsX3()`. X3 shows `+/-: 1 min Side buttons: 5
min`;
    X4 keeps the original `Left/Right: 1 min  Up/Down: 5 min`.
* Same fix applied to both slider pickers that read the raw up/down side
    buttons: the Time-to-Sleep picker and the "Go to %" picker
(`EpubReaderPercentSelectionActivity`), each with its own X3 hint string
    (`STR_SLEEP_TIMER_STEP_HINT_X3`, `STR_PERCENT_STEP_HINT_X3`).

## Additional Context

* **Root cause:** the X3's side buttons sit one on each edge of the
screen
(power on top), whereas the X4 has a vertical up/down rocker on the
right
edge. So `BTN_UP` is physically the *left* button on X3 but the *top*
button
  on X4. The picker mapped up→+5 / down→−5 unconditionally, which reads
naturally on the X4 rocker but inverted on the X3's left/right buttons.
The
  static legend ("Up/Down: 5 min") had the same X3-only mismatch.
* The codebase already detects the device at runtime and handles this
layout
difference elsewhere (e.g. `LyraTheme::drawSideButtonHints` draws "Up on
left,
Down on right" for X3), so this reuses the same `gpio.deviceIsX3()`
signal.
* Swept the codebase for other side-button sliders:
`ClockOffsetActivity` already
uses the `Next/Previous` (`ButtonNavigator`) abstraction, which resolves
to
left=decrement / right=increment on X3, so it needs no change. List/page
navigation (Wi-Fi, KOReader sync, BMP viewer) and the keyboard cursor
are also
unaffected. The two slider pickers above were the only ones using raw
up/down.
* **X4 is untouched** — same direction, same legend wording as before.
* **Tested on X3 hardware:** left side button now decreases, right
increases, and
  the legend matches. X4 not yet tested on device (no unit on hand); its
  behaviour and strings are unchanged from master.
* **Translations:** the new `STR_SLEEP_TIMER_STEP_HINT_X3` and
`STR_PERCENT_STEP_HINT_X3` were added to all 26 languages, but the
non-English
  ones are AI-generated and would benefit from a native-speaker pass —
particularly Hebrew (RTL ordering with a leading `+/-`), Kazakh, and
Vietnamese.

---

### AI Usage

Did you use AI tools to help write this code? _**YES**_

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 11:06:31 -04:00
Bastian 13bd00bf9d fix: sort sleep screen menu options to be more logically consistent (#2480) 2026-06-30 08:47:25 +03:00
Uri Tauberandpablohc fef39da23c feat: Selection Popup (#2358)
Co-authored-by: pablohc <pablonoviello@outlook.com>
2026-06-29 16:59:25 -04:00
Uri Tauber fd43ca2fe1 chore: Initial multi-core compatibility (#2294) 2026-06-29 21:57:21 +03:00
Pietro Campagnano 28255061fb fix(icons): align home menu icons with their labels (#2470) 2026-06-29 13:59:54 -04:00
Justin Mitchell 6edeed73c5 fix: x4 sleep/boot ghosting (#2471) 2026-06-29 12:04:33 +03:00
Julia Nguyen b6ce599b20 fix: address release review feedback 2026-06-26 16:22:20 -04:00