/ README.md
README.md
1 # SignalOS 2 3 Open-source e-reader firmware for the Xteink X4. ESP32-C3. 380KB RAM. No telemetry. No accounts. Just reading. 4 5 A [DWS Engineering](https://dws.rip) project. 6 7  8 9 --- 10 11 ## Why SignalOS? 12 13 The Xteink X4 is a fun, hackable device with solid hardware. But the stock firmware is closed-source and requires converting your EPUBs to XTC format for the best experience. No custom fonts. No WiFi transfers. No theming. 14 15 **SignalOS changes the equation.** 16 17 We started with the excellent [Papyrix Reader](https://github.com/bigbag/papyrix-reader) — open-source firmware that already brings EPUB support, WiFi transfers, and custom themes to the X4. Then we made it better for serious readers. 18 19 **What we added:** 20 21 - **In-reader menu** — TOC, bookmarks, and reading stats without leaving your book 22 - **Library indexing** — Browse thousands of books with pagination 23 - **File management** — Delete files and folders directly on the device 24 - **Configurable action button** — Instant bookmark or TOC access 25 - **Reading time tracking** — See how long you've spent with each book 26 - **Quote-based sleep screen** — Literary quotes instead of blank screens 27 - **UI consistency** — Coherent design across all screens 28 - **Stability hardening** — Runs smoothly on 380KB RAM 29 30 **The bottom line:** Native EPUB support, custom fonts, WiFi transfers, Calibre sync, and a refined interface that gets out of your way. 31 32 It's your device. Read however you want. 33 34 Not affiliated with Xteink. 35 36 --- 37 38 ## Documentation 39 40 [User Guide](docs/user_guide.md) · [Customization](docs/customization.md) · [Fonts](docs/fonts.md) · [Architecture](docs/architecture.md) · [Device Specs](docs/device-specifications.md) · [File Formats](docs/file-formats.md) · [Images](docs/images.md) · [Webserver](docs/webserver.md) · [Calibre](docs/calibre.md) · [Changelog](CHANGELOG.md) 41 42 --- 43 44 ## Features 45 46 ### What Makes SignalOS Different 47 48 **Reading Experience** 49 - In-reader menu with TOC, bookmarks, and reading stats 50 - Configurable action button for instant bookmark or TOC 51 - Library indexing with pagination and folder position memory 52 - File and folder deletion from the device 53 - Reading time tracking 54 55 **Design** 56 - Quote-based sleep screen with literary excerpts 57 - Refreshed sleep screen visuals 58 - Consistent UI across all views 59 - Clear button bar indicators 60 61 **Performance & Stability** 62 - Reader hardening with cache reset on failure 63 - Deadlock avoidance and mutex timeout protection 64 - Parser safety with limits for fonts, themes, and EPUBs 65 - Defensive memory management 66 67 ### Core Capabilities 68 69 **Formats** 70 - EPUB 2/3 — Full CSS parsing, nav.xhtml + NCX fallback, inline images (JPEG/PNG/BMP up to 2048×3072) 71 - XTC/XTCH — Native compressed format 72 - Markdown & Plain Text — Clean rendering with ATX headers 73 - Book Covers — JPG/PNG/BMP with dithering options 74 75 **Typography** 76 - Knuth-Plass line breaking (TeX-quality justified text) 77 - CJK & Thai text layout with proper mark positioning 78 - 3 font sizes, 4 alignments, 4 text layout presets 79 - Streaming font system with LRU cache for memory-efficient custom fonts 80 81 **Display** 82 - Line spacing: compact, normal, relaxed, large 83 - Pages per refresh: 1/5/10/15/30 84 - 4 screen orientations 85 - Sunlight fading fix (display power-down after refresh) 86 87 **Customization** 88 - Custom themes from `/config/themes/` 89 - Custom fonts from `/config/fonts/` (`.epdfont` format) 90 - Sleep screens: dark, light, custom image, or book cover 91 - Button remapping (side or bottom page turn) 92 - Power button page turn for one-handed reading 93 94 **Connectivity** 95 - WiFi file transfer via built-in web server 96 - Calibre Wireless Device support 97 98 **File System** 99 - exFAT and FAT32 support 100 - UTF-8 filenames (Cyrillic, CJK, etc.) 101 - Nested folder browser 102 - Library indexing 103 104 Example themes and fonts: [`docs/examples/`](docs/examples/) 105 106 --- 107 108 ## Installation 109 110 ### Flasher (Recommended) 111 112 [signalos-flasher](https://github.com/dws-signal/signalos-flasher) — Cross-platform CLI with auto-detection. 113 114 ```bash 115 signalos-flasher flash firmware.bin 116 ``` 117 118 ### From Source 119 120 See [Development](#development). 121 122 --- 123 124 ## Development 125 126 ### Prerequisites 127 128 - PlatformIO (`pio` CLI or VS Code extension) 129 - Node.js 18+ (build scripts) 130 - USB-C cable 131 - Xteink X4 132 133 ### Nix (Recommended) 134 135 All dependencies via `shell.nix`: 136 137 ```bash 138 nix-shell 139 make build 140 ``` 141 142 <details> 143 <summary>First-time Nix setup</summary> 144 145 ```bash 146 sh <(curl -L https://nixos.org/nix/install) --daemon 147 nix-channel --add https://nixos.org/channels/nixos-unstable nixpkgs 148 nix-channel --update 149 ``` 150 151 </details> 152 153 ### Clone 154 155 ```bash 156 git clone --recursive https://github.com/dws-signal/dws-signal 157 158 # Already cloned without --recursive: 159 git submodule update --init --recursive 160 ``` 161 162 ### Build 163 164 ```bash 165 make build # Debug 166 make release # Release 167 pio run # PlatformIO directly 168 ``` 169 170 ### Flash 171 172 Connect Xteink X4 via USB-C: 173 174 ```bash 175 make flash 176 # or 177 pio run --target upload 178 ``` 179 180 Manual flash with esptool: 181 182 ```bash 183 esptool.py --chip esp32c3 --port /dev/ttyACM0 --baud 460800 \ 184 write_flash -z 0x0 firmware.bin 185 ``` 186 187 Port varies: `COM3` (Windows), `/dev/tty.usbmodem*` (macOS), `/dev/ttyACM0` (Linux). 188 189 ### Build Scripts 190 191 All in `scripts/`. Require Node.js 18+. 192 193 ```bash 194 cd scripts && npm install 195 ``` 196 197 #### Fonts 198 199 Convert TTF/OTF to `.epdfont`: 200 201 ```bash 202 cd scripts 203 204 # Basic 205 node convert-fonts.mjs my-font -r MyFont-Regular.ttf 206 207 # Full family 208 node convert-fonts.mjs my-font -r Regular.ttf -b Bold.ttf -i Italic.ttf --all-sizes 209 210 # Variable font weight 211 node convert-fonts.mjs roboto -r Roboto-Variable.ttf --var wght=400 212 213 # CJK/Thai (streamed .bin format) 214 node convert-fonts.mjs noto-cjk -r NotoSansSC-Regular.ttf --bin --size 24 215 216 # Preview 217 node convert-fonts.mjs my-font -r MyFont-Regular.ttf --preview 218 ``` 219 220 See [font docs](docs/fonts.md). 221 222 #### Sleep Screens 223 224 ```bash 225 make sleep-screen INPUT=photo.jpg OUTPUT=sleep.bmp 226 make sleep-screen INPUT=photo.jpg OUTPUT=sleep.bmp ARGS='--dither --bits 8' 227 ``` 228 229 Options: `--orientation portrait|landscape`, `--bits 2|4|8`, `--dither`, `--fit contain|cover|stretch` 230 231 Copy output to `/sleep/` or `/sleep.bmp` on SD card. 232 233 #### Logo 234 235 128×128 monochrome, converted to C header: 236 237 ```bash 238 cd scripts && node convert-logo.mjs logo.png ../src/images/SignalOSLogo.h 239 ``` 240 241 #### Calibre Simulators 242 243 Test Calibre Wireless without hardware: 244 245 ```bash 246 cd scripts 247 node device-simulator.mjs # Simulate SignalOS device 248 node calibre-simulator.mjs # Simulate Calibre desktop 249 ``` 250 251 ### Releases 252 253 ```bash 254 make gh-release VERSION=0.1.1 255 make gh-release VERSION=0.1.1 NOTES="Release notes" 256 make changelog 257 ``` 258 259 --- 260 261 ## Architecture 262 263 380KB of RAM. Every byte matters. 264 265 SignalOS is built for predictable performance on constrained hardware. 266 267 ### Core Design 268 269 - **State machine** — 10 pre-allocated states, no dynamic allocation after init 270 - **Dual-boot** — UI mode (full features) vs Reader mode (minimal RAM). Device restarts between modes to reclaim memory 271 - **Content providers** — Unified `ContentHandle` for EPUB, XTC, TXT, Markdown 272 - **Page cache** — Partial caching with background pre-rendering 273 274 ### Memory Management 275 276 The ESP32 WiFi stack allocates ~100KB and fragments heap irreversibly. After WiFi features, the device restarts to reclaim memory. This is by design. 277 278 ### Performance 279 280 | Optimization | Technique | 281 |-------------|-----------| 282 | EPUB spine/TOC lookup | FNV-1a hash maps, O(1) | 283 | Glyph cache | FNV-1a hash, O(1) | 284 | XTC rendering | Byte-level 1-bit processing | 285 | Image compression | CCITT Group5 for fast decompression | 286 | Word width cache | 512-entry cache | 287 | Image cache | Convert once, cache to SD | 288 | Font streaming | LRU cache for custom fonts | 289 290 ### Cache 291 292 Chapters are cached to SD on first load. Subsequent reads served from cache. 293 294 ``` 295 .signalos/ 296 ├── epub_<hash>/ 297 │ ├── progress.bin # Reading progress 298 │ ├── cover.bmp # Cover image 299 │ ├── book.bin # Metadata 300 │ ├── sections/ 301 │ │ └── 0.bin # Chapter data 302 │ └── images/ 303 │ └── <hash>.bmp # Inline images 304 ├── txt_<hash>/ 305 │ ├── progress.bin 306 │ ├── index.bin 307 │ └── cover.bmp 308 └── md_<hash>/ 309 ├── progress.bin 310 ├── section.bin 311 └── cover.bmp 312 ``` 313 314 Clear via **Settings > Cleanup** or delete `.signalos/` manually. 315 316 See [file formats](docs/file-formats.md). 317 318 --- 319 320 ## Related Tools 321 322 - [epub-to-xtc-converter](https://github.com/bigbag/epub-to-xtc-converter) — Browser-based EPUB to XTC/XTCH converter 323 - [xteink-epub-optimizer](https://github.com/bigbag/xteink-epub-optimizer) — CLI to optimize EPUBs for 480×800 e-ink 324 325 --- 326 327 ## Contributing 328 329 1. Fork 330 2. Branch (`feature/your-feature`) 331 3. PR 332 333 --- 334 335 ## Acknowledgments 336 337 - **[Papyrix](https://github.com/bigbag/papyrix-reader)** — Pavel Liashkov. Direct upstream. Calibre Wireless, custom themes, Thai rendering, many UI improvements. 338 - **[CrossPoint Reader](https://github.com/daveallie/crosspoint-reader)** — Dave Allie. Original open-source X4 firmware. 339 - **[bb_epaper](https://github.com/bitbank2/bb_epaper)** — Larry Bank. Hardware insights, e-paper driver. 340 - **[MD4C](https://github.com/mity/md4c)** — Martin Mitas. Markdown parser. 341 - **[microreader](https://github.com/CidVonHighwind/microreader)** — CidVonHighwind. CSS parser. 342 343 --- 344 345 **[DWS Engineering LLC](https://dws.rip)** — It's your internet. Take it back. 346 347 Not affiliated with Xteink. 348 349 © 2026 DWS Engineering LLC