Thursday, July 18, 2013

txtr Beagle - part 3 - storage and transfer protocol

I'm wrapping this up for now as one of the COG (chip-on-glass) devices has apparently fried and the reader has sold out.

UPDATE: Andreas Schier has written an open-source java toolchain for Beagle:

UPDATE: Florian Echtler has built two Python scripts, one emulating the server and another one for the client. The server allows you to send images to your reader:

Part 1:

Part 2:

Part 4:

Part 5:

I've scratched some of the white glue-like stuff away but the burn can be seen inside the glass. It was drawing abour 1A upon changing pages and the COG was getting very hot.

The current consumption seems to be at around 200mA when changing pages, 140mA when bluetooth is on and <10mA when running.

SD-card organization

The card is used as a raw continuous "file" split up into page sizes of 40000h (262144 bytes). The first page is just some setup and internal data (I assume) along with perhaps some indexes.
Starting with 40000h, each multiple of that contains one raw image: 40000h-7A980h, with the rest of the space containing 8 bytes of EOF(?) and blank data until the next mark (80000h).

The size 3A980h (240000 decimal) corresponds to a screen resolution of 600x800x4bpp, consistent to what the code was suggesting.
From each nibble only the upper 3 bits are used and the lower (LSB) one is left blank, not sure why. This means that there are 8 possible grayscale values.

I used IrfanViewer with a bit of the dataand the settings on the right. The result is on the left, at half width (IrfanView does not provide a 4bpp raw mode).

The second file requires a height of 800 confirming the correct data layout.

On my card the data stops at around the 16644610h mark, leading to a page count of 1565, consistent to the book loaded on it.

Transfer protocol

I haven't tested everything so I'm just describing what I could figure out by reverse-engineering.
The pages are rendered in grayscale on the Android device as described in the previous post. Prior to sending, a native method is called which converts the data into a bitmap of 600x800x4bpp and then compresses it using the standard DEFLATE algorithm.

The compressed byte[] array is then returned to the Dalvik code which sends it via bluetooth using the "PAGE " command. This particular command takes two parameters, the first one being the page number and the second one the byte[], one after another.
It's possible that the byte array is Base64-encoded, I haven't checked that.

In order to send a page, a new book must be started. This requires sending "BOOK ID="+number, "TITLE "+title, "AUTHOR "+author. After finalizing the transfer the "ENDBOOK" command is sent.

A good practice would be to check for all the acknowledgements and error codes sent back by the reader: BOOKOKTITLEOKAUTHOROKDELETEBOOKOKENDBOOKOK, PAGEOK.

I haven't touched upon the issue of pairing and partnership. This is done through commands like VIRGIN (remove partnership), GETPARTNER (returns NOPARTNER or a PARTNER_ID) and PARTNER_ID=(partners the phone with the reader through a generated 16 character hexadecimal string).

Post Scriptum

I would love if people that get their hands on them will start using the reader as a low-cost, low-power, large-area display alternative. The reader already provides plenty of 3.3V power, microSD slot and storage with breakout pads for the SPI and breakout for the BT module.
So the idea would be to turn the reader off, write custom data to the card, turn the reader back on. This was the main reason why I pulled this thing apart and documented the storage format.

Another idea would be to have another uC listen in on the BT connections while the reader is off (the cover screen can be replaced) and wake the reader up once-in-a-while to update the display and cover. The cover will only get updated while the device is powered on.


  1. Where is part 1?
    My beagle broke and I want to open it... :-/

    1. Sorry, the link was broken, I've updated it just now.
      There's not much you can do to open the reader, it's glued (or plastic welded) shut. I've used a screwdriver and guitar picks to unglue it, but I've also broken it in the process. Maybe using a hairdryer would help soften the glue/plastic.

      Try not to use hard parts (screwdriver) near the screen edges, that's how I've damaged mine.

      I would say it's probably unfixable anyway.