Fix shifted pictures: non-blocking Nano drawing, frame check, refresh settings

The Nano's periodic full redraw blocked for ~0.8 s. A frame that arrived
meanwhile overflowed its 64-byte serial buffer; lost bytes in a bitmap
shift the rest of the image (picture moved up), and diff frames never
repaired it.

- Nano: all drawing (frames, effects, the dot refresh) runs from update()
  in ~1 ms slices; the refresh pauses while a frame is received or shown
- New commands: C (reply with the image checksum) and I (refresh minutes,
  EEPROM)
- ESP32: NanoMonitor asks for the checksum after frames and sends the whole
  image again on a mismatch, missing answer or Nano restart; counts ERR
  replies. Periodic whole-image resync.
- Settings: "Dot refresh" and "Image resync" intervals (settings v5,
  v4 records are migrated)
- System tab: loop timing, free memory, frame check counts
- test_driver: the real driver against a simulated panel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-16 15:20:26 +02:00
1 parent 58a7cb03c2
commit 090c2bf8ae
45 files changed
+1265 -157

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <stdint.h>
// CRC-16/CCITT-FALSE of a display buffer as BROSE9323 keeps it: rows of (width + 7) / 8
// bytes, bit (x & 7) is dot x. The unused bits at the end of each row are left out, so
// only the dots count (fillScreen sets them, drawPixel never does). The Nano answers the
// C command with it; the ESP32 compares it with its own copy (src/esp32/nano_link).
inline uint16_t bufferCrc(const uint8_t *buffer, uint8_t width, uint8_t height)
{
const uint8_t row_bytes = (width + 7) / 8;
const uint8_t last_mask = (width & 7) ? (uint8_t)((1 << (width & 7)) - 1) : 0xFF;
uint16_t crc = 0xFFFF;
for (uint8_t y = 0; y < height; y++)
for (uint8_t i = 0; i < row_bytes; i++)
{
uint8_t b = buffer[y * row_bytes + i];
if (i == row_bytes - 1)
b &= last_mask;
crc ^= (uint16_t)b << 8;
for (uint8_t k = 0; k < 8; k++)
crc = (crc & 0x8000) ? (uint16_t)((crc << 1) ^ 0x1021) : (uint16_t)(crc << 1);
}
return crc;
}