MCPcopy Create free account
hub / github.com/TactilityProject/Tactility / flushInternal

Method flushInternal

Drivers/EPDiyDisplay/Source/EpdiyDisplay.cpp:348–404  ·  view source on GitHub ↗

Internal functions

Source from the content-addressed store, hash-verified

346
347// Internal functions
348void EpdiyDisplay::flushInternal(const lv_area_t* area, uint8_t* pixelMap, bool isLast) {
349 if (!initialized) {
350 LOG_E(TAG, "Cannot flush - EPD not initialized");
351 return;
352 }
353
354 if (!powered) {
355 setPowerOn(true);
356 }
357
358 const int x = area->x1;
359 const int y = area->y1;
360 const int width = lv_area_get_width(area);
361 const int height = lv_area_get_height(area);
362
363 LOG_D(TAG, "Flushing area: x=%d, y=%d, w=%d, h=%d isLast=%d", x, y, width, height, (int)isLast);
364
365 // Convert L8 (8-bit grayscale, 0=black/255=white) to EPDiy 4-bit (0=black/15=white).
366 // Pack 2 pixels per byte: lower nibble = even column, upper nibble = odd column.
367 // Row stride includes one padding nibble for odd widths to keep rows aligned.
368 // Threshold at 128 (matching FastEPD BB_MODE_1BPP): pixels > 127 → full white (15),
369 // pixels ≤ 127 → full black (0). Maximum contrast for the Mono theme and correct for
370 // MODE_DU which only drives two levels. For greyscale content / MODE_GL16, replace
371 // the threshold with `src[col] >> 4` to preserve intermediate grey levels.
372 const int row_stride = (width + 1) / 2;
373 for (int row = 0; row < height; ++row) {
374 const uint8_t* src = pixelMap + static_cast<size_t>(row) * width;
375 uint8_t* dst = packedBuffer + static_cast<size_t>(row) * row_stride;
376 for (int col = 0; col < width; col += 2) {
377 const uint8_t p0 = (src[col] > 127) ? 15u : 0u;
378 const uint8_t p1 = (col + 1 < width) ? ((src[col + 1] > 127) ? 15u : 0u) : 0u;
379 dst[col / 2] = static_cast<uint8_t>((p1 << 4) | p0);
380 }
381 }
382
383 const EpdRect update_area = {
384 .x = x,
385 .y = y,
386 .width = static_cast<uint16_t>(width),
387 .height = static_cast<uint16_t>(height)
388 };
389
390 // Write pixels into EPDiy's framebuffer (no hardware I/O, just memory)
391 epd_draw_rotated_image(update_area, packedBuffer, framebuffer);
392
393 // Only trigger EPD hardware update on the last flush of this render cycle.
394 // EPDiy's epd_prep tasks run at configMAX_PRIORITIES-1 with busy-wait loops; calling
395 // epd_hl_update_area on every partial flush starves IDLE and triggers the task watchdog
396 // during scroll animations. Batching to one hardware update per LVGL render cycle fixes this.
397 if (isLast) {
398 epd_hl_update_screen(
399 &highlevelState,
400 static_cast<EpdDrawMode>(configuration->defaultDrawMode | MODE_PACKING_2PPB),
401 configuration->defaultTemperature
402 );
403 }
404}
405

Callers 1

flushCallbackMethod · 0.80

Calls

no outgoing calls

Tested by

no test coverage detected