eink/otp.hpp

354 lines
6.6 KiB
C++

#pragma once
#include <cstddef>
#include <cstdint>
namespace eink {
// [SOURCE]_[VCOM]
enum class Voltage : std::uint8_t {
VSS1 = 0b00,
VSH1 = 0b01,
VSL1 = 0b10,
VSH2 = 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