Implement OTP dumping
This commit is contained in:
parent
7a0f00ceab
commit
91b49cd536
84
eink.hpp
84
eink.hpp
@ -7,11 +7,11 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#include "eink_spi.hpp"
|
#include "eink_spi.hpp"
|
||||||
|
#include "otp.hpp"
|
||||||
|
|
||||||
#include "../clock.hpp"
|
#include "../clock.hpp"
|
||||||
|
#include "../flash/flash.hpp"
|
||||||
#include "../io/io.hpp"
|
#include "../io/io.hpp"
|
||||||
#include "../util/util.hpp"
|
#include "../util/util.hpp"
|
||||||
|
|
||||||
@ -24,17 +24,6 @@ class Eink {
|
|||||||
static io::Pin<RstPin> m_rst;
|
static io::Pin<RstPin> m_rst;
|
||||||
static io::Pin<BusyPin> m_busy;
|
static io::Pin<BusyPin> m_busy;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static T pgm_load(const T &object)
|
|
||||||
{
|
|
||||||
auto buffer = T{};
|
|
||||||
auto rawBuffer = reinterpret_cast<std::byte *>(&buffer);
|
|
||||||
for (auto i = std::size_t{0}; i < sizeof(T); ++i) {
|
|
||||||
rawBuffer[i] = static_cast<std::byte>(pgm_read_byte(&reinterpret_cast<const std::byte *>(&object)[i]));
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Cmd : std::uint8_t {
|
enum class Cmd : std::uint8_t {
|
||||||
DRIVER_OUTPUT_CONTROL = 0x01,
|
DRIVER_OUTPUT_CONTROL = 0x01,
|
||||||
@ -46,7 +35,10 @@ class Eink {
|
|||||||
DISPLAY_UPDATE_CONTROL_2 = 0x22,
|
DISPLAY_UPDATE_CONTROL_2 = 0x22,
|
||||||
WRITE_RAM_BLACK = 0x24,
|
WRITE_RAM_BLACK = 0x24,
|
||||||
WRITE_RAM_RED = 0x26,
|
WRITE_RAM_RED = 0x26,
|
||||||
|
READ_RAM = 0x27,
|
||||||
|
LOAD_OTP_TO_RAM = 0x31,
|
||||||
BORDER_WAVEFORM_CONTROL = 0x3C,
|
BORDER_WAVEFORM_CONTROL = 0x3C,
|
||||||
|
READ_RAM_CHANNEL = 0x41,
|
||||||
SET_RAM_X_ADDR_POSITIONS = 0x44,
|
SET_RAM_X_ADDR_POSITIONS = 0x44,
|
||||||
SET_RAM_Y_ADDR_POSITIONS = 0x45,
|
SET_RAM_Y_ADDR_POSITIONS = 0x45,
|
||||||
SET_RAM_X_ADDR = 0x4E,
|
SET_RAM_X_ADDR = 0x4E,
|
||||||
@ -54,9 +46,9 @@ class Eink {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class Color : std::uint8_t {
|
enum class Color : std::uint8_t {
|
||||||
BLACK,
|
BLACK = 0x00,
|
||||||
WHITE,
|
RED = 0x01,
|
||||||
RED,
|
WHITE = 0x02,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class RamDirection : std::uint8_t {
|
enum class RamDirection : std::uint8_t {
|
||||||
@ -152,7 +144,7 @@ class Eink {
|
|||||||
constexpr auto sendImageChannel = [](const auto command, const auto &image) {
|
constexpr auto sendImageChannel = [](const auto command, const auto &image) {
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
for (auto j = std::size_t{0}; j < image.size(); ++j) {
|
for (auto j = std::size_t{0}; j < image.size(); ++j) {
|
||||||
const auto [count, data] = pgm_load(image[j]);
|
const auto [count, data] = flash::load(image[j]);
|
||||||
for (auto i = std::uint16_t{0}; i < count; ++i) {
|
for (auto i = std::uint16_t{0}; i < count; ++i) {
|
||||||
if (command == Cmd::WRITE_RAM_BLACK) {
|
if (command == Cmd::WRITE_RAM_BLACK) {
|
||||||
sendData(data);
|
sendData(data);
|
||||||
@ -176,12 +168,12 @@ class Eink {
|
|||||||
{
|
{
|
||||||
constexpr auto getFillData = [](const auto &color) -> std::pair<std::uint8_t, std::uint8_t> {
|
constexpr auto getFillData = [](const auto &color) -> std::pair<std::uint8_t, std::uint8_t> {
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case Color::WHITE:
|
|
||||||
return {0xFF, 0x00};
|
|
||||||
case Color::BLACK:
|
case Color::BLACK:
|
||||||
return {0x00, 0x00};
|
return {0x00, 0x00};
|
||||||
case Color::RED:
|
case Color::RED:
|
||||||
return {0xFF, 0xFF};
|
return {0xFF, 0xFF};
|
||||||
|
case Color::WHITE:
|
||||||
|
return {0xFF, 0x00};
|
||||||
}
|
}
|
||||||
return {0xFF, 0x00};
|
return {0xFF, 0x00};
|
||||||
};
|
};
|
||||||
@ -264,6 +256,60 @@ class Eink {
|
|||||||
sendData((pos >> 8) & 0b1);
|
sendData((pos >> 8) & 0b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename PrintFn>
|
||||||
|
static void dumpOTP(PrintFn &&printFn)
|
||||||
|
{
|
||||||
|
constexpr auto byteWidth = Width / 8;
|
||||||
|
constexpr auto ramHeight = Height + 46;
|
||||||
|
|
||||||
|
constexpr auto xRamRange = std::pair<std::uint8_t, std::uint8_t>{0, byteWidth - 1};
|
||||||
|
constexpr auto yRamRange = std::pair<std::uint16_t, std::uint16_t>{0, ramHeight - 1};
|
||||||
|
|
||||||
|
setDataEntryMode(RamDirection::INCREMENT, RamDirection::INCREMENT, FastestMovingIndex::X);
|
||||||
|
setRamRange(xRamRange, yRamRange);
|
||||||
|
setRamXPos(0);
|
||||||
|
setRamYPos(0);
|
||||||
|
|
||||||
|
sendCommand(Cmd::WRITE_RAM_BLACK);
|
||||||
|
for (auto i = std::uint16_t{0}; i < byteWidth * ramHeight; i++) {
|
||||||
|
sendData(0xFF);
|
||||||
|
}
|
||||||
|
sendCommand(Cmd::WRITE_RAM_RED);
|
||||||
|
for (auto i = std::uint16_t{0}; i < byteWidth * ramHeight; i++) {
|
||||||
|
sendData(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommand(Cmd::DISPLAY_UPDATE_CONTROL_2);
|
||||||
|
sendData(0xF7);
|
||||||
|
sendCommand(Cmd::UPDATE_DISPLAY);
|
||||||
|
waitUntilIdle();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
sendCommand(Cmd::DISPLAY_UPDATE_CONTROL_2);
|
||||||
|
sendData(0x80);
|
||||||
|
sendCommand(Cmd::UPDATE_DISPLAY);
|
||||||
|
waitUntilIdle();
|
||||||
|
|
||||||
|
sendCommand(Cmd::LOAD_OTP_TO_RAM);
|
||||||
|
waitUntilIdle();
|
||||||
|
|
||||||
|
setRamXPos(0);
|
||||||
|
setRamYPos(0);
|
||||||
|
|
||||||
|
sendCommand(Cmd::READ_RAM_CHANNEL);
|
||||||
|
sendData(static_cast<word_t>(Color::BLACK));
|
||||||
|
|
||||||
|
sendCommand(Cmd::READ_RAM);
|
||||||
|
readData(); // First byte must be discarded
|
||||||
|
|
||||||
|
for (auto i = std::size_t{0}; i < sizeof(OTP); ++i) {
|
||||||
|
printFn(readData());
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
static void sleep()
|
static void sleep()
|
||||||
{
|
{
|
||||||
sendCommand(Cmd::DEEP_SLEEP_MODE);
|
sendCommand(Cmd::DEEP_SLEEP_MODE);
|
||||||
|
353
otp.hpp
Normal file
353
otp.hpp
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace eink {
|
||||||
|
|
||||||
|
// [SOURCE]_[VCOM]
|
||||||
|
enum class Voltage : std::uint8_t {
|
||||||
|
VSS_DCVCOM = 0b00,
|
||||||
|
VSH1_VSH1DCVCOM = 0b01,
|
||||||
|
VSL_VSLDCVCOM = 0b10,
|
||||||
|
VSH2_NA = 0b11,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] Phases
|
||||||
|
{
|
||||||
|
Voltage phaseD : 2;
|
||||||
|
Voltage phaseC : 2;
|
||||||
|
Voltage phaseB : 2;
|
||||||
|
Voltage phaseA : 2;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Phases) == 1);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] VoltageGroups
|
||||||
|
{
|
||||||
|
Phases group[12];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(VoltageGroups) == 12);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] Timings
|
||||||
|
{
|
||||||
|
std::uint8_t frameCountPhaseA;
|
||||||
|
std::uint8_t frameCountPhaseB;
|
||||||
|
std::uint8_t repeatSubPhaseAB;
|
||||||
|
std::uint8_t frameCountPhaseC;
|
||||||
|
std::uint8_t frameCountPhaseD;
|
||||||
|
std::uint8_t repeatSubPhaseCD;
|
||||||
|
std::uint8_t repeat;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Timings) == 7);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] FrameRates
|
||||||
|
{
|
||||||
|
std::uint8_t group11 : 4;
|
||||||
|
std::uint8_t group10 : 4;
|
||||||
|
std::uint8_t group9 : 4;
|
||||||
|
std::uint8_t group8 : 4;
|
||||||
|
std::uint8_t group7 : 4;
|
||||||
|
std::uint8_t group6 : 4;
|
||||||
|
std::uint8_t group5 : 4;
|
||||||
|
std::uint8_t group4 : 4;
|
||||||
|
std::uint8_t group3 : 4;
|
||||||
|
std::uint8_t group2 : 4;
|
||||||
|
std::uint8_t group1 : 4;
|
||||||
|
std::uint8_t group0 : 4;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(FrameRates) == 6);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] SubPhaseGateStates
|
||||||
|
{
|
||||||
|
bool group11SubPhaseCD : 1;
|
||||||
|
bool group11SubPhaseAB : 1;
|
||||||
|
bool group10SubPhaseCD : 1;
|
||||||
|
bool group10SubPhaseAB : 1;
|
||||||
|
bool group9SubPhaseCD : 1;
|
||||||
|
bool group9SubPhaseAB : 1;
|
||||||
|
bool group8SubPhaseCD : 1;
|
||||||
|
bool group8SubPhaseAB : 1;
|
||||||
|
bool group7SubPhaseCD : 1;
|
||||||
|
bool group7SubPhaseAB : 1;
|
||||||
|
bool group6SubPhaseCD : 1;
|
||||||
|
bool group6SubPhaseAB : 1;
|
||||||
|
bool group5SubPhaseCD : 1;
|
||||||
|
bool group5SubPhaseAB : 1;
|
||||||
|
bool group4SubPhaseCD : 1;
|
||||||
|
bool group4SubPhaseAB : 1;
|
||||||
|
bool group3SubPhaseCD : 1;
|
||||||
|
bool group3SubPhaseAB : 1;
|
||||||
|
bool group2SubPhaseCD : 1;
|
||||||
|
bool group2SubPhaseAB : 1;
|
||||||
|
bool group1SubPhaseCD : 1;
|
||||||
|
bool group1SubPhaseAB : 1;
|
||||||
|
bool group0SubPhaseCD : 1;
|
||||||
|
bool group0SubPhaseAB : 1;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SubPhaseGateStates) == 3);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] Waveform
|
||||||
|
{
|
||||||
|
VoltageGroups lut[5];
|
||||||
|
Timings timings[12];
|
||||||
|
FrameRates frameRates;
|
||||||
|
SubPhaseGateStates subPhaseGateStates;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Waveform) == 153);
|
||||||
|
|
||||||
|
enum class LutEndOption : std::uint8_t {
|
||||||
|
KEEP_PREVIOUS_SOURCE_OUTPUT_LEVEL_BEFORE_POWER_OFF = 0x07,
|
||||||
|
NORMAL = 0x22,
|
||||||
|
};
|
||||||
|
static_assert(sizeof(LutEndOption) == 1);
|
||||||
|
|
||||||
|
enum class GateVoltage : std::uint8_t {
|
||||||
|
V_20_DEFAULT = 0x00,
|
||||||
|
V_10 = 0x03,
|
||||||
|
V_10_5 = 0x04,
|
||||||
|
V_11 = 0x05,
|
||||||
|
V_11_5 = 0x06,
|
||||||
|
V_12 = 0x07,
|
||||||
|
V_12_5 = 0x08,
|
||||||
|
V_13 = 0x09,
|
||||||
|
V_13_5 = 0x0A,
|
||||||
|
V_14 = 0x0B,
|
||||||
|
V_14_5 = 0x0C,
|
||||||
|
V_15 = 0x0D,
|
||||||
|
V_15_5 = 0x0E,
|
||||||
|
V_16 = 0x0F,
|
||||||
|
V_16_5 = 0x10,
|
||||||
|
V_17 = 0x11,
|
||||||
|
V_17_5 = 0x12,
|
||||||
|
V_18 = 0x13,
|
||||||
|
V_18_5 = 0x14,
|
||||||
|
V_19 = 0x15,
|
||||||
|
V_19_5 = 0x16,
|
||||||
|
V_20 = 0x17,
|
||||||
|
};
|
||||||
|
static_assert(sizeof(GateVoltage) == 1);
|
||||||
|
|
||||||
|
enum class VoltageSourceHigh : std::uint8_t {
|
||||||
|
V_9 = 0x23,
|
||||||
|
V_9_2 = 0x24,
|
||||||
|
V_9_4 = 0x25,
|
||||||
|
V_9_6 = 0x26,
|
||||||
|
V_9_8 = 0x27,
|
||||||
|
V_10 = 0x28,
|
||||||
|
V_10_2 = 0x29,
|
||||||
|
V_10_4 = 0x2A,
|
||||||
|
V_10_6 = 0x2B,
|
||||||
|
V_10_8 = 0x2C,
|
||||||
|
V_11 = 0x2D,
|
||||||
|
V_11_2 = 0x2E,
|
||||||
|
V_11_4 = 0x2F,
|
||||||
|
V_11_6 = 0x30,
|
||||||
|
V_11_8 = 0x31,
|
||||||
|
V_12 = 0x32,
|
||||||
|
V_12_2 = 0x33,
|
||||||
|
V_12_4 = 0x34,
|
||||||
|
V_12_6 = 0x35,
|
||||||
|
V_12_8 = 0x36,
|
||||||
|
V_13 = 0x37,
|
||||||
|
V_13_2 = 0x38,
|
||||||
|
V_13_4 = 0x39,
|
||||||
|
V_13_6 = 0x3A,
|
||||||
|
V_13_8 = 0x3B,
|
||||||
|
V_14 = 0x3C,
|
||||||
|
V_14_2 = 0x3D,
|
||||||
|
V_14_4 = 0x3E,
|
||||||
|
V_14_6 = 0x3F,
|
||||||
|
V_14_8 = 0x40,
|
||||||
|
V_15 = 0x41,
|
||||||
|
V_15_2 = 0x42,
|
||||||
|
V_15_4 = 0x43,
|
||||||
|
V_15_6 = 0x44,
|
||||||
|
V_15_8 = 0x45,
|
||||||
|
V_16 = 0x46,
|
||||||
|
V_16_2 = 0x47,
|
||||||
|
V_16_4 = 0x48,
|
||||||
|
V_16_6 = 0x49,
|
||||||
|
V_16_8 = 0x4A,
|
||||||
|
V_17 = 0x4B,
|
||||||
|
V_2_4 = 0x8E,
|
||||||
|
V_2_5 = 0x8F,
|
||||||
|
V_2_6 = 0x90,
|
||||||
|
V_2_7 = 0x91,
|
||||||
|
V_2_8 = 0x92,
|
||||||
|
V_2_9 = 0x93,
|
||||||
|
V_3 = 0x94,
|
||||||
|
V_3_1 = 0x95,
|
||||||
|
V_3_2 = 0x96,
|
||||||
|
V_3_3 = 0x97,
|
||||||
|
V_3_4 = 0x98,
|
||||||
|
V_3_5 = 0x99,
|
||||||
|
V_3_6 = 0x9A,
|
||||||
|
V_3_7 = 0x9B,
|
||||||
|
V_3_8 = 0x9C,
|
||||||
|
V_3_9 = 0x9D,
|
||||||
|
V_4 = 0x9E,
|
||||||
|
V_4_1 = 0x9F,
|
||||||
|
V_4_2 = 0xA0,
|
||||||
|
V_4_3 = 0xA1,
|
||||||
|
V_4_4 = 0xA2,
|
||||||
|
V_4_5 = 0xA3,
|
||||||
|
V_4_6 = 0xA4,
|
||||||
|
V_4_7 = 0xA5,
|
||||||
|
V_4_8 = 0xA6,
|
||||||
|
V_4_9 = 0xA7,
|
||||||
|
V_5 = 0xA8,
|
||||||
|
V_5_1 = 0xA9,
|
||||||
|
V_5_2 = 0xAA,
|
||||||
|
V_5_3 = 0xAB,
|
||||||
|
V_5_4 = 0xAC,
|
||||||
|
V_5_5 = 0xAD,
|
||||||
|
V_5_6 = 0xAE,
|
||||||
|
V_5_7 = 0xAF,
|
||||||
|
V_5_8 = 0xB0,
|
||||||
|
V_5_9 = 0xB1,
|
||||||
|
V_6 = 0xB2,
|
||||||
|
V_6_1 = 0xB3,
|
||||||
|
V_6_2 = 0xB4,
|
||||||
|
V_6_3 = 0xB5,
|
||||||
|
V_6_4 = 0xB6,
|
||||||
|
V_6_5 = 0xB7,
|
||||||
|
V_6_6 = 0xB8,
|
||||||
|
V_6_7 = 0xB9,
|
||||||
|
V_6_8 = 0xBA,
|
||||||
|
V_6_9 = 0xBB,
|
||||||
|
V_7 = 0xBC,
|
||||||
|
V_7_1 = 0xBD,
|
||||||
|
V_7_2 = 0xBE,
|
||||||
|
V_7_3 = 0xBF,
|
||||||
|
V_7_4 = 0xC0,
|
||||||
|
V_7_5 = 0xC1,
|
||||||
|
V_7_6 = 0xC2,
|
||||||
|
V_7_7 = 0xC3,
|
||||||
|
V_7_8 = 0xC4,
|
||||||
|
V_7_9 = 0xC5,
|
||||||
|
V_8 = 0xC6,
|
||||||
|
V_8_1 = 0xC7,
|
||||||
|
V_8_2 = 0xC8,
|
||||||
|
V_8_3 = 0xC9,
|
||||||
|
V_8_4 = 0xCA,
|
||||||
|
V_8_5 = 0xCB,
|
||||||
|
V_8_6 = 0xCC,
|
||||||
|
V_8_7 = 0xCD,
|
||||||
|
V_8_8 = 0xCE,
|
||||||
|
};
|
||||||
|
static_assert(sizeof(VoltageSourceHigh) == 1);
|
||||||
|
|
||||||
|
enum class VoltageSourceLow : std::uint8_t {
|
||||||
|
NEG_5 = 0x0A,
|
||||||
|
NEG_5_5 = 0x0C,
|
||||||
|
NEG_6 = 0x0E,
|
||||||
|
NEG_6_5 = 0x10,
|
||||||
|
NEG_7 = 0x12,
|
||||||
|
NEG_7_5 = 0x14,
|
||||||
|
NEG_8 = 0x16,
|
||||||
|
NEG_8_5 = 0x18,
|
||||||
|
NEG_9 = 0x1A,
|
||||||
|
NEG_9_5 = 0x1C,
|
||||||
|
NEG_10 = 0x1E,
|
||||||
|
NEG_10_5 = 0x20,
|
||||||
|
NEG_11 = 0x22,
|
||||||
|
NEG_11_5 = 0x24,
|
||||||
|
NEG_12 = 0x26,
|
||||||
|
NEG_12_5 = 0x28,
|
||||||
|
NEG_13 = 0x2A,
|
||||||
|
NEG_13_5 = 0x2C,
|
||||||
|
NEG_14 = 0x2E,
|
||||||
|
NEG_14_5 = 0x30,
|
||||||
|
NEG_15 = 0x32,
|
||||||
|
NEG_15_5 = 0x34,
|
||||||
|
NEG_16 = 0x36,
|
||||||
|
NEG_16_5 = 0x38,
|
||||||
|
NEG_17 = 0x3A,
|
||||||
|
};
|
||||||
|
static_assert(sizeof(VoltageSourceLow) == 1);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] SourceVoltage
|
||||||
|
{
|
||||||
|
VoltageSourceHigh vsh1;
|
||||||
|
VoltageSourceHigh vsh2;
|
||||||
|
VoltageSourceLow vsl;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SourceVoltage) == 3);
|
||||||
|
|
||||||
|
enum class CommonVoltage : std::uint8_t {
|
||||||
|
NEG_0_2 = 0x08,
|
||||||
|
NEG_0_3 = 0x0C,
|
||||||
|
NEG_0_4 = 0x10,
|
||||||
|
NEG_0_5 = 0x14,
|
||||||
|
NEG_0_6 = 0x18,
|
||||||
|
NEG_0_7 = 0x1C,
|
||||||
|
NEG_0_8 = 0x20,
|
||||||
|
NEG_0_9 = 0x24,
|
||||||
|
NEG_1 = 0x28,
|
||||||
|
NEG_1_1 = 0x2C,
|
||||||
|
NEG_1_2 = 0x30,
|
||||||
|
NEG_1_3 = 0x34,
|
||||||
|
NEG_1_4 = 0x38,
|
||||||
|
NEG_1_5 = 0x3C,
|
||||||
|
NEG_1_6 = 0x40,
|
||||||
|
NEG_1_7 = 0x44,
|
||||||
|
NEG_1_8 = 0x48,
|
||||||
|
NEG_1_9 = 0x4C,
|
||||||
|
NEG_2 = 0x50,
|
||||||
|
NEG_2_1 = 0x54,
|
||||||
|
NEG_2_2 = 0x58,
|
||||||
|
NEG_2_3 = 0x5C,
|
||||||
|
NEG_2_4 = 0x60,
|
||||||
|
NEG_2_5 = 0x64,
|
||||||
|
NEG_2_6 = 0x68,
|
||||||
|
NEG_2_7 = 0x6C,
|
||||||
|
NEG_2_8 = 0x70,
|
||||||
|
NEG_2_9 = 0x74,
|
||||||
|
NEG_3 = 0x78,
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CommonVoltage) == 1);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] WaveformSetting
|
||||||
|
{
|
||||||
|
Waveform waveform;
|
||||||
|
LutEndOption lutEndOption;
|
||||||
|
GateVoltage gateVoltage;
|
||||||
|
SourceVoltage sourceVoltage;
|
||||||
|
CommonVoltage commonVoltage;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(WaveformSetting) == 159);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] TemperatureRange
|
||||||
|
{
|
||||||
|
std::uint8_t lowerBoundLowBits;
|
||||||
|
std::uint8_t lowerBoundHighBits : 4;
|
||||||
|
std::uint8_t upperBoundLowBits : 4;
|
||||||
|
std::uint8_t upperBoundHighBits;
|
||||||
|
|
||||||
|
inline constexpr operator std::pair<float, float>() const
|
||||||
|
{
|
||||||
|
constexpr auto convertTemp = [](const auto &temp) {
|
||||||
|
auto signedTemp = static_cast<std::int16_t>(temp);
|
||||||
|
if (signedTemp >> 11 & 1) {
|
||||||
|
signedTemp |= 0b1111 << 12;
|
||||||
|
}
|
||||||
|
const auto tempDegrees = signedTemp / 16.0f;
|
||||||
|
return tempDegrees;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto lowerBound = static_cast<std::uint16_t>(lowerBoundHighBits) << 8 | lowerBoundLowBits;
|
||||||
|
const auto upperBound = static_cast<std::uint16_t>(upperBoundHighBits) << 4 | upperBoundLowBits;
|
||||||
|
|
||||||
|
return {convertTemp(lowerBound), convertTemp(upperBound)};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(TemperatureRange) == 3);
|
||||||
|
|
||||||
|
struct [[gnu::packed]] OTP
|
||||||
|
{
|
||||||
|
WaveformSetting waveforms[36];
|
||||||
|
TemperatureRange temperatures[36];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(OTP) == 5832);
|
||||||
|
|
||||||
|
} // namespace eink
|
Loading…
Reference in New Issue
Block a user