Implement multi-channel run length encoded images in flash memory
This commit is contained in:
parent
75046d1c1a
commit
83a064ddc1
50
eink.hpp
50
eink.hpp
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <utility>
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
@ -146,41 +148,35 @@ class Eink {
|
|||||||
_delay_ms(200);
|
_delay_ms(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Image>
|
template <typename RleImage>
|
||||||
static void draw(const Image &image)
|
static void draw(const RleImage &rleImage)
|
||||||
{
|
{
|
||||||
constexpr auto lookup = [](std::uint8_t bits) {
|
constexpr auto pgm_load = [](const auto &object) {
|
||||||
auto block = ImageBlock{};
|
using object_t = std::remove_cvref_t<decltype(object)>;
|
||||||
util::for_constexpr(
|
auto buffer = object_t{};
|
||||||
[&](const auto idx) {
|
auto rawBuffer = reinterpret_cast<std::byte *>(&buffer);
|
||||||
block[idx.value] = static_cast<Color>(bits % 3);
|
for (auto i = std::size_t{0}; i < sizeof(object_t); ++i) {
|
||||||
bits /= 3;
|
rawBuffer[i] = static_cast<std::byte>(pgm_read_byte(&reinterpret_cast<const std::byte *>(&object)[i]));
|
||||||
},
|
}
|
||||||
std::make_index_sequence<BLOCK_SIZE>{});
|
return buffer;
|
||||||
return block;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto sendImageChannel = [lookup](const auto command, const auto image) {
|
constexpr auto sendImageChannel = [pgm_load](const auto command, const auto &image) {
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
auto buffer = std::uint8_t{0};
|
for (auto j = std::size_t{0}; j < image.size(); ++j) {
|
||||||
auto bufferPos = std::uint8_t{0};
|
const auto [count, data] = pgm_load(image[j]);
|
||||||
for (auto i = std::uint16_t{0}; i < Width * Height / BLOCK_SIZE; i++) {
|
for (auto i = std::uint16_t{0}; i < count; ++i) {
|
||||||
const auto block = lookup(pgm_read_byte(&image[i]));
|
if (command == Cmd::WRITE_RAM_BLACK) {
|
||||||
for (auto p = std::uint8_t{0}; p < BLOCK_SIZE; ++p) {
|
sendData(data);
|
||||||
const auto pixel = std::uint8_t{(command == Cmd::WRITE_RAM_BLACK) ? (block[p] != Color::BLACK)
|
} else {
|
||||||
: (block[p] == Color::RED)};
|
sendData(~data);
|
||||||
buffer |= pixel << (7 - bufferPos++);
|
|
||||||
if (bufferPos == 8) {
|
|
||||||
sendData(buffer);
|
|
||||||
buffer = 0;
|
|
||||||
bufferPos = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sendImageChannel(Cmd::WRITE_RAM_BLACK, image.data());
|
sendImageChannel(Cmd::WRITE_RAM_BLACK, std::get<0>(rleImage));
|
||||||
sendImageChannel(Cmd::WRITE_RAM_RED, image.data());
|
sendImageChannel(Cmd::WRITE_RAM_RED, std::get<1>(rleImage));
|
||||||
|
|
||||||
sendCommand(Cmd::DISPLAY_UPDATE_CONTROL_2);
|
sendCommand(Cmd::DISPLAY_UPDATE_CONTROL_2);
|
||||||
sendData(0xF7);
|
sendData(0xF7);
|
||||||
|
Loading…
Reference in New Issue
Block a user