512 KB E-READER
24 OCTOBER 2023
First project with e-paper displays and ESP32.
ESP-WROOM-32, 7.5” Waveshare e-paper display, three-button interface (prev/next/sleep).
Memory: 512KB SRAM + 4MB flash. Internal 4 MB flash unsuitable for storing books due to P/E cycle limits. HTTP Range requests for on-demand bitmap streaming. Progress saved to RTC memory to survive deep sleep without flash wear.
EBM format: Raw bitmap sequence. 1 byte = 8 pixels, 1 page = 48 KB (display resolution), headerless. Optimized for HTTP Range requests:
int r0 = ((page_n - 1) * PAGE_SIZE);
int rn = page_n * PAGE_SIZE - 1;
int n = snprintf(NULL, 0, "bytes=%d-%d", r0, rn) + 1;
char *buf = malloc(sizeof(char) * n);
snprintf(buf, n, "bytes=%d-%d", r0, rn);
esp_http_client_set_header(http_client, "Range", buf);
esp_http_client_perform(http_client);
Page buffer: Three pages (prev/current/next) in RAM—maximum possible. On request: cycles buffer, updates screen, prefetches next page.
c_page_num++;
pg.page_num = c_page_num + 2;
pg.page_buf = pages[(c_page_num + 1) % PAGE_LEN];
xSemaphoreGive(mutex);
xQueueSend(http_evt_queue, &pg, portMAX_DELAY);
epd_draw_async(pages[c_page_num % PAGE_LEN], PAGE_SIZE);
epd_draw_await();
Responsiveness: inadequate. Scheduling GPIO, SPI, and HTTP tasks on a single thread causes input lag. Pinned GPIO/SPI tasks to one core and the HTTP task to the other.
Better, but screen updates block user input. Moved SPI buffers to DMA and made transfers async. Few more cycles saved.
Can’t think of anything else.
Verdict: Functional but limited. Led to Etlas.
Commit: 7f691c4