# CrossPoint Reader Firmware for **Xteink** e-paper display readers (X3 and X4) (unaffiliated with Xteink). Built using **PlatformIO** and targeting the **ESP32-C3** microcontroller. CrossPoint Reader is a purpose-built firmware designed to be a drop-in, fully open-source replacement for the official Xteink firmware. It aims to match or improve upon the standard EPUB reading experience. ![](./docs/images/cover.jpg) ## Motivation E-paper devices are fantastic for reading, but most commercially available readers are closed systems with limited customisation. **Xteink** devices (such as the X3 and X4) are affordable e-paper readers, however the official firmware remains closed. CrossPoint exists partly as a fun side-project and partly to open up the ecosystem and truly unlock the device's potential. CrossPoint Reader aims to: * Provide a **fully open-source alternative** to the official firmware. * Offer a **document reader** capable of handling EPUB content on constrained hardware. * Support **customisable font, layout, and display** options. * Run purely on **Xteink hardware**. This project is **not affiliated with Xteink**; it's built as a community project. ## Features & Usage - [x] EPUB parsing and rendering (EPUB 2 and EPUB 3) - [x] Image support within EPUB - [x] Saved reading position - [x] File explorer with file picker - [x] Basic EPUB picker from root directory - [x] Support nested folders - [ ] EPUB picker with cover art - [x] Custom sleep screen - [x] Cover sleep screen - [x] Wifi book upload - [x] Wifi OTA updates - [x] KOReader Sync integration for cross-device reading progress - [x] Configurable font, layout, and display options - [ ] User provided fonts - [ ] Full UTF support - [x] Screen rotation Multi-language support: Read EPUBs in various languages, including English, Spanish, French, German, Italian, Portuguese, Russian, Ukrainian, Polish, Swedish, Norwegian, [and more](./USER_GUIDE.md#supported-languages). See [the user guide](./USER_GUIDE.md) for instructions on operating CrossPoint, including the [KOReader Sync quick setup](./USER_GUIDE.md#367-koreader-sync-quick-setup). For more details about the scope of the project, see the [SCOPE.md](SCOPE.md) document. ## USB-locked devices (Xteink Unlocker) Some Xteink units purchased from third-party stores (e.g. AliExpress) ship with USB flashing locked from the factory. If your device is locked, you will need to use the **Xteink Unlocker** tool available at https://crosspointreader.com/#unlock-tool before you can flash CrossPoint. **You do not need this tool if you bought your device directly from xteink.com.** Those units are not locked. **Not sure if your device is locked?** Power it on, connect the USB-C cable, and try flashing via the web flasher first (see [Installing](#installing) below). If the browser's serial device picker does not show your device, try a different USB port or browser before assuming the device is locked. Only reach for the unlocker if the device still doesn't appear. > ### ⚠️ WARNING: READ THIS BEFORE USING THE UNLOCKER ⚠️ > > **The only officially supported firmwares in the unlock tool are CrossPoint and CrossInk.** > > Flashing any other firmware on a USB-locked device may **permanently brick the device** or leave it **permanently > stuck on that firmware with no recovery path**. Once USB flashing is re-locked, your only way back is via OTA, and if > the firmware you flashed doesn't support OTA, **there is no way out**. > > **The Papyrix fork has removed OTA update support from its code.** If you flash Papyrix onto a > USB-locked unit, you will have **zero update or recovery path** and will be stuck on it forever. **Do not flash > Papyrix (or any other unsupported firmware) on a locked device.** ## Installing ### Web (latest firmware) 1. Connect your Xteink device to your computer via USB-C and wake/unlock the device 2. Go to https://xteink.dve.al/ and click "Flash CrossPoint firmware" To revert back to the official firmware, you can flash the latest official firmware from https://xteink.dve.al/, or swap back to the other partition using the "Swap boot partition" button here https://xteink.dve.al/debug. ### Web (specific firmware version) 1. Connect your Xteink device to your computer via USB-C 2. Download the `firmware.bin` file from the release of your choice via the [releases page](https://github.com/crosspoint-reader/crosspoint-reader/releases) 3. Go to https://xteink.dve.al/ and flash the firmware file using the "OTA fast flash controls" section To revert back to the official firmware, you can flash the latest official firmware from https://xteink.dve.al/, or swap back to the other partition using the "Swap boot partition" button here https://xteink.dve.al/debug. ### Command line (specific firmware version) 1. Install [`esptool`](https://github.com/espressif/esptool) : ```bash pip install esptool ``` 2. Download the `firmware.bin` file from the release of your choice via the [releases page](https://github.com/crosspoint-reader/crosspoint-reader/releases) 3. Connect your Xteink device to your computer via USB-C. 4. Note the device location. On Linux, run `dmesg` after connecting. On MacOS, run : ```bash log stream --predicate 'subsystem == "com.apple.iokit"' --info ``` 5. Flash the firmware : ```bash esptool.py --chip esp32c3 --port /dev/ttyACM0 --baud 921600 write_flash 0x10000 /path/to/firmware.bin ``` Change `/dev/ttyACM0` to the device for your system. ### Manual See [Development](#development) below. ## Development ### Prerequisites * **PlatformIO Core** (`pio`) or **VS Code + PlatformIO IDE** * Python 3.8+ * USB-C cable for flashing the ESP32-C3 * Xteink device (X3 or X4) ### Checking out the code CrossPoint uses PlatformIO for building and flashing the firmware. To get started, clone the repository: ``` git clone --recursive https://github.com/crosspoint-reader/crosspoint-reader # Or, if you've already cloned without --recursive: git submodule update --init --recursive ``` ### Flashing your device Connect your Xteink device to your computer via USB-C and run the following command. ```sh pio run --target upload ``` ### Debugging After flashing the new features, it’s recommended to capture detailed logs from the serial port. First, make sure all required Python packages are installed: ```python python3 -m pip install pyserial colorama matplotlib ``` after that run the script: ```sh # For Linux # This was tested on Debian and should work on most Linux systems. python3 scripts/debugging_monitor.py # For macOS python3 scripts/debugging_monitor.py /dev/cu.usbmodem2101 ``` Minor adjustments may be required for Windows. ## Internals CrossPoint Reader is pretty aggressive about caching data down to the SD card to minimise RAM usage. The ESP32-C3 only has ~380KB of usable RAM, so we have to be careful. A lot of the decisions made in the design of the firmware were based on this constraint. ### Data caching The first time chapters of a book are loaded, they are cached to the SD card. Subsequent loads are served from the cache. This cache directory exists at `.crosspoint` on the SD card. The structure is as follows: ``` .crosspoint/ ├── epub_12471232/ # Each EPUB is cached to a subdirectory named `epub_` │ ├── progress.bin # Stores reading progress (chapter, page, etc.) │ ├── cover.bmp # Book cover image (once generated) │ ├── book.bin # Book metadata (title, author, spine, table of contents, etc.) │ └── sections/ # All chapter data is stored in the sections subdirectory │ ├── 0.bin # Chapter data (screen count, all text layout info, etc.) │ ├── 1.bin # files are named by their index in the spine │ └── ... │ └── epub_189013891/ ``` Deleting the `.crosspoint` directory will clear the entire cache. Due the way it's currently implemented, the cache is not automatically cleared when a book is deleted and moving a book file will use a new cache directory, resetting the reading progress. For more details on the internal file structures, see the [file formats document](./docs/file-formats.md). ## Contributing Contributions are very welcome! If you are new to the codebase, start with the [contributing docs](./docs/contributing/README.md). If you're looking for a way to help out, take a look at the [ideas discussion board](https://github.com/crosspoint-reader/crosspoint-reader/discussions/categories/ideas). If there's something there you'd like to work on, leave a comment so that we can avoid duplicated effort. Everyone here is a volunteer, so please be respectful and patient. For more details on our governance and community principles, please see [GOVERNANCE.md](GOVERNANCE.md). ### To submit a contribution: 1. Fork the repo 2. Create a branch (`feature/dithering-improvement`) 3. Make changes 4. Submit a PR --- CrossPoint Reader is **not affiliated with Xteink or any manufacturer of the hardware**. Huge shoutout to [**diy-esp32-epub-reader** by atomic14](https://github.com/atomic14/diy-esp32-epub-reader), which was a project I took a lot of inspiration from as I was making CrossPoint.