Created
February 17, 2022 05:10
-
-
Save ashald/b681180ebdc327021407da6c39ca770e to your computer and use it in GitHub Desktop.
Monochrome drawing with epdiy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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