Skip to content

Instantly share code, notes, and snippets.

@ashald
Created February 17, 2022 05:10
Show Gist options
  • Save ashald/b681180ebdc327021407da6c39ca770e to your computer and use it in GitHub Desktop.
Save ashald/b681180ebdc327021407da6c39ca770e to your computer and use it in GitHub Desktop.
Monochrome drawing with epdiy
#include <Arduino.h>
#include "esp_log.h"
extern "C" {
#include "display_ops.h"
#include "epd_driver.h"
#include "lut.h"
}
#define FRAME_BUFFER_SIZE EPD_WIDTH*EPD_HEIGHT/8
static const char* TAG = "monochrome";
static const uint8_t ROW_DELAY = 30;
static const uint8_t PIXEL_WHITE = 0b10;
static const uint8_t PIXEL_BLACK = 0b01;
static uint8_t FRAME_BUFFER[FRAME_BUFFER_SIZE] = {0};
void bit_set(uint8_t* buffer, uint32_t index, bool value) {
uint32_t byte = index / 8;
uint32_t bit = index % 8;
uint8_t mask = 1 << bit;
if (value) {
buffer[byte] |= mask;
} else {
buffer[byte] &= ~mask;
}
}
bool bit_test(uint8_t* buffer, uint32_t index) {
uint32_t byte = index / 8;
uint32_t bit = index % 8;
uint8_t mask = 1 << bit;
return buffer[byte] & mask;
}
// fill screen with solid color
void fill(uint8_t color) {
uint8_t row[EPD_LINE_BYTES] = {0};
for (uint32_t i = 0; i < EPD_WIDTH; i++) {
uint8_t mask = color << (2 * (i % 4));
row[i / 4] |= mask;
}
reorder_line_buffer((uint32_t *)row);
epd_start_frame();
for (int i = 0; i < EPD_HEIGHT; i++) {
epd_switch_buffer();
memcpy(epd_get_current_buffer(), row, EPD_LINE_BYTES);
epd_switch_buffer();
memcpy(epd_get_current_buffer(), row, EPD_LINE_BYTES);
write_row(ROW_DELAY);
}
write_row(ROW_DELAY);
epd_end_frame();
}
// fill 10 times
void flush(uint8_t color) {
for (int i = 0; i < 10; i++) {
fill(color);
}
}
// draw a monochrom framebuffer
void draw(uint8_t* buffer) {
uint8_t row[EPD_LINE_BYTES] = {0};
epd_start_frame();
for (uint32_t y = 0; y < EPD_HEIGHT; y++) {
memset(row, 0, EPD_LINE_BYTES);
for (uint32_t x = 0; x < EPD_WIDTH; x++) {
uint8_t color = bit_test(buffer, y*EPD_WIDTH + x) ? PIXEL_BLACK : PIXEL_WHITE;
uint8_t mask = color << (2 * (x % 4));
row[x / 4] |= mask;
}
reorder_line_buffer((uint32_t *)row);
epd_switch_buffer();
memcpy(epd_get_current_buffer(), row, EPD_LINE_BYTES);
epd_switch_buffer();
memcpy(epd_get_current_buffer(), row, EPD_LINE_BYTES);
write_row(ROW_DELAY);
}
// Since we "pipeline" row output, we still have to latch out the last row.
write_row(ROW_DELAY);
epd_end_frame();
}
// draw 10 times
void render(uint8_t* buffer) {
for (int i = 0; i < 10; i++) {
draw(buffer);
}
}
void setup() {
}
void loop() {
ESP_LOGI(LOG_TAG, "[%ld] loop(): start", millis());
epd_base_init(EPD_WIDTH);
epd_poweron();
clear(PIXEL_BLACK);
clear(PIXEL_WHITE);
memset(FRAME_BUFFER, 0x00, FRAME_BUFFER_SIZE);
// Draw a horizontal or vertical line
static line_direction = true;
if (line_direction) {
line_direction = !line_direction;
for (int x = 0; x < EPD_WIDTH; x++) {
bit_set(FRAME_BUFFER, EPD_WIDTH*(EPD_HEIGHT/2) + x, true);
}
} else {
line_direction = !line_direction;
for (int y = 0; y < EPD_HEIGHT; y++) {
bit_set(FRAME_BUFFER, y*EPD_WIDTH + EPD_WIDTH/2, true);
}
}
render(FRAME_BUFFER);
epd_poweroff();
epd_deinit();
ESP_LOGI(LOG_TAG, "[%ld] loop(): finish", millis());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment