diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 90 |
1 files changed, 68 insertions, 22 deletions
@@ -139,28 +139,74 @@ Send chunks sequentially with ~100ms delay between each. ### enterMakeDial (watch face) -Watch face header packet (write/6E40FC20) -``` -byte[0] = 0xE4 (ZK_DIAL command) -byte[1] = 0x51 (mode flag) -byte[2] = 0x01 (start) -byte[3] = 0x00 -byte[4-5] = total packet count (big endian) -byte[6-9] = total image bytes (big endian) -byte[10] = 0x00 -byte[11-12] = MTU size (big endian) -byte[13] = rotation flag -byte[14] = 0x01 -byte[15] = time text direction -byte[16] = 0x00 -byte[17-18] = transparent color (RGB565) -byte[19-20] = checksum (sum of all image bytes, big endian) -byte[21] = show date (0x01 = yes, 0x00 = no) -``` - -Header packet is followed by chunked RGB565 data, 1 chunk = MTU-14 bytes - -This function/protocol has not been tested yet, don't expect this structure of headers and RGB565 data to work at the moment. Could very well change drastically if other parts of the protocol are found +This protocol sends a custom watchface to the watch. The watch expects raw RGB565 pixel data, sent in chunks. + +Protocol flow: + +1. Send header packet (command 0x51) +2. Wait for ACK from watch +3. Send data chunks (command 0x52) +4. Wait for ACK after each chunk + +Watchface header packet (write/6E40FC20): +``` +byte[0] = 0xE4 (ZK_DIAL command) +byte[1] = 0x51 (mode flag) +byte[2] = 0x01 +byte[3] = 0x00 +byte[4-5] = total packet count (big endian) +byte[6-9] = total image bytes (big endian) = width * height * 2 +byte[10] = 0x00 (unknown, padding) +byte[11-12] = chunk size (big endian, usually 140) +byte[13] = dial type (0x01 = background, 0x02 = full watchface) +byte[14] = 0x01 (always) +byte[15] = UI overlay enable (0x00 = no UI, 0x01 = show time/date) +byte[16] = 0x00 (padding) +byte[17-18] = text color (RGB565, big endian) +byte[19-20] = checksum (sum of all pixel bytes, big endian) +byte[21] = hide date flag (0x00 = show date, 0x01 = hide date) +``` + +Data chunk packet (write/6E40FC20) +``` +byte[0-3] = 0xE4, 0x52, 0x01, 0x02 (command) +byte[4-5] = chunk number (1-indexed, big endian) +byte[6-9] = byte offset (big endian) +byte[10] = progress percentage (0-100) +byte[11] = last chunk flag (0x01 if last, else 0x00) +byte[12-13] = checksum (sum of header[0:14] + data bytes, big endian) +byte[14+] = raw RGB565 pixel data (up to chunk size bytes) +``` + + +**Image format:** +- Resolution: 240x296 (actual display size, not 240x280 as advertised) +- Format: Raw RGB565, no headers +- Byte order: High byte first, low byte second (big endian) +- Pixel layout: Top to bottom, left to right +- Color conversion: RGB888 -> RGB565 = ((R>>3)<<11) | ((G>>2)<<5) | (B>>3) + +**MTU/chunk settings:** +- Fixed packet size: 148 bytes +- Data payload per chunk: 140 bytes +- Header size: 14 bytes + +**Chunked data example:** +- 240x296 = 142,080 bytes total +- 142,080 / 140 = 1,015 chunks + +**Response (notify/6E40FC21):** +- Header ACK: `0xE4 0x51 0x02 ... 0x00` (byte[9] = 0x00 for success) +- Chunk ACK: `0xE4 0x52 0x02 ... 0x00` (byte[9] = 0x00 for success) + +**Test script:** `FereFit_enterMakeDial_BLE.py` + +**Notes:** +- UI overlay (time/date) only appears if byte[15] = 0x01 +- Text color is presumably set via bytes[17-18] (RGB565) [unconfirmed] +- The watch does NOT automatically overlay UI - you must enable it +- Actual display height is 296, not 280 (white bar appears at bottom with 280) +- Resolution and variables can vary quite a lot depending on watch variant ## Scripts and tests |
