#pragma once #include #include 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() const { constexpr auto convertTemp = [](const auto &temp) { auto signedTemp = static_cast(temp); if (signedTemp >> 11 & 1) { signedTemp |= 0b1111 << 12; } const auto tempDegrees = signedTemp / 16.0f; return tempDegrees; }; const auto lowerBound = static_cast(lowerBoundHighBits) << 8 | lowerBoundLowBits; const auto upperBound = static_cast(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