cottongin 5464d9de3a
fix: webserver stability, memory leaks, epub underlining, flash screen
Webserver:
- Remove MD5 hash computation from file listings (caused EAGAIN errors)
- Implement JSON batching (2KB) with pacing for file listings
- Simplify sendContentSafe() flow control

Memory:
- Cache QR codes on server start instead of regenerating per render
- Optimize WiFi scan: vector deduplication, 20 network limit, early scanDelete()
- Fix 48KB cover buffer leak when navigating Home -> File Transfer

EPUB Reader:
- Fix errant underlining by flushing partWordBuffer before style changes
- Text before styled inline elements (e.g., <a> with CSS underline) no longer
  incorrectly receives the element's styling

Flash Screen:
- Fix version string buffer overflow (30 -> 50 char limit)
- Use half refresh for cleaner display
- Adjust pre_flash.py timing for half refresh completion
2026-01-30 22:00:15 -05:00

53 lines
1.7 KiB
Python

"""
Pre-upload script that sends FLASH command to device before firmware upload.
This allows the firmware to display "Flashing firmware..." on the e-ink display
before the actual flash begins. The e-ink retains this message throughout the
flash process since it doesn't require power to maintain the display.
Protocol (Plan A - Simple timing):
1. Host opens serial port and sends "FLASH:version"
2. Host keeps port open briefly for device to receive and process
3. Device displays flash screen when it receives the command
4. Host proceeds with flash
"""
Import("env")
import serial
import time
from version_utils import get_version
def before_upload(source, target, env):
"""Send FLASH command to device before uploading firmware."""
port = env.GetProjectOption("upload_port", None)
if not port:
import serial.tools.list_ports
# Look for common ESP32-C3 USB serial port patterns
ports = [
p.device
for p in serial.tools.list_ports.comports()
if "usbmodem" in p.device.lower() or "ttyacm" in p.device.lower()
]
port = ports[0] if ports else None
if not port:
print("[pre_flash] No serial port found, skipping notification")
return
try:
version = get_version(env)
ser = serial.Serial(port, 115200, timeout=1)
ser.write(f"FLASH:{version}\n".encode())
ser.flush()
time.sleep(4.0) # Keep port open for device to receive and complete full refresh (~2-3s)
ser.close()
print(f"[pre_flash] Flash notification sent to {port} (version {version})")
except Exception as e:
print(f"[pre_flash] Notification skipped: {e}")
env.AddPreAction("upload", before_upload)