From 2deb34e856836ef071151f599c778f90c86b1a06 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:15:58 +0200 Subject: [PATCH] Update epdiy library - ESP32 Platform from 2025.07.31 to 2025.08.30, Framework (Arduino Core) from v3.1.3.250712 to v3.1.3.250808 and IDF from v5.3.3.250707 to v5.3.3.250801 (#23778) - Epdiy library from v1.0.0 to v2.0.0 --- CHANGELOG.md | 2 + RELEASENOTES.md | 3 +- lib/libesp32_eink/epdiy/.clang-format | 11 + lib/libesp32_eink/epdiy/.gitignore | 10 + lib/libesp32_eink/epdiy/.gitmodules | 6 - lib/libesp32_eink/epdiy/.readthedocs.yml | 6 +- lib/libesp32_eink/epdiy/LICENSE | 165 ++++ lib/libesp32_eink/epdiy/Makefile | 28 +- lib/libesp32_eink/epdiy/README.md | 140 ++-- lib/libesp32_eink/epdiy/boards.local.txt | 452 ----------- lib/libesp32_eink/epdiy/idf_component.yml | 4 + lib/libesp32_eink/epdiy/library.json | 32 + lib/libesp32_eink/epdiy/library.properties | 4 +- lib/libesp32_eink/epdiy/scripts/README.md | 101 +++ .../epdiy/scripts/fontconvert.py | 202 ++++- lib/libesp32_eink/epdiy/scripts/imgconvert.py | 2 +- .../epdiy/scripts/waveform_hdrgen.py | 36 +- .../epdiy/src/{epd_driver => }/Makefile | 0 lib/libesp32_eink/epdiy/src/board/epd_board.c | 77 ++ .../epdiy/src/board/epd_board_common.c | 34 + .../epdiy/src/board/epd_board_common.h | 8 + .../epdiy/src/board/epd_board_lilygo_t5_47.c | 227 ++++++ .../epdiy/src/board/epd_board_v2_v3.c | 172 +++++ .../epdiy/src/board/epd_board_v4.c | 194 +++++ .../epdiy/src/board/epd_board_v5.c | 196 +++++ .../epdiy/src/board/epd_board_v6.c | 359 +++++++++ .../epdiy/src/board/epd_board_v7.c | 338 +++++++++ .../epdiy/src/board/epd_board_v7_raw.c | 288 +++++++ .../epdiy/src/board/lilygo_board_s3.c | 273 +++++++ lib/libesp32_eink/epdiy/src/board/pca9555.c | 107 +++ lib/libesp32_eink/epdiy/src/board/pca9555.h | 35 + lib/libesp32_eink/epdiy/src/board/tps65185.c | 128 ++++ lib/libesp32_eink/epdiy/src/board/tps65185.h | 56 ++ lib/libesp32_eink/epdiy/src/board_specific.c | 5 + .../src/{epd_driver => }/builtin_waveforms.c | 11 +- lib/libesp32_eink/epdiy/src/diff.S | 159 ++++ lib/libesp32_eink/epdiy/src/displays.c | 83 ++ lib/libesp32_eink/epdiy/src/epd4in7.cpp | 6 +- .../epdiy/src/epd4in7.cppZone.Identifier | 0 .../epdiy/src/epd4in7.hZone.Identifier | 0 lib/libesp32_eink/epdiy/src/epd_board.h | 133 ++++ .../epdiy/src/epd_board_specific.h | 32 + lib/libesp32_eink/epdiy/src/epd_display.h | 43 ++ lib/libesp32_eink/epdiy/src/epd_driver.h | 4 - .../epdiy/src/epd_driver/CMakeLists.txt | 16 - .../epdiy/src/epd_driver/Kconfig | 52 -- .../epdiy/src/epd_driver/LICENSE | 674 ----------------- .../epdiy/src/epd_driver/config_reg_v2.h | 84 --- .../epdiy/src/epd_driver/config_reg_v4.h | 108 --- .../epdiy/src/epd_driver/display_ops.c | 195 ----- .../epdiy/src/epd_driver/display_ops.h | 111 --- .../epdiy/src/epd_driver/epd_driver.c | 344 --------- .../epdiy/src/epd_driver/epd_temperature.c | 34 - .../epdiy/src/epd_driver/epd_temperature.h | 11 - lib/libesp32_eink/epdiy/src/epd_driver/font.c | 375 ---------- .../epdiy/src/epd_driver/highlevel.c | 102 --- .../epdiy/src/epd_driver/i2s_data_bus.c | 262 ------- .../epdiy/src/epd_driver/i2s_data_bus.h | 67 -- .../epdiy/src/epd_driver/include/epd_driver.h | 471 ------------ .../src/epd_driver/include/epd_highlevel.h | 130 ---- .../src/epd_driver/include/epd_internals.h | 146 ---- lib/libesp32_eink/epdiy/src/epd_driver/lut.c | 617 --------------- lib/libesp32_eink/epdiy/src/epd_driver/lut.h | 54 -- .../epdiy/src/epd_driver/render.c | 382 ---------- .../epdiy/src/epd_driver/rmt_pulse.c | 80 -- lib/libesp32_eink/epdiy/src/epd_highlevel.h | 159 +++- lib/libesp32_eink/epdiy/src/epd_internals.h | 89 +++ lib/libesp32_eink/epdiy/src/epdiy.c | 545 ++++++++++++++ lib/libesp32_eink/epdiy/src/epdiy.h | 605 +++++++++++++++ lib/libesp32_eink/epdiy/src/font.c | 434 +++++++++++ .../epdiy/src/{epd_driver => }/hacks.cmake | 0 lib/libesp32_eink/epdiy/src/highlevel.c | 216 ++++++ .../epdiy/src/output_common/line_queue.c | 86 +++ .../epdiy/src/output_common/line_queue.h | 40 + .../epdiy/src/output_common/lut.S | 145 ++++ .../epdiy/src/output_common/lut.c | 495 ++++++++++++ .../epdiy/src/output_common/lut.h | 47 ++ .../epdiy/src/output_common/render_context.c | 106 +++ .../epdiy/src/output_common/render_context.h | 110 +++ .../epdiy/src/output_common/render_method.c | 10 + .../epdiy/src/output_common/render_method.h | 29 + .../epdiy/src/output_i2s/i2s_data_bus.c | 303 ++++++++ .../epdiy/src/output_i2s/i2s_data_bus.h | 77 ++ .../epdiy/src/output_i2s/render_i2s.c | 402 ++++++++++ .../epdiy/src/output_i2s/render_i2s.h | 59 ++ .../epdiy/src/output_i2s/rmt_pulse.c | 97 +++ .../{epd_driver => output_i2s}/rmt_pulse.h | 15 +- .../epdiy/src/output_lcd/idf-4-backports.h | 22 + .../epdiy/src/output_lcd/lcd_driver.c | 706 ++++++++++++++++++ .../epdiy/src/output_lcd/lcd_driver.h | 50 ++ .../epdiy/src/output_lcd/render_lcd.c | 246 ++++++ .../epdiy/src/output_lcd/render_lcd.h | 19 + lib/libesp32_eink/epdiy/src/render.c | 526 +++++++++++++ lib/libesp32_eink/epdiy/src/render.h | 12 + .../waveforms/epdiy_ED047TC1.h | 0 .../ED047TC2.h => waveforms/epdiy_ED047TC2.h} | 92 +-- .../waveforms/epdiy_ED060SC4.h | 0 .../waveforms/epdiy_ED060SCT.h | 0 .../waveforms/epdiy_ED060XC3.h | 0 .../waveforms/epdiy_ED097OC4.h | 0 .../waveforms/epdiy_ED097TC2.h | 0 .../waveforms/epdiy_ED133UT2.h | 0 .../epdiy/src/waveforms/epdiy_NULL.h | 28 + tasmota/tasmota_support/support.ino | 8 - 104 files changed, 9309 insertions(+), 4956 deletions(-) create mode 100644 lib/libesp32_eink/epdiy/.clang-format delete mode 100755 lib/libesp32_eink/epdiy/.gitmodules create mode 100644 lib/libesp32_eink/epdiy/LICENSE delete mode 100755 lib/libesp32_eink/epdiy/boards.local.txt create mode 100644 lib/libesp32_eink/epdiy/idf_component.yml create mode 100644 lib/libesp32_eink/epdiy/library.json create mode 100644 lib/libesp32_eink/epdiy/scripts/README.md rename lib/libesp32_eink/epdiy/src/{epd_driver => }/Makefile (100%) mode change 100755 => 100644 create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_common.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_common.h create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_lilygo_t5_47.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_v2_v3.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_v4.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_v5.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_v6.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_v7.c create mode 100644 lib/libesp32_eink/epdiy/src/board/epd_board_v7_raw.c create mode 100644 lib/libesp32_eink/epdiy/src/board/lilygo_board_s3.c create mode 100644 lib/libesp32_eink/epdiy/src/board/pca9555.c create mode 100644 lib/libesp32_eink/epdiy/src/board/pca9555.h create mode 100644 lib/libesp32_eink/epdiy/src/board/tps65185.c create mode 100644 lib/libesp32_eink/epdiy/src/board/tps65185.h create mode 100644 lib/libesp32_eink/epdiy/src/board_specific.c rename lib/libesp32_eink/epdiy/src/{epd_driver => }/builtin_waveforms.c (56%) mode change 100755 => 100644 create mode 100644 lib/libesp32_eink/epdiy/src/diff.S create mode 100644 lib/libesp32_eink/epdiy/src/displays.c create mode 100644 lib/libesp32_eink/epdiy/src/epd4in7.cppZone.Identifier create mode 100644 lib/libesp32_eink/epdiy/src/epd4in7.hZone.Identifier create mode 100644 lib/libesp32_eink/epdiy/src/epd_board.h create mode 100644 lib/libesp32_eink/epdiy/src/epd_board_specific.h create mode 100644 lib/libesp32_eink/epdiy/src/epd_display.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/CMakeLists.txt delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/Kconfig delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/LICENSE delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v2.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v4.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/display_ops.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/display_ops.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/epd_driver.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/font.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/highlevel.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/include/epd_driver.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/include/epd_highlevel.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/include/epd_internals.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/lut.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/lut.h delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/render.c delete mode 100755 lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.c create mode 100644 lib/libesp32_eink/epdiy/src/epd_internals.h create mode 100644 lib/libesp32_eink/epdiy/src/epdiy.c create mode 100644 lib/libesp32_eink/epdiy/src/epdiy.h create mode 100644 lib/libesp32_eink/epdiy/src/font.c rename lib/libesp32_eink/epdiy/src/{epd_driver => }/hacks.cmake (100%) mode change 100755 => 100644 create mode 100644 lib/libesp32_eink/epdiy/src/highlevel.c create mode 100644 lib/libesp32_eink/epdiy/src/output_common/line_queue.c create mode 100644 lib/libesp32_eink/epdiy/src/output_common/line_queue.h create mode 100644 lib/libesp32_eink/epdiy/src/output_common/lut.S create mode 100644 lib/libesp32_eink/epdiy/src/output_common/lut.c create mode 100644 lib/libesp32_eink/epdiy/src/output_common/lut.h create mode 100644 lib/libesp32_eink/epdiy/src/output_common/render_context.c create mode 100644 lib/libesp32_eink/epdiy/src/output_common/render_context.h create mode 100644 lib/libesp32_eink/epdiy/src/output_common/render_method.c create mode 100644 lib/libesp32_eink/epdiy/src/output_common/render_method.h create mode 100644 lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.c create mode 100644 lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.h create mode 100644 lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.c create mode 100644 lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.h create mode 100644 lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.c rename lib/libesp32_eink/epdiy/src/{epd_driver => output_i2s}/rmt_pulse.h (78%) mode change 100755 => 100644 create mode 100644 lib/libesp32_eink/epdiy/src/output_lcd/idf-4-backports.h create mode 100644 lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.c create mode 100644 lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.h create mode 100644 lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.c create mode 100644 lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.h create mode 100644 lib/libesp32_eink/epdiy/src/render.c create mode 100644 lib/libesp32_eink/epdiy/src/render.h rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED047TC1.h (100%) mode change 100755 => 100644 rename lib/libesp32_eink/epdiy/src/{epd_driver/waveforms/ED047TC2.h => waveforms/epdiy_ED047TC2.h} (98%) rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED060SC4.h (100%) mode change 100755 => 100644 rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED060SCT.h (100%) mode change 100755 => 100644 rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED060XC3.h (100%) mode change 100755 => 100644 rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED097OC4.h (100%) mode change 100755 => 100644 rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED097TC2.h (100%) mode change 100755 => 100644 rename lib/libesp32_eink/epdiy/src/{epd_driver => }/waveforms/epdiy_ED133UT2.h (100%) mode change 100755 => 100644 create mode 100644 lib/libesp32_eink/epdiy/src/waveforms/epdiy_NULL.h diff --git a/CHANGELOG.md b/CHANGELOG.md index a9928f2fb..b89bf0276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ All notable changes to this project will be documented in this file. ### Breaking Changed ### Changed +- ESP32 Platform from 2025.07.31 to 2025.08.30, Framework (Arduino Core) from v3.1.3.250712 to v3.1.3.250808 and IDF from v5.3.3.250707 to v5.3.3.250801 (#23778) +- Epdiy library from v1.0.0 to v2.0.0 ### Fixed - Syslog RFC5424 compliance (#23509) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b6db3c06d..613810fda 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -132,8 +132,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ### Breaking Changed ### Changed -- ESP32 Platform from 2025.05.30 to 2025.07.31, Framework (Arduino Core) from v3.1.3.250504 to v3.1.3.250712 and IDF from v5.3.3.250501 to v5.3.3.250707 [#23685](https://github.com/arendst/Tasmota/issues/23685) - ESP8266 platform update from 2025.05.00 to 2025.07.00 [#23700](https://github.com/arendst/Tasmota/issues/23700) +- ESP32 Platform from 2025.05.30 to 2025.08.30, Framework (Arduino Core) from v3.1.3.250504 to v3.1.3.250808 and IDF from v5.3.3.250501 to v5.3.3.250801 [#23778](https://github.com/arendst/Tasmota/issues/23778) +- Epdiy library from v1.0.0 to v2.0.0 - OpenTherm library from v0.9.0 to v1.1.5 [#23704](https://github.com/arendst/Tasmota/issues/23704) - Library names [#23560](https://github.com/arendst/Tasmota/issues/23560) - CSS uses named colors variables [#23597](https://github.com/arendst/Tasmota/issues/23597) diff --git a/lib/libesp32_eink/epdiy/.clang-format b/lib/libesp32_eink/epdiy/.clang-format new file mode 100644 index 000000000..a05539ca4 --- /dev/null +++ b/lib/libesp32_eink/epdiy/.clang-format @@ -0,0 +1,11 @@ +BasedOnStyle: chromium +IndentWidth: 4 +ColumnLimit: 100 +AlignAfterOpenBracket: BlockIndent +IncludeBlocks: Preserve +BreakBeforeBinaryOperators: All +Cpp11BracedListStyle: false +AllowAllParametersOfDeclarationOnNextLine: true +BinPackArguments: false +BinPackParameters: false +SortIncludes: false diff --git a/lib/libesp32_eink/epdiy/.gitignore b/lib/libesp32_eink/epdiy/.gitignore index b7b2db4a8..5ab771df7 100755 --- a/lib/libesp32_eink/epdiy/.gitignore +++ b/lib/libesp32_eink/epdiy/.gitignore @@ -1,6 +1,9 @@ .pio +.vscode build/ +build.clang sdkconfig.old +sdkconfig **/build/ .ccls-cache doc/source/xml/ @@ -16,3 +19,10 @@ fp-info-cache __pycache__ examples/weather/components sdkconfig +managed_components/ +epaper-breakout-backups/ +dependencies.lock +ED*.h +ES*.h +examples/private_*/ +*.code-workspace diff --git a/lib/libesp32_eink/epdiy/.gitmodules b/lib/libesp32_eink/epdiy/.gitmodules deleted file mode 100755 index c7efb9205..000000000 --- a/lib/libesp32_eink/epdiy/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "hardware/epaper-breakout/esp32-wrover-kicad"] - path = hardware/epaper-breakout/esp32-wrover-kicad - url = https://github.com/aliafshar/esp32-wrover-kicad -[submodule "hardware/epaper-breakout/tp4056"] - path = hardware/epaper-breakout/tp4056 - url = https://github.com/alltheworld/tp4056/ diff --git a/lib/libesp32_eink/epdiy/.readthedocs.yml b/lib/libesp32_eink/epdiy/.readthedocs.yml index 4d21d9b40..e7c2b25d5 100755 --- a/lib/libesp32_eink/epdiy/.readthedocs.yml +++ b/lib/libesp32_eink/epdiy/.readthedocs.yml @@ -12,8 +12,12 @@ sphinx: # Optionally build your docs in additional formats such as PDF and ePub formats: all +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # Optionally set the version of Python and requirements required to build your docs python: - version: 3.7 install: - requirements: doc/requirements.txt diff --git a/lib/libesp32_eink/epdiy/LICENSE b/lib/libesp32_eink/epdiy/LICENSE new file mode 100644 index 000000000..0a041280b --- /dev/null +++ b/lib/libesp32_eink/epdiy/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/lib/libesp32_eink/epdiy/Makefile b/lib/libesp32_eink/epdiy/Makefile index 545c55a5e..385cc55f6 100755 --- a/lib/libesp32_eink/epdiy/Makefile +++ b/lib/libesp32_eink/epdiy/Makefile @@ -8,27 +8,41 @@ EXPORTED_MODES ?= 1,2,5,16,17 # Generate waveforms in room temperature range EXPORT_TEMPERATURE_RANGE ?= 15,35 +FORMATTED_FILES := $(shell find ./ -regex '.*\.\(c\|cpp\|h\|ino\)$$' \ + -not -regex '.*/\(.ccls-cache\|.cache\|waveforms\|\components\|build\)/.*' \ + -not -regex '.*/img_.*.h' \ + -not -regex '.*/build.*' \ + -not -regex '.*/\(firasans_.*.h\|opensans.*.h\|amiri.h\|alexandria.h\|dragon.h\)' \ + -not -regex '.*E[DS][0-9]*[A-Za-z]*[0-9].h') + # the default headers that should come with the distribution default: \ - $(patsubst %,src/epd_driver/waveforms/epdiy_%.h,$(SUPPORTRED_DISPLAYS)) + $(patsubst %,src/waveforms/epdiy_%.h,$(SUPPORTRED_DISPLAYS)) clean: - rm src/epd_driver/waveforms/epdiy_*.h - rm src/epd_driver/waveforms/eink_*.h + rm src/waveforms/epdiy_*.h + rm src/waveforms/eink_*.h -src/epd_driver/waveforms/epdiy_%.h: src/epd_driver/waveforms/epdiy_%.json +format: + clang-format --style=file -i $(FORMATTED_FILES) + +format-check: + clang-format --style=file --dry-run -Werror $(FORMATTED_FILES) + + +src/waveforms/epdiy_%.h: src/waveforms/epdiy_%.json python3 scripts/waveform_hdrgen.py \ --export-modes $(EXPORTED_MODES) \ --temperature-range $(EXPORT_TEMPERATURE_RANGE) \ epdiy_$* < $< > $@ -src/epd_driver/waveforms/eink_%.h: src/epd_driver/waveforms/eink_%.json +src/waveforms/eink_%.h: src/waveforms/eink_%.json python3 scripts/waveform_hdrgen.py \ --export-modes $(EXPORTED_MODES) \ --temperature-range $(EXPORT_TEMPERATURE_RANGE) \ eink_$* < $< > $@ -src/epd_driver/waveforms/epdiy_%.json: +src/waveforms/epdiy_%.json: python3 scripts/epdiy_waveform_gen.py $* > $@ -.PHONY: default +.PHONY: default format diff --git a/lib/libesp32_eink/epdiy/README.md b/lib/libesp32_eink/epdiy/README.md index fc3135a04..33cbd4847 100755 --- a/lib/libesp32_eink/epdiy/README.md +++ b/lib/libesp32_eink/epdiy/README.md @@ -1,4 +1,4 @@ -[![Documentation Status](https://readthedocs.org/projects/epdiy/badge/?version=latest)](https://epdiy.readthedocs.io/en/latest/?badge=latest) [![Matrix](https://img.shields.io/matrix/epdiy-general:matrix.vroland.de?label=Matrix%20Chat)](https://matrix.to/#/!GUXWriqsBKkWyXzsBK:matrix.vroland.de?via=matrix.vroland.de) [![JoinSlack](https://img.shields.io/badge/Join%20us-on%20Slack-blueviolet.svg)](https://join.slack.com/t/epdiy/shared_invite/zt-mw3iat5g-6jRylNrK2g79HSxeznvmPg) +[![Documentation Status](https://readthedocs.org/projects/epdiy/badge/?version=latest)](https://epdiy.readthedocs.io/en/latest/?badge=latest) [![Matrix](https://img.shields.io/matrix/epdiy-general:matrix.vroland.de?label=Matrix%20Chat)](https://matrix.to/#/!GUXWriqsBKkWyXzsBK:matrix.vroland.de?via=matrix.vroland.de) [![JoinSlack](https://img.shields.io/badge/Join%20us-on%20Slack-blueviolet.svg)](https://join.slack.com/t/epdiy/shared_invite/zt-189eo7328-bs94cfB~eXPbLYAD1rKQcg) EPDiy E-Paper Driver ======================================= @@ -9,35 +9,53 @@ EPDiy is a driver board which talks to affordable E-Paper (or E-Ink) screens, wh * No power consumption when not updating * Sunlight-readable -Ready-made DIY modules for this size and with 4bpp (16 Grayscale) color support are currently quite expensive. This project uses Kindle replacement screens, which are available for 20$ (small) / 30$ (large) on ebay! +Ready-made DIY modules for this size and with 4bpp (16 Grayscale) color support are currently quite expensive and / or slow. +The EPDiy controller can drive the bare display modules, e.g. from old e-Readers, which are available for 20$ (small) / 30$ (large) on ebay! +Additionally, since it is based on the ESP32S3 (V7) / ESP32 (V2-V6) microcontroller, it features WiFi and Bluetooth connectivity. -The EPDiy driver board targets multiple E-Paper displays. As the driving method for all matrix-based E-ink displays seems to be more or less the same, only the right connector and timings are needed. The EPDiy PCB v5 features 33pin, 34pin and a 39pin connectors, which allow to drive the following display types: ED097OC4, ED060SC4, ED097TC2, ED060SC7. For the full list of supported displays, refer to the table below. +The EPDiy driver board targets a range of E-Paper displays, as shown in the table below. +As the driving method for all matrix-based E-ink displays is more or less the same, only the right connector and timings are needed. +The current V7 board has three different display connectors, other display will require an adapter board. -Revision 5 of the board is optimized for the use with LiPo batteries, featuring a LiPo charger and ultra-low deep sleep current. +The controller is optimized for the use with LiPo batteries, featuring a LiPo charger and ultra-low deep sleep current. This project supports a driver for the ESP-IDF and Arduino. For installation instructions, please refer to the [documentation](https://epdiy.readthedocs.io/en/latest/getting_started.html#getting-your-board). +Note that for epdiy V7, update speeds are significantly lower when using the Arduino IDE, because it does not allow to change +the sub-optimal cache configuration. + +Get Inspired +------------ + +The `examples` directory contains some example applications like a weather station or a screen diagnostic test. +If you want to build something more useful though, how about: + +- A serial terminal for connecting to a raspberry pi: [video](https://cdn.hackaday.io/files/1681937195969312/terminal_demo.mp4) [repository](https://github.com/vroland/epdiy-terminal)] +- A Music Player Daemon (MPD) dashboard: [repository](https://github.com/vroland/epdiy-mpd)] +- An e-Paper picture frame: [video](https://www.youtube.com/watch?v=r7AcNQsSZUw) +- And more to come! Building It ----------- -If you want to build a board right now, there are two possible routes: +On the [EPDiy Hardware Page](https://vroland.github.io/epdiy-hardware/), you'll find a list of all boards and variants, adapters, and helpers. +Next to each board, there are manufacturing files (gerbers), Bill of Materials (BoM), part placement files, +and 3D models ready to use! - - Use the new v5 PCB (`hardware/epaper-breakout/gerbers_v5.zip`). - **So far, I only tested a prototype of it. The newest gerbers should work, but are untested!** - **If you have tested them, please let me know!** - The BOM is available at (`hardware/epaper-breakout/BOM.csv`). - Positioning files for SMT assembly are available at (`hardware/epaper-breakout/gerbers/epaper-breakout-top-pos.csv`). - Please double check the part positioning and Rotation with your assembly service! - More information on the order process and where to find parts is in the [documentation](https://epdiy.readthedocs.io/en/latest/getting_started.html#getting-your-board). +![demo image](doc/source/img/hardware_page.png) + +For ordering from JLCPCB for example, ordering is as easy as downloading the zipped gerbers, BoM, and placement file +and uploading them. The process is very similar for other manufacturers, check your vendor's documentation for details. +Don't forget to oder adapters if the board doesn't have connectors for your specific display. + +The current latest version is epdiy V7, beased on the ESP32S3. +Older versions are also available on the hardware page. + + +#### Contributing Hardware + +Want to contribute your own board variant or adapter? +Check out the [epdiy-hardware repository](https://github.com/vroland/epdiy-hardware) for instructions. - Make sure to select the `V5` board revision in `idf.py menuconfig` when building the examples. - - - Use the old v4 PCB (`hardware/epaper-breakout/gerbers_v4.zip`). This is a bit more fresh, but should work. - The BOM is available at (`hardware/epaper-breakout/BOM.csv`). - Positioning files for SMT assembly are available at (`hardware/epaper-breakout/gerbers/epaper-breakout-top-pos.csv`). - Please double check the part positioning and Rotation with your assembly service! - - Make sure to select the `V4` board revision in `idf.py menuconfig` when building the examples. Gettings Started ---------------- @@ -48,37 +66,40 @@ Join the Discussion ---------------- - [![Matrix](https://img.shields.io/matrix/epdiy-general:matrix.vroland.de?label=Join%20Matrix)](https://matrix.to/#/!GUXWriqsBKkWyXzsBK:matrix.vroland.de?via=matrix.vroland.de) Matrix Community: +epdiy:matrix.vroland.de - - [![JoinSlack](https://img.shields.io/badge/Join%20us-on%20Slack-blueviolet.svg)](https://join.slack.com/t/epdiy/shared_invite/zt-mw3iat5g-6jRylNrK2g79HSxeznvmPg) + - Slack: See badge Displays -------- -|Name|Size|Resolution|Compatible|Connector|Pin count|Compatible since pcb version|Notes -| --: | --: | --: | --: | --: | --: |--: |--: | -|ED060SC4|6"|800 x 600|yes, tested|FH26W-39S-0.3SHW(60)|39|v2| -|ED097OC4|9.7"|1200 x 825|yes, tested|XF2M-3315-1A|33|V2|Cheap, inferior contrast -|ED097TC2|9.7"|1200 x 825|yes, tested|XF2M-3315-1A|33|V2|Slightly higher price, better contrast -|ED097OC1|9.7"|1200 x 825|yes (should work)|XF2M-3315-1A|33|V2|Cheap, inferior performance -|ED047TC1|4.7"|960 x 540|yes, tested|40-pin|40|LILYGO 4.7" EPD|Supported only by 4.7" e-paper board by LILYGO -|ED133UT2|13.3"|1600 x 1200|yes, tested|adapter board|39|V2|Adapter Board required, also PENG133D -|ED060XC3|6"|758 x 1024|yes, tested|THD0515-34CL-SN|34|V5|Cheapest, good contrast and resolution -|ED060XD4|6"|758 x 1024|yes, tested|THD0515-34CL-SN|34|V5| -|ED060XC5|6"|758 x 1024|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5| -|ED060XD6|6"|758 x 1024|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5| -|ED060XH2|6"|758 x 1024|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5| -|ED060XC9|6"|758 x 1024|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5| -|ED060KD1|6"|1072 x 1448|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5| -|ED060KC1|6"|1072 x 1448|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5| -|ED060SCF|6"|600 x 800|yes, tested|THD0515-34CL-SN|34|V5|Different flex cable shape -|ED060SCN|6"|600 x 800|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5|Different flex cable shape -|ED060SCP|6"|600 x 800|yes (should work as ED060XC3)|THD0515-34CL-SN|34|V5|Different flex cable shape -|ED060SC7|6"|600 x 800|yes (should work) |AXT434124|34|v5| -|ED060SCG|6"|600 x 800|yes (should work) |AXT434124|34|v5| -| ED060SCE | 6" | 600 x 800 | yes (should work) | AXT434124 | 34 | v5 | -| ED060SCM | 6" | 600 x 800 | yes (should work) | AXT434124 | 34 | v5 | -| ED060SCT | 6" | 600 x 800 | yes, tested | AXT434124 | 34 | v5 | +|Name |Size |Resolution|Compatible|Connector|Pin count|Compatible since pcb version|Notes +| --: | --: | --: | --: | --: | --: | --: | --: | +| ED060SC4 | 6" | 800 x 600
167 PPI | yes, tested | FH26W-39S-0.3SHW(60) | 39 | v2 | | +|ED097OC4|9.7"|1200 x 825
150 PPI|yes, tested|XF2M-3315-1A|33|v2|Cheap, inferior contrast +|ED097TC2|9.7"|1200 x 825
150 PPI|yes, tested|XF2M-3315-1A|33|v2|Slightly higher price, better contrast +|ED097OC1|9.7"|1200 x 825
150 PPI|yes (should work)|XF2M-3315-1A|33|v2|Cheap, inferior performance +|ED047TC1|4.7"|960 x 540
234 PPI|yes, tested|40-pin|40|LILYGO 4.7" EPD|Supported only by 4.7" e-paper board by LILYGO +| ED050SC5 | 5" | 600 x 800
200 PPI | yes, tested | THD0510-33CL-GF | 33 | v5 | +| ED050SC3 | 5" | 600 x 800
200 PPI | yes (should work) | THD0510-33CL-GF | 33 | v5 | +| ED052TC4 | 5.2" | 1280 x 780
??? PPI | yes (should work) | WP27D-P050VA3 | 50 | v5 | +| ED133UT2 | 13.3" | 1600 x 1200
150 PPI | yes, tested | adapter board | 39 | v2 | Adapter Board required, also PENG133D +| ED060XC3 | 6" | 758 x 1024
212 PPI | yes, tested | THD0515-34CL-SN | 34 | v5 | Cheapest, good contrast and resolution +| ED060XD4 | 6" | 758 x 1024
212 PPI | yes, tested | THD0515-34CL-SN | 34 | v5 | +| ED060XC5 | 6" | 758 x 1024
212 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | +| ED060XD6 | 6" | 758 x 1024
212 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | +| ED060XH2 | 6" | 758 x 1024
212 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | +| ED060XC9 | 6" | 758 x 1024
212 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | +| ED060KD1 | 6" | 1072 x 1448
300 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | +| ED060KC1 | 6" | 1072 x 1448
300 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | +| ED060SCF | 6" | 600 x 800
167 PPI | yes, tested | THD0515-34CL-SN | 34 | v5 | Different flex cable shape +| ED060SCN | 6" | 600 x 800
167 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | Different flex cable shape +| ED060SCP | 6" | 600 x 800
167 PPI | yes (should work as ED060XC3) | THD0515-34CL-SN | 34 | v5 | Different flex cable shape +| ED060SC7 | 6" | 600 x 800
167 PPI | yes (should work) | AXT334124 | 34 | v5 | connector dropped in v6 +| ED060SCG | 6" | 600 x 800
167 PPI | yes (should work) | AXT334124 | 34 | v5 | connector dropped in v6 +| ED060SCE | 6" | 600 x 800
167 PPI | yes (should work) | AXT334124 | 34 | v5 | connector dropped in v6 +| ED060SCM | 6" | 600 x 800
167 PPI | yes (should work) | AXT334124 | 34 | v5 | connector dropped in v6 +| ED060SCT | 6" | 600 x 800
167 PPI | yes, tested | AXT334124 | 34 | v5 | connector dropped in v6 +| ED078KC1 | 7.8" | 1872 x 1404
300 PPI | yes, tested | FH12-40S-0.5SH | 40 | v7 | 16 data lines -**Please note that board revision v5 is still in prototype stage!** Troubleshooting --------------- @@ -88,7 +109,26 @@ The following list is compiled from past experiences and GitHub issues: * **The existing image fades / darkens when updating a partial screen region.** Make sure the VCOM voltage is [calibrated](https://epdiy.readthedocs.io/en/latest/getting_started.html#calibrate-vcom) for your specific display. * **The second third of the image is replaced with the last third.** This seems to be a timing issue we could not yet quite figure out the reason for. For a workarround or suggestions please [join the discussion](https://github.com/vroland/epdiy/issues/15). * **The ESP does not boot correctly when external periperals are connected.** Make sure not to pull GPIO12 high during boot, as it is a strapping pin internal voltage selection (https://github.com/vroland/epdiy/issues/17). - + * **The ESP power consumption in deep sleep is too high.** Add `rtc_gpio_isolate(GPIO_NUM_12);` to your solution. See also [Configuring IOs (Deep-sleep Only)](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html?highlight=rtc_gpio_isolate#configuring-ios-deep-sleep-only). + +LilyGo Boards +--------------- +There are several differences with these boards. +One particular one is the way the LilyGo handles power to the display the official lilygo code has two states. +This is now handled in epdiy in a different way to the lilygo code. +**epd_poweroff()** completely turns the power off to the display and the other peripherals of the lilygo. +The new function **epd_powerdown()** keeps the peripherals on (this allows the touch functions to continue to work). +**epd_poweroff() should allways be called before sleeping the system** +You can still use touch to wake the screen with the following. +In Arduino it works like this. +`epd_poweroff();` + + `epd_deinit();` + + `esp_sleep_enable_ext1_wakeup(GPIO_SEL_13, ESP_EXT1_WAKEUP_ANY_HIGH);` + + `esp_deep_sleep_start();` + More on E-Paper Displays ------------------------ @@ -106,8 +146,7 @@ Hackaday Project For more details, see the project page on Hackaday: https://hackaday.io/project/168193-epdiy-976-e-paper-controller ![demo image](doc/source/img/demo.jpg) -![board front](doc/source/img/board_p1.jpg) -![board back](doc/source/img/board_p2.jpg) +![board front](doc/source/img/v6.jpg) Licenses -------- @@ -116,6 +155,5 @@ The weather example is Copyright (c) David Bird 2018 (except for minor modificat The board and schematic are licensed under a Creative Commons License Creative Commons Attribution-ShareAlike 4.0 International License. -Firmware and remaining examples are licensed under the terms of the GNU GPL version 3. +Firmware and remaining examples are licensed under the terms of the GNU Lesser GPL version 3. Utilities are licensed under the terms of the MIT license. - diff --git a/lib/libesp32_eink/epdiy/boards.local.txt b/lib/libesp32_eink/epdiy/boards.local.txt deleted file mode 100755 index c72bb245f..000000000 --- a/lib/libesp32_eink/epdiy/boards.local.txt +++ /dev/null @@ -1,452 +0,0 @@ -############################## Revision 5 Board ############################## -epdiy_v5.name=EPDIY Board Revision 5 - -epdiy_v5.upload.tool=esp32:esptool_py -epdiy_v5.upload.maximum_size=1310720 -epdiy_v5.upload.maximum_data_size=327680 -epdiy_v5.upload.wait_for_upload_port=true - -epdiy_v5.serial.disableDTR=true -epdiy_v5.serial.disableRTS=true - -epdiy_v5.build.mcu=esp32 -epdiy_v5.build.core=esp32:esp32 -epdiy_v5.build.variant=esp32 -epdiy_v5.build.board=ESP32_EPDIY - -epdiy_v5.build.f_cpu=240000000L -epdiy_v5.build.flash_size=4MB -epdiy_v5.build.flash_freq=40m -epdiy_v5.build.flash_mode=dio -epdiy_v5.build.boot=dio -epdiy_v5.build.partitions=default -epdiy_v5.build.defines= - -epdiy_v5.menu.DisplayType.default=ED097OC4 -epdiy_v5.menu.DisplayType.default.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V5 -epdiy_v5.menu.DisplayType.ed097oc4_lq=ED097OC4 Low Quality -epdiy_v5.menu.DisplayType.ed097oc4_lq.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V5 -epdiy_v5.menu.DisplayType.ed060sc4=ED060SC4 -epdiy_v5.menu.DisplayType.ed060sc4.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED060SC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V5 -epdiy_v5.menu.DisplayType.ed097tc2=ED097TC2 -epdiy_v5.menu.DisplayType.ed097tc2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097TC2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V5 -epdiy_v5.menu.DisplayType.ed047tc1=ED047TC1 (LILYGO 4.7 inch) -epdiy_v5.menu.DisplayType.ed047tc1.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED047TC1 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V5 -epdiy_v5.menu.DisplayType.ed133ut2=ED133UT2 -epdiy_v5.menu.DisplayType.ed133ut2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED133UT2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V5 - -epdiy_v5.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) -epdiy_v5.menu.PartitionScheme.default.build.partitions=default -epdiy_v5.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) -epdiy_v5.menu.PartitionScheme.defaultffat.build.partitions=default_ffat -epdiy_v5.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT) -epdiy_v5.menu.PartitionScheme.default_8MB.build.partitions=default_8MB -epdiy_v5.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) -epdiy_v5.menu.PartitionScheme.minimal.build.partitions=minimal -epdiy_v5.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) -epdiy_v5.menu.PartitionScheme.no_ota.build.partitions=no_ota -epdiy_v5.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 -epdiy_v5.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) -epdiy_v5.menu.PartitionScheme.noota_3g.build.partitions=noota_3g -epdiy_v5.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 -epdiy_v5.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) -epdiy_v5.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat -epdiy_v5.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 -epdiy_v5.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) -epdiy_v5.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat -epdiy_v5.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 -epdiy_v5.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) -epdiy_v5.menu.PartitionScheme.huge_app.build.partitions=huge_app -epdiy_v5.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 -epdiy_v5.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) -epdiy_v5.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs -epdiy_v5.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 -epdiy_v5.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT) -epdiy_v5.menu.PartitionScheme.fatflash.build.partitions=ffat - -epdiy_v5.menu.FlashMode.qio=QIO -epdiy_v5.menu.FlashMode.qio.build.flash_mode=dio -epdiy_v5.menu.FlashMode.qio.build.boot=qio -epdiy_v5.menu.FlashMode.dio=DIO -epdiy_v5.menu.FlashMode.dio.build.flash_mode=dio -epdiy_v5.menu.FlashMode.dio.build.boot=dio -epdiy_v5.menu.FlashMode.qout=QOUT -epdiy_v5.menu.FlashMode.qout.build.flash_mode=dout -epdiy_v5.menu.FlashMode.qout.build.boot=qout -epdiy_v5.menu.FlashMode.dout=DOUT -epdiy_v5.menu.FlashMode.dout.build.flash_mode=dout -epdiy_v5.menu.FlashMode.dout.build.boot=dout - -epdiy_v5.menu.FlashFreq.80=80MHz -epdiy_v5.menu.FlashFreq.80.build.flash_freq=80m -epdiy_v5.menu.FlashFreq.40=40MHz -epdiy_v5.menu.FlashFreq.40.build.flash_freq=40m - -epdiy_v5.menu.UploadSpeed.921600=921600 -epdiy_v5.menu.UploadSpeed.921600.upload.speed=921600 -epdiy_v5.menu.UploadSpeed.115200=115200 -epdiy_v5.menu.UploadSpeed.115200.upload.speed=115200 -epdiy_v5.menu.UploadSpeed.256000.windows=256000 -epdiy_v5.menu.UploadSpeed.256000.upload.speed=256000 -epdiy_v5.menu.UploadSpeed.230400.windows.upload.speed=256000 -epdiy_v5.menu.UploadSpeed.230400=230400 -epdiy_v5.menu.UploadSpeed.230400.upload.speed=230400 -epdiy_v5.menu.UploadSpeed.460800.linux=460800 -epdiy_v5.menu.UploadSpeed.460800.macosx=460800 -epdiy_v5.menu.UploadSpeed.460800.upload.speed=460800 -epdiy_v5.menu.UploadSpeed.512000.windows=512000 -epdiy_v5.menu.UploadSpeed.512000.upload.speed=512000 - -epdiy_v5.menu.DebugLevel.none=None -epdiy_v5.menu.DebugLevel.none.build.code_debug=0 -epdiy_v5.menu.DebugLevel.error=Error -epdiy_v5.menu.DebugLevel.error.build.code_debug=1 -epdiy_v5.menu.DebugLevel.warn=Warn -epdiy_v5.menu.DebugLevel.warn.build.code_debug=2 -epdiy_v5.menu.DebugLevel.info=Info -epdiy_v5.menu.DebugLevel.info.build.code_debug=3 -epdiy_v5.menu.DebugLevel.debug=Debug -epdiy_v5.menu.DebugLevel.debug.build.code_debug=4 -epdiy_v5.menu.DebugLevel.verbose=Verbose -epdiy_v5.menu.DebugLevel.verbose.build.code_debug=5 - - - -############################################################## - -menu.DisplayType=DisplayType - -epdiy_v2.name=EPDIY Board Revision 2/3 - -epdiy_v2.upload.tool=esptool_py -epdiy_v2.upload.maximum_size=1310720 -epdiy_v2.upload.maximum_data_size=327680 -epdiy_v2.upload.wait_for_upload_port=true - -epdiy_v2.serial.disableDTR=true -epdiy_v2.serial.disableRTS=true - -epdiy_v2.build.mcu=esp32 -epdiy_v2.build.core=esp32:esp32 -epdiy_v2.build.variant=esp32 -epdiy_v2.build.board=ESP32_EPDIY - -epdiy_v2.build.f_cpu=240000000L -epdiy_v2.build.flash_size=4MB -epdiy_v2.build.flash_freq=40m -epdiy_v2.build.flash_mode=dio -epdiy_v2.build.boot=dio -epdiy_v2.build.partitions=default - -epdiy_v2.menu.DisplayType.default=ED097OC4 -epdiy_v2.menu.DisplayType.default.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V2_V3 -epdiy_v2.menu.DisplayType.ed097oc4_lq=ED097OC4 Low Quality -epdiy_v2.menu.DisplayType.ed097oc4_lq.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V2_V3 -epdiy_v2.menu.DisplayType.ed060sc4=ED060SC4 -epdiy_v2.menu.DisplayType.ed060sc4.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED060SC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V2_V3 -epdiy_v2.menu.DisplayType.ed097tc2=ED097TC2 -epdiy_v2.menu.DisplayType.ed097tc2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097TC2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V2_V3 -epdiy_v2.menu.DisplayType.ed047tc1=ED047TC1 (LILYGO 4.7 inch) -epdiy_v2.menu.DisplayType.ed047tc1.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED047TC1 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V2_V3 -epdiy_v2.menu.DisplayType.ed133ut2=ED133UT2 -epdiy_v2.menu.DisplayType.ed133ut2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED133UT2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V2_V3 - -epdiy_v2.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) -epdiy_v2.menu.PartitionScheme.default.build.partitions=default -epdiy_v2.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) -epdiy_v2.menu.PartitionScheme.defaultffat.build.partitions=default_ffat -epdiy_v2.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT) -epdiy_v2.menu.PartitionScheme.default_8MB.build.partitions=default_8MB -epdiy_v2.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) -epdiy_v2.menu.PartitionScheme.minimal.build.partitions=minimal -epdiy_v2.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) -epdiy_v2.menu.PartitionScheme.no_ota.build.partitions=no_ota -epdiy_v2.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 -epdiy_v2.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) -epdiy_v2.menu.PartitionScheme.noota_3g.build.partitions=noota_3g -epdiy_v2.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 -epdiy_v2.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) -epdiy_v2.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat -epdiy_v2.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 -epdiy_v2.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) -epdiy_v2.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat -epdiy_v2.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 -epdiy_v2.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) -epdiy_v2.menu.PartitionScheme.huge_app.build.partitions=huge_app -epdiy_v2.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 -epdiy_v2.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) -epdiy_v2.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs -epdiy_v2.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 -epdiy_v2.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT) -epdiy_v2.menu.PartitionScheme.fatflash.build.partitions=ffat - -epdiy_v2.menu.FlashMode.qio=QIO -epdiy_v2.menu.FlashMode.qio.build.flash_mode=dio -epdiy_v2.menu.FlashMode.qio.build.boot=qio -epdiy_v2.menu.FlashMode.dio=DIO -epdiy_v2.menu.FlashMode.dio.build.flash_mode=dio -epdiy_v2.menu.FlashMode.dio.build.boot=dio -epdiy_v2.menu.FlashMode.qout=QOUT -epdiy_v2.menu.FlashMode.qout.build.flash_mode=dout -epdiy_v2.menu.FlashMode.qout.build.boot=qout -epdiy_v2.menu.FlashMode.dout=DOUT -epdiy_v2.menu.FlashMode.dout.build.flash_mode=dout -epdiy_v2.menu.FlashMode.dout.build.boot=dout - -epdiy_v2.menu.FlashFreq.80=80MHz -epdiy_v2.menu.FlashFreq.80.build.flash_freq=80m -epdiy_v2.menu.FlashFreq.40=40MHz -epdiy_v2.menu.FlashFreq.40.build.flash_freq=40m - -epdiy_v2.menu.UploadSpeed.921600=921600 -epdiy_v2.menu.UploadSpeed.921600.upload.speed=921600 -epdiy_v2.menu.UploadSpeed.115200=115200 -epdiy_v2.menu.UploadSpeed.115200.upload.speed=115200 -epdiy_v2.menu.UploadSpeed.256000.windows=256000 -epdiy_v2.menu.UploadSpeed.256000.upload.speed=256000 -epdiy_v2.menu.UploadSpeed.230400.windows.upload.speed=256000 -epdiy_v2.menu.UploadSpeed.230400=230400 -epdiy_v2.menu.UploadSpeed.230400.upload.speed=230400 -epdiy_v2.menu.UploadSpeed.460800.linux=460800 -epdiy_v2.menu.UploadSpeed.460800.macosx=460800 -epdiy_v2.menu.UploadSpeed.460800.upload.speed=460800 -epdiy_v2.menu.UploadSpeed.512000.windows=512000 -epdiy_v2.menu.UploadSpeed.512000.upload.speed=512000 - -epdiy_v2.menu.DebugLevel.none=None -epdiy_v2.menu.DebugLevel.none.build.code_debug=0 -epdiy_v2.menu.DebugLevel.error=Error -epdiy_v2.menu.DebugLevel.error.build.code_debug=1 -epdiy_v2.menu.DebugLevel.warn=Warn -epdiy_v2.menu.DebugLevel.warn.build.code_debug=2 -epdiy_v2.menu.DebugLevel.info=Info -epdiy_v2.menu.DebugLevel.info.build.code_debug=3 -epdiy_v2.menu.DebugLevel.debug=Debug -epdiy_v2.menu.DebugLevel.debug.build.code_debug=4 -epdiy_v2.menu.DebugLevel.verbose=Verbose -epdiy_v2.menu.DebugLevel.verbose.build.code_debug=5 - -############################## Revision 4 Board ############################## -epdiy_v4.name=EPDIY Board Revision 4 - -epdiy_v4.upload.tool=esp32:esptool_py -epdiy_v4.upload.maximum_size=1310720 -epdiy_v4.upload.maximum_data_size=327680 -epdiy_v4.upload.wait_for_upload_port=true - -epdiy_v4.serial.disableDTR=true -epdiy_v4.serial.disableRTS=true - -epdiy_v4.build.mcu=esp32 -epdiy_v4.build.core=esp32:esp32 -epdiy_v4.build.variant=esp32 -epdiy_v4.build.board=ESP32_EPDIY - -epdiy_v4.build.f_cpu=240000000L -epdiy_v4.build.flash_size=4MB -epdiy_v4.build.flash_freq=40m -epdiy_v4.build.flash_mode=dio -epdiy_v4.build.boot=dio -epdiy_v4.build.partitions=default -epdiy_v4.build.defines= - -epdiy_v4.menu.DisplayType.default=ED097OC4 -epdiy_v4.menu.DisplayType.default.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V4 -epdiy_v4.menu.DisplayType.ed097oc4_lq=ED097OC4 Low Quality -epdiy_v4.menu.DisplayType.ed097oc4_lq.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V4 -epdiy_v4.menu.DisplayType.ed060sc4=ED060SC4 -epdiy_v4.menu.DisplayType.ed060sc4.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED060SC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V4 -epdiy_v4.menu.DisplayType.ed097tc2=ED097TC2 -epdiy_v4.menu.DisplayType.ed097tc2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097TC2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V4 -epdiy_v4.menu.DisplayType.ed047tc1=ED047TC1 (LILYGO 4.7 inch) -epdiy_v4.menu.DisplayType.ed047tc1.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED047TC1 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V4 -epdiy_v4.menu.DisplayType.ed133ut2=ED133UT2 -epdiy_v4.menu.DisplayType.ed133ut2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED133UT2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_V4 - -epdiy_v4.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) -epdiy_v4.menu.PartitionScheme.default.build.partitions=default -epdiy_v4.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) -epdiy_v4.menu.PartitionScheme.defaultffat.build.partitions=default_ffat -epdiy_v4.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT) -epdiy_v4.menu.PartitionScheme.default_8MB.build.partitions=default_8MB -epdiy_v4.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) -epdiy_v4.menu.PartitionScheme.minimal.build.partitions=minimal -epdiy_v4.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) -epdiy_v4.menu.PartitionScheme.no_ota.build.partitions=no_ota -epdiy_v4.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 -epdiy_v4.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) -epdiy_v4.menu.PartitionScheme.noota_3g.build.partitions=noota_3g -epdiy_v4.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 -epdiy_v4.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) -epdiy_v4.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat -epdiy_v4.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 -epdiy_v4.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) -epdiy_v4.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat -epdiy_v4.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 -epdiy_v4.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) -epdiy_v4.menu.PartitionScheme.huge_app.build.partitions=huge_app -epdiy_v4.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 -epdiy_v4.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) -epdiy_v4.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs -epdiy_v4.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 -epdiy_v4.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT) -epdiy_v4.menu.PartitionScheme.fatflash.build.partitions=ffat - -epdiy_v4.menu.FlashMode.qio=QIO -epdiy_v4.menu.FlashMode.qio.build.flash_mode=dio -epdiy_v4.menu.FlashMode.qio.build.boot=qio -epdiy_v4.menu.FlashMode.dio=DIO -epdiy_v4.menu.FlashMode.dio.build.flash_mode=dio -epdiy_v4.menu.FlashMode.dio.build.boot=dio -epdiy_v4.menu.FlashMode.qout=QOUT -epdiy_v4.menu.FlashMode.qout.build.flash_mode=dout -epdiy_v4.menu.FlashMode.qout.build.boot=qout -epdiy_v4.menu.FlashMode.dout=DOUT -epdiy_v4.menu.FlashMode.dout.build.flash_mode=dout -epdiy_v4.menu.FlashMode.dout.build.boot=dout - -epdiy_v4.menu.FlashFreq.80=80MHz -epdiy_v4.menu.FlashFreq.80.build.flash_freq=80m -epdiy_v4.menu.FlashFreq.40=40MHz -epdiy_v4.menu.FlashFreq.40.build.flash_freq=40m - -epdiy_v4.menu.UploadSpeed.921600=921600 -epdiy_v4.menu.UploadSpeed.921600.upload.speed=921600 -epdiy_v4.menu.UploadSpeed.115200=115200 -epdiy_v4.menu.UploadSpeed.115200.upload.speed=115200 -epdiy_v4.menu.UploadSpeed.256000.windows=256000 -epdiy_v4.menu.UploadSpeed.256000.upload.speed=256000 -epdiy_v4.menu.UploadSpeed.230400.windows.upload.speed=256000 -epdiy_v4.menu.UploadSpeed.230400=230400 -epdiy_v4.menu.UploadSpeed.230400.upload.speed=230400 -epdiy_v4.menu.UploadSpeed.460800.linux=460800 -epdiy_v4.menu.UploadSpeed.460800.macosx=460800 -epdiy_v4.menu.UploadSpeed.460800.upload.speed=460800 -epdiy_v4.menu.UploadSpeed.512000.windows=512000 -epdiy_v4.menu.UploadSpeed.512000.upload.speed=512000 - -epdiy_v4.menu.DebugLevel.none=None -epdiy_v4.menu.DebugLevel.none.build.code_debug=0 -epdiy_v4.menu.DebugLevel.error=Error -epdiy_v4.menu.DebugLevel.error.build.code_debug=1 -epdiy_v4.menu.DebugLevel.warn=Warn -epdiy_v4.menu.DebugLevel.warn.build.code_debug=2 -epdiy_v4.menu.DebugLevel.info=Info -epdiy_v4.menu.DebugLevel.info.build.code_debug=3 -epdiy_v4.menu.DebugLevel.debug=Debug -epdiy_v4.menu.DebugLevel.debug.build.code_debug=4 -epdiy_v4.menu.DebugLevel.verbose=Verbose -epdiy_v4.menu.DebugLevel.verbose.build.code_debug=5 - - -############################## Revision 4 Board ############################## -lilygo_t5_47.name=LILYGO T5-4.7 inch e-paper - -lilygo_t5_47.upload.tool=esp32:esptool_py -lilygo_t5_47.upload.maximum_size=1310720 -lilygo_t5_47.upload.maximum_data_size=327680 -lilygo_t5_47.upload.wait_for_upload_port=true - -lilygo_t5_47.serial.disableDTR=true -lilygo_t5_47.serial.disableRTS=true - -lilygo_t5_47.build.mcu=esp32 -lilygo_t5_47.build.core=esp32:esp32 -lilygo_t5_47.build.variant=esp32 -lilygo_t5_47.build.board=ESP32_EPDIY - -lilygo_t5_47.build.f_cpu=240000000L -lilygo_t5_47.build.flash_size=4MB -lilygo_t5_47.build.flash_freq=40m -lilygo_t5_47.build.flash_mode=dio -lilygo_t5_47.build.boot=dio -lilygo_t5_47.build.partitions=default -lilygo_t5_47.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 - -lilygo_t5_47.menu.DisplayType.default=ED097OC4 -lilygo_t5_47.menu.DisplayType.default.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 -lilygo_t5_47.menu.DisplayType.ed097oc4_lq=ED097OC4 Low Quality -lilygo_t5_47.menu.DisplayType.ed097oc4_lq.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 -lilygo_t5_47.menu.DisplayType.ed060sc4=ED060SC4 -lilygo_t5_47.menu.DisplayType.ed060sc4.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED060SC4 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 -lilygo_t5_47.menu.DisplayType.ed097tc2=ED097TC2 -lilygo_t5_47.menu.DisplayType.ed097tc2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED097TC2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 -lilygo_t5_47.menu.DisplayType.ed047tc1=ED047TC1 (LILYGO 4.7 inch) -lilygo_t5_47.menu.DisplayType.ed047tc1.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED047TC1 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 -lilygo_t5_47.menu.DisplayType.ed133ut2=ED133UT2 -lilygo_t5_47.menu.DisplayType.ed133ut2.build.defines=-DCONFIG_EPD_DISPLAY_TYPE_ED133UT2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 - -lilygo_t5_47.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) -lilygo_t5_47.menu.PartitionScheme.default.build.partitions=default -lilygo_t5_47.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) -lilygo_t5_47.menu.PartitionScheme.defaultffat.build.partitions=default_ffat -lilygo_t5_47.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT) -lilygo_t5_47.menu.PartitionScheme.default_8MB.build.partitions=default_8MB -lilygo_t5_47.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) -lilygo_t5_47.menu.PartitionScheme.minimal.build.partitions=minimal -lilygo_t5_47.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) -lilygo_t5_47.menu.PartitionScheme.no_ota.build.partitions=no_ota -lilygo_t5_47.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 -lilygo_t5_47.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) -lilygo_t5_47.menu.PartitionScheme.noota_3g.build.partitions=noota_3g -lilygo_t5_47.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 -lilygo_t5_47.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) -lilygo_t5_47.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat -lilygo_t5_47.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 -lilygo_t5_47.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) -lilygo_t5_47.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat -lilygo_t5_47.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 -lilygo_t5_47.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) -lilygo_t5_47.menu.PartitionScheme.huge_app.build.partitions=huge_app -lilygo_t5_47.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 -lilygo_t5_47.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) -lilygo_t5_47.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs -lilygo_t5_47.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 -lilygo_t5_47.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT) -lilygo_t5_47.menu.PartitionScheme.fatflash.build.partitions=ffat - -lilygo_t5_47.menu.FlashMode.qio=QIO -lilygo_t5_47.menu.FlashMode.qio.build.flash_mode=dio -lilygo_t5_47.menu.FlashMode.qio.build.boot=qio -lilygo_t5_47.menu.FlashMode.dio=DIO -lilygo_t5_47.menu.FlashMode.dio.build.flash_mode=dio -lilygo_t5_47.menu.FlashMode.dio.build.boot=dio -lilygo_t5_47.menu.FlashMode.qout=QOUT -lilygo_t5_47.menu.FlashMode.qout.build.flash_mode=dout -lilygo_t5_47.menu.FlashMode.qout.build.boot=qout -lilygo_t5_47.menu.FlashMode.dout=DOUT -lilygo_t5_47.menu.FlashMode.dout.build.flash_mode=dout -lilygo_t5_47.menu.FlashMode.dout.build.boot=dout - -lilygo_t5_47.menu.FlashFreq.80=80MHz -lilygo_t5_47.menu.FlashFreq.80.build.flash_freq=80m -lilygo_t5_47.menu.FlashFreq.40=40MHz -lilygo_t5_47.menu.FlashFreq.40.build.flash_freq=40m - -lilygo_t5_47.menu.UploadSpeed.921600=921600 -lilygo_t5_47.menu.UploadSpeed.921600.upload.speed=921600 -lilygo_t5_47.menu.UploadSpeed.115200=115200 -lilygo_t5_47.menu.UploadSpeed.115200.upload.speed=115200 -lilygo_t5_47.menu.UploadSpeed.256000.windows=256000 -lilygo_t5_47.menu.UploadSpeed.256000.upload.speed=256000 -lilygo_t5_47.menu.UploadSpeed.230400.windows.upload.speed=256000 -lilygo_t5_47.menu.UploadSpeed.230400=230400 -lilygo_t5_47.menu.UploadSpeed.230400.upload.speed=230400 -lilygo_t5_47.menu.UploadSpeed.460800.linux=460800 -lilygo_t5_47.menu.UploadSpeed.460800.macosx=460800 -lilygo_t5_47.menu.UploadSpeed.460800.upload.speed=460800 -lilygo_t5_47.menu.UploadSpeed.512000.windows=512000 -lilygo_t5_47.menu.UploadSpeed.512000.upload.speed=512000 - -lilygo_t5_47.menu.DebugLevel.none=None -lilygo_t5_47.menu.DebugLevel.none.build.code_debug=0 -lilygo_t5_47.menu.DebugLevel.error=Error -lilygo_t5_47.menu.DebugLevel.error.build.code_debug=1 -lilygo_t5_47.menu.DebugLevel.warn=Warn -lilygo_t5_47.menu.DebugLevel.warn.build.code_debug=2 -lilygo_t5_47.menu.DebugLevel.info=Info -lilygo_t5_47.menu.DebugLevel.info.build.code_debug=3 -lilygo_t5_47.menu.DebugLevel.debug=Debug -lilygo_t5_47.menu.DebugLevel.debug.build.code_debug=4 -lilygo_t5_47.menu.DebugLevel.verbose=Verbose -lilygo_t5_47.menu.DebugLevel.verbose.build.code_debug=5 diff --git a/lib/libesp32_eink/epdiy/idf_component.yml b/lib/libesp32_eink/epdiy/idf_component.yml new file mode 100644 index 000000000..468e38647 --- /dev/null +++ b/lib/libesp32_eink/epdiy/idf_component.yml @@ -0,0 +1,4 @@ +version: "2.0.0" +description: "Drive parallel e-Paper displays with epdiy-based boards." +url: "https://github.com/vroland/epdiy" +license: LGPL-3.0-or-later diff --git a/lib/libesp32_eink/epdiy/library.json b/lib/libesp32_eink/epdiy/library.json new file mode 100644 index 000000000..b0336ba43 --- /dev/null +++ b/lib/libesp32_eink/epdiy/library.json @@ -0,0 +1,32 @@ +{ + "name": "epdiy", + "version": "2.0.0", + "description": "Drive parallel e-Paper displays with epdiy-based boards.", + "keywords": "epd, driver, e-ink", + "repository": { + "type": "git", + "url": "https://github.com/vroland/epdiy.git" + }, + "authors": [ + { + "name": "Valentin Roland", + "email": "github@vroland.de", + "maintainer": true + } + ], + "license": "LGPL-3.0", + "frameworks": [ + "arduino", + "espidf" + ], + "platforms": "espressif32", + "export": { + "exclude": [ + "hardware" + ] + }, + "build": { + "includeDir": "include", + "srcDir": "src/" + } +} diff --git a/lib/libesp32_eink/epdiy/library.properties b/lib/libesp32_eink/epdiy/library.properties index 4635900d1..32f2aaac4 100755 --- a/lib/libesp32_eink/epdiy/library.properties +++ b/lib/libesp32_eink/epdiy/library.properties @@ -1,9 +1,9 @@ name=epdiy -version=1.0.0 +version=2.0.0 author=Valentin Roland maintainer=Valentin Roland sentence=Drive parallel e-Paper displays with epdiy-based boards. paragraph=See https://github.com/vroland/epdiy for details. -architectures=esp32 +architectures=esp32,esp32s3 url=https://github.com/vroland/epdiy category=Display diff --git a/lib/libesp32_eink/epdiy/scripts/README.md b/lib/libesp32_eink/epdiy/scripts/README.md new file mode 100644 index 000000000..5d74802fb --- /dev/null +++ b/lib/libesp32_eink/epdiy/scripts/README.md @@ -0,0 +1,101 @@ +## Scripts in this folder are for adding addtional capabilities to epdiy. + + + +## imgconvert.py + +#### usage: + +python3 imgconvert.py [-h] -i INPUTFILE -n NAME -o OUTPUTFILE [-maxw MAX_WIDTH] + [-maxh MAX_HEIGHT] + +**optional arguments:** + + * **-h, --help** show this help message and exit + + * **-i INPUTFILE** + + * **-n NAME** + + * **-o OUTPUTFILE** + + * **-maxw MAX_WIDTH** + + * **-maxh MAX_HEIGHT** + + +========================================================== + +## fontconvert.py + +#### usage: + +python3 fontconvert.py [-h] [--compress] [--additional-intervals ADDITIONAL_INTERVALS] + [--string STRING] + name size fontstack [fontstack ...] + +Generate a header file from a font to be used with epdiy. + +**positional arguments:** + + * **name** name of the font to be used in epdiy. + * **size** font size to use. + * **fontstack** list of font files, ordered by descending priority. This is not actually implemented as yet. Please just use one file for now. + +**optional arguments:** + + * **-h**, --help show this help message and exit + + * **--compress** compress glyph bitmaps. + + * **--additional-intervals** ADDITIONAL_INTERVALS + + Additional code point intervals to export as min,max. This argument + can be repeated. + + * **--string STRING** A quoted string of all required characters. The intervals are will be made from these characters if they exist in the ttf file. Missing characters will warn about their abscence. + + + +####example: + 1. Download a ttf from where you like to a directory. As in: "~/Downloads/any_old_ttf.ttf" +in the download directory + + 2. Run + + `python3 fontconvert.py my_font 30 ~/Downloads/any_old_ttf.ttf --string '/0123456789:;@ABCDEFGH[\]^_`abcdefgh\{|}~¡¢£¤¥¦§¨©ª' > fonts.h` + + * you will need to use special escapes for characters like ' or " This is system dependant though. + + 3. copy fonts.h into your app folder or where ever your app can find it. + 4. include it into your project with +`#include fonts.h` +Then use it just like any other font file in epdiy. + +**To run this script the freetype module needs to be installed. This can be done with `pip install freetype-py` You will be warned if it is not accessible by the script.** + +========================================================== + +##waveform_hdrgen.py + +####usage: + +waveform_hdrgen.py [-h] [--list-modes] [--temperature-range TEMPERATURE_RANGE] + [--export-modes EXPORT_MODES] + name + +**positional arguments:** + name name of the waveform object. + +**optional arguments:** + + * **-h, --help** show this help message and exit + + * **--list-modes** list the available modes for tis file. + + * **--temperature-range TEMPERATURE_RANGE** + only export waveforms in the temperature range of min,max °C. + + * **--export-modes EXPORT_MODES** + comma-separated list of waveform mode IDs to export. + diff --git a/lib/libesp32_eink/epdiy/scripts/fontconvert.py b/lib/libesp32_eink/epdiy/scripts/fontconvert.py index aa233c90d..36cd62322 100755 --- a/lib/libesp32_eink/epdiy/scripts/fontconvert.py +++ b/lib/libesp32_eink/epdiy/scripts/fontconvert.py @@ -1,29 +1,11 @@ #!python3 -import freetype -import zlib import sys -import re -import math -import argparse -from collections import namedtuple - -parser = argparse.ArgumentParser(description="Generate a header file from a font to be used with epdiy.") -parser.add_argument("name", action="store", help="name of the font.") -parser.add_argument("size", type=int, help="font size to use.") -parser.add_argument("fontstack", action="store", nargs='+', help="list of font files, ordered by descending priority.") -parser.add_argument("--compress", dest="compress", action="store_true", help="compress glyph bitmaps.") -parser.add_argument("--additional-intervals", dest="additional_intervals", action="append", help="Additional code point intervals to export as min,max. This argument can be repeated.") -args = parser.parse_args() - -GlyphProps = namedtuple("GlyphProps", ["width", "height", "advance_x", "left", "top", "compressed_size", "data_offset", "code_point"]) - -font_stack = [freetype.Face(f) for f in args.fontstack] -compress = args.compress -size = args.size -font_name = args.name # inclusive unicode code point intervals # must not overlap and be in ascending order +# modify intervals here +# however if the "string" command line argument is used these are ignored + intervals = [ (32, 126), (160, 255), @@ -48,12 +30,107 @@ intervals = [ #(0x1F600, 0x1F680), ] + + +try: + import freetype +except ImportError as error: + sys.exit("To run this script the freetype module needs to be installed.\nThis can be done using:\npip install freetype-py") +import zlib +import sys +import re +import math +import argparse +from collections import namedtuple +#see https://freetype-py.readthedocs.io/en/latest/ for documentation +parser = argparse.ArgumentParser(description="Generate a header file from a font to be used with epdiy.") +parser.add_argument("name", action="store", help="name of the font.") +parser.add_argument("size", type=int, help="font size to use.") +parser.add_argument("fontstack", action="store", nargs='+', help="list of font files, ordered by descending priority. This is not actually implemented please just use one file for now.") +parser.add_argument("--compress", dest="compress", action="store_true", help="compress glyph bitmaps.") +parser.add_argument("--additional-intervals", dest="additional_intervals", action="append", help="Additional code point intervals to export as min,max. This argument can be repeated.") +parser.add_argument("--string", action="store", help="A string of all required characters. intervals are made up of this" ) + +args = parser.parse_args() +command_line = "" +prev_arg = "" +for arg in sys.argv: + # ~ if prev_arg == "--string": + # ~ command_line = command_line + " '" + arg +"'" + # ~ else: + command_line = command_line + " " + arg + # ~ prev_arg = arg + +# ~ print (command_line) +GlyphProps = namedtuple("GlyphProps", ["width", "height", "advance_x", "left", "top", "compressed_size", "data_offset", "code_point"]) + +font_stack = [freetype.Face(f) for f in args.fontstack] +font_files = args.fontstack +face_index = 0 +font_file = font_files[face_index] +compress = args.compress +size = args.size +font_name = args.name + +for face in font_stack: + # shift by 6 bytes, because sizes are given as 6-bit fractions + # the display has about 150 dpi. + face.set_char_size(size << 6, size << 6, 150, 150) + + +# assign intervals from argument parrameters ie. handle the string arg + +if args.string != None: + font_file = font_files[face_index] + string = " " + args.string # always add space to the string it is easily forgotten + chars = sorted(set(string)) + #make array of code pointscode_ponts.append(ord(char)) + code_points = list() + intervals = [] # empty the intevals array NB. if you want to allways add default characters comment out this line + # go through the sorted characters and make the intervals + for char in chars: + if( face.get_char_index(ord(char)) != 0 ): + # this character is in the font file so add it to the new string. + code_points.append(ord(char)) + else: + print("The character ", char, " is not available in ", font_file, file=sys.stderr) + lower = code_points[0] + len_x = len(code_points) + x = 0 + while x < len_x: + # ~ print ("loop value x = ", x , file=sys.stderr) + a = code_points[x]; + b = a; + if( x < len_x - 1): + b = code_points[x + 1]; + + if( a == b - 1 ): + # ~ print("sequential", a, b, file=sys.stderr) + if( lower == -1): + lower = a + else: + # ~ print("non sequential", a, b , file=sys.stderr) + if( lower == -1): + # ~ print("single character") + interval = (a , a) + else: + interval = (lower, a) + # ~ print("interval", interval , file=sys.stderr) + intervals.append(interval) + lower = -1 + x = x + 1 + + +# base intervals are assigned dditional intervals from arguments add_ints = [] -if args.additional_intervals: +if args.additional_intervals != None: add_ints = [tuple([int(n, base=0) for n in i.split(",")]) for i in args.additional_intervals] intervals = sorted(intervals + add_ints) +# ~ print("Intervals are now: ", intervals, file=sys.stderr) + + def norm_floor(val): return int(math.floor(val / (1 << 6))) @@ -73,21 +150,48 @@ total_size = 0 total_packed = 0 all_glyphs = [] +# new globals +total_chars = 0 +ascender = 0 +descender = 100 +f_height = 0 + def load_glyph(code_point): + global face_index face_index = 0 while face_index < len(font_stack): face = font_stack[face_index] glyph_index = face.get_char_index(code_point) if glyph_index > 0: face.load_glyph(glyph_index, freetype.FT_LOAD_RENDER) + #count characters found and find bounds of characters + global ascender + if ascender < face.size.ascender: + ascender = face.size.ascender + global descender + if descender > face.size.descender: + descender = face.size.descender + global f_height + if f_height < face.size.height: + f_height = face.size.height + global total_chars + total_chars += 1 return face break face_index += 1 + # this needs work + # this needs to be handled better to show failed character and continue not just die a questionable death + # this appears to have been designed to combine several font files + # but that is not clear to the end user and this then looks like a bug print (f"falling back to font {face_index} for {chr(code_point)}.", file=sys.stderr) raise ValueError(f"code point {code_point} not found in font stack!") for i_start, i_end in intervals: for code_point in range(i_start, i_end + 1): + # handle missing characters in font file + if( face.get_char_index(code_point) == 0 ): + print("Character ", chr(code_point), "(", code_point, ") is not in ", font_file, file=sys.stderr) + continue face = load_glyph(code_point) bitmap = face.glyph.bitmap pixels = [] @@ -126,7 +230,8 @@ for i_start, i_end in intervals: all_glyphs.append((glyph, compressed)) # pipe seems to be a good heuristic for the "real" descender -face = load_glyph(ord('|')) +# face = load_glyph(ord('|')) +# removed as max descender and assender are handled above glyph_data = [] glyph_props = [] @@ -134,23 +239,38 @@ for index, glyph in enumerate(all_glyphs): props, compressed = glyph glyph_data.extend([b for b in compressed]) glyph_props.append(props) +print("", file=sys.stderr) +print(f"Original font file {font_file} as {font_name} using {total_chars} characters", file=sys.stderr) print("total", total_packed, file=sys.stderr) print("compressed", total_size, file=sys.stderr) print("#pragma once") -print("#include \"epd_driver.h\"") -print(f"const uint8_t {font_name}Bitmaps[{len(glyph_data)}] = {{") +print("#include \"epdiy.h\"") + +# add font file origin and characters at the head of the output file +print("/*") +print ( "Created with") +print(command_line) +print(f"As '{font_name}' with available {total_chars} characters") +for i, g in enumerate(glyph_props): + print (f"{chr(g.code_point)}", end ="" ) +print("") +print("*/") + +print(f"const uint8_t {font_name}_Bitmaps[{len(glyph_data)}] = {{") for c in chunks(glyph_data, 16): print (" " + " ".join(f"0x{b:02X}," for b in c)) print ("};"); -print(f"const EpdGlyph {font_name}Glyphs[] = {{") + +print ('// GlyphProps[width, height, advance_x, left, top, compressed_size, data_offset, code_point]') +print(f"const EpdGlyph {font_name}_Glyphs[] = {{") for i, g in enumerate(glyph_props): - print (" { " + ", ".join([f"{a}" for a in list(g[:-1])]),"},", f"// {chr(g.code_point) if g.code_point != 92 else ''}") + print (" { " + ", ".join([f"{a}" for a in list(g[:-1])]),"},", f"// '{chr(g.code_point) if g.code_point != 92 else ''}'") print ("};"); -print(f"const EpdUnicodeInterval {font_name}Intervals[] = {{") +print(f"const EpdUnicodeInterval {font_name}_Intervals[] = {{") offset = 0 for i_start, i_end in intervals: print (f" {{ 0x{i_start:X}, 0x{i_end:X}, 0x{offset:X} }},") @@ -158,12 +278,22 @@ for i_start, i_end in intervals: print ("};"); print(f"const EpdFont {font_name} = {{") -print(f" {font_name}Bitmaps,") -print(f" {font_name}Glyphs,") -print(f" {font_name}Intervals,") -print(f" {len(intervals)},") -print(f" {1 if compress else 0},") -print(f" {norm_ceil(face.size.height)},") -print(f" {norm_ceil(face.size.ascender)},") -print(f" {norm_floor(face.size.descender)},") +print(f" {font_name}_Bitmaps, // (*bitmap) Glyph bitmap pointer, all concatenated together") +print(f" {font_name}_Glyphs, // glyphs Glyph array") +print(f" {font_name}_Intervals, // intervals Valid unicode intervals for this font") +print(f" {len(intervals)}, // interval_count Number of unicode intervals.intervals") +print(f" {1 if compress else 0}, // compressed Does this font use compressed glyph bitmaps?") +print(f" {norm_ceil(f_height)}, // advance_y Newline distance (y axis)") +print(f" {norm_ceil(ascender)}, // ascender Maximal height of a glyph above the base line") +print(f" {norm_floor(descender)}, // descender Maximal height of a glyph below the base line") print("};") +print("/*") +print("Included intervals") +for i_start, i_end in intervals: + print (f" ( {i_start}, {i_end}), ie. '{chr(i_start)}' - '{chr(i_end)}'") +print("Included intervals", file=sys.stderr) +for i_start, i_end in intervals: + print (f" ( {i_start}, {i_end}), ie. '{chr(i_start)}' - '{chr(i_end)}'", file=sys.stderr) +print("") +print("*/") + diff --git a/lib/libesp32_eink/epdiy/scripts/imgconvert.py b/lib/libesp32_eink/epdiy/scripts/imgconvert.py index ba7c581b3..be91f0b06 100755 --- a/lib/libesp32_eink/epdiy/scripts/imgconvert.py +++ b/lib/libesp32_eink/epdiy/scripts/imgconvert.py @@ -17,7 +17,7 @@ args = parser.parse_args() im = Image.open(args.inputfile) # convert to grayscale im = im.convert(mode='L') -im.thumbnail((args.max_width, args.max_height), Image.ANTIALIAS) +im.thumbnail((args.max_width, args.max_height), Image.LANCZOS) # Write out the output file. with open(args.outputfile, 'w') as f: diff --git a/lib/libesp32_eink/epdiy/scripts/waveform_hdrgen.py b/lib/libesp32_eink/epdiy/scripts/waveform_hdrgen.py index bb2e5c382..7d8722324 100755 --- a/lib/libesp32_eink/epdiy/scripts/waveform_hdrgen.py +++ b/lib/libesp32_eink/epdiy/scripts/waveform_hdrgen.py @@ -18,24 +18,36 @@ waveforms = json.load(sys.stdin); total_size = 0 -def phase_to_c(phase): - """ - Convert a 5 bit phase to a 4 bit C LUT. - """ - global total_size +def phase_to_c(phase,bits_per_pixel_c=4): + + N1 = len(phase) + N2 = len(phase[0]) + N = 2**bits_per_pixel_c + + if N1%N != 0: + raise ValueError(f"first dimension of phases is {N1}. Allowed are multiples of {N}") + + step1 = int(N1/N) + + if N2%N != 0: + raise ValueError(f"second dimension of phases is {N2}. Allowed are multiples of {N}") + + step2 = int(N2/N) targets = [] - for t in range(0, 32, 2): + for t in range(0, N1, step1): chunk = 0 line = [] - for f in range(0, 32, 2): + i = 0 + for f in range(0, N2, step2): fr = phase[t][f] chunk = (chunk << 2) | fr - if f and f % 8 == 6: + i += 1 + if i == 4: + i = 0 line.append(chunk) chunk = 0 targets.append(line) - total_size += len(line) return targets @@ -61,7 +73,7 @@ if args.temperature_range: modes = [] -mode_filter = list(range(len(waveforms["modes"]))) +mode_filter = [wm["mode"] for wm in waveforms["modes"]] if args.export_modes: mode_filter = list(map(int, args.export_modes.split(","))) @@ -72,6 +84,8 @@ num_modes = len(mode_filter) temp_intervals = [] for bounds in waveforms["temperature_ranges"]["range_bounds"]: + if bounds["to"] < tmin or bounds["from"] > tmax: + continue temp_intervals.append(f"{{ .min = {bounds['from']}, .max = {bounds['to']} }}") modes = [] @@ -84,7 +98,7 @@ for m_index, mode in enumerate(waveforms["modes"]): ranges = [] for i, r in enumerate(mode["ranges"]): bounds = waveforms["temperature_ranges"]["range_bounds"][i] - if bounds["from"] < tmin or bounds["from"] > tmax: + if bounds["to"] < tmin or bounds["from"] > tmax: continue phases = [] diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/Makefile b/lib/libesp32_eink/epdiy/src/Makefile old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/Makefile rename to lib/libesp32_eink/epdiy/src/Makefile diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board.c b/lib/libesp32_eink/epdiy/src/board/epd_board.c new file mode 100644 index 000000000..ce0944c44 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board.c @@ -0,0 +1,77 @@ +#include "epd_board.h" + +#include +#include + +#include "epdiy.h" + +/** + * The board's display control pin state. + */ +static epd_ctrl_state_t ctrl_state; + +/** + * The EPDIY board in use. + */ +const EpdBoardDefinition* epd_board = NULL; + +void IRAM_ATTR epd_busy_delay(uint32_t cycles) { + volatile unsigned long counts = XTHAL_GET_CCOUNT() + cycles; + while (XTHAL_GET_CCOUNT() < counts) { + }; +} + +void epd_set_board(const EpdBoardDefinition* board_definition) { + if (epd_board == NULL) { + epd_board = board_definition; + } else { + ESP_LOGW("epdiy", "EPD board can only be set once!"); + } +} + +const EpdBoardDefinition* epd_current_board() { + return epd_board; +} + +void epd_set_mode(bool state) { + ctrl_state.ep_output_enable = state; + ctrl_state.ep_mode = state; + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + }; + epd_board->set_ctrl(&ctrl_state, &mask); +} + +epd_ctrl_state_t* epd_ctrl_state() { + return &ctrl_state; +} + +void epd_control_reg_init() { + ctrl_state.ep_latch_enable = false; + ctrl_state.ep_output_enable = false; + ctrl_state.ep_sth = true; + ctrl_state.ep_mode = false; + ctrl_state.ep_stv = true; + epd_ctrl_state_t mask = { + .ep_latch_enable = true, + .ep_output_enable = true, + .ep_sth = true, + .ep_mode = true, + .ep_stv = true, + }; + + epd_board->set_ctrl(&ctrl_state, &mask); +} + +void epd_control_reg_deinit() { + ctrl_state.ep_output_enable = false; + ctrl_state.ep_mode = false; + ctrl_state.ep_stv = false; + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + .ep_stv = true, + }; + epd_board->set_ctrl(&ctrl_state, &mask); +} diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_common.c b/lib/libesp32_eink/epdiy/src/board/epd_board_common.c new file mode 100644 index 000000000..21dd9cc1b --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_common.c @@ -0,0 +1,34 @@ +#include "driver/adc.h" +#include "epd_board.h" +#include "esp_adc_cal.h" +#include "esp_log.h" + +static const adc1_channel_t channel = ADC1_CHANNEL_7; +static esp_adc_cal_characteristics_t adc_chars; + +#define NUMBER_OF_SAMPLES 100 + +void epd_board_temperature_init_v2() { + esp_adc_cal_value_t val_type + = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_12, 1100, &adc_chars); + if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { + ESP_LOGI("epd_temperature", "Characterized using Two Point Value\n"); + } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { + ESP_LOGI("esp_temperature", "Characterized using eFuse Vref\n"); + } else { + ESP_LOGI("esp_temperature", "Characterized using Default Vref\n"); + } + adc1_config_width(ADC_WIDTH_BIT_12); + adc1_config_channel_atten(channel, ADC_ATTEN_DB_6); +} + +float epd_board_ambient_temperature_v2() { + uint32_t value = 0; + for (int i = 0; i < NUMBER_OF_SAMPLES; i++) { + value += adc1_get_raw(channel); + } + value /= NUMBER_OF_SAMPLES; + // voltage in mV + float voltage = esp_adc_cal_raw_to_voltage(value, &adc_chars); + return (voltage - 500.0) / 10.0; +} diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_common.h b/lib/libesp32_eink/epdiy/src/board/epd_board_common.h new file mode 100644 index 000000000..eaedbd367 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_common.h @@ -0,0 +1,8 @@ +/** + * @file "epd_board_common.h" + * @brief Common board functions shared between boards. + */ +#pragma once + +void epd_board_temperature_init_v2(); +float epd_board_ambient_temperature_v2(); diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_lilygo_t5_47.c b/lib/libesp32_eink/epdiy/src/board/epd_board_lilygo_t5_47.c new file mode 100644 index 000000000..e153d7c3e --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_lilygo_t5_47.c @@ -0,0 +1,227 @@ +#include "epd_board.h" + +#include +#include "../output_i2s/i2s_data_bus.h" +#include "../output_i2s/render_i2s.h" +#include "../output_i2s/rmt_pulse.h" + +// Make this compile on the S3 to avoid long ifdefs +#ifndef CONFIG_IDF_TARGET_ESP32 +#define GPIO_NUM_22 0 +#define GPIO_NUM_23 0 +#define GPIO_NUM_24 0 +#define GPIO_NUM_25 0 +#endif + +#define CFG_DATA GPIO_NUM_23 +#define CFG_CLK GPIO_NUM_18 +#define CFG_STR GPIO_NUM_0 +#define D7 GPIO_NUM_22 +#define D6 GPIO_NUM_21 +#define D5 GPIO_NUM_27 +#define D4 GPIO_NUM_2 +#define D3 GPIO_NUM_19 +#define D2 GPIO_NUM_4 +#define D1 GPIO_NUM_32 +#define D0 GPIO_NUM_33 + +/* Control Lines */ +#define CKV GPIO_NUM_25 +#define STH GPIO_NUM_26 + +#define V4_LATCH_ENABLE GPIO_NUM_15 + +/* Edges */ +#define CKH GPIO_NUM_5 + +typedef struct { + bool power_disable : 1; + bool pos_power_enable : 1; + bool neg_power_enable : 1; + bool ep_scan_direction : 1; +} epd_config_register_t; + +static i2s_bus_config i2s_config = { + .clock = CKH, + .start_pulse = STH, + .data_0 = D0, + .data_1 = D1, + .data_2 = D2, + .data_3 = D3, + .data_4 = D4, + .data_5 = D5, + .data_6 = D6, + .data_7 = D7, +}; + +static void IRAM_ATTR push_cfg_bit(bool bit) { + gpio_set_level(CFG_CLK, 0); + gpio_set_level(CFG_DATA, bit); + gpio_set_level(CFG_CLK, 1); +} + +static epd_config_register_t config_reg; + +static void epd_board_init(uint32_t epd_row_width) { + /* Power Control Output/Off */ + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_DATA], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_CLK], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_STR], PIN_FUNC_GPIO); + gpio_set_direction(CFG_DATA, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_CLK, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_STR, GPIO_MODE_OUTPUT); + fast_gpio_set_lo(CFG_STR); + + config_reg.power_disable = true; + config_reg.pos_power_enable = false; + config_reg.neg_power_enable = false; + config_reg.ep_scan_direction = true; + + // Setup I2S + // add an offset off dummy bytes to allow for enough timing headroom + i2s_bus_init(&i2s_config, epd_row_width + 32); + + rmt_pulse_init(CKV); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + if (state->ep_sth) { + fast_gpio_set_hi(STH); + } else { + fast_gpio_set_lo(STH); + } + + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv || mask->ep_latch_enable) { + fast_gpio_set_lo(CFG_STR); + + // push config bits in reverse order + push_cfg_bit(state->ep_output_enable); + push_cfg_bit(state->ep_mode); + push_cfg_bit(config_reg.ep_scan_direction); + push_cfg_bit(state->ep_stv); + + push_cfg_bit(config_reg.neg_power_enable); + push_cfg_bit(config_reg.pos_power_enable); + push_cfg_bit(config_reg.power_disable); + push_cfg_bit(state->ep_latch_enable); + + fast_gpio_set_hi(CFG_STR); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + i2s_gpio_attach(&i2s_config); + + // This was re-purposed as power enable. + config_reg.ep_scan_direction = true; + + // POWERON + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.power_disable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + config_reg.neg_power_enable = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.pos_power_enable = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + state->ep_stv = true; + state->ep_sth = true; + mask.ep_sth = true; + epd_board_set_ctrl(state, &mask); + // END POWERON +} + +void epd_powerdown_lilygo_t5_47() { + epd_ctrl_state_t* state = epd_ctrl_state(); + + // This was re-purposed as power enable however it also disables the touch. + // this workaround may still leave power on to epd and as such may cause other + // problems such as grey screen. + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.pos_power_enable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(10 * 240); + + config_reg.neg_power_enable = false; + config_reg.pos_power_enable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + + state->ep_stv = false; + mask.ep_stv = true; + state->ep_output_enable = false; + mask.ep_output_enable = true; + state->ep_mode = false; + mask.ep_mode = true; + config_reg.power_disable = true; + epd_board_set_ctrl(state, &mask); + + i2s_gpio_detach(&i2s_config); +} + +static void epd_board_poweroff_common(epd_ctrl_state_t* state) { + // POWEROFF + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.pos_power_enable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(10 * 240); + + config_reg.neg_power_enable = false; + config_reg.pos_power_enable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + + state->ep_stv = false; + mask.ep_stv = true; + state->ep_output_enable = false; + mask.ep_output_enable = true; + state->ep_mode = false; + mask.ep_mode = true; + config_reg.power_disable = true; + epd_board_set_ctrl(state, &mask); + + i2s_gpio_detach(&i2s_config); + // END POWEROFF +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + // This was re-purposed as power enable. + config_reg.ep_scan_direction = false; + epd_board_poweroff_common(state); +} + +static void epd_board_poweroff_touch(epd_ctrl_state_t* state) { + // This was re-purposed as power enable. + config_reg.ep_scan_direction = true; + epd_board_poweroff_common(state); +} + +const EpdBoardDefinition epd_board_lilygo_t5_47 = { + .init = epd_board_init, + .deinit = NULL, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + .get_temperature = NULL, +}; + +const EpdBoardDefinition epd_board_lilygo_t5_47_touch = { + .init = epd_board_init, + .deinit = NULL, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff_touch, + .get_temperature = NULL, + .set_vcom = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_v2_v3.c b/lib/libesp32_eink/epdiy/src/board/epd_board_v2_v3.c new file mode 100644 index 000000000..87fe25437 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_v2_v3.c @@ -0,0 +1,172 @@ +#include "epd_board.h" + +#include +#include "../output_i2s/i2s_data_bus.h" +#include "../output_i2s/render_i2s.h" +#include "../output_i2s/rmt_pulse.h" +#include "epd_board_common.h" + +// Make this compile on the S3 to avoid long ifdefs +#ifndef CONFIG_IDF_TARGET_ESP32 +#define GPIO_NUM_22 0 +#define GPIO_NUM_23 0 +#define GPIO_NUM_24 0 +#define GPIO_NUM_25 0 +#endif + +#define CFG_DATA GPIO_NUM_23 +#define CFG_CLK GPIO_NUM_18 +#define CFG_STR GPIO_NUM_19 +#define D7 GPIO_NUM_22 +#define D6 GPIO_NUM_21 +#define D5 GPIO_NUM_27 +#define D4 GPIO_NUM_2 +#define D3 GPIO_NUM_0 +#define D2 GPIO_NUM_4 +#define D1 GPIO_NUM_32 +#define D0 GPIO_NUM_33 + +/* Control Lines */ +#define CKV GPIO_NUM_25 +#define STH GPIO_NUM_26 + +/* Edges */ +#define CKH GPIO_NUM_5 + +typedef struct { + bool power_disable : 1; + bool pos_power_enable : 1; + bool neg_power_enable : 1; + bool ep_scan_direction : 1; +} epd_config_register_t; + +static i2s_bus_config i2s_config = { + .clock = CKH, + .start_pulse = STH, + .data_0 = D0, + .data_1 = D1, + .data_2 = D2, + .data_3 = D3, + .data_4 = D4, + .data_5 = D5, + .data_6 = D6, + .data_7 = D7, +}; + +static void IRAM_ATTR push_cfg_bit(bool bit) { + gpio_set_level(CFG_CLK, 0); + gpio_set_level(CFG_DATA, bit); + gpio_set_level(CFG_CLK, 1); +} + +static epd_config_register_t config_reg; + +static void epd_board_init(uint32_t epd_row_width) { + /* Power Control Output/Off */ + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_DATA], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_CLK], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_STR], PIN_FUNC_GPIO); + gpio_set_direction(CFG_DATA, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_CLK, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_STR, GPIO_MODE_OUTPUT); + fast_gpio_set_lo(CFG_STR); + + config_reg.power_disable = true; + config_reg.pos_power_enable = false; + config_reg.neg_power_enable = false; + config_reg.ep_scan_direction = true; + + // Setup I2S + // add an offset off dummy bytes to allow for enough timing headroom + i2s_bus_init(&i2s_config, epd_row_width + 32); + + rmt_pulse_init(CKV); + + epd_board_temperature_init_v2(); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + if (state->ep_sth) { + fast_gpio_set_hi(STH); + } else { + fast_gpio_set_lo(STH); + } + + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv || mask->ep_latch_enable) { + fast_gpio_set_lo(CFG_STR); + + // push config bits in reverse order + push_cfg_bit(state->ep_output_enable); + push_cfg_bit(state->ep_mode); + push_cfg_bit(config_reg.ep_scan_direction); + push_cfg_bit(state->ep_stv); + + push_cfg_bit(config_reg.neg_power_enable); + push_cfg_bit(config_reg.pos_power_enable); + push_cfg_bit(config_reg.power_disable); + push_cfg_bit(state->ep_latch_enable); + + fast_gpio_set_hi(CFG_STR); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + // POWERON + i2s_gpio_attach(&i2s_config); + + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.power_disable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + config_reg.neg_power_enable = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.pos_power_enable = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + state->ep_stv = true; + state->ep_sth = true; + mask.ep_sth = true; + epd_board_set_ctrl(state, &mask); + // END POWERON +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + // POWEROFF + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.pos_power_enable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(10 * 240); + + config_reg.neg_power_enable = false; + config_reg.pos_power_enable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + + state->ep_stv = false; + state->ep_output_enable = false; + mask.ep_output_enable = true; + state->ep_mode = false; + mask.ep_mode = true; + config_reg.power_disable = true; + epd_board_set_ctrl(state, &mask); + + i2s_gpio_detach(&i2s_config); + // END POWEROFF +} + +const EpdBoardDefinition epd_board_v2_v3 = { + .init = epd_board_init, + .deinit = NULL, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + .get_temperature = epd_board_ambient_temperature_v2, + .set_vcom = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_v4.c b/lib/libesp32_eink/epdiy/src/board/epd_board_v4.c new file mode 100644 index 000000000..be0d65784 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_v4.c @@ -0,0 +1,194 @@ +#include "epd_board.h" + +#include +#include "../output_i2s/i2s_data_bus.h" +#include "../output_i2s/render_i2s.h" +#include "../output_i2s/rmt_pulse.h" +#include "epd_board_common.h" + +// Make this compile on the S3 to avoid long ifdefs +#ifndef CONFIG_IDF_TARGET_ESP32 +#define GPIO_NUM_22 0 +#define GPIO_NUM_23 0 +#define GPIO_NUM_24 0 +#define GPIO_NUM_25 0 +#endif + +#define CFG_DATA GPIO_NUM_23 +#define CFG_CLK GPIO_NUM_18 +#define CFG_STR GPIO_NUM_19 +#define D7 GPIO_NUM_22 +#define D6 GPIO_NUM_21 +#define D5 GPIO_NUM_27 +#define D4 GPIO_NUM_2 +#define D3 GPIO_NUM_0 +#define D2 GPIO_NUM_4 +#define D1 GPIO_NUM_32 +#define D0 GPIO_NUM_33 + +/* Control Lines */ +#define CKV GPIO_NUM_25 +#define STH GPIO_NUM_26 + +#define V4_LATCH_ENABLE GPIO_NUM_15 + +/* Edges */ +#define CKH GPIO_NUM_5 + +typedef struct { + bool power_disable : 1; + bool power_enable_vpos : 1; + bool power_enable_vneg : 1; + bool power_enable_gl : 1; + bool power_enable_gh : 1; +} epd_config_register_t; + +static i2s_bus_config i2s_config = { + .clock = CKH, + .start_pulse = STH, + .data_0 = D0, + .data_1 = D1, + .data_2 = D2, + .data_3 = D3, + .data_4 = D4, + .data_5 = D5, + .data_6 = D6, + .data_7 = D7, +}; + +static void IRAM_ATTR push_cfg_bit(bool bit) { + gpio_set_level(CFG_CLK, 0); + gpio_set_level(CFG_DATA, bit); + gpio_set_level(CFG_CLK, 1); +} + +static epd_config_register_t config_reg; + +static void epd_board_init(uint32_t epd_row_width) { + /* Power Control Output/Off */ + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_DATA], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_CLK], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_STR], PIN_FUNC_GPIO); + gpio_set_direction(CFG_DATA, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_CLK, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_STR, GPIO_MODE_OUTPUT); + fast_gpio_set_lo(CFG_STR); + + config_reg.power_disable = true; + config_reg.power_enable_vpos = false; + config_reg.power_enable_vneg = false; + config_reg.power_enable_gl = false; + config_reg.power_enable_gh = false; + + // use latch pin as GPIO + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[V4_LATCH_ENABLE], PIN_FUNC_GPIO); + ESP_ERROR_CHECK(gpio_set_direction(V4_LATCH_ENABLE, GPIO_MODE_OUTPUT)); + gpio_set_level(V4_LATCH_ENABLE, 0); + + // Setup I2S + // add an offset off dummy bytes to allow for enough timing headroom + i2s_bus_init(&i2s_config, epd_row_width + 32); + + rmt_pulse_init(CKV); + + epd_board_temperature_init_v2(); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + if (state->ep_sth) { + fast_gpio_set_hi(STH); + } else { + fast_gpio_set_lo(STH); + } + + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv) { + fast_gpio_set_lo(CFG_STR); + + // push config bits in reverse order + push_cfg_bit(state->ep_output_enable); + push_cfg_bit(state->ep_mode); + push_cfg_bit(config_reg.power_enable_gh); + push_cfg_bit(state->ep_stv); + + push_cfg_bit(config_reg.power_enable_gl); + push_cfg_bit(config_reg.power_enable_vneg); + push_cfg_bit(config_reg.power_enable_vpos); + push_cfg_bit(config_reg.power_disable); + + fast_gpio_set_hi(CFG_STR); + fast_gpio_set_lo(CFG_STR); + } + + if (state->ep_latch_enable) { + fast_gpio_set_hi(V4_LATCH_ENABLE); + } else { + fast_gpio_set_lo(V4_LATCH_ENABLE); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + // POWERON + i2s_gpio_attach(&i2s_config); + + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.power_disable = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + config_reg.power_enable_gl = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.power_enable_vneg = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.power_enable_gh = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.power_enable_vpos = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + state->ep_stv = true; + state->ep_sth = true; + mask.ep_sth = true; + epd_board_set_ctrl(state, &mask); + // END POWERON +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + // POWEROFF + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.power_enable_gh = false; + config_reg.power_enable_vpos = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(10 * 240); + config_reg.power_enable_gl = false; + config_reg.power_enable_vneg = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + + state->ep_stv = false; + state->ep_output_enable = false; + mask.ep_output_enable = true; + state->ep_mode = false; + mask.ep_mode = true; + config_reg.power_disable = true; + epd_board_set_ctrl(state, &mask); + + i2s_gpio_detach(&i2s_config); + // END POWEROFF +} + +const EpdBoardDefinition epd_board_v4 = { + .init = epd_board_init, + .deinit = NULL, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + .get_temperature = epd_board_ambient_temperature_v2, + .set_vcom = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_v5.c b/lib/libesp32_eink/epdiy/src/board/epd_board_v5.c new file mode 100644 index 000000000..e413d0d98 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_v5.c @@ -0,0 +1,196 @@ +#include "epd_board.h" + +#include +#include "epd_board_common.h" + +#include "../output_i2s/i2s_data_bus.h" +#include "../output_i2s/render_i2s.h" +#include "../output_i2s/rmt_pulse.h" +#include "driver/rtc_io.h" + +// Make this compile on the S3 to avoid long ifdefs +#ifndef CONFIG_IDF_TARGET_ESP32 +#define GPIO_NUM_22 0 +#define GPIO_NUM_23 0 +#define GPIO_NUM_24 0 +#define GPIO_NUM_25 0 +#endif + +#define CFG_DATA GPIO_NUM_33 +#define CFG_CLK GPIO_NUM_32 +#define CFG_STR GPIO_NUM_0 +#define D7 GPIO_NUM_23 +#define D6 GPIO_NUM_22 +#define D5 GPIO_NUM_21 +#define D4 GPIO_NUM_19 +#define D3 GPIO_NUM_18 +#define D2 GPIO_NUM_5 +#define D1 GPIO_NUM_4 +#define D0 GPIO_NUM_25 + +/* Control Lines */ +#define CKV GPIO_NUM_26 +#define STH GPIO_NUM_27 + +#define V4_LATCH_ENABLE GPIO_NUM_2 + +/* Edges */ +#define CKH GPIO_NUM_15 + +typedef struct { + bool power_enable : 1; + bool power_enable_vpos : 1; + bool power_enable_vneg : 1; + bool power_enable_gl : 1; + bool power_enable_gh : 1; +} epd_config_register_t; +static epd_config_register_t config_reg; + +static i2s_bus_config i2s_config = { + .clock = CKH, + .start_pulse = STH, + .data_0 = D0, + .data_1 = D1, + .data_2 = D2, + .data_3 = D3, + .data_4 = D4, + .data_5 = D5, + .data_6 = D6, + .data_7 = D7, +}; + +static void IRAM_ATTR push_cfg_bit(bool bit) { + gpio_set_level(CFG_CLK, 0); + gpio_set_level(CFG_DATA, bit); + gpio_set_level(CFG_CLK, 1); +} + +static void epd_board_init(uint32_t epd_row_width) { + /* Power Control Output/Off */ + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_DATA], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_CLK], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_STR], PIN_FUNC_GPIO); + gpio_set_direction(CFG_DATA, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_CLK, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_STR, GPIO_MODE_OUTPUT); + fast_gpio_set_lo(CFG_STR); + + config_reg.power_enable = false; + config_reg.power_enable_vpos = false; + config_reg.power_enable_vneg = false; + config_reg.power_enable_gl = false; + config_reg.power_enable_gh = false; + + // use latch pin as GPIO + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[V4_LATCH_ENABLE], PIN_FUNC_GPIO); + ESP_ERROR_CHECK(gpio_set_direction(V4_LATCH_ENABLE, GPIO_MODE_OUTPUT)); + gpio_set_level(V4_LATCH_ENABLE, 0); + + // Setup I2S + // add an offset off dummy bytes to allow for enough timing headroom + i2s_bus_init(&i2s_config, epd_row_width + 32); + + rmt_pulse_init(CKV); + + epd_board_temperature_init_v2(); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + if (state->ep_sth) { + fast_gpio_set_hi(STH); + } else { + fast_gpio_set_lo(STH); + } + + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv) { + fast_gpio_set_lo(CFG_STR); + + // push config bits in reverse order + push_cfg_bit(state->ep_output_enable); + push_cfg_bit(state->ep_mode); + push_cfg_bit(config_reg.power_enable_gh); + push_cfg_bit(state->ep_stv); + + push_cfg_bit(config_reg.power_enable_gl); + push_cfg_bit(config_reg.power_enable_vneg); + push_cfg_bit(config_reg.power_enable_vpos); + push_cfg_bit(config_reg.power_enable); + + fast_gpio_set_hi(CFG_STR); + fast_gpio_set_lo(CFG_STR); + } + + if (state->ep_latch_enable) { + fast_gpio_set_hi(V4_LATCH_ENABLE); + } else { + fast_gpio_set_lo(V4_LATCH_ENABLE); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + // POWERON + i2s_gpio_attach(&i2s_config); + + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.power_enable = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + config_reg.power_enable_gl = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.power_enable_vneg = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.power_enable_gh = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(500 * 240); + config_reg.power_enable_vpos = true; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + + state->ep_stv = true; + state->ep_sth = true; + mask.ep_sth = true; + epd_board_set_ctrl(state, &mask); + // END POWERON +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + // POWEROFF + epd_ctrl_state_t mask = { + // Trigger output to shift register + .ep_stv = true, + }; + config_reg.power_enable_gh = false; + config_reg.power_enable_vpos = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(10 * 240); + config_reg.power_enable_gl = false; + config_reg.power_enable_vneg = false; + epd_board_set_ctrl(state, &mask); + epd_busy_delay(100 * 240); + + state->ep_stv = false; + state->ep_output_enable = false; + mask.ep_output_enable = true; + state->ep_mode = false; + mask.ep_mode = true; + config_reg.power_enable = false; + epd_board_set_ctrl(state, &mask); + + i2s_gpio_detach(&i2s_config); + // END POWEROFF +} + +const EpdBoardDefinition epd_board_v5 = { + .init = epd_board_init, + .deinit = NULL, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + .get_temperature = epd_board_ambient_temperature_v2, + .set_vcom = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_v6.c b/lib/libesp32_eink/epdiy/src/board/epd_board_v6.c new file mode 100644 index 000000000..f544d1a8c --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_v6.c @@ -0,0 +1,359 @@ +#include "driver/gpio.h" +#include "epd_board.h" + +#include +#include +#include +#include "../output_i2s/i2s_data_bus.h" +#include "../output_i2s/render_i2s.h" +#include "../output_i2s/rmt_pulse.h" +#include "pca9555.h" +#include "tps65185.h" + +// Make this compile on the S3 to avoid long ifdefs +#ifndef CONFIG_IDF_TARGET_ESP32 +#define GPIO_NUM_22 0 +#define GPIO_NUM_23 0 +#define GPIO_NUM_24 0 +#define GPIO_NUM_25 0 +#endif + +#define CFG_SCL GPIO_NUM_33 +#define CFG_SDA GPIO_NUM_32 +#define CFG_INTR GPIO_NUM_35 +#define EPDIY_I2C_PORT I2C_NUM_0 +#define CFG_PIN_OE (PCA_PIN_PC10 >> 8) +#define CFG_PIN_MODE (PCA_PIN_PC11 >> 8) +#define CFG_PIN_STV (PCA_PIN_PC12 >> 8) +#define CFG_PIN_PWRUP (PCA_PIN_PC13 >> 8) +#define CFG_PIN_VCOM_CTRL (PCA_PIN_PC14 >> 8) +#define CFG_PIN_WAKEUP (PCA_PIN_PC15 >> 8) +#define CFG_PIN_PWRGOOD (PCA_PIN_PC16 >> 8) +#define CFG_PIN_INT (PCA_PIN_PC17 >> 8) +#define D7 GPIO_NUM_23 +#define D6 GPIO_NUM_22 +#define D5 GPIO_NUM_21 +#define D4 GPIO_NUM_19 +#define D3 GPIO_NUM_18 +#define D2 GPIO_NUM_5 +#define D1 GPIO_NUM_4 +#define D0 GPIO_NUM_25 + +/* Control Lines */ +#define CKV GPIO_NUM_26 +#define STH GPIO_NUM_27 + +#define V4_LATCH_ENABLE GPIO_NUM_2 + +/* Edges */ +#define CKH GPIO_NUM_15 + +typedef struct { + i2c_port_t port; + bool pwrup; + bool vcom_ctrl; + bool wakeup; + bool others[8]; +} epd_config_register_t; + +static i2s_bus_config i2s_config = { + .clock = CKH, + .start_pulse = STH, + .data_0 = D0, + .data_1 = D1, + .data_2 = D2, + .data_3 = D3, + .data_4 = D4, + .data_5 = D5, + .data_6 = D6, + .data_7 = D7, +}; + +/** The VCOM voltage to use. */ +static int vcom = 1600; + +static bool interrupt_done = false; + +static void IRAM_ATTR interrupt_handler(void* arg) { + interrupt_done = true; +} + +static epd_config_register_t config_reg; + +static void epd_board_init(uint32_t epd_row_width) { + gpio_hold_dis(CKH); // free CKH after wakeup + + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = CFG_SDA; + conf.scl_io_num = CFG_SCL; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf.master.clk_speed = 400000; + conf.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL; + ESP_ERROR_CHECK(i2c_param_config(EPDIY_I2C_PORT, &conf)); + + ESP_ERROR_CHECK(i2c_driver_install(EPDIY_I2C_PORT, I2C_MODE_MASTER, 0, 0, 0)); + + config_reg.port = EPDIY_I2C_PORT; + config_reg.pwrup = false; + config_reg.vcom_ctrl = false; + config_reg.wakeup = false; + for (int i = 0; i < 8; i++) { + config_reg.others[i] = false; + } + + gpio_set_direction(CFG_INTR, GPIO_MODE_INPUT); + gpio_set_intr_type(CFG_INTR, GPIO_INTR_NEGEDGE); + + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_EDGE)); + + ESP_ERROR_CHECK(gpio_isr_handler_add(CFG_INTR, interrupt_handler, (void*)CFG_INTR)); + + // set all epdiy lines to output except TPS interrupt + PWR good + ESP_ERROR_CHECK(pca9555_set_config(config_reg.port, CFG_PIN_PWRGOOD | CFG_PIN_INT, 1)); + + // use latch pin as GPIO + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[V4_LATCH_ENABLE], PIN_FUNC_GPIO); + ESP_ERROR_CHECK(gpio_set_direction(V4_LATCH_ENABLE, GPIO_MODE_OUTPUT)); + gpio_set_level(V4_LATCH_ENABLE, 0); + + // Setup I2S + // add an offset off dummy bytes to allow for enough timing headroom + i2s_bus_init(&i2s_config, epd_row_width + 32); + + rmt_pulse_init(CKV); +} + +static void epd_board_deinit() { + // gpio_reset_pin(CFG_INTR); + // rtc_gpio_isolate(CFG_INTR); + + ESP_ERROR_CHECK(pca9555_set_config( + config_reg.port, CFG_PIN_PWRGOOD | CFG_PIN_INT | CFG_PIN_VCOM_CTRL | CFG_PIN_PWRUP, 1 + )); + + int tries = 0; + while (!((pca9555_read_input(config_reg.port, 1) & 0xC0) == 0x80)) { + if (tries >= 500) { + ESP_LOGE("epdiy", "failed to shut down TPS65185!"); + break; + } + tries++; + vTaskDelay(1); + printf("%X\n", pca9555_read_input(config_reg.port, 1)); + } + // Not sure why we need this delay, but the TPS65185 seems to generate an interrupt after some + // time that needs to be cleared. + vTaskDelay(500); + pca9555_read_input(config_reg.port, 0); + pca9555_read_input(config_reg.port, 1); + i2c_driver_delete(EPDIY_I2C_PORT); + gpio_isr_handler_remove(CFG_INTR); + gpio_uninstall_isr_service(); + gpio_reset_pin(CFG_INTR); + gpio_reset_pin(V4_LATCH_ENABLE); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + uint8_t value = 0x00; + if (state->ep_sth) { + fast_gpio_set_hi(STH); + } else { + fast_gpio_set_lo(STH); + } + + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv) { + if (state->ep_output_enable) + value |= CFG_PIN_OE; + if (state->ep_mode) + value |= CFG_PIN_MODE; + if (state->ep_stv) + value |= CFG_PIN_STV; + if (config_reg.pwrup) + value |= CFG_PIN_PWRUP; + if (config_reg.vcom_ctrl) + value |= CFG_PIN_VCOM_CTRL; + if (config_reg.wakeup) + value |= CFG_PIN_WAKEUP; + + ESP_ERROR_CHECK(pca9555_set_value(config_reg.port, value, 1)); + } + + if (state->ep_latch_enable) { + fast_gpio_set_hi(V4_LATCH_ENABLE); + } else { + fast_gpio_set_lo(V4_LATCH_ENABLE); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + i2s_gpio_attach(&i2s_config); + + epd_ctrl_state_t mask = { + .ep_stv = true, + }; + state->ep_stv = true; + config_reg.wakeup = true; + epd_board_set_ctrl(state, &mask); + config_reg.pwrup = true; + epd_board_set_ctrl(state, &mask); + config_reg.vcom_ctrl = true; + epd_board_set_ctrl(state, &mask); + + // give the IC time to powerup and set lines + vTaskDelay(1); + + int tries = 0; + while (!(pca9555_read_input(config_reg.port, 1) & CFG_PIN_PWRGOOD)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! INT status: 0x%X 0x%X", + tps_read_register(config_reg.port, TPS_REG_INT1), + tps_read_register(config_reg.port, TPS_REG_INT2) + ); + return; + } + tries++; + vTaskDelay(1); + } + + ESP_ERROR_CHECK(tps_write_register(config_reg.port, TPS_REG_ENABLE, 0x3F)); + + tps_set_vcom(config_reg.port, vcom); + + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + while (!((tps_read_register(config_reg.port, TPS_REG_PG) & 0xFA) == 0xFA)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! PG status: %X", + tps_read_register(config_reg.port, TPS_REG_PG) + ); + return; + } + tries++; + vTaskDelay(1); + } +} + +static void epd_board_measure_vcom(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + .ep_stv = true, + }; + state->ep_stv = true; + state->ep_mode = false; + state->ep_output_enable = true; + config_reg.wakeup = true; + epd_board_set_ctrl(state, &mask); + config_reg.pwrup = true; + epd_board_set_ctrl(state, &mask); + + // give the IC time to powerup and set lines + vTaskDelay(1); + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + while (!(pca9555_read_input(config_reg.port, 1) & CFG_PIN_PWRGOOD)) { + } + ESP_LOGI("epdiy", "Power rails enabled"); + + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + int tries = 0; + while (!((tps_read_register(config_reg.port, TPS_REG_PG) & 0xFA) == 0xFA)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! PG status: %X", + tps_read_register(config_reg.port, TPS_REG_PG) + ); + return; + } + tries++; + vTaskDelay(1); + } +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_stv = true, + .ep_output_enable = true, + .ep_mode = true, + }; + config_reg.vcom_ctrl = false; + config_reg.pwrup = false; + state->ep_stv = false; + state->ep_output_enable = false; + state->ep_mode = false; + epd_board_set_ctrl(state, &mask); + vTaskDelay(1); + config_reg.wakeup = false; + epd_board_set_ctrl(state, &mask); + + i2s_gpio_detach(&i2s_config); +} + +static float epd_board_ambient_temperature() { + return tps_read_thermistor(EPDIY_I2C_PORT); +} + +static esp_err_t gpio_set_direction_v6(int pin, bool make_input) { + static uint8_t direction = 0; + uint8_t mask = ~(1 << pin); + direction = (direction & mask) | (make_input << pin); + + return pca9555_set_config(EPDIY_I2C_PORT, direction, 0); +} + +/** + * Get the input level of the broken-out GPIO extender port. + */ +static bool gpio_get_level_v6(int pin) { + return (pca9555_read_input(EPDIY_I2C_PORT, 0) >> pin) & 1; +} + +/** + * Get the input level of the broken-out GPIO extender port. + */ +static esp_err_t gpio_set_value_v6(int pin, bool value) { + static uint8_t state = 0; + uint8_t mask = ~(1 << pin); + state = (state & mask) | (value << pin); + + return pca9555_set_value(EPDIY_I2C_PORT, state, 0); +} + +static void set_vcom(int value) { + vcom = value; +} + +const EpdBoardDefinition epd_board_v6 = { + .init = epd_board_init, + .deinit = epd_board_deinit, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + .measure_vcom = epd_board_measure_vcom, + .get_temperature = epd_board_ambient_temperature, + .set_vcom = set_vcom, + + .gpio_set_direction = gpio_set_direction_v6, + .gpio_read = gpio_get_level_v6, + .gpio_write = gpio_set_value_v6, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_v7.c b/lib/libesp32_eink/epdiy/src/board/epd_board_v7.c new file mode 100644 index 000000000..1dd4414a4 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_v7.c @@ -0,0 +1,338 @@ +#include +#include "epd_board.h" +#include "epdiy.h" + +#include "../output_common/render_method.h" +#include "../output_lcd/lcd_driver.h" +#include "esp_log.h" +#include "pca9555.h" +#include "tps65185.h" + +#include +#include +#include + +// Make this compile von the ESP32 without ifdefing the whole file +#ifndef CONFIG_IDF_TARGET_ESP32S3 +#define GPIO_NUM_40 -1 +#define GPIO_NUM_41 -1 +#define GPIO_NUM_42 -1 +#define GPIO_NUM_43 -1 +#define GPIO_NUM_44 -1 +#define GPIO_NUM_45 -1 +#define GPIO_NUM_46 -1 +#define GPIO_NUM_47 -1 +#define GPIO_NUM_48 -1 +#endif + +#define CFG_SCL GPIO_NUM_40 +#define CFG_SDA GPIO_NUM_39 +#define CFG_INTR GPIO_NUM_38 +#define EPDIY_I2C_PORT I2C_NUM_0 + +#define CFG_PIN_OE (PCA_PIN_PC10 >> 8) +#define CFG_PIN_MODE (PCA_PIN_PC11 >> 8) +#define __CFG_PIN_STV (PCA_PIN_PC12 >> 8) +#define CFG_PIN_PWRUP (PCA_PIN_PC13 >> 8) +#define CFG_PIN_VCOM_CTRL (PCA_PIN_PC14 >> 8) +#define CFG_PIN_WAKEUP (PCA_PIN_PC15 >> 8) +#define CFG_PIN_PWRGOOD (PCA_PIN_PC16 >> 8) +#define CFG_PIN_INT (PCA_PIN_PC17 >> 8) + +#define D15 GPIO_NUM_47 +#define D14 GPIO_NUM_21 +#define D13 GPIO_NUM_14 +#define D12 GPIO_NUM_13 +#define D11 GPIO_NUM_12 +#define D10 GPIO_NUM_11 +#define D9 GPIO_NUM_10 +#define D8 GPIO_NUM_9 + +#define D7 GPIO_NUM_8 +#define D6 GPIO_NUM_18 +#define D5 GPIO_NUM_17 +#define D4 GPIO_NUM_16 +#define D3 GPIO_NUM_15 +#define D2 GPIO_NUM_7 +#define D1 GPIO_NUM_6 +#define D0 GPIO_NUM_5 + +/* Control Lines */ +#define CKV GPIO_NUM_48 +#define STH GPIO_NUM_41 +#define LEH GPIO_NUM_42 +#define STV GPIO_NUM_45 + +/* Edges */ +#define CKH GPIO_NUM_4 + +typedef struct { + i2c_port_t port; + bool pwrup; + bool vcom_ctrl; + bool wakeup; + bool others[8]; +} epd_config_register_t; + +/** The VCOM voltage to use. */ +static int vcom = 1600; + +static epd_config_register_t config_reg; + +static bool interrupt_done = false; + +static void IRAM_ATTR interrupt_handler(void* arg) { + interrupt_done = true; +} + +static lcd_bus_config_t lcd_config = { + .clock = CKH, + .ckv = CKV, + .leh = LEH, + .start_pulse = STH, + .stv = STV, + .data[0] = D0, + .data[1] = D1, + .data[2] = D2, + .data[3] = D3, + .data[4] = D4, + .data[5] = D5, + .data[6] = D6, + .data[7] = D7, + .data[8] = D8, + .data[9] = D9, + .data[10] = D10, + .data[11] = D11, + .data[12] = D12, + .data[13] = D13, + .data[14] = D14, + .data[15] = D15, +}; + +static void epd_board_init(uint32_t epd_row_width) { + gpio_hold_dis(CKH); // free CKH after wakeup + + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = CFG_SDA; + conf.scl_io_num = CFG_SCL; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf.master.clk_speed = 100000; + conf.clk_flags = 0; + ESP_ERROR_CHECK(i2c_param_config(EPDIY_I2C_PORT, &conf)); + + ESP_ERROR_CHECK(i2c_driver_install(EPDIY_I2C_PORT, I2C_MODE_MASTER, 0, 0, 0)); + + config_reg.port = EPDIY_I2C_PORT; + config_reg.pwrup = false; + config_reg.vcom_ctrl = false; + config_reg.wakeup = false; + for (int i = 0; i < 8; i++) { + config_reg.others[i] = false; + } + + gpio_set_direction(CFG_INTR, GPIO_MODE_INPUT); + gpio_set_intr_type(CFG_INTR, GPIO_INTR_NEGEDGE); + + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_EDGE)); + + ESP_ERROR_CHECK(gpio_isr_handler_add(CFG_INTR, interrupt_handler, (void*)CFG_INTR)); + + // set all epdiy lines to output except TPS interrupt + PWR good + ESP_ERROR_CHECK(pca9555_set_config(config_reg.port, CFG_PIN_PWRGOOD | CFG_PIN_INT, 1)); + + const EpdDisplay_t* display = epd_get_display(); + + LcdEpdConfig_t config = { + .pixel_clock = display->bus_speed * 1000 * 1000, + .ckv_high_time = 60, + .line_front_porch = 4, + .le_high_time = 4, + .bus_width = display->bus_width, + .bus = lcd_config, + }; + epd_lcd_init(&config, display->width, display->height); +} + +static void epd_board_deinit() { + epd_lcd_deinit(); + + ESP_ERROR_CHECK(pca9555_set_config( + config_reg.port, CFG_PIN_PWRGOOD | CFG_PIN_INT | CFG_PIN_VCOM_CTRL | CFG_PIN_PWRUP, 1 + )); + + int tries = 0; + while (!((pca9555_read_input(config_reg.port, 1) & 0xC0) == 0x80)) { + if (tries >= 50) { + ESP_LOGE("epdiy", "failed to shut down TPS65185!"); + break; + } + tries++; + vTaskDelay(1); + } + + // Not sure why we need this delay, but the TPS65185 seems to generate an interrupt after some + // time that needs to be cleared. + vTaskDelay(50); + pca9555_read_input(config_reg.port, 0); + pca9555_read_input(config_reg.port, 1); + i2c_driver_delete(EPDIY_I2C_PORT); + + gpio_uninstall_isr_service(); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + uint8_t value = 0x00; + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv) { + if (state->ep_output_enable) + value |= CFG_PIN_OE; + if (state->ep_mode) + value |= CFG_PIN_MODE; + // if (state->ep_stv) value |= CFG_PIN_STV; + if (config_reg.pwrup) + value |= CFG_PIN_PWRUP; + if (config_reg.vcom_ctrl) + value |= CFG_PIN_VCOM_CTRL; + if (config_reg.wakeup) + value |= CFG_PIN_WAKEUP; + + ESP_ERROR_CHECK(pca9555_set_value(config_reg.port, value, 1)); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + .ep_stv = true, + }; + state->ep_stv = true; + state->ep_mode = false; + state->ep_output_enable = true; + config_reg.wakeup = true; + epd_board_set_ctrl(state, &mask); + config_reg.pwrup = true; + epd_board_set_ctrl(state, &mask); + config_reg.vcom_ctrl = true; + epd_board_set_ctrl(state, &mask); + + // give the IC time to powerup and set lines + vTaskDelay(1); + + while (!(pca9555_read_input(config_reg.port, 1) & CFG_PIN_PWRGOOD)) { + } + + ESP_ERROR_CHECK(tps_write_register(config_reg.port, TPS_REG_ENABLE, 0x3F)); + + tps_set_vcom(config_reg.port, vcom); + + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + int tries = 0; + while (!((tps_read_register(config_reg.port, TPS_REG_PG) & 0xFA) == 0xFA)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! PG status: %X", + tps_read_register(config_reg.port, TPS_REG_PG) + ); + return; + } + tries++; + vTaskDelay(1); + } +} + +static void epd_board_measure_vcom(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + .ep_stv = true, + }; + state->ep_stv = true; + state->ep_mode = false; + state->ep_output_enable = true; + config_reg.wakeup = true; + epd_board_set_ctrl(state, &mask); + config_reg.pwrup = true; + epd_board_set_ctrl(state, &mask); + + // give the IC time to powerup and set lines + vTaskDelay(1); + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + while (!(pca9555_read_input(config_reg.port, 1) & CFG_PIN_PWRGOOD)) { + } + ESP_LOGI("epdiy", "Power rails enabled"); + + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + int tries = 0; + while (!((tps_read_register(config_reg.port, TPS_REG_PG) & 0xFA) == 0xFA)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! PG status: %X", + tps_read_register(config_reg.port, TPS_REG_PG) + ); + return; + } + tries++; + vTaskDelay(1); + } +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_stv = true, + .ep_output_enable = true, + .ep_mode = true, + }; + config_reg.vcom_ctrl = false; + config_reg.pwrup = false; + state->ep_stv = false; + state->ep_output_enable = false; + state->ep_mode = false; + epd_board_set_ctrl(state, &mask); + vTaskDelay(1); + config_reg.wakeup = false; + epd_board_set_ctrl(state, &mask); +} + +static float epd_board_ambient_temperature() { + return 20; +} + +static void set_vcom(int value) { + vcom = value; +} + +const EpdBoardDefinition epd_board_v7 = { + .init = epd_board_init, + .deinit = epd_board_deinit, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + + .measure_vcom = epd_board_measure_vcom, + .get_temperature = epd_board_ambient_temperature, + .set_vcom = set_vcom, + + // unimplemented for now, but shares v6 implementation + .gpio_set_direction = NULL, + .gpio_read = NULL, + .gpio_write = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/epd_board_v7_raw.c b/lib/libesp32_eink/epdiy/src/board/epd_board_v7_raw.c new file mode 100644 index 000000000..8c9865cf9 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/epd_board_v7_raw.c @@ -0,0 +1,288 @@ +/** + * @file epd_board_v7_raw.c + * @author Martin Fasani www.fasani.de + * @brief Small v7 board without IO expander targeted only to 8-bit einks + * @date 2025-02-10 + */ +#include +#include "epd_board.h" +#include "epdiy.h" + +#include "../output_common/render_method.h" +#include "../output_lcd/lcd_driver.h" +#include "esp_log.h" +#include "tps65185.h" + +#include +#include +#include + +// Make this compile on the ESP32 without ifdefing the whole file +#ifndef CONFIG_IDF_TARGET_ESP32S3 +#define GPIO_NUM_40 -1 +#define GPIO_NUM_41 -1 +#define GPIO_NUM_42 -1 +#define GPIO_NUM_43 -1 +#define GPIO_NUM_44 -1 +#define GPIO_NUM_45 -1 +#define GPIO_NUM_46 -1 +#define GPIO_NUM_47 -1 +#define GPIO_NUM_48 -1 +#endif + +#define CFG_SCL GPIO_NUM_40 +#define CFG_SDA GPIO_NUM_39 +#define EPDIY_I2C_PORT I2C_NUM_0 + +#define CFG_PIN_OE GPIO_NUM_9 +#define CFG_PIN_MODE GPIO_NUM_10 +#define __CFG_PIN_STV GPIO_NUM_45 +#define CFG_PIN_PWRUP GPIO_NUM_11 +#define CFG_PIN_VCOM_CTRL GPIO_NUM_12 +#define CFG_PIN_WAKEUP GPIO_NUM_14 +#define CFG_PIN_PWRGOOD GPIO_NUM_47 +#define CFG_PIN_INT GPIO_NUM_13 // TPS65185 INT + +#define D7 GPIO_NUM_8 +#define D6 GPIO_NUM_18 +#define D5 GPIO_NUM_17 +#define D4 GPIO_NUM_16 +#define D3 GPIO_NUM_15 +#define D2 GPIO_NUM_7 +#define D1 GPIO_NUM_6 +#define D0 GPIO_NUM_5 + +/* Control Lines */ +#define CKV GPIO_NUM_48 +#define STH GPIO_NUM_41 +#define LEH GPIO_NUM_42 +#define STV GPIO_NUM_45 + +/* Edges */ +#define CKH GPIO_NUM_4 + +typedef struct { + i2c_port_t port; + bool pwrup; + bool vcom_ctrl; + bool wakeup; + bool others[8]; +} epd_config_register_t; + +/** The VCOM voltage to use. */ +static int vcom = 1900; + +static epd_config_register_t config_reg; + +static bool interrupt_done = false; + +static void IRAM_ATTR interrupt_handler(void* arg) { + interrupt_done = true; +} + +static lcd_bus_config_t lcd_config = { .clock = CKH, + .ckv = CKV, + .leh = LEH, + .start_pulse = STH, + .stv = STV, + .data[0] = D0, + .data[1] = D1, + .data[2] = D2, + .data[3] = D3, + .data[4] = D4, + .data[5] = D5, + .data[6] = D6, + .data[7] = D7 }; + +static void epd_board_init(uint32_t epd_row_width) { + gpio_hold_dis(CKH); // free CKH after wakeup + + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = CFG_SDA; + conf.scl_io_num = CFG_SCL; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf.master.clk_speed = 100000; + conf.clk_flags = 0; + ESP_ERROR_CHECK(i2c_param_config(EPDIY_I2C_PORT, &conf)); + + ESP_ERROR_CHECK(i2c_driver_install(EPDIY_I2C_PORT, I2C_MODE_MASTER, 0, 0, 0)); + + config_reg.port = EPDIY_I2C_PORT; + config_reg.pwrup = false; + config_reg.vcom_ctrl = false; + config_reg.wakeup = false; + for (int i = 0; i < 8; i++) { + config_reg.others[i] = false; + } + + gpio_set_direction(CFG_PIN_INT, GPIO_MODE_INPUT); + gpio_set_intr_type(CFG_PIN_INT, GPIO_INTR_NEGEDGE); + + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_EDGE)); + + ESP_ERROR_CHECK(gpio_isr_handler_add(CFG_PIN_INT, interrupt_handler, (void*)CFG_PIN_INT)); + + // set all epdiy lines to output except TPS interrupt + PWR good + gpio_set_direction(CFG_PIN_PWRGOOD, GPIO_MODE_INPUT); + gpio_set_pull_mode(CFG_PIN_PWRGOOD, GPIO_PULLUP_ONLY); + + gpio_set_direction(CFG_PIN_WAKEUP, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_PIN_PWRUP, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_PIN_VCOM_CTRL, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_PIN_OE, GPIO_MODE_OUTPUT); + gpio_set_direction(CFG_PIN_MODE, GPIO_MODE_OUTPUT); + + const EpdDisplay_t* display = epd_get_display(); + if (display->bus_width > 8) { + ESP_LOGE("v7_RAW", "displays > 8 bit width are not supported in this board"); + } + + LcdEpdConfig_t config = { + .pixel_clock = display->bus_speed * 1000 * 1000, + .ckv_high_time = 60, + .line_front_porch = 4, + .le_high_time = 4, + .bus_width = display->bus_width, + .bus = lcd_config, + }; + + epd_lcd_init(&config, display->width, display->height); +} + +static void epd_board_deinit() { + epd_lcd_deinit(); + gpio_set_level(CFG_PIN_PWRUP, false); + + // Not sure why we need this delay, but the TPS65185 seems to generate an interrupt after some + // time that needs to be cleared. + vTaskDelay(50); + i2c_driver_delete(EPDIY_I2C_PORT); + + gpio_uninstall_isr_service(); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + if (state->ep_output_enable) { + gpio_set_level(CFG_PIN_OE, 1); + } else { + gpio_set_level(CFG_PIN_OE, 0); + } + + if (state->ep_mode) { + gpio_set_level(CFG_PIN_MODE, 1); + } else { + gpio_set_level(CFG_PIN_MODE, 0); + } + + if (config_reg.pwrup && !gpio_get_level(CFG_PIN_PWRUP)) { + gpio_set_level(CFG_PIN_PWRUP, 1); + } else { + gpio_set_level(CFG_PIN_PWRUP, 0); + } + + if (config_reg.vcom_ctrl && !gpio_get_level(CFG_PIN_VCOM_CTRL)) { + gpio_set_level(CFG_PIN_VCOM_CTRL, 1); + } else { + gpio_set_level(CFG_PIN_VCOM_CTRL, 0); + } + + if (config_reg.wakeup && !gpio_get_level(CFG_PIN_WAKEUP)) { + gpio_set_level(CFG_PIN_WAKEUP, 1); + } else { + gpio_set_level(CFG_PIN_WAKEUP, 0); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + .ep_stv = true, + }; + state->ep_stv = true; + state->ep_mode = true; + state->ep_output_enable = true; + config_reg.wakeup = true; + epd_board_set_ctrl(state, &mask); + vTaskDelay(pdMS_TO_TICKS(10)); + config_reg.pwrup = true; + epd_board_set_ctrl(state, &mask); + vTaskDelay(pdMS_TO_TICKS(10)); + config_reg.vcom_ctrl = true; + epd_board_set_ctrl(state, &mask); + + // give the IC time to powerup and set lines + vTaskDelay(1); + + // Check if PWRs lines are up + int timeout_counter = 0; + const int timeout_limit = 20; // 20 * 100ms = 2 seconds + while (gpio_get_level(CFG_PIN_PWRGOOD) == 0) { + if (timeout_counter >= timeout_limit) { + ESP_LOGE("v7_RAW", "Timeout waiting for PWRGOOD signal"); + break; + } + timeout_counter++; + vTaskDelay(pdMS_TO_TICKS(100)); + } + ESP_LOGI("v7_RAW", "PWRGOOD OK"); + + tps_set_vcom(config_reg.port, vcom); + + int tries = 0; + while (!((tps_read_register(config_reg.port, TPS_REG_PG) & 0xFA) == 0xFA)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! PG status: %X", + tps_read_register(config_reg.port, TPS_REG_PG) + ); + return; + } + tries++; + vTaskDelay(1); + } +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_stv = true, + .ep_output_enable = true, + .ep_mode = true, + }; + config_reg.vcom_ctrl = false; + config_reg.pwrup = false; + state->ep_stv = false; + state->ep_output_enable = false; + state->ep_mode = false; + epd_board_set_ctrl(state, &mask); + vTaskDelay(1); + config_reg.wakeup = false; + epd_board_set_ctrl(state, &mask); +} + +static float epd_board_ambient_temperature() { + return tps_read_thermistor(EPDIY_I2C_PORT); +} + +static void set_vcom(int value) { + vcom = value; +} + +const EpdBoardDefinition epd_board_v7_raw = { + .init = epd_board_init, + .deinit = epd_board_deinit, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + + .get_temperature = epd_board_ambient_temperature, + .set_vcom = set_vcom, + + // unimplemented for now, but shares v6 implementation + .gpio_set_direction = NULL, + .gpio_read = NULL, + .gpio_write = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/lilygo_board_s3.c b/lib/libesp32_eink/epdiy/src/board/lilygo_board_s3.c new file mode 100644 index 000000000..500259380 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/lilygo_board_s3.c @@ -0,0 +1,273 @@ +#include +#include "epd_board.h" +#include "epdiy.h" + +#include "../output_common/render_method.h" +#include "../output_lcd/lcd_driver.h" +#include "esp_log.h" +#include "pca9555.h" +#include "tps65185.h" + +#include +#include +#include + +// Make this compile von the ESP32 without ifdefing the whole file +#ifndef CONFIG_IDF_TARGET_ESP32S3 +#define GPIO_NUM_40 -1 +#define GPIO_NUM_41 -1 +#define GPIO_NUM_42 -1 +#define GPIO_NUM_43 -1 +#define GPIO_NUM_44 -1 +#define GPIO_NUM_45 -1 +#define GPIO_NUM_46 -1 +#define GPIO_NUM_47 -1 +#define GPIO_NUM_48 -1 +#endif + +#define CFG_SCL GPIO_NUM_40 +#define CFG_SDA GPIO_NUM_39 +#define CFG_INTR GPIO_NUM_38 +#define EPDIY_I2C_PORT I2C_NUM_0 + +#define CFG_PIN_OE (PCA_PIN_PC10 >> 8) +#define CFG_PIN_MODE (PCA_PIN_PC11 >> 8) +#define __CFG_PIN_STV (PCA_PIN_PC12 >> 8) +#define CFG_PIN_PWRUP (PCA_PIN_PC13 >> 8) +#define CFG_PIN_VCOM_CTRL (PCA_PIN_PC14 >> 8) +#define CFG_PIN_WAKEUP (PCA_PIN_PC15 >> 8) +#define CFG_PIN_PWRGOOD (PCA_PIN_PC16 >> 8) +#define CFG_PIN_INT (PCA_PIN_PC17 >> 8) + +#define D7 GPIO_NUM_8 +#define D6 GPIO_NUM_18 +#define D5 GPIO_NUM_17 +#define D4 GPIO_NUM_16 +#define D3 GPIO_NUM_15 +#define D2 GPIO_NUM_7 +#define D1 GPIO_NUM_6 +#define D0 GPIO_NUM_5 + +/* Control Lines */ +#define CKV GPIO_NUM_48 +#define STH GPIO_NUM_41 +#define LEH GPIO_NUM_42 +#define STV GPIO_NUM_45 + +/* Edges */ +#define CKH GPIO_NUM_4 + +typedef struct { + i2c_port_t port; + bool pwrup; + bool vcom_ctrl; + bool wakeup; + bool others[8]; +} epd_config_register_t; + +/** The VCOM voltage to use. */ +static int vcom = 1600; + +static epd_config_register_t config_reg; + +static bool interrupt_done = false; + +static void IRAM_ATTR interrupt_handler(void* arg) { + interrupt_done = true; +} + +static lcd_bus_config_t lcd_config = { + .clock = CKH, + .ckv = CKV, + .leh = LEH, + .start_pulse = STH, + .stv = STV, + .data[0] = D0, + .data[1] = D1, + .data[2] = D2, + .data[3] = D3, + .data[4] = D4, + .data[5] = D5, + .data[6] = D6, + .data[7] = D7, +}; + +static void epd_board_init(uint32_t epd_row_width) { + gpio_hold_dis(CKH); // free CKH after wakeup + + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = CFG_SDA; + conf.scl_io_num = CFG_SCL; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf.master.clk_speed = 100000; + conf.clk_flags = 0; + ESP_ERROR_CHECK(i2c_param_config(EPDIY_I2C_PORT, &conf)); + + ESP_ERROR_CHECK(i2c_driver_install(EPDIY_I2C_PORT, I2C_MODE_MASTER, 0, 0, 0)); + + config_reg.port = EPDIY_I2C_PORT; + config_reg.pwrup = false; + config_reg.vcom_ctrl = false; + config_reg.wakeup = false; + for (int i = 0; i < 8; i++) { + config_reg.others[i] = false; + } + + gpio_set_direction(CFG_INTR, GPIO_MODE_INPUT); + gpio_set_intr_type(CFG_INTR, GPIO_INTR_NEGEDGE); + + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_EDGE)); + + ESP_ERROR_CHECK(gpio_isr_handler_add(CFG_INTR, interrupt_handler, (void*)CFG_INTR)); + + // set all epdiy lines to output except TPS interrupt + PWR good + ESP_ERROR_CHECK(pca9555_set_config(config_reg.port, CFG_PIN_PWRGOOD | CFG_PIN_INT, 1)); + + const EpdDisplay_t* display = epd_get_display(); + + LcdEpdConfig_t config = { + .pixel_clock = display->bus_speed * 1000 * 1000, + .ckv_high_time = 60, + .line_front_porch = 4, + .le_high_time = 4, + .bus_width = display->bus_width, + .bus = lcd_config, + }; + epd_lcd_init(&config, display->width, display->height); +} + +static void epd_board_deinit() { + epd_lcd_deinit(); + + ESP_ERROR_CHECK(pca9555_set_config( + config_reg.port, CFG_PIN_PWRGOOD | CFG_PIN_INT | CFG_PIN_VCOM_CTRL | CFG_PIN_PWRUP, 1 + )); + + int tries = 0; + while (!((pca9555_read_input(config_reg.port, 1) & 0xC0) == 0x80)) { + if (tries >= 50) { + ESP_LOGE("epdiy", "failed to shut down TPS65185!"); + break; + } + tries++; + vTaskDelay(1); + } + + // Not sure why we need this delay, but the TPS65185 seems to generate an interrupt after some + // time that needs to be cleared. + vTaskDelay(50); + pca9555_read_input(config_reg.port, 0); + pca9555_read_input(config_reg.port, 1); + i2c_driver_delete(EPDIY_I2C_PORT); + + gpio_uninstall_isr_service(); +} + +static void epd_board_set_ctrl(epd_ctrl_state_t* state, const epd_ctrl_state_t* const mask) { + uint8_t value = 0x00; + if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv) { + if (state->ep_output_enable) + value |= CFG_PIN_OE; + if (state->ep_mode) + value |= CFG_PIN_MODE; + // if (state->ep_stv) value |= CFG_PIN_STV; + if (config_reg.pwrup) + value |= CFG_PIN_PWRUP; + if (config_reg.vcom_ctrl) + value |= CFG_PIN_VCOM_CTRL; + if (config_reg.wakeup) + value |= CFG_PIN_WAKEUP; + + ESP_ERROR_CHECK(pca9555_set_value(config_reg.port, value, 1)); + } +} + +static void epd_board_poweron(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_output_enable = true, + .ep_mode = true, + .ep_stv = true, + }; + state->ep_stv = true; + state->ep_mode = false; + state->ep_output_enable = true; + config_reg.wakeup = true; + epd_board_set_ctrl(state, &mask); + config_reg.pwrup = true; + epd_board_set_ctrl(state, &mask); + config_reg.vcom_ctrl = true; + epd_board_set_ctrl(state, &mask); + + // give the IC time to powerup and set lines + vTaskDelay(1); + + while (!(pca9555_read_input(config_reg.port, 1) & CFG_PIN_PWRGOOD)) { + } + + ESP_ERROR_CHECK(tps_write_register(config_reg.port, TPS_REG_ENABLE, 0x3F)); + + tps_set_vcom(config_reg.port, vcom); + + state->ep_sth = true; + mask = (const epd_ctrl_state_t){ + .ep_sth = true, + }; + epd_board_set_ctrl(state, &mask); + + int tries = 0; + while (!((tps_read_register(config_reg.port, TPS_REG_PG) & 0xFA) == 0xFA)) { + if (tries >= 500) { + ESP_LOGE( + "epdiy", + "Power enable failed! PG status: %X", + tps_read_register(config_reg.port, TPS_REG_PG) + ); + return; + } + tries++; + vTaskDelay(1); + } +} + +static void epd_board_poweroff(epd_ctrl_state_t* state) { + epd_ctrl_state_t mask = { + .ep_stv = true, + .ep_output_enable = true, + .ep_mode = true, + }; + config_reg.vcom_ctrl = false; + config_reg.pwrup = false; + state->ep_stv = false; + state->ep_output_enable = false; + state->ep_mode = false; + epd_board_set_ctrl(state, &mask); + vTaskDelay(1); + config_reg.wakeup = false; + epd_board_set_ctrl(state, &mask); +} + +static float epd_board_ambient_temperature() { + return 20; +} + +static void set_vcom(int value) { + vcom = value; +} + +const EpdBoardDefinition lilygo_board_s3 = { + .init = epd_board_init, + .deinit = epd_board_deinit, + .set_ctrl = epd_board_set_ctrl, + .poweron = epd_board_poweron, + .poweroff = epd_board_poweroff, + + .get_temperature = epd_board_ambient_temperature, + .set_vcom = set_vcom, + + // unimplemented for now, but shares v6 implementation + .gpio_set_direction = NULL, + .gpio_read = NULL, + .gpio_write = NULL, +}; diff --git a/lib/libesp32_eink/epdiy/src/board/pca9555.c b/lib/libesp32_eink/epdiy/src/board/pca9555.c new file mode 100644 index 000000000..5faabba17 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/pca9555.c @@ -0,0 +1,107 @@ + + +#include "pca9555.h" +#include +#include +#include +#include + +#define REG_INPUT_PORT0 0 +#define REG_INPUT_PORT1 1 + +#define REG_OUTPUT_PORT0 2 +#define REG_OUTPUT_PORT1 3 + +#define REG_INVERT_PORT0 4 +#define REG_INVERT_PORT1 5 + +#define REG_CONFIG_PORT0 6 +#define REG_CONFIG_PORT1 7 + +static esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t* data_rd, size_t size, int reg) { + if (size == 0) { + return ESP_OK; + } + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + if (cmd == NULL) { + ESP_LOGE("epdiy", "insufficient memory for I2C transaction"); + } + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (EPDIY_PCA9555_ADDR << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg, true); + i2c_master_stop(cmd); + + esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS); + if (ret != ESP_OK) { + return ret; + } + i2c_cmd_link_delete(cmd); + + cmd = i2c_cmd_link_create(); + if (cmd == NULL) { + ESP_LOGE("epdiy", "insufficient memory for I2C transaction"); + } + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (EPDIY_PCA9555_ADDR << 1) | I2C_MASTER_READ, true); + if (size > 1) { + i2c_master_read(cmd, data_rd, size - 1, I2C_MASTER_ACK); + } + i2c_master_read_byte(cmd, data_rd + size - 1, I2C_MASTER_NACK); + i2c_master_stop(cmd); + + ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS); + if (ret != ESP_OK) { + return ret; + } + i2c_cmd_link_delete(cmd); + + return ESP_OK; +} + +static esp_err_t i2c_master_write_slave( + i2c_port_t i2c_num, uint8_t ctrl, uint8_t* data_wr, size_t size +) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + if (cmd == NULL) { + ESP_LOGE("epdiy", "insufficient memory for I2C transaction"); + } + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (EPDIY_PCA9555_ADDR << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, ctrl, true); + + i2c_master_write(cmd, data_wr, size, true); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return ret; +} + +static esp_err_t pca9555_write_single(i2c_port_t port, int reg, uint8_t value) { + uint8_t w_data[1] = { value }; + return i2c_master_write_slave(port, reg, w_data, sizeof(w_data)); +} + +esp_err_t pca9555_set_config(i2c_port_t port, uint8_t config_value, int high_port) { + return pca9555_write_single(port, REG_CONFIG_PORT0 + high_port, config_value); +} + +esp_err_t pca9555_set_inversion(i2c_port_t port, uint8_t config_value, int high_port) { + return pca9555_write_single(port, REG_INVERT_PORT0 + high_port, config_value); +} + +esp_err_t pca9555_set_value(i2c_port_t port, uint8_t config_value, int high_port) { + return pca9555_write_single(port, REG_OUTPUT_PORT0 + high_port, config_value); +} + +uint8_t pca9555_read_input(i2c_port_t i2c_port, int high_port) { + esp_err_t err; + uint8_t r_data[1]; + + err = i2c_master_read_slave(i2c_port, r_data, 1, REG_INPUT_PORT0 + high_port); + if (err != ESP_OK) { + ESP_LOGE("PCA9555", "%s failed", __func__); + return 0; + } + + return r_data[0]; +} diff --git a/lib/libesp32_eink/epdiy/src/board/pca9555.h b/lib/libesp32_eink/epdiy/src/board/pca9555.h new file mode 100644 index 000000000..8f31b031f --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/pca9555.h @@ -0,0 +1,35 @@ +#ifndef PCA9555_H +#define PCA9555_H + +#include +#include + +#define PCA_PIN_P00 0x0001 +#define PCA_PIN_P01 0x0002 +#define PCA_PIN_P02 0x0004 +#define PCA_PIN_P03 0x0008 +#define PCA_PIN_P04 0x0010 +#define PCA_PIN_P05 0x0020 +#define PCA_PIN_P06 0x0040 +#define PCA_PIN_P07 0x0080 +#define PCA_PIN_PC10 0x0100 +#define PCA_PIN_PC11 0x0200 +#define PCA_PIN_PC12 0x0400 +#define PCA_PIN_PC13 0x0800 +#define PCA_PIN_PC14 0x1000 +#define PCA_PIN_PC15 0x2000 +#define PCA_PIN_PC16 0x4000 +#define PCA_PIN_PC17 0x8000 +#define PCA_PIN_P_ALL 0x00FF +#define PCA_PIN_PC_ALL 0xFF00 +#define PCA_PIN_ALL 0xFFFF +#define PCA_PIN_NULL 0x0000 + +static const int EPDIY_PCA9555_ADDR = 0x20; + +uint8_t pca9555_read_input(i2c_port_t port, int high_port); +esp_err_t pca9555_set_value(i2c_port_t port, uint8_t config_value, int high_port); +esp_err_t pca9555_set_inversion(i2c_port_t port, uint8_t config_value, int high_port); +esp_err_t pca9555_set_config(i2c_port_t port, uint8_t config_value, int high_port); + +#endif // PCA9555_H diff --git a/lib/libesp32_eink/epdiy/src/board/tps65185.c b/lib/libesp32_eink/epdiy/src/board/tps65185.c new file mode 100644 index 000000000..ef5cb3dac --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/tps65185.c @@ -0,0 +1,128 @@ + +#include "tps65185.h" +#include "pca9555.h" +#include "epd_board.h" +#include "esp_err.h" +#include "esp_log.h" + +#include +#include + +static const int EPDIY_TPS_ADDR = 0x68; + +static uint8_t i2c_master_read_slave(i2c_port_t i2c_num, int reg) { + uint8_t r_data[1]; + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (EPDIY_TPS_ADDR << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg, true); + i2c_master_stop(cmd); + + ESP_ERROR_CHECK(i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS)); + i2c_cmd_link_delete(cmd); + + cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (EPDIY_TPS_ADDR << 1) | I2C_MASTER_READ, true); + /* + if (size > 1) { + i2c_master_read(cmd, data_rd, size - 1, I2C_MASTER_ACK); + } + */ + i2c_master_read_byte(cmd, r_data, I2C_MASTER_NACK); + i2c_master_stop(cmd); + + ESP_ERROR_CHECK(i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS)); + i2c_cmd_link_delete(cmd); + + return r_data[0]; +} + +static esp_err_t i2c_master_write_slave( + i2c_port_t i2c_num, uint8_t ctrl, uint8_t* data_wr, size_t size +) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (EPDIY_TPS_ADDR << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, ctrl, true); + + i2c_master_write(cmd, data_wr, size, true); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS); + i2c_cmd_link_delete(cmd); + return ret; +} + +esp_err_t tps_write_register(i2c_port_t port, int reg, uint8_t value) { + uint8_t w_data[1]; + esp_err_t err; + + w_data[0] = value; + + err = i2c_master_write_slave(port, reg, w_data, 1); + return err; +} + +uint8_t tps_read_register(i2c_port_t i2c_num, int reg) { + return i2c_master_read_slave(i2c_num, reg); +} + +void tps_set_vcom(i2c_port_t i2c_num, unsigned vcom_mV) { + unsigned val = vcom_mV / 10; + ESP_ERROR_CHECK(tps_write_register(i2c_num, 4, (val & 0x100) >> 8)); + ESP_ERROR_CHECK(tps_write_register(i2c_num, 3, val & 0xFF)); +} + +int8_t tps_read_thermistor(i2c_port_t i2c_num) { + tps_write_register(i2c_num, TPS_REG_TMST1, 0x80); + int tries = 0; + while (true) { + uint8_t val = tps_read_register(i2c_num, TPS_REG_TMST1); + // temperature conversion done + if (val & 0x20) { + break; + } + tries++; + + if (tries >= 100) { + ESP_LOGE("epdiy", "thermistor read timeout!"); + break; + } + } + return (int8_t)tps_read_register(i2c_num, TPS_REG_TMST_VALUE); +} + +void tps_vcom_kickback() { + printf("VCOM Kickback test\n"); + // pull the WAKEUP pin and the PWRUP pin high to enable all output rails. + epd_current_board()->measure_vcom(epd_ctrl_state()); + // set the HiZ bit in the VCOM2 register (BIT 5) 0x20 + // this puts the VCOM pin in a high-impedance state. + // bit 3 & 4 Number of acquisitions that is averaged to a single kick-back V. measurement + tps_write_register(I2C_NUM_0, 4, 0x38); + vTaskDelay(1); + + uint8_t int1reg = tps_read_register(I2C_NUM_0, TPS_REG_INT1); + uint8_t vcomreg = tps_read_register(I2C_NUM_0, TPS_REG_VCOM2); +} + +void tps_vcom_kickback_start() { + uint8_t int1reg = tps_read_register(I2C_NUM_0, TPS_REG_INT1); + // set the ACQ bit in the VCOM2 register to 1 (BIT 7) + tps_write_register(I2C_NUM_0, TPS_REG_VCOM2, 0xA0); +} + +unsigned tps_vcom_kickback_rdy() { + uint8_t int1reg = tps_read_register(I2C_NUM_0, TPS_REG_INT1); + + if (int1reg == 0x02) { + uint8_t lsb = tps_read_register(I2C_NUM_0, 3); + uint8_t msb = tps_read_register(I2C_NUM_0, 4); + int u16Value = (lsb | (msb << 8)) & 0x1ff; + ESP_LOGI("vcom", "raw value:%d temperature:%d C", u16Value, tps_read_thermistor(I2C_NUM_0)); + return u16Value * 10; + } else { + return 0; + } +} \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/board/tps65185.h b/lib/libesp32_eink/epdiy/src/board/tps65185.h new file mode 100644 index 000000000..96ba1d35f --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board/tps65185.h @@ -0,0 +1,56 @@ +#ifndef TPS65185_H +#define TPS65185_H + +#include + +#define TPS_REG_TMST_VALUE 0x00 +#define TPS_REG_ENABLE 0x01 +#define TPS_REG_VADJ 0x02 +#define TPS_REG_VCOM1 0x03 +#define TPS_REG_VCOM2 0x04 +#define TPS_REG_INT_EN1 0x05 +#define TPS_REG_INT_EN2 0x06 +#define TPS_REG_INT1 0x07 +#define TPS_REG_INT2 0x08 +#define TPS_REG_UPSEQ0 0x09 +#define TPS_REG_UPSEQ1 0x0A +#define TPS_REG_DWNSEQ0 0x0B +#define TPS_REG_DWNSEQ1 0x0C +#define TPS_REG_TMST1 0x0D +#define TPS_REG_TMST2 0x0E +#define TPS_REG_PG 0x0F +#define TPS_REG_REVID 0x10 + +esp_err_t tps_write_register(i2c_port_t port, int reg, uint8_t value); +uint8_t tps_read_register(i2c_port_t i2c_num, int reg); + +/** + * Sets the VCOM voltage in positive milivolts: 1600 -> -1.6V + */ +void tps_set_vcom(i2c_port_t i2c_num, unsigned vcom_mV); + +/** + * @brief Please read datasheet section 8.3.7.1 Kick-Back Voltage Measurement + * 1 Device enters ACTIVE mode + * 2 All power rails are up except VCOM + * VCOM pin is in HiZ state + */ +void tps_vcom_kickback(); + +/** + * @brief start VCOM kick-back voltage measurements + */ +void tps_vcom_kickback_start(); + +/** + * VCOM kick-back ACQC (Acquisition Complete) bit in the INT1 register is set + * @return unsigned: 0 is not read + */ +unsigned tps_vcom_kickback_rdy(); + +/** + * Read the temperature via the on-board thermistor. + */ +int8_t tps_read_thermistor(i2c_port_t i2c_num); + +#endif // TPS65185_H diff --git a/lib/libesp32_eink/epdiy/src/board_specific.c b/lib/libesp32_eink/epdiy/src/board_specific.c new file mode 100644 index 000000000..6bea72098 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/board_specific.c @@ -0,0 +1,5 @@ +#include "epd_board_specific.h" + +void epd_powerdown() { + epd_powerdown_lilygo_t5_47(); +} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/builtin_waveforms.c b/lib/libesp32_eink/epdiy/src/builtin_waveforms.c old mode 100755 new mode 100644 similarity index 56% rename from lib/libesp32_eink/epdiy/src/epd_driver/builtin_waveforms.c rename to lib/libesp32_eink/epdiy/src/builtin_waveforms.c index 5d85cd8f1..ba4ff8c19 --- a/lib/libesp32_eink/epdiy/src/epd_driver/builtin_waveforms.c +++ b/lib/libesp32_eink/epdiy/src/builtin_waveforms.c @@ -1,10 +1,15 @@ -#include "epd_driver.h" +#include "epdiy.h" -#include "waveforms/ED047TC2.h" #include "waveforms/epdiy_ED047TC1.h" + +// Note: Alternative Waveform added by Lilygo on Oct 2021, size: 266 Kb (ED047TC1 is 37 Kb, 7 times +// smaller) +#include "waveforms/epdiy_ED047TC2.h" + #include "waveforms/epdiy_ED060SC4.h" -#include "waveforms/epdiy_ED060XC3.h" #include "waveforms/epdiy_ED060SCT.h" +#include "waveforms/epdiy_ED060XC3.h" #include "waveforms/epdiy_ED097OC4.h" #include "waveforms/epdiy_ED097TC2.h" #include "waveforms/epdiy_ED133UT2.h" +#include "waveforms/epdiy_NULL.h" \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/diff.S b/lib/libesp32_eink/epdiy/src/diff.S new file mode 100644 index 000000000..1210049db --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/diff.S @@ -0,0 +1,159 @@ +#include +#include +#include "sdkconfig.h" + +#ifdef CONFIG_IDF_TARGET_ESP32S3 + +.text +.align 4 +.global epd_interlace_4bpp_line_VE +.type epd_interlace_4bpp_line_VE,@function + +// // CRASH AND BURN for debugging +// EE.MOVI.32.A q3, a2, 0 +// EE.MOVI.32.A q3, a3, 1 +// EE.MOVI.32.A q3, a4, 2 +// EE.MOVI.32.A q3, a5, 3 +// l8ui a10, a10, 0 + +// bool interlace_line( +// const uint8_t *to, +// const uint8_t *from, +// uint8_t *col_dirtyness; +// uint8_t *interlaced, +// int fb_width +// ) +epd_interlace_4bpp_line_VE: +// to - a2 +// from - a3 +// interlaced - a4 +// col_dirtyness - a5 +// fb_width - a6 + + entry a1, 32 + + // divide by 32 for loop count + srli a11, a6, 5 + + movi.n a10, 0xF0F0F0F0; + EE.MOVI.32.Q q6,a10,0 + EE.MOVI.32.Q q6,a10,1 + EE.MOVI.32.Q q6,a10,2 + EE.MOVI.32.Q q6,a10,3 + + movi.n a10, 0x0F0F0F0F + EE.MOVI.32.Q q7,a10,0 + EE.MOVI.32.Q q7,a10,1 + EE.MOVI.32.Q q7,a10,2 + EE.MOVI.32.Q q7,a10,3 + + // put 4 into shift amount + movi.n a10, 4 + WSR.SAR a10 + + // "dirtyness" register + EE.ZERO.Q q5 + + // Instructions sometimes are in an unexpected order + // for best pipeline utilization + loopnez a11, .loop_end_difference + + EE.VLD.128.IP q0, a2, 16 + EE.VLD.128.IP q1, a3, 16 + + // load column dirtyness + EE.VLD.128.IP q3, a5, 0 + + // update dirtyness + EE.XORQ q4, q1, q0 + + // line dirtyness accumulator + EE.ORQ q5, q5, q4 + // column dirtyness + EE.ORQ q3, q3, q4 + + // store column dirtyness + EE.VST.128.IP q3, a5, 16 + + // mask out every second value + EE.ANDQ q2, q0, q7 + EE.ANDQ q0, q0, q6 + EE.ANDQ q3, q1, q7 + EE.ANDQ q1, q1, q6 + + // shift vectors to align + EE.VSL.32 q2, q2 + EE.VSR.32 q1, q1 + + // the right shift sign-extends, + // so we make sure the resulting shift is logical by masking again + EE.ANDQ q1, q1, q7 + + // Combine "from" and "to" nibble + EE.ORQ q2, q2, q3 + EE.ORQ q0, q0, q1 + + // Zip masked out values together + EE.VZIP.8 q2, q0 + + // store interlaced buffer data + EE.VST.128.IP q2, a4, 16 + EE.VST.128.IP q0, a4, 16 + +.loop_end_difference: + + EE.MOVI.32.A q5, a2, 0 + EE.MOVI.32.A q5, a3, 1 + EE.MOVI.32.A q5, a4, 2 + EE.MOVI.32.A q5, a5, 3 + or a2, a2, a3 + or a2, a2, a4 + or a2, a2, a5 + + //movi.n a2, 1 // return "true" + + // CRASH AND BURN for debugging + //EE.MOVI.32.A q5, a2, 0 + //EE.MOVI.32.A q5, a3, 1 + //EE.MOVI.32.A q5, a4, 2 + //EE.MOVI.32.A q5, a5, 3 + //movi.n a10, 0 + //l8ui a10, a10, 0 + + retw.n + + +.global epd_apply_line_mask_VE +.type epd_apply_line_mask_VE,@function + +// void epd_apply_line_mask_VE( +// uint8_t *line, +// const uint8_t *mask, +// int mask_len +// ) +epd_apply_line_mask_VE: +// line - a2 +// mask - a3 +// mask_len - a4 + + entry a1, 32 + + // divide by 16 for loop count + srli a4, a4, 4 + + // Instructions sometimes are in an unexpected order + // for best pipeline utilization + loopnez a4, .loop_end_mask + + EE.VLD.128.IP q0, a2, 0 + EE.VLD.128.IP q1, a3, 16 + + EE.ANDQ q0, q0, q1 + + EE.VST.128.IP q0, a2, 16 + +.loop_end_mask: + + retw.n + +#endif \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/displays.c b/lib/libesp32_eink/epdiy/src/displays.c new file mode 100644 index 000000000..394761b41 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/displays.c @@ -0,0 +1,83 @@ +#include "epd_display.h" + +const EpdDisplay_t ED060SCT = { + .width = 800, + .height = 600, + .bus_width = 8, + .bus_speed = 20, + .default_waveform = &epdiy_ED060SCT, + .display_type = DISPLAY_TYPE_GENERIC, +}; + +const EpdDisplay_t ED060XC3 = { + .width = 1024, + .height = 768, + .bus_width = 8, + .bus_speed = 20, + .default_waveform = &epdiy_ED060XC3, + .display_type = DISPLAY_TYPE_GENERIC, +}; + +const EpdDisplay_t ED097OC4 = { + .width = 1200, + .height = 825, + .bus_width = 8, + .bus_speed = 15, + .default_waveform = &epdiy_ED097OC4, + .display_type = DISPLAY_TYPE_GENERIC, +}; + +const EpdDisplay_t ED097TC2 = { + .width = 1200, + .height = 825, + .bus_width = 8, + .bus_speed = 22, + .default_waveform = &epdiy_ED097TC2, + .display_type = DISPLAY_TYPE_ED097TC2, +}; + +const EpdDisplay_t ED133UT2 = { + .width = 1600, + .height = 1200, + .bus_width = 8, + .bus_speed = 20, + .default_waveform = &epdiy_ED097TC2, + .display_type = DISPLAY_TYPE_ED097TC2, +}; + +const EpdDisplay_t ED047TC1 = { + .width = 960, + .height = 540, + .bus_width = 8, + .bus_speed = 20, + .default_waveform = &epdiy_ED047TC1, + .display_type = DISPLAY_TYPE_GENERIC, +}; + +const EpdDisplay_t ED047TC2 = { + .width = 960, + .height = 540, + .bus_width = 8, + .bus_speed = 20, + .default_waveform = &epdiy_ED047TC2, + .display_type = DISPLAY_TYPE_GENERIC, +}; + +const EpdDisplay_t ED078KC1 = { + .width = 1872, + .height = 1404, + .bus_width = 16, + .bus_speed = 11, + .default_waveform = &epdiy_ED047TC2, + .display_type = DISPLAY_TYPE_GENERIC, +}; + +// Attention is by default horizontal rows mirrored +const EpdDisplay_t ED052TC4 = { + .width = 1280, + .height = 720, + .bus_width = 8, + .bus_speed = 22, + .default_waveform = &epdiy_ED097TC2, + .display_type = DISPLAY_TYPE_ED097TC2, +}; \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/epd4in7.cpp b/lib/libesp32_eink/epdiy/src/epd4in7.cpp index 252abfde5..5f85bc438 100644 --- a/lib/libesp32_eink/epdiy/src/epd4in7.cpp +++ b/lib/libesp32_eink/epdiy/src/epd4in7.cpp @@ -37,7 +37,7 @@ #include #include #include -#include "epd_driver.h" +//#include "epd_driver.h" #include "epd_highlevel.h" #define WAVEFORM EPD_BUILTIN_WAVEFORM @@ -58,8 +58,8 @@ Epd47::Epd47(int16_t dwidth, int16_t dheight) : Renderer(dwidth, dheight) { disp_bpp = 4; } -int32_t Epd47::Init(void) { - epd_init(EPD_LUT_1K); +int Epd47::Init(void) { + epd_init(&epd_board_lilygo_t5_47, &ED097TC2, EPD_LUT_1K); hl = epd_hl_init(WAVEFORM); epd47_buffer = epd_hl_get_framebuffer(&hl); framebuffer = epd47_buffer; diff --git a/lib/libesp32_eink/epdiy/src/epd4in7.cppZone.Identifier b/lib/libesp32_eink/epdiy/src/epd4in7.cppZone.Identifier new file mode 100644 index 000000000..e69de29bb diff --git a/lib/libesp32_eink/epdiy/src/epd4in7.hZone.Identifier b/lib/libesp32_eink/epdiy/src/epd4in7.hZone.Identifier new file mode 100644 index 000000000..e69de29bb diff --git a/lib/libesp32_eink/epdiy/src/epd_board.h b/lib/libesp32_eink/epdiy/src/epd_board.h new file mode 100644 index 000000000..c5b1d29fd --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/epd_board.h @@ -0,0 +1,133 @@ +/** + * @file "epd_board.h" + * @brief Board-definitions provided by epdiy. + */ + +#pragma once + +#include +#include + +#include +#include + +/** + * State of display control pins. + */ +typedef struct { + bool ep_latch_enable : 1; + bool ep_output_enable : 1; + bool ep_sth : 1; + bool ep_mode : 1; + bool ep_stv : 1; +} epd_ctrl_state_t; + +/** + * Operations available on an epdiy board. + */ +typedef struct { + /** + * Initialize the board. + */ + void (*init)(uint32_t epd_row_width); + /** + * Clean up resources and peripherals used by the board. + */ + void (*deinit)(void); + /** + * Set display line state + */ + void (*set_ctrl)(epd_ctrl_state_t*, const epd_ctrl_state_t* const); + /** + * Enable power to the display. + */ + void (*poweron)(epd_ctrl_state_t*); + + /** + * Measure VCOM kick-back. Only in v6 & v7 boards! + */ + void (*measure_vcom)(epd_ctrl_state_t* state); + + /** + * Disable power to the display. + */ + void (*poweroff)(epd_ctrl_state_t*); + + /** + * Set the display common voltage if supported. + * + * Voltage is set as absolute value in millivolts. + * Although VCOM is negative, this function takes a positive (absolute) value. + */ + void (*set_vcom)(int); + + /** + * Get the current temperature if supported by the board. + */ + float (*get_temperature)(void); + + /** + * Set GPIO direction of the broken-out GPIO extender port, + * if available. + * Setting `make_input` to `1` corresponds to input, `0` corresponds to output. + */ + esp_err_t (*gpio_set_direction)(int pin, bool make_input); + + /** + * Get the input level of a GPIO extender pin, if available. + */ + bool (*gpio_read)(int pin); + + /** + * Set the output level of a GPIO extender, if available. + */ + esp_err_t (*gpio_write)(int pin, bool value); +} EpdBoardDefinition; + +/** + * Get the current board. + */ +const EpdBoardDefinition* epd_current_board(); + +/** + * Set the board hardware definition. This must be called before epd_init() + * + * The implementation of this method is in board/epd_board.c. + **/ +void epd_set_board(const EpdBoardDefinition* board); + +/** + * Get the board's current control register state. + */ +epd_ctrl_state_t* epd_ctrl_state(); + +/** + * Set the display mode pin. + */ +void epd_set_mode(bool state); + +/** + * Initialize the control register + */ +void epd_control_reg_init(); + +/** + * Put the control register into the state of lowest power consumption. + */ +void epd_control_reg_deinit(); + +// Built in board definitions +extern const EpdBoardDefinition epd_board_lilygo_t5_47; +extern const EpdBoardDefinition epd_board_lilygo_t5_47_touch; +extern const EpdBoardDefinition lilygo_board_s3; +extern const EpdBoardDefinition epd_board_v2_v3; +extern const EpdBoardDefinition epd_board_v4; +extern const EpdBoardDefinition epd_board_v5; +extern const EpdBoardDefinition epd_board_v6; +extern const EpdBoardDefinition epd_board_v7; +extern const EpdBoardDefinition epd_board_v7_raw; + +/** + * Helper for short, precise delays. + */ +void epd_busy_delay(uint32_t cycles); diff --git a/lib/libesp32_eink/epdiy/src/epd_board_specific.h b/lib/libesp32_eink/epdiy/src/epd_board_specific.h new file mode 100644 index 000000000..abb0138f8 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/epd_board_specific.h @@ -0,0 +1,32 @@ +/** + * @file "epd_board_specific.h" + * @brief Board-specific functions that are only conditionally defined. + */ + +#pragma once + +#include + +/** This is a Lilygo47 specific function + + This is a work around a hardware issue with the Lilygo47 epd_poweroff() turns off the epaper + completely however the hardware of the Lilygo47 is different than the official boards. Which means + that on the Lilygo47 this disables power to the touchscreen. + + This is a workaround to allow to disable display power but not the touch screen. + On the Lilygo the epd power flag was re-purposed as power enable + for everything. This is a hardware thing. + \warning This workaround may still leave power on to epd and as such may cause other problems such + as grey screen. + + Please use epd_poweroff() and epd_deinit() whenever you sleep the system. + The following code can be used to sleep the lilygo and power down the peripherals and wake the + unit on touch. However is should be noted that the touch controller is not powered and as such the + touch coordinates will not be captured. Arduino specific code: \code{.c} epd_poweroff(); + epd_deinit(); + esp_sleep_enable_ext1_wakeup(GPIO_SEL_13, ESP_EXT1_WAKEUP_ANY_HIGH); + esp_deep_sleep_start(); + \endcode +*/ +void epd_powerdown_lilygo_t5_47(); +void epd_powerdown() __attribute__((deprecated)); diff --git a/lib/libesp32_eink/epdiy/src/epd_display.h b/lib/libesp32_eink/epdiy/src/epd_display.h new file mode 100644 index 000000000..c22e58735 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/epd_display.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include "epd_internals.h" + +/** + * Display type as "compatibility classes", + * Grouping displays by workarounds needed. + */ +enum EpdDisplayType { + /// A generic EPD, assume default config. + DISPLAY_TYPE_GENERIC, + /// Fast display where we can get away with low hold times. + DISPLAY_TYPE_ED097TC2, +}; + +typedef struct { + /// Width of the display in pixels. + int width; + /// Height of the display in pixels. + int height; + + /// Width of the data bus in bits. + uint8_t bus_width; + /// Speed of the data bus in MHz, if configurable. + /// (Only used by the LCD based renderer in V7+) + int bus_speed; + + /// Default waveform to use. + const EpdWaveform* default_waveform; + /// Display type + enum EpdDisplayType display_type; +} EpdDisplay_t; + +extern const EpdDisplay_t ED060SCT; +extern const EpdDisplay_t ED060XC3; +extern const EpdDisplay_t ED097OC4; +extern const EpdDisplay_t ED097TC2; +extern const EpdDisplay_t ED133UT2; +extern const EpdDisplay_t ED047TC1; +extern const EpdDisplay_t ED047TC2; +extern const EpdDisplay_t ED078KC1; +extern const EpdDisplay_t ED052TC4; \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/epd_driver.h b/lib/libesp32_eink/epdiy/src/epd_driver.h deleted file mode 100755 index 2635d0712..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// This file is only used in the Arduino IDE -// and just includes the IDF component header. -#include "epd_driver/include/epd_driver.h" diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/CMakeLists.txt b/lib/libesp32_eink/epdiy/src/epd_driver/CMakeLists.txt deleted file mode 100755 index 9df188ad8..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ - -set(app_sources "epd_driver.c" - "render.c" - "display_ops.c" - "font.c" - "lut.c" - "builtin_waveforms.c" - "i2s_data_bus.c" - "rmt_pulse.c" - "highlevel.c" - "epd_temperature.c") - - -idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "include" REQUIRES esp_adc_cal) - -set_source_files_properties("lut.c" PROPERTIES COMPILE_OPTIONS -mno-fix-esp32-psram-cache-issue) diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/Kconfig b/lib/libesp32_eink/epdiy/src/epd_driver/Kconfig deleted file mode 100755 index e6c32f3e6..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/Kconfig +++ /dev/null @@ -1,52 +0,0 @@ -menu "E-Paper Driver" - choice EPD_DRIVER_DISPLAY_TYPE - prompt "Display Type" - default EPD_DISPLAY_TYPE_ED097OC4 - help - This option sets the display type to drive. - - config EPD_DISPLAY_TYPE_ED097OC4 - bool "ED097OC4" - - config EPD_DISPLAY_TYPE_ED060SC4 - bool "ED060SC4" - - config EPD_DISPLAY_TYPE_ED060XC3 - bool "ED060XC3" - - config EPD_DISPLAY_TYPE_ED060SCT - bool "ED060SCT" - - config EPD_DISPLAY_TYPE_ED097TC2 - bool "ED097TC2" - - config EPD_DISPLAY_TYPE_ED133UT2 - bool "ED133UT2" - - config EPD_DISPLAY_TYPE_ED047TC1 - bool "ED047TC1 (LILYGO 4.7 inch)" - - config EPD_DISPLAY_TYPE_ED097OC4_LQ - bool "ED097OC4 Low Quality" - endchoice - - - choice EPD_DRIVER_BOARD_REVISION - prompt "Board / Board Revision" - default EPD_BOARD_REVISION_V2_V3 - help - The board revision to compile for. - - config EPD_BOARD_REVISION_LILYGO_T5_47 - bool "LILYGO T5-4.7 inch e-paper" - - config EPD_BOARD_REVISION_V2_V3 - bool "epdiy v2 / v3" - - config EPD_BOARD_REVISION_V4 - bool "epdiy v4" - - config EPD_BOARD_REVISION_V5 - bool "epdiy v5" - endchoice -endmenu diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/LICENSE b/lib/libesp32_eink/epdiy/src/epd_driver/LICENSE deleted file mode 100755 index f288702d2..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v2.h b/lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v2.h deleted file mode 100755 index 6f300e21e..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v2.h +++ /dev/null @@ -1,84 +0,0 @@ -#include "display_ops.h" -#include - -typedef struct { - bool ep_latch_enable : 1; - bool power_disable : 1; - bool pos_power_enable : 1; - bool neg_power_enable : 1; - bool ep_stv : 1; - bool ep_scan_direction : 1; - bool ep_mode : 1; - bool ep_output_enable : 1; -} epd_config_register_t; - -static void config_reg_init(epd_config_register_t *cfg) { - cfg->ep_latch_enable = false; - cfg->power_disable = true; - cfg->pos_power_enable = false; - cfg->neg_power_enable = false; - cfg->ep_stv = true; - cfg->ep_scan_direction = true; - cfg->ep_mode = false; - cfg->ep_output_enable = false; -} - -inline static void IRAM_ATTR push_cfg_bit(bool bit); -void IRAM_ATTR busy_delay(uint32_t cycles); -inline static void fast_gpio_set_hi(gpio_num_t gpio_num); -inline static void fast_gpio_set_lo(gpio_num_t gpio_num); - -static void IRAM_ATTR push_cfg(const epd_config_register_t *cfg) { - fast_gpio_set_lo(CFG_STR); - - // push config bits in reverse order - push_cfg_bit(cfg->ep_output_enable); - push_cfg_bit(cfg->ep_mode); - push_cfg_bit(cfg->ep_scan_direction); - push_cfg_bit(cfg->ep_stv); - - push_cfg_bit(cfg->neg_power_enable); - push_cfg_bit(cfg->pos_power_enable); - push_cfg_bit(cfg->power_disable); - push_cfg_bit(cfg->ep_latch_enable); - - fast_gpio_set_hi(CFG_STR); -} - -static void cfg_poweron(epd_config_register_t *cfg) { -#if defined(CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47) - // This was re-purposed as power enable. - cfg->ep_scan_direction = true; -#endif - // POWERON - cfg->power_disable = false; - push_cfg(cfg); - busy_delay(100 * 240); - cfg->neg_power_enable = true; - push_cfg(cfg); - busy_delay(500 * 240); - cfg->pos_power_enable = true; - push_cfg(cfg); - busy_delay(100 * 240); - cfg->ep_stv = true; - push_cfg(cfg); - fast_gpio_set_hi(STH); - // END POWERON -} - -static void cfg_poweroff(epd_config_register_t *cfg) { -#if defined(CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47) - // This was re-purposed as power enable. - cfg->ep_scan_direction = false; -#endif - // POWEROFF - cfg->pos_power_enable = false; - push_cfg(cfg); - busy_delay(10 * 240); - cfg->neg_power_enable = false; - push_cfg(cfg); - busy_delay(100 * 240); - cfg->power_disable = true; - push_cfg(cfg); - // END POWEROFF -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v4.h b/lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v4.h deleted file mode 100755 index b4848e323..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/config_reg_v4.h +++ /dev/null @@ -1,108 +0,0 @@ -#include "display_ops.h" - -typedef struct { -#if defined(CONFIG_EPD_BOARD_REVISION_V5) - bool power_enable : 1; -#else - bool power_disable : 1; -#endif - bool power_enable_vpos : 1; - bool power_enable_vneg : 1; - bool power_enable_gl : 1; - bool ep_stv : 1; - bool power_enable_gh : 1; - bool ep_mode : 1; - bool ep_output_enable : 1; -} epd_config_register_t; - -static void config_reg_init(epd_config_register_t *cfg) { -#if defined(CONFIG_EPD_BOARD_REVISION_V5) - cfg->power_enable = false; -#else - cfg->power_disable = true; -#endif - cfg->power_enable_vpos = false; - cfg->power_enable_vneg = false; - cfg->power_enable_gl = false; - cfg->ep_stv = true; - cfg->power_enable_gh = false; - cfg->ep_mode = false; - cfg->ep_output_enable = false; -} - -inline static void IRAM_ATTR push_cfg_bit(bool bit); -void IRAM_ATTR busy_delay(uint32_t cycles); -inline static void fast_gpio_set_hi(gpio_num_t gpio_num); -inline static void fast_gpio_set_lo(gpio_num_t gpio_num); - -static void IRAM_ATTR push_cfg(const epd_config_register_t *cfg) { - fast_gpio_set_lo(CFG_STR); - - // push config bits in reverse order - push_cfg_bit(cfg->ep_output_enable); - push_cfg_bit(cfg->ep_mode); - push_cfg_bit(cfg->power_enable_gh); - push_cfg_bit(cfg->ep_stv); - - push_cfg_bit(cfg->power_enable_gl); - push_cfg_bit(cfg->power_enable_vneg); - push_cfg_bit(cfg->power_enable_vpos); -#if defined(CONFIG_EPD_BOARD_REVISION_V5) - push_cfg_bit(cfg->power_enable); -#else - push_cfg_bit(cfg->power_disable); -#endif - - fast_gpio_set_hi(CFG_STR); - fast_gpio_set_lo(CFG_STR); -} - -static void cfg_poweron(epd_config_register_t *cfg) { - // POWERON -#if defined(CONFIG_EPD_BOARD_REVISION_V5) - cfg->power_enable = true; -#else - cfg->power_disable = false; -#endif - push_cfg(cfg); - busy_delay(100 * 240); - cfg->power_enable_gl = true; - push_cfg(cfg); - busy_delay(500 * 240); - cfg->power_enable_vneg = true; - push_cfg(cfg); - busy_delay(500 * 240); - cfg->power_enable_gh = true; - push_cfg(cfg); - busy_delay(500 * 240); - cfg->power_enable_vpos = true; - push_cfg(cfg); - busy_delay(100 * 240); - cfg->ep_stv = true; - push_cfg(cfg); - fast_gpio_set_hi(STH); - // END POWERON -} - -static void cfg_poweroff(epd_config_register_t *cfg) { - // POWEROFF - cfg->power_enable_gh = false; - cfg->power_enable_vpos = false; - push_cfg(cfg); - busy_delay(10 * 240); - cfg->power_enable_gl = false; - cfg->power_enable_vneg = false; - push_cfg(cfg); - busy_delay(100 * 240); - - cfg->ep_stv = false; - cfg->ep_output_enable = false; - cfg->ep_mode = false; -#if defined(CONFIG_EPD_BOARD_REVISION_V5) - cfg->power_enable = false; -#else - cfg->power_disable = true; -#endif - push_cfg(cfg); - // END POWEROFF -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/display_ops.c b/lib/libesp32_eink/epdiy/src/epd_driver/display_ops.c deleted file mode 100755 index abfef3a26..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/display_ops.c +++ /dev/null @@ -1,195 +0,0 @@ -#include "display_ops.h" -#include "esp_timer.h" -#include "esp_log.h" -#include "i2s_data_bus.h" -#include "rmt_pulse.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "xtensa/core-macros.h" - -#if defined(CONFIG_EPD_BOARD_REVISION_V2_V3) || defined(CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47) -#include "config_reg_v2.h" -#else -#if defined(CONFIG_EPD_BOARD_REVISION_V4) || defined(CONFIG_EPD_BOARD_REVISION_V5) -#include "config_reg_v4.h" -#else -#error "unknown revision" -#endif -#endif - -static epd_config_register_t config_reg; - -/* - * Write bits directly using the registers. - * Won't work for some pins (>= 32). - */ -inline static void fast_gpio_set_hi(gpio_num_t gpio_num) { - GPIO.out_w1ts = (1 << gpio_num); -} - -inline static void fast_gpio_set_lo(gpio_num_t gpio_num) { - GPIO.out_w1tc = (1 << gpio_num); -} - -void IRAM_ATTR busy_delay(uint32_t cycles) { - volatile unsigned long counts = XTHAL_GET_CCOUNT() + cycles; - while (XTHAL_GET_CCOUNT() < counts) { - }; -} - -inline static void IRAM_ATTR push_cfg_bit(bool bit) { - gpio_set_level(CFG_CLK, 0); - if (bit) { - gpio_set_level(CFG_DATA, 1); - } else { - gpio_set_level(CFG_DATA, 0); - } - gpio_set_level(CFG_CLK, 1); -} - -void epd_base_init(uint32_t epd_row_width) { - - config_reg_init(&config_reg); - - /* Power Control Output/Off */ - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_DATA], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_CLK], PIN_FUNC_GPIO); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_STR], PIN_FUNC_GPIO); - gpio_set_direction(CFG_DATA, GPIO_MODE_OUTPUT); - gpio_set_direction(CFG_CLK, GPIO_MODE_OUTPUT); - gpio_set_direction(CFG_STR, GPIO_MODE_OUTPUT); - -#if defined(CONFIG_EPD_BOARD_REVISION_V4) || defined(CONFIG_EPD_BOARD_REVISION_V5) - // use latch pin as GPIO - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[V4_LATCH_ENABLE], PIN_FUNC_GPIO); - ESP_ERROR_CHECK(gpio_set_direction(V4_LATCH_ENABLE, GPIO_MODE_OUTPUT)); - gpio_set_level(V4_LATCH_ENABLE, 0); -#endif - fast_gpio_set_lo(CFG_STR); - - push_cfg(&config_reg); - - // Setup I2S - i2s_bus_config i2s_config; - // add an offset off dummy bytes to allow for enough timing headroom - i2s_config.epd_row_width = epd_row_width + 32; - i2s_config.clock = CKH; - i2s_config.start_pulse = STH; - i2s_config.data_0 = D0; - i2s_config.data_1 = D1; - i2s_config.data_2 = D2; - i2s_config.data_3 = D3; - i2s_config.data_4 = D4; - i2s_config.data_5 = D5; - i2s_config.data_6 = D6; - i2s_config.data_7 = D7; - - i2s_bus_init(&i2s_config); - - rmt_pulse_init(CKV); -} - -void epd_poweron() { cfg_poweron(&config_reg); } - -void epd_poweroff() { cfg_poweroff(&config_reg); } - -void epd_base_deinit(){ - epd_poweroff(); - i2s_deinit(); -} - -void epd_start_frame() { - while (i2s_is_busy() || rmt_busy()) { - }; - config_reg.ep_mode = true; - push_cfg(&config_reg); - - pulse_ckv_us(1, 1, true); - - // This is very timing-sensitive! - config_reg.ep_stv = false; - push_cfg(&config_reg); - //busy_delay(240); - pulse_ckv_us(100, 100, false); - config_reg.ep_stv = true; - push_cfg(&config_reg); - //pulse_ckv_us(0, 10, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - - config_reg.ep_output_enable = true; - push_cfg(&config_reg); -} - -static inline void latch_row() { -#if defined(CONFIG_EPD_BOARD_REVISION_V2_V3) || defined(CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47) - config_reg.ep_latch_enable = true; - push_cfg(&config_reg); - - config_reg.ep_latch_enable = false; - push_cfg(&config_reg); -#else -#if defined(CONFIG_EPD_BOARD_REVISION_V4) || defined(CONFIG_EPD_BOARD_REVISION_V5) - fast_gpio_set_hi(V4_LATCH_ENABLE); - fast_gpio_set_lo(V4_LATCH_ENABLE); -#else -#error "unknown revision" -#endif -#endif -} - -void IRAM_ATTR epd_skip() { -#if defined(CONFIG_EPD_DISPLAY_TYPE_ED097TC2) || \ - defined(CONFIG_EPD_DISPLAY_TYPE_ED133UT2) - pulse_ckv_ticks(5, 5, false); -#else - // According to the spec, the OC4 maximum CKV frequency is 200kHz. - pulse_ckv_ticks(45, 5, false); -#endif -} - -void IRAM_ATTR epd_output_row(uint32_t output_time_dus) { - - while (i2s_is_busy() || rmt_busy()) { - }; - - fast_gpio_set_hi(STH); - - latch_row(); - -#if defined(CONFIG_EPD_DISPLAY_TYPE_ED097TC2) || \ - defined(CONFIG_EPD_DISPLAY_TYPE_ED133UT2) - pulse_ckv_ticks(output_time_dus, 1, false); -#else - pulse_ckv_ticks(output_time_dus, 50, false); -#endif - - i2s_start_line_output(); - i2s_switch_buffer(); -} - -void epd_end_frame() { - config_reg.ep_stv = false; - push_cfg(&config_reg); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - config_reg.ep_mode = false; - push_cfg(&config_reg); - pulse_ckv_us(0, 10, true); - config_reg.ep_output_enable = false; - push_cfg(&config_reg); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); - pulse_ckv_us(1, 1, true); -} - -void IRAM_ATTR epd_switch_buffer() { i2s_switch_buffer(); } -uint8_t IRAM_ATTR *epd_get_current_buffer() { - return (uint8_t *)i2s_get_current_buffer(); -}; diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/display_ops.h b/lib/libesp32_eink/epdiy/src/epd_driver/display_ops.h deleted file mode 100755 index f60affa02..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/display_ops.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "driver/gpio.h" - -#define CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 - - -#if defined(CONFIG_EPD_BOARD_REVISION_V5) -#define D7 GPIO_NUM_23 -#define D6 GPIO_NUM_22 -#define D5 GPIO_NUM_21 -#define D4 GPIO_NUM_19 -#define D3 GPIO_NUM_18 -#define D2 GPIO_NUM_5 -#define D1 GPIO_NUM_4 -#define D0 GPIO_NUM_25 - - -/* Config Reggister Control */ -#define CFG_DATA GPIO_NUM_33 -#define CFG_CLK GPIO_NUM_32 -#define CFG_STR GPIO_NUM_0 - -/* Control Lines */ -#define CKV GPIO_NUM_26 -#define STH GPIO_NUM_27 - - -#define V4_LATCH_ENABLE GPIO_NUM_2 - -/* Edges */ -#define CKH GPIO_NUM_15 - -#else -#define D7 GPIO_NUM_22 -#define D6 GPIO_NUM_21 -#define D5 GPIO_NUM_27 -#define D4 GPIO_NUM_2 -#if defined(CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47) -#define D3 GPIO_NUM_19 -#else -#define D3 GPIO_NUM_0 -#endif -#define D2 GPIO_NUM_4 -#define D1 GPIO_NUM_32 -#define D0 GPIO_NUM_33 - -#define CFG_DATA GPIO_NUM_23 -#define CFG_CLK GPIO_NUM_18 -#if defined(CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47) -#define CFG_STR GPIO_NUM_0 -#else -#define CFG_STR GPIO_NUM_19 -#endif - -/* Control Lines */ -#define CKV GPIO_NUM_25 -#define STH GPIO_NUM_26 - -#define V4_LATCH_ENABLE GPIO_NUM_15 - -/* Edges */ -#define CKH GPIO_NUM_5 - -#endif - -void epd_base_init(uint32_t epd_row_width); -void epd_base_deinit(); -void epd_poweron(); -void epd_poweroff(); - -/** - * Start a draw cycle. - */ -void epd_start_frame(); - -/** - * End a draw cycle. - */ -void epd_end_frame(); - -/** - * Waits until all previously submitted data has been written. - * Then, the following operations are initiated: - * - * - Previously submitted data is latched to the output register. - * - The RMT peripheral is set up to pulse the vertical (gate) driver for - * `output_time_dus` / 10 microseconds. - * - The I2S peripheral starts transmission of the current buffer to - * the source driver. - * - The line buffers are switched. - * - * This sequence of operations allows for pipelining data preparation and - * transfer, reducing total refresh times. - */ -void IRAM_ATTR epd_output_row(uint32_t output_time_dus); - -/** Skip a row without writing to it. */ -void IRAM_ATTR epd_skip(); - -/** - * Get the currently writable line buffer. - */ -uint8_t IRAM_ATTR *epd_get_current_buffer(); - -/** - * Switches front and back line buffer. - * If the switched-to line buffer is currently in use, - * this function blocks until transmission is done. - */ -void IRAM_ATTR epd_switch_buffer(); diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/epd_driver.c b/lib/libesp32_eink/epdiy/src/epd_driver/epd_driver.c deleted file mode 100755 index 565b570d4..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/epd_driver.c +++ /dev/null @@ -1,344 +0,0 @@ -#include "epd_driver.h" -#include "epd_temperature.h" - -#include "esp_assert.h" -#include "esp_heap_caps.h" -#include "esp_log.h" -#include "esp_types.h" - - -#ifndef _swap_int -#define _swap_int(a, b) \ - { \ - int t = a; \ - a = b; \ - b = t; \ - } -#endif - - -EpdRect epd_full_screen() { - EpdRect area = {.x = 0, .y = 0, .width = EPD_WIDTH, .height = EPD_HEIGHT}; - return area; -} - -void epd_clear() { epd_clear_area(epd_full_screen()); } - -void epd_draw_hline(int x, int y, int length, uint8_t color, - uint8_t *framebuffer) { - for (int i = 0; i < length; i++) { - int xx = x + i; - epd_draw_pixel(xx, y, color, framebuffer); - } -} - -void epd_draw_vline(int x, int y, int length, uint8_t color, - uint8_t *framebuffer) { - for (int i = 0; i < length; i++) { - int yy = y + i; - epd_draw_pixel(x, yy, color, framebuffer); - } -} - -void epd_draw_pixel(int x, int y, uint8_t color, uint8_t *framebuffer) { - if (x < 0 || x >= EPD_WIDTH) { - return; - } - if (y < 0 || y >= EPD_HEIGHT) { - return; - } - uint8_t *buf_ptr = &framebuffer[y * EPD_WIDTH / 2 + x / 2]; - if (x % 2) { - *buf_ptr = (*buf_ptr & 0x0F) | (color & 0xF0); - } else { - *buf_ptr = (*buf_ptr & 0xF0) | (color >> 4); - } -} - -void epd_draw_circle(int x0, int y0, int r, uint8_t color, - uint8_t *framebuffer) { - int f = 1 - r; - int ddF_x = 1; - int ddF_y = -2 * r; - int x = 0; - int y = r; - - epd_draw_pixel(x0, y0 + r, color, framebuffer); - epd_draw_pixel(x0, y0 - r, color, framebuffer); - epd_draw_pixel(x0 + r, y0, color, framebuffer); - epd_draw_pixel(x0 - r, y0, color, framebuffer); - - while (x < y) { - if (f >= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - epd_draw_pixel(x0 + x, y0 + y, color, framebuffer); - epd_draw_pixel(x0 - x, y0 + y, color, framebuffer); - epd_draw_pixel(x0 + x, y0 - y, color, framebuffer); - epd_draw_pixel(x0 - x, y0 - y, color, framebuffer); - epd_draw_pixel(x0 + y, y0 + x, color, framebuffer); - epd_draw_pixel(x0 - y, y0 + x, color, framebuffer); - epd_draw_pixel(x0 + y, y0 - x, color, framebuffer); - epd_draw_pixel(x0 - y, y0 - x, color, framebuffer); - } -} - -void epd_fill_circle(int x0, int y0, int r, uint8_t color, - uint8_t *framebuffer) { - epd_draw_vline(x0, y0 - r, 2 * r + 1, color, framebuffer); - epd_fill_circle_helper(x0, y0, r, 3, 0, color, framebuffer); -} - -void epd_fill_circle_helper(int x0, int y0, int r, int corners, int delta, - uint8_t color, uint8_t *framebuffer) { - - int f = 1 - r; - int ddF_x = 1; - int ddF_y = -2 * r; - int x = 0; - int y = r; - int px = x; - int py = y; - - delta++; // Avoid some +1's in the loop - - while (x < y) { - if (f >= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - // These checks avoid double-drawing certain lines, important - // for the SSD1306 library which has an INVERT drawing mode. - if (x < (y + 1)) { - if (corners & 1) - epd_draw_vline(x0 + x, y0 - y, 2 * y + delta, color, framebuffer); - if (corners & 2) - epd_draw_vline(x0 - x, y0 - y, 2 * y + delta, color, framebuffer); - } - if (y != py) { - if (corners & 1) - epd_draw_vline(x0 + py, y0 - px, 2 * px + delta, color, framebuffer); - if (corners & 2) - epd_draw_vline(x0 - py, y0 - px, 2 * px + delta, color, framebuffer); - py = y; - } - px = x; - } -} - -void epd_draw_rect(EpdRect rect, uint8_t color, - uint8_t *framebuffer) { - - int x = rect.x; int y = rect.y; int w = rect.width; int h = rect.height; - epd_draw_hline(x, y, w, color, framebuffer); - epd_draw_hline(x, y + h - 1, w, color, framebuffer); - epd_draw_vline(x, y, h, color, framebuffer); - epd_draw_vline(x + w - 1, y, h, color, framebuffer); -} - -void epd_fill_rect(EpdRect rect, uint8_t color, uint8_t *framebuffer) { - - int x = rect.x; int y = rect.y; int w = rect.width; int h = rect.height; - for (int i = y; i < y + h; i++) { - epd_draw_hline(x, i, w, color, framebuffer); - } -} - -static void epd_write_line(int x0, int y0, int x1, int y1, uint8_t color, - uint8_t *framebuffer) { - int steep = abs(y1 - y0) > abs(x1 - x0); - if (steep) { - _swap_int(x0, y0); - _swap_int(x1, y1); - } - - if (x0 > x1) { - _swap_int(x0, x1); - _swap_int(y0, y1); - } - - int dx, dy; - dx = x1 - x0; - dy = abs(y1 - y0); - - int err = dx / 2; - int ystep; - - if (y0 < y1) { - ystep = 1; - } else { - ystep = -1; - } - - for (; x0 <= x1; x0++) { - if (steep) { - epd_draw_pixel(y0, x0, color, framebuffer); - } else { - epd_draw_pixel(x0, y0, color, framebuffer); - } - err -= dy; - if (err < 0) { - y0 += ystep; - err += dx; - } - } -} - -void epd_draw_line(int x0, int y0, int x1, int y1, uint8_t color, - uint8_t *framebuffer) { - // Update in subclasses if desired! - if (x0 == x1) { - if (y0 > y1) - _swap_int(y0, y1); - epd_draw_vline(x0, y0, y1 - y0 + 1, color, framebuffer); - } else if (y0 == y1) { - if (x0 > x1) - _swap_int(x0, x1); - epd_draw_hline(x0, y0, x1 - x0 + 1, color, framebuffer); - } else { - epd_write_line(x0, y0, x1, y1, color, framebuffer); - } -} - -void epd_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2, - uint8_t color, uint8_t *framebuffer) { - epd_draw_line(x0, y0, x1, y1, color, framebuffer); - epd_draw_line(x1, y1, x2, y2, color, framebuffer); - epd_draw_line(x2, y2, x0, y0, color, framebuffer); -} - -void epd_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2, - uint8_t color, uint8_t *framebuffer) { - - int a, b, y, last; - - // Sort coordinates by Y order (y2 >= y1 >= y0) - if (y0 > y1) { - _swap_int(y0, y1); - _swap_int(x0, x1); - } - if (y1 > y2) { - _swap_int(y2, y1); - _swap_int(x2, x1); - } - if (y0 > y1) { - _swap_int(y0, y1); - _swap_int(x0, x1); - } - - if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing - a = b = x0; - if (x1 < a) - a = x1; - else if (x1 > b) - b = x1; - if (x2 < a) - a = x2; - else if (x2 > b) - b = x2; - epd_draw_hline(a, y0, b - a + 1, color, framebuffer); - return; - } - - int dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0, - dx12 = x2 - x1, dy12 = y2 - y1; - int32_t sa = 0, sb = 0; - - // For upper part of triangle, find scanline crossings for segments - // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 - // is included here (and second loop will be skipped, avoiding a /0 - // error there), otherwise scanline y1 is skipped here and handled - // in the second loop...which also avoids a /0 error here if y0=y1 - // (flat-topped triangle). - if (y1 == y2) - last = y1; // Include y1 scanline - else - last = y1 - 1; // Skip it - - for (y = y0; y <= last; y++) { - a = x0 + sa / dy01; - b = x0 + sb / dy02; - sa += dx01; - sb += dx02; - /* longhand: - a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if (a > b) - _swap_int(a, b); - epd_draw_hline(a, y, b - a + 1, color, framebuffer); - } - - // For lower part of triangle, find scanline crossings for segments - // 0-2 and 1-2. This loop is skipped if y1=y2. - sa = (int32_t)dx12 * (y - y1); - sb = (int32_t)dx02 * (y - y0); - for (; y <= y2; y++) { - a = x1 + sa / dy12; - b = x0 + sb / dy02; - sa += dx12; - sb += dx02; - /* longhand: - a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if (a > b) - _swap_int(a, b); - epd_draw_hline(a, y, b - a + 1, color, framebuffer); - } -} - -void epd_copy_to_framebuffer(EpdRect image_area, const uint8_t *image_data, - uint8_t *framebuffer) { - - assert(framebuffer != NULL); - - for (uint32_t i = 0; i < image_area.width * image_area.height; i++) { - - uint32_t value_index = i; - // for images of uneven width, - // consume an additional nibble per row. - if (image_area.width % 2) { - value_index += i / image_area.width; - } - uint8_t val = (value_index % 2) ? (image_data[value_index / 2] & 0xF0) >> 4 - : image_data[value_index / 2] & 0x0F; - - int xx = image_area.x + i % image_area.width; - if (xx < 0 || xx >= EPD_WIDTH) { - continue; - } - int yy = image_area.y + i / image_area.width; - if (yy < 0 || yy >= EPD_HEIGHT) { - continue; - } - uint8_t *buf_ptr = &framebuffer[yy * EPD_WIDTH / 2 + xx / 2]; - if (xx % 2) { - *buf_ptr = (*buf_ptr & 0x0F) | (val << 4); - } else { - *buf_ptr = (*buf_ptr & 0xF0) | val; - } - } -} - -enum EpdDrawError epd_draw_image(EpdRect area, const uint8_t *data, const EpdWaveform *waveform) { - int temperature = epd_ambient_temperature(); - assert(waveform != NULL); - EpdRect no_crop = { - .x = 0, - .y = 0, - .width = 0, - .height = 0, - }; - return epd_draw_base(area, data, no_crop, EPD_MODE_DEFAULT, temperature, NULL, waveform); -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.c b/lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.c deleted file mode 100755 index fa9b03842..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "driver/adc.h" -#include "esp_adc_cal.h" -#include "esp_log.h" - -/// Use GPIO 35 -static const adc1_channel_t channel = ADC1_CHANNEL_7; -static esp_adc_cal_characteristics_t adc_chars; - -#define NUMBER_OF_SAMPLES 100 - -void epd_temperature_init() { - esp_adc_cal_value_t val_type = esp_adc_cal_characterize( - ADC_UNIT_1, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_12, 1100, &adc_chars); - if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { - ESP_LOGI("epd_temperature", "Characterized using Two Point Value\n"); - } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { - ESP_LOGI("esp_temperature", "Characterized using eFuse Vref\n"); - } else { - ESP_LOGI("esp_temperature", "Characterized using Default Vref\n"); - } - adc1_config_width(ADC_WIDTH_BIT_12); - adc1_config_channel_atten(channel, ADC_ATTEN_DB_6); -} - -float epd_ambient_temperature() { - uint32_t value = 0; - for (int i = 0; i < NUMBER_OF_SAMPLES; i++) { - value += adc1_get_raw(channel); - } - value /= NUMBER_OF_SAMPLES; - // voltage in mV - float voltage = esp_adc_cal_raw_to_voltage(value, &adc_chars); - return (voltage - 500.0) / 10.0; -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.h b/lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.h deleted file mode 100755 index ae615e2b1..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/epd_temperature.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -/** - * Initialize the ADC for temperature measurement. - */ -void epd_temperature_init(); - -/** - * Get the current ambient temperature in °C. - */ -float epd_ambient_temperature(); diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/font.c b/lib/libesp32_eink/epdiy/src/epd_driver/font.c deleted file mode 100755 index 07e8f58f8..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/font.c +++ /dev/null @@ -1,375 +0,0 @@ -#include "epd_driver.h" -#include "esp_assert.h" -#include "esp_heap_caps.h" -#include "esp_log.h" -#if ESP_IDF_VERSION < (4, 0, 0) || ARDUINO_ARCH_ESP32 -#include "rom/miniz.h" -#else -#include "esp32/rom/miniz.h" -#endif -#include -#include -#include - -typedef struct { - uint8_t mask; /* char data will be bitwise AND with this */ - uint8_t lead; /* start bytes of current char in utf-8 encoded character */ - uint32_t beg; /* beginning of codepoint range */ - uint32_t end; /* end of codepoint range */ - int bits_stored; /* the number of bits from the codepoint that fits in char */ -} utf_t; - -/* - * UTF-8 decode inspired from rosetta code - * https://rosettacode.org/wiki/UTF-8_encode_and_decode#C - */ -static utf_t *utf[] = { - /* mask lead beg end bits */ - [0] = &(utf_t){0b00111111, 0b10000000, 0, 0, 6}, - [1] = &(utf_t){0b01111111, 0b00000000, 0000, 0177, 7}, - [2] = &(utf_t){0b00011111, 0b11000000, 0200, 03777, 5}, - [3] = &(utf_t){0b00001111, 0b11100000, 04000, 0177777, 4}, - [4] = &(utf_t){0b00000111, 0b11110000, 0200000, 04177777, 3}, - &(utf_t){0}, -}; - -/** - * static decompressor object for compressed fonts. - */ -static tinfl_decompressor decomp; - -static inline int min(int x, int y) { return x < y ? x : y; } -static inline int max(int x, int y) { return x > y ? x : y; } - -static int utf8_len(const uint8_t ch) { - int len = 0; - for (utf_t **u = utf; *u; ++u) { - if ((ch & ~(*u)->mask) == (*u)->lead) { - break; - } - ++len; - } - if (len > 4) { /* Malformed leading byte */ - assert("invalid unicode."); - } - return len; -} - -static uint32_t next_cp(const uint8_t **string) { - if (**string == 0) { - return 0; - } - int bytes = utf8_len(**string); - const uint8_t *chr = *string; - *string += bytes; - int shift = utf[0]->bits_stored * (bytes - 1); - uint32_t codep = (*chr++ & utf[bytes]->mask) << shift; - - for (int i = 1; i < bytes; ++i, ++chr) { - shift -= utf[0]->bits_stored; - codep |= ((const uint8_t)*chr & utf[0]->mask) << shift; - } - - return codep; -} - -EpdFontProperties epd_font_properties_default() { - EpdFontProperties props = { - .fg_color = 0, .bg_color = 15, .fallback_glyph = 0, .flags = EPD_DRAW_ALIGN_LEFT}; - return props; -} - -const EpdGlyph* epd_get_glyph(const EpdFont *font, uint32_t code_point) { - const EpdUnicodeInterval *intervals = font->intervals; - for (int i = 0; i < font->interval_count; i++) { - const EpdUnicodeInterval *interval = &intervals[i]; - if (code_point >= interval->first && code_point <= interval->last) { - return &font->glyph[interval->offset + (code_point - interval->first)]; - } - if (code_point < interval->first) { - return NULL; - } - } - return NULL; -} - -static int uncompress(uint8_t *dest, uint32_t uncompressed_size, const uint8_t *source, uint32_t source_size) { - if (uncompressed_size == 0 || dest == NULL || source_size == 0 || source == NULL) { - return -1; - } - tinfl_init(&decomp); - - // we know everything will fit into the buffer. - tinfl_status decomp_status = tinfl_decompress(&decomp, source, &source_size, dest, dest, &uncompressed_size, TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - if (decomp_status != TINFL_STATUS_DONE) { - return decomp_status; - } - return 0; -} - -/*! - @brief Draw a single character to a pre-allocated buffer. -*/ -static enum EpdDrawError IRAM_ATTR draw_char(const EpdFont *font, uint8_t *buffer, - int *cursor_x, int cursor_y, uint16_t buf_width, - uint16_t buf_height, uint32_t cp, - const EpdFontProperties *props) { - - assert(props != NULL); - - const EpdGlyph *glyph = epd_get_glyph(font, cp); - if (!glyph) { - glyph = epd_get_glyph(font, props->fallback_glyph); - } - - if (!glyph) { - return EPD_DRAW_GLYPH_FALLBACK_FAILED; - } - - uint32_t offset = glyph->data_offset; - uint8_t width = glyph->width, height = glyph->height; - int left = glyph->left; - - int byte_width = (width / 2 + width % 2); - unsigned long bitmap_size = byte_width * height; - const uint8_t *bitmap = NULL; - if (font->compressed) { - uint8_t* tmp_bitmap = (uint8_t *)malloc(bitmap_size); - if (tmp_bitmap == NULL && bitmap_size) { - ESP_LOGE("font", "malloc failed."); - return EPD_DRAW_FAILED_ALLOC; - } - uncompress(tmp_bitmap, bitmap_size, &font->bitmap[offset], - glyph->compressed_size); - bitmap = tmp_bitmap; - } else { - bitmap = &font->bitmap[offset]; - } - - uint8_t color_lut[16]; - for (int c = 0; c < 16; c++) { - int color_difference = (int)props->fg_color - (int)props->bg_color; - color_lut[c] = max(0, min(15, props->bg_color + c * color_difference / 15)); - } - - for (int y = 0; y < height; y++) { - int yy = cursor_y - glyph->top + y; - if (yy < 0 || yy >= buf_height) { - continue; - } - int start_pos = *cursor_x + left; - bool byte_complete = start_pos % 2; - int x = max(0, -start_pos); - int max_x = min(start_pos + width, buf_width * 2); - for (int xx = start_pos; xx < max_x; xx++) { - uint32_t buf_pos = yy * buf_width + xx / 2; - uint8_t old = buffer[buf_pos]; - uint8_t bm = bitmap[y * byte_width + x / 2]; - if ((x & 1) == 0) { - bm = bm & 0xF; - } else { - bm = bm >> 4; - } - - if ((xx & 1) == 0) { - buffer[buf_pos] = (old & 0xF0) | color_lut[bm]; - } else { - buffer[buf_pos] = (old & 0x0F) | (color_lut[bm] << 4); - } - byte_complete = !byte_complete; - x++; - } - } - if (font->compressed) { - free((uint8_t*)bitmap); - } - *cursor_x += glyph->advance_x; - return EPD_DRAW_SUCCESS; -} - -/*! - * @brief Calculate the bounds of a character when drawn at (x, y), move the - * cursor (*x) forward, adjust the given bounds. - */ -static void get_char_bounds(const EpdFont *font, uint32_t cp, int *x, int *y, - int *minx, int *miny, int *maxx, int *maxy, - const EpdFontProperties *props) { - - assert(props != NULL); - - const EpdGlyph *glyph = epd_get_glyph(font, cp); - - if (!glyph) { - glyph = epd_get_glyph(font, props->fallback_glyph); - } - - if (!glyph) { - return; - } - - int x1 = *x + glyph->left, y1 = *y + glyph->top - glyph->height, - x2 = x1 + glyph->width, y2 = y1 + glyph->height; - - // background needs to be taken into account - if (props->flags & EPD_DRAW_BACKGROUND) { - *minx = min(*x, min(*minx, x1)); - *maxx = max(max(*x + glyph->advance_x, x2), *maxx); - *miny = min(*y + font->descender, min(*miny, y1)); - *maxy = max(*y + font->ascender, max(*maxy, y2)); - } else { - if (x1 < *minx) - *minx = x1; - if (y1 < *miny) - *miny = y1; - if (x2 > *maxx) - *maxx = x2; - if (y2 > *maxy) - *maxy = y2; - } - *x += glyph->advance_x; -} - -void epd_get_text_bounds(const EpdFont *font, const char *string, - const int *x, const int *y, - int *x1, int *y1, int *w, int *h, - const EpdFontProperties *properties) { - // FIXME: Does not respect alignment! - - assert(properties != NULL); - EpdFontProperties props = *properties; - - if (*string == '\0') { - *w = 0; - *h = 0; - *y1 = *y; - *x1 = *x; - return; - } - int minx = 100000, miny = 100000, maxx = -1, maxy = -1; - int original_x = *x; - int temp_x = *x; - int temp_y = *y; - uint32_t c; - while ((c = next_cp((const uint8_t **)&string))) { - get_char_bounds(font, c, &temp_x, &temp_y, &minx, &miny, &maxx, &maxy, &props); - } - *x1 = min(original_x, minx); - *w = maxx - *x1; - *y1 = miny; - *h = maxy - miny; -} - -static enum EpdDrawError epd_write_line( - const EpdFont *font, const char *string, int *cursor_x, - int *cursor_y, uint8_t *framebuffer, - const EpdFontProperties *properties) -{ - - assert(framebuffer != NULL); - - if (*string == '\0') { - return EPD_DRAW_SUCCESS; - } - - assert(properties != NULL); - EpdFontProperties props = *properties; - enum EpdFontFlags alignment_mask = EPD_DRAW_ALIGN_LEFT | EPD_DRAW_ALIGN_RIGHT | EPD_DRAW_ALIGN_CENTER; - enum EpdFontFlags alignment = props.flags & alignment_mask; - - // alignments are mutually exclusive! - if ((alignment & (alignment - 1)) != 0) { - return EPD_DRAW_INVALID_FONT_FLAGS; - } - - - int x1 = 0, y1 = 0, w = 0, h = 0; - int tmp_cur_x = *cursor_x; - int tmp_cur_y = *cursor_y; - epd_get_text_bounds(font, string, &tmp_cur_x, &tmp_cur_y, &x1, &y1, &w, &h, &props); - - // no printable characters - if (w < 0 || h < 0) { - return EPD_DRAW_NO_DRAWABLE_CHARACTERS; - } - - int baseline_height = *cursor_y - y1; - - int buf_width = EPD_WIDTH / 2; - int buf_height = EPD_HEIGHT; - - uint8_t* buffer = framebuffer; - int local_cursor_x = *cursor_x; - int local_cursor_y = *cursor_y; - uint32_t c; - - int cursor_x_init = local_cursor_x; - int cursor_y_init = local_cursor_y; - - switch (alignment) { - case EPD_DRAW_ALIGN_LEFT: { - break; - } - case EPD_DRAW_ALIGN_CENTER: { - local_cursor_x -= w / 2; - break; - } - case EPD_DRAW_ALIGN_RIGHT: { - local_cursor_x -= w; - break; - } - default: - break; - } - - uint8_t bg = props.bg_color; - if (props.flags & EPD_DRAW_BACKGROUND) { - for (int l = local_cursor_y - font->ascender; - l < local_cursor_y - font->descender; l++) { - epd_draw_hline(local_cursor_x, l, w, bg << 4, buffer); - } - } - enum EpdDrawError err = EPD_DRAW_SUCCESS; - while ((c = next_cp((const uint8_t **)&string))) { - err |= draw_char(font, buffer, &local_cursor_x, local_cursor_y, buf_width, - buf_height, c, &props); - } - - *cursor_x += local_cursor_x - cursor_x_init; - *cursor_y += local_cursor_y - cursor_y_init; - return err; -} - -enum EpdDrawError epd_write_default(const EpdFont *font, const char *string, int *cursor_x, - int *cursor_y, uint8_t *framebuffer) { - const EpdFontProperties props = epd_font_properties_default(); - return epd_write_string(font, string, cursor_x, cursor_y, framebuffer, &props); -} - -enum EpdDrawError epd_write_string( - const EpdFont *font, const char *string, int *cursor_x, - int *cursor_y, uint8_t *framebuffer, - const EpdFontProperties *properties -) { - char *token, *newstring, *tofree; - if (string == NULL) { - ESP_LOGE("font.c", "cannot draw a NULL string!"); - return EPD_DRAW_STRING_INVALID; - } - tofree = newstring = strdup(string); - if (newstring == NULL) { - ESP_LOGE("font.c", "cannot allocate string copy!"); - return EPD_DRAW_FAILED_ALLOC; - } - - enum EpdDrawError err = EPD_DRAW_SUCCESS; - // taken from the strsep manpage - int line_start = *cursor_x; - while ((token = strsep(&newstring, "\n")) != NULL) { - *cursor_x = line_start; - err |= epd_write_line(font, token, cursor_x, cursor_y, framebuffer, properties); - *cursor_y += font->advance_y; - } - - free(tofree); - return err; -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/highlevel.c b/lib/libesp32_eink/epdiy/src/epd_driver/highlevel.c deleted file mode 100755 index ac68d8268..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/highlevel.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * High-level API implementation for epdiy. - */ - -#include "epd_highlevel.h" -#include -#include -#include -#include -#include - -static bool already_initialized = 0; - -const static int fb_size = EPD_WIDTH / 2 * EPD_HEIGHT; - -EpdiyHighlevelState epd_hl_init(const EpdWaveform* waveform) { - assert(!already_initialized); - assert(waveform != NULL); - - EpdiyHighlevelState state; - state.front_fb = heap_caps_malloc(fb_size, MALLOC_CAP_SPIRAM); - assert(state.front_fb != NULL); - state.back_fb = heap_caps_malloc(fb_size, MALLOC_CAP_SPIRAM); - assert(state.back_fb != NULL); - state.difference_fb = heap_caps_malloc(2 * fb_size, MALLOC_CAP_SPIRAM); - assert(state.difference_fb != NULL); - state.dirty_lines = malloc(EPD_HEIGHT * sizeof(bool)); - assert(state.dirty_lines != NULL); - state.waveform = waveform; - - memset(state.front_fb, 0xFF, fb_size); - memset(state.back_fb, 0xFF, fb_size); - - already_initialized = true; - return state; -} - - -uint8_t* epd_hl_get_framebuffer(EpdiyHighlevelState* state) { - assert(state != NULL); - return state->front_fb; -} - -enum EpdDrawError epd_hl_update_screen(EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature) { - return epd_hl_update_area(state, mode, temperature, epd_full_screen()); -} - -enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature, EpdRect area) { - assert(state != NULL); - - bool previously_white = false; - bool previously_black = false; - - //FIXME: use crop information here, if available - EpdRect diff_area = epd_difference_image_cropped( - state->front_fb, - state->back_fb, - area, - state->difference_fb, - state->dirty_lines, - &previously_white, - &previously_black - ); - - if (diff_area.height == 0 || diff_area.width == 0) { - return EPD_DRAW_SUCCESS; - } - - enum EpdDrawError err; - if (previously_white) { - err = epd_draw_base(epd_full_screen(), state->front_fb, diff_area, MODE_PACKING_2PPB | PREVIOUSLY_WHITE | mode, temperature, state->dirty_lines, state->waveform); - } else if (previously_black) { - err = epd_draw_base(epd_full_screen(), state->front_fb, diff_area, MODE_PACKING_2PPB | PREVIOUSLY_BLACK | mode, temperature, state->dirty_lines, state->waveform); - } else { - err = epd_draw_base(epd_full_screen(), state->difference_fb, diff_area, MODE_PACKING_1PPB_DIFFERENCE | mode, temperature, state->dirty_lines, state->waveform); - } - - for (int l=diff_area.y; l < diff_area.y + diff_area.height; l++) { - if (state->dirty_lines[l]) { - memcpy( - state->back_fb + EPD_WIDTH / 2 * l, - state->front_fb + EPD_WIDTH / 2 * l, - EPD_WIDTH / 2 - ); - } - } - return err; -} - - -void epd_hl_set_all_white(EpdiyHighlevelState* state) { - assert(state != NULL); - memset(state->front_fb, 0xFF, fb_size); -} - -void epd_fullclear(EpdiyHighlevelState* state, int temperature) { - assert(state != NULL); - epd_hl_set_all_white(state); - enum EpdDrawError err = epd_hl_update_screen(state, MODE_GC16, temperature); - assert(err == EPD_DRAW_SUCCESS); - epd_clear(); -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.c b/lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.c deleted file mode 100755 index f7082b3fb..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "i2s_data_bus.h" -#include "driver/periph_ctrl.h" -#if ESP_IDF_VERSION < (4, 0, 0) || ARDUINO_ARCH_ESP32 -#include "rom/lldesc.h" -#else -#include "esp32/rom/lldesc.h" -#endif -#include "esp_heap_caps.h" -#include "soc/i2s_reg.h" -#include "soc/i2s_struct.h" -#include "soc/rtc.h" - -/// DMA descriptors for front and back line buffer. -/// We use two buffers, so one can be filled while the other -/// is transmitted. -typedef struct { - volatile lldesc_t *dma_desc_a; - volatile lldesc_t *dma_desc_b; - - /// Front and back line buffer. - uint8_t *buf_a; - uint8_t *buf_b; -} i2s_parallel_state_t; - -/// Indicates which line buffer is currently back / front. -static int current_buffer = 0; - -/// The I2S state instance. -static i2s_parallel_state_t i2s_state; - -static intr_handle_t gI2S_intr_handle = NULL; - -/// Indicates the device has finished its transmission and is ready again. -static volatile bool output_done = true; -/// The start pulse pin extracted from the configuration for use in the "done" -/// interrupt. -static gpio_num_t start_pulse_pin; - -/// Initializes a DMA descriptor. -static void fill_dma_desc(volatile lldesc_t *dmadesc, uint8_t *buf, - i2s_bus_config *cfg) { - dmadesc->size = cfg->epd_row_width / 4; - dmadesc->length = cfg->epd_row_width / 4; - dmadesc->buf = buf; - dmadesc->eof = 1; - dmadesc->sosf = 1; - dmadesc->owner = 1; - dmadesc->qe.stqe_next = 0; - dmadesc->offset = 0; -} - -/// Address of the currently front DMA descriptor, -/// which uses only the lower 20bits (according to TRM) -uint32_t dma_desc_addr() { - return (uint32_t)(current_buffer ? i2s_state.dma_desc_a - : i2s_state.dma_desc_b) & - 0x000FFFFF; -} - -/// Set up a GPIO as output and route it to a signal. -static void gpio_setup_out(int gpio, int sig, bool invert) { - if (gpio == -1) - return; - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); - gpio_set_direction(gpio, GPIO_MODE_DEF_OUTPUT); - gpio_matrix_out(gpio, sig, invert, false); -} - -/// Resets "Start Pulse" signal when the current row output is done. -static void IRAM_ATTR i2s_int_hdl(void *arg) { - i2s_dev_t *dev = &I2S1; - if (dev->int_st.out_done) { - //gpio_set_level(start_pulse_pin, 1); - //gpio_set_level(GPIO_NUM_26, 0); - output_done = true; - } - // Clear the interrupt. Otherwise, the whole device would hang. - dev->int_clr.val = dev->int_raw.val; -} - -volatile uint8_t IRAM_ATTR *i2s_get_current_buffer() { - return current_buffer ? i2s_state.dma_desc_a->buf : i2s_state.dma_desc_b->buf; -} - -bool IRAM_ATTR i2s_is_busy() { - // DMA and FIFO must be done - return !output_done || !I2S1.state.tx_idle; -} - -void IRAM_ATTR i2s_switch_buffer() { - // either device is done transmitting or the switch must be away from the - // buffer currently used by the DMA engine. - while (i2s_is_busy() && dma_desc_addr() != I2S1.out_link.addr) { - }; - current_buffer = !current_buffer; -} - -void IRAM_ATTR i2s_start_line_output() { - output_done = false; - - i2s_dev_t *dev = &I2S1; - dev->conf.tx_start = 0; - dev->conf.tx_reset = 1; - dev->conf.tx_fifo_reset = 1; - dev->conf.rx_fifo_reset = 1; - dev->conf.tx_reset = 0; - dev->conf.tx_fifo_reset = 0; - dev->conf.rx_fifo_reset = 0; - dev->out_link.addr = dma_desc_addr(); - dev->out_link.start = 1; - - // sth is pulled up through peripheral interrupt - // This is timing-critical! - gpio_set_level(start_pulse_pin, 0); - dev->conf.tx_start = 1; -} - -void i2s_bus_init(i2s_bus_config *cfg) { - // TODO: Why? - gpio_num_t I2S_GPIO_BUS[] = {cfg->data_6, cfg->data_7, cfg->data_4, - cfg->data_5, cfg->data_2, cfg->data_3, - cfg->data_0, cfg->data_1}; - - gpio_set_direction(cfg->start_pulse, GPIO_MODE_OUTPUT); - gpio_set_level(cfg->start_pulse, 1); - // store pin in global variable for use in interrupt. - start_pulse_pin = cfg->start_pulse; - - // Use I2S1 with no signal offset (for some reason the offset seems to be - // needed in 16-bit mode, but not in 8 bit mode. - int signal_base = I2S1O_DATA_OUT0_IDX; - - // Setup and route GPIOS - for (int x = 0; x < 8; x++) { - gpio_setup_out(I2S_GPIO_BUS[x], signal_base + x, false); - } - // Invert word select signal - gpio_setup_out(cfg->clock, I2S1O_WS_OUT_IDX, true); - - periph_module_enable(PERIPH_I2S1_MODULE); - - i2s_dev_t *dev = &I2S1; - - // Initialize device - dev->conf.tx_reset = 1; - dev->conf.tx_reset = 0; - - // Reset DMA - dev->lc_conf.in_rst = 1; - dev->lc_conf.in_rst = 0; - dev->lc_conf.out_rst = 1; - dev->lc_conf.out_rst = 0; - - // Setup I2S config. See section 12 of Technical Reference Manual - // Enable LCD mode - dev->conf2.val = 0; - dev->conf2.lcd_en = 1; - - // Enable FRAME1-Mode (See technical reference manual) - dev->conf2.lcd_tx_wrx2_en = 1; - dev->conf2.lcd_tx_sdx2_en = 0; - - // Set to 8 bit parallel output - dev->sample_rate_conf.val = 0; - dev->sample_rate_conf.tx_bits_mod = 8; - - // Half speed of bit clock in LCD mode. - // (Smallest possible divider according to the spec). - dev->sample_rate_conf.tx_bck_div_num = 2; - -#if defined(CONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ) - // Initialize Audio Clock (APLL) for 120 Mhz. - rtc_clk_apll_enable(1, 0, 0, 8, 0); -#else - // Initialize Audio Clock (APLL) for 100 Mhz. - rtc_clk_apll_enable(1, 0, 0, 8, 0); -#endif - - // Set Audio Clock Dividers - dev->clkm_conf.val = 0; - dev->clkm_conf.clka_en = 1; - dev->clkm_conf.clkm_div_a = 1; - dev->clkm_conf.clkm_div_b = 0; - // 2 is the smallest possible divider according to the spec. - dev->clkm_conf.clkm_div_num = 2; - - // Set up FIFO - dev->fifo_conf.val = 0; - dev->fifo_conf.tx_fifo_mod_force_en = 1; - dev->fifo_conf.tx_fifo_mod = 1; - dev->fifo_conf.tx_data_num = 32; - dev->fifo_conf.dscr_en = 1; - - // Stop after transmission complete - dev->conf1.val = 0; - dev->conf1.tx_stop_en = 1; - dev->conf1.tx_pcm_bypass = 1; - - // Configure TX channel - dev->conf_chan.val = 0; - dev->conf_chan.tx_chan_mod = 1; - dev->conf.tx_right_first = 1; - - dev->timing.val = 0; - - // Allocate DMA descriptors - i2s_state.buf_a = heap_caps_malloc(cfg->epd_row_width / 4, MALLOC_CAP_DMA); - i2s_state.buf_b = heap_caps_malloc(cfg->epd_row_width / 4, MALLOC_CAP_DMA); - i2s_state.dma_desc_a = heap_caps_malloc(sizeof(lldesc_t), MALLOC_CAP_DMA); - i2s_state.dma_desc_b = heap_caps_malloc(sizeof(lldesc_t), MALLOC_CAP_DMA); - - // and fill them - fill_dma_desc(i2s_state.dma_desc_a, i2s_state.buf_a, cfg); - fill_dma_desc(i2s_state.dma_desc_b, i2s_state.buf_b, cfg); - - // enable "done" interrupt - SET_PERI_REG_BITS(I2S_INT_ENA_REG(1), I2S_OUT_DONE_INT_ENA_V, 1, - I2S_OUT_DONE_INT_ENA_S); - // register interrupt - esp_intr_alloc(ETS_I2S1_INTR_SOURCE, 0, i2s_int_hdl, 0, &gI2S_intr_handle); - - // Reset FIFO/DMA - dev->lc_conf.in_rst = 1; - dev->lc_conf.out_rst = 1; - dev->lc_conf.ahbm_rst = 1; - dev->lc_conf.ahbm_fifo_rst = 1; - dev->lc_conf.in_rst = 0; - dev->lc_conf.out_rst = 0; - dev->lc_conf.ahbm_rst = 0; - dev->lc_conf.ahbm_fifo_rst = 0; - dev->conf.tx_reset = 1; - dev->conf.tx_fifo_reset = 1; - dev->conf.rx_fifo_reset = 1; - dev->conf.tx_reset = 0; - dev->conf.tx_fifo_reset = 0; - dev->conf.rx_fifo_reset = 0; - - // Start dma on front buffer - dev->lc_conf.val = - I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN; - dev->out_link.addr = ((uint32_t)(i2s_state.dma_desc_a)); - dev->out_link.start = 1; - - dev->int_clr.val = dev->int_raw.val; - - dev->int_ena.val = 0; - dev->int_ena.out_done = 1; - - dev->conf.tx_start = 0; -} - -void i2s_deinit() { - esp_intr_free(gI2S_intr_handle); - - free(i2s_state.buf_a); - free(i2s_state.buf_b); - free((void *)i2s_state.dma_desc_a); - free((void *)i2s_state.dma_desc_b); - - rtc_clk_apll_enable(0, 0, 0, 8, 0); - periph_module_disable(PERIPH_I2S1_MODULE); -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.h b/lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.h deleted file mode 100755 index cef7a1091..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/i2s_data_bus.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Implements a 8bit parallel interface to transmit pixel - * data to the display, based on the I2S peripheral. - */ - -#pragma once - -#include "driver/gpio.h" -#include "esp_attr.h" -#include - -/** - * I2S bus configuration parameters. - */ -typedef struct { - /// GPIO numbers of the parallel bus pins. - gpio_num_t data_0; - gpio_num_t data_1; - gpio_num_t data_2; - gpio_num_t data_3; - gpio_num_t data_4; - gpio_num_t data_5; - gpio_num_t data_6; - gpio_num_t data_7; - - /// Data clock pin. - gpio_num_t clock; - - /// "Start Pulse", enabling data input on the slave device (active low) - gpio_num_t start_pulse; - - // Width of a display row in pixels. - uint32_t epd_row_width; -} i2s_bus_config; - -/** - * Initialize the I2S data bus for communication - * with a 8bit parallel display interface. - */ -void i2s_bus_init(i2s_bus_config *cfg); - -/** - * Get the currently writable line buffer. - */ -volatile uint8_t IRAM_ATTR *i2s_get_current_buffer(); - -/** - * Switches front and back line buffer. - * If the switched-to line buffer is currently in use, - * this function blocks until transmission is done. - */ -void IRAM_ATTR i2s_switch_buffer(); - -/** - * Start transmission of the current back buffer. - */ -void IRAM_ATTR i2s_start_line_output(); - -/** - * Returns true if there is an ongoing transmission. - */ -bool IRAM_ATTR i2s_is_busy(); - -/** - * Give up allocated resources. - */ -void i2s_deinit(); diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_driver.h b/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_driver.h deleted file mode 100755 index 3c983e465..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_driver.h +++ /dev/null @@ -1,471 +0,0 @@ -/** - * @file epd_driver.h - * A driver library for drawing to an EPD. - */ -#ifdef __cplusplus -extern "C" { -#endif - -#define CONFIG_EPD_DISPLAY_TYPE_ED047TC1 -#define CONFIG_EPD_BOARD_REVISION_LILYGO_T5_47 - -#pragma once -#include "esp_attr.h" -#include "epd_internals.h" - -#include -#include - -/// An area on the display. -typedef struct { - /// Horizontal position. - int x; - /// Vertical position. - int y; - /// Area / image width, must be positive. - int width; - /// Area / image height, must be positive. - int height; -} EpdRect; - -/// Possible failures when drawing. -enum EpdDrawError { - EPD_DRAW_SUCCESS = 0x0, - /// No valid framebuffer packing mode was specified. - EPD_DRAW_INVALID_PACKING_MODE = 0x1, - - /// No lookup table implementation for this mode / packing. - EPD_DRAW_LOOKUP_NOT_IMPLEMENTED = 0x2, - - /// The string to draw is invalid. - EPD_DRAW_STRING_INVALID = 0x4, - - /// The string was not empty, but no characters where drawable. - EPD_DRAW_NO_DRAWABLE_CHARACTERS = 0x8, - - /// Allocation failed - EPD_DRAW_FAILED_ALLOC = 0x10, - - /// A glyph could not be drawn, and not fallback was present. - EPD_DRAW_GLYPH_FALLBACK_FAILED = 0x20, - - /// The specified crop area is invalid. - EPD_DRAW_INVALID_CROP = 0x40, - - /// No such mode is available with the current waveform. - EPD_DRAW_MODE_NOT_FOUND = 0x80, - - /// The waveform info file contains no applicable temperature range. - EPD_DRAW_NO_PHASES_AVAILABLE = 0x100, - - /// An invalid combination of font flags was used. - EPD_DRAW_INVALID_FONT_FLAGS = 0x200, -}; - -/// Global EPD driver options. -enum EpdInitOptions { - /// Use the default options. - EPD_OPTIONS_DEFAULT = 0, - /// Use a small look-up table of 1024 bytes. - /// The EPD driver will use less space, but performance may be worse. - EPD_LUT_1K = 1, - /// Use a 64K lookup table. (default) - /// Best performance, but permanently occupies a 64k block of internal memory. - EPD_LUT_64K = 2, - - /// Use a small feed queue of 8 display lines. - /// This uses less memory, but may impact performance. - EPD_FEED_QUEUE_8 = 4, - /// Use a feed queue of 32 display lines. (default) - /// Best performance, but larger memory footprint. - EPD_FEED_QUEUE_32 = 8, -}; - -/// The image drawing mode. -enum EpdDrawMode { - /// An init waveform. - /// This is currently unused, use `epd_clear()` instead. - MODE_INIT = 0x0, - /// Direct Update: Go from any color to black for white only. - MODE_DU = 0x1, - /// Go from any grayscale value to another with a flashing update. - MODE_GC16 = 0x2, - /// Faster version of `MODE_GC16`. - /// Not available with default epdiy waveforms. - MODE_GC16_FAST = 0x3, - /// Animation Mode: Fast, monochrom updates. - /// Not available with default epdiy waveforms. - MODE_A2 = 0x4, - /// Go from any grayscale value to another with a non-flashing update. - MODE_GL16 = 0x5, - /// Faster version of `MODE_GL16`. - /// Not available with default epdiy waveforms. - MODE_GL16_FAST = 0x6, - /// A 4-grayscale version of `MODE_DU`. - /// Not available with default epdiy waveforms. - MODE_DU4 = 0x7, - /// Arbitrary transitions for 4 grayscale values. - /// Not available with default epdiy waveforms. - MODE_GL4 = 0xA, - /// Not available with default epdiy waveforms. - MODE_GL16_INV = 0xB, - - /// Go from a white screen to arbitrary grayscale, quickly. - /// Exclusively available with epdiy waveforms. - MODE_EPDIY_WHITE_TO_GL16 = 0x10, - /// Go from a black screen to arbitrary grayscale, quickly. - /// Exclusively available with epdiy waveforms. - MODE_EPDIY_BLACK_TO_GL16 = 0x11, - - /// Monochrome mode. Only supported with 1bpp buffers. - MODE_EPDIY_MONOCHROME = 0x20, - - MODE_UNKNOWN_WAVEFORM = 0x3F, - - // Framebuffer packing modes - /// 1 bit-per-pixel framebuffer with 0 = black, 1 = white. - /// MSB is left is the leftmost pixel, LSB the rightmost pixel. - MODE_PACKING_8PPB = 0x40, - /// 4 bit-per pixel framebuffer with 0x0 = black, 0xF = white. - /// The upper nibble corresponds to the left pixel. - /// A byte cannot wrap over multiple rows, images of uneven width - /// must add a padding nibble per line. - MODE_PACKING_2PPB = 0x80, - /// A difference image with one pixel per byte. - /// The upper nibble marks the "from" color, - /// the lower nibble the "to" color. - MODE_PACKING_1PPB_DIFFERENCE = 0x100, - // reserver for 4PPB mode - - /// Assert that the display has a uniform color, e.g. after initialization. - /// If `MODE_PACKING_2PPB` is specified, a optimized output calculation can be used. - /// Draw on a white background - PREVIOUSLY_WHITE = 0x200, - /// See `PREVIOUSLY_WHITE`. - /// Draw on a black background - PREVIOUSLY_BLACK = 0x400, -}; - -/// The default draw mode (non-flashy refresh, whith previously white screen). -#define EPD_MODE_DEFAULT (MODE_GL16 | PREVIOUSLY_WHITE) - -/// Font drawing flags -enum EpdFontFlags { - /// Draw a background. - /// - /// Take the background into account - /// when calculating the size. - EPD_DRAW_BACKGROUND = 0x1, - - /// Left-Align lines - EPD_DRAW_ALIGN_LEFT = 0x2, - /// Right-align lines - EPD_DRAW_ALIGN_RIGHT = 0x4, - /// Center-align lines - EPD_DRAW_ALIGN_CENTER = 0x8, -}; - -/// Font properties. -typedef struct { - /// Foreground color - uint8_t fg_color : 4; - /// Background color - uint8_t bg_color : 4; - /// Use the glyph for this codepoint for missing glyphs. - uint32_t fallback_glyph; - /// Additional flags, reserved for future use - enum EpdFontFlags flags; -} EpdFontProperties; - -/** Initialize the ePaper display */ -void epd_init(enum EpdInitOptions options); - -/** Deinit the ePaper display */ -void epd_deinit(); - -/** Enable display power supply. */ -void epd_poweron(); - -/** Disable display power supply. */ -void epd_poweroff(); - -/** Clear the whole screen by flashing it. */ -void epd_clear(); - -/** - * Clear an area by flashing it. - * - * @param area: The area to clear. - */ -void epd_clear_area(EpdRect area); - -/** - * Clear an area by flashing it. - * - * @param area: The area to clear. - * @param cycles: The number of black-to-white clear cycles. - * @param cycle_time: Length of a cycle. Default: 50 (us). - */ -void epd_clear_area_cycles(EpdRect area, int cycles, int cycle_time); - -/** - * @returns Rectancle representing the whole screen area. - */ -EpdRect epd_full_screen(); - -/** - * Draw a picture to a given framebuffer. - * - * @param image_area: The area to copy to. `width` and `height` of the area - * must correspond to the image dimensions in pixels. - * @param image_data: The image data, as a buffer of 4 bit wide brightness - * values. Pixel data is packed (two pixels per byte). A byte cannot wrap over - * multiple rows, images of uneven width must add a padding nibble per line. - * @param framebuffer: The framebuffer object, - * which must be `EPD_WIDTH / 2 * EPD_HEIGHT` large. - */ -void epd_copy_to_framebuffer(EpdRect image_area, const uint8_t *image_data, - uint8_t *framebuffer); - -/** - * Draw a pixel a given framebuffer. - * - * @param x: Horizontal position in pixels. - * @param y: Vertical position in pixels. - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_draw_pixel(int x, int y, uint8_t color, uint8_t *framebuffer); - -/** - * Draw a horizontal line to a given framebuffer. - * - * @param x: Horizontal start position in pixels. - * @param y: Vertical start position in pixels. - * @param length: Length of the line in pixels. - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - * which must be `EPD_WIDTH / 2 * EPD_HEIGHT` bytes large. - */ -void epd_draw_hline(int x, int y, int length, uint8_t color, - uint8_t *framebuffer); - -/** - * Draw a horizontal line to a given framebuffer. - * - * @param x: Horizontal start position in pixels. - * @param y: Vertical start position in pixels. - * @param length: Length of the line in pixels. - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - * which must be `EPD_WIDTH / 2 * EPD_HEIGHT` bytes large. - */ -void epd_draw_vline(int x, int y, int length, uint8_t color, - uint8_t *framebuffer); - -void epd_fill_circle_helper(int x0, int y0, int r, int corners, int delta, - uint8_t color, uint8_t *framebuffer); - -/** - * Draw a circle with given center and radius - * - * @param x: Center-point x coordinate - * @param y: Center-point y coordinate - * @param r: Radius of the circle in pixels - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_draw_circle(int x, int y, int r, uint8_t color, uint8_t *framebuffer); - -/** - * Draw a circle with fill with given center and radius - * - * @param x: Center-point x coordinate - * @param y: Center-point y coordinate - * @param r: Radius of the circle in pixels - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_fill_circle(int x, int y, int r, uint8_t color, uint8_t *framebuffer); - -/** - * Draw a rectanle with no fill color - * - * @param rect: The rectangle to draw. - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_draw_rect(EpdRect rect, uint8_t color, uint8_t *framebuffer); - -/** - * Draw a rectanle with fill color - * - * @param rect: The rectangle to fill. - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_fill_rect(EpdRect rect, uint8_t color, uint8_t *framebuffer); - -/** - * Draw a line - * - * @param x0 Start point x coordinate - * @param y0 Start point y coordinate - * @param x1 End point x coordinate - * @param y1 End point y coordinate - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_draw_line(int x0, int y0, int x1, int y1, uint8_t color, - uint8_t *framebuffer); - -/** - * Draw a triangle with no fill color - * - * @param x0 Vertex #0 x coordinate - * @param y0 Vertex #0 y coordinate - * @param x1 Vertex #1 x coordinate - * @param y1 Vertex #1 y coordinate - * @param x2 Vertex #2 x coordinate - * @param y2 Vertex #2 y coordinate - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2, - uint8_t color, uint8_t *framebuffer); - -/** - * Draw a triangle with color-fill - * - * @param x0 Vertex #0 x coordinate - * @param y0 Vertex #0 y coordinate - * @param x1 Vertex #1 x coordinate - * @param y1 Vertex #1 y coordinate - * @param x2 Vertex #2 x coordinate - * @param y2 Vertex #2 y coordinate - * @param color: The gray value of the line (0-255); - * @param framebuffer: The framebuffer to draw to, - */ -void epd_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2, - uint8_t color, uint8_t *framebuffer); -/** - * Get the current ambient temperature in °C, if supported by the board. - * Requires the display to be powered on. - */ -float epd_ambient_temperature(); - -/** - * The default font properties. - */ -EpdFontProperties epd_font_properties_default(); - -/*! - * Get the text bounds for string, when drawn at (x, y). - * Set font properties to NULL to use the defaults. - */ -void epd_get_text_bounds(const EpdFont *font, const char *string, - const int *x, const int *y, - int *x1, int *y1, int *w, int *h, - const EpdFontProperties *props); - -/** - * Write text to the EPD. - */ -enum EpdDrawError epd_write_string(const EpdFont *font, const char *string, int *cursor_x, - int *cursor_y, uint8_t *framebuffer, - const EpdFontProperties *properties); - -/** - * Write a (multi-line) string to the EPD. - */ -enum EpdDrawError epd_write_default(const EpdFont *font, const char *string, int *cursor_x, - int *cursor_y, uint8_t *framebuffer); - -/** - * Get the font glyph for a unicode code point. - */ -const EpdGlyph* epd_get_glyph(const EpdFont *font, uint32_t code_point); - - -/** - * Darken / lighten an area for a given time. - * - * @param area: The area to darken / lighten. - * @param time: The time in us to apply voltage to each pixel. - * @param color: 1: lighten, 0: darken. - */ -void epd_push_pixels(EpdRect area, short time, int color); - -/** - * Base function for drawing an image on the screen. - * If It is very customizable, and the documentation below should be studied carefully. - * For simple applications, use the epdiy highlevel api in "epd_higlevel.h". - * - * @param area: The area of the screen to draw to. - * This can be imagined as shifting the origin of the frame buffer. - * @param data: A full framebuffer of display data. - * It's structure depends on the chosen `mode`. - * @param crop_to: Only draw a part of the frame buffer. - * Set to `epd_full_screen()` to draw the full buffer. - * @param mode: Specifies the Waveform used, the framebuffer format - * and additional information, like if the display is cleared. - * @param temperature: The temperature of the display in °C. - * Currently, this is unused by the default waveforms at can be - * set to room temperature, e.g. 20-25°C. - * @param drawn_lines: If not NULL, an array of at least the height of the - * image. Every line where the corresponding value in `lines` is `false` will be - * skipped. - * @param waveform: The waveform information to use for drawing. - * If you don't have special waveforms, use `EPD_BUILTIN_WAVEFORM`. - * @returns `EPD_DRAW_SUCCESS` on sucess, a combination of error flags otherwise. - */ -enum EpdDrawError IRAM_ATTR epd_draw_base(EpdRect area, - const uint8_t *data, - EpdRect crop_to, - enum EpdDrawMode mode, - int temperature, - const bool *drawn_lines, - const EpdWaveform *waveform); -/** - * Calculate a `MODE_PACKING_1PPB_DIFFERENCE` difference image - * from two `MODE_PACKING_2PPB` (4 bit-per-pixel) buffers. - * If you're using the epdiy highlevel api, this is handled by the update functions. - * - * @param to: The goal image as 4-bpp (`MODE_PACKING_2PPB`) framebuffer. - * @param from: The previous image as 4-bpp (`MODE_PACKING_2PPB`) framebuffer. - * @param crop_to: Only calculate the difference for a crop of the input framebuffers. - * The `interlaced` will not be modified outside the crop area. - * @param interlaced: The resulting difference image in `MODE_PACKING_1PPB_DIFFERENCE` format. - * @param dirty_lines: An array of at least `EPD_HEIGHT`. - * The positions corresponding to lines where `to` and `from` differ - * are set to `true`, otherwise to `false`. - * @param previously_white: If not NULL, it is set to `true` - * if the considered crop of the `from`-image is completely white. - * @param previously_black: If not NULL, it is set to `true` - * if the considered crop of the `from`-image is completely black. - * @returns The smallest rectangle containing all changed pixels. - */ -EpdRect epd_difference_image_cropped( - const uint8_t* to, - const uint8_t* from, - EpdRect crop_to, - uint8_t* interlaced, - bool* dirty_lines, - bool* previously_white, - bool* previously_black -); - -/** - * Simplified version of `epd_difference_image_cropped()`, which considers the - * whole display frame buffer. - * - * See `epd_difference_image_cropped() for details.` - */ -EpdRect epd_difference_image(const uint8_t* to, const uint8_t* from, uint8_t* interlaced, bool* dirty_lines); - - - - -#ifdef __cplusplus -} -#endif diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_highlevel.h b/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_highlevel.h deleted file mode 100755 index d22bc0df4..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_highlevel.h +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file "epd_highlevel.h" - * @brief High-level API for drawing to e-paper displays. - * - * The functions in this library provide a simple way to manage updates of e-paper display. - * To use it, follow the steps below: - * - * 1. First, we declare a global object that manages the display state. - * - * EpdiyHighlevelState hl; - * - * 2. Then, the driver and framebuffers must be initialized. - * - * epd_init(EPD_LUT_1K); - * hl = epd_hl_init(EPD_BUILTIN_WAVEFORM); - * - * 3. Now, we can draw to the allocated framebuffer, - * using the draw and text functions defined in `epd_driver.h`. - * This will not yet update the display, but only its representation in memory. - * - * // A reference to the framebuffer - * uint8_t* fb = epd_hl_get_framebuffer(&hl); - * - * // draw a black rectangle - * EpdRect some_rect = { - * .x = 100, - * .y = 100, - * .width = 100, - * .height = 100 - * }; - * epd_fill_rect(some_rect, 0x0, fb); - * - * // write a message - * int cursor_x = 100; - * int cursor_y = 300; - * epd_write_default(&FiraSans, "Hello, World!", &cursor_x, &cursor_y, fb); - * - * // finally, update the display! - * int temperature = 25; - * epd_poweron(); - * EpdDrawError err = epd_hl_update_screen(&hl, MODE_GC16, temperature); - * epd_poweroff(); - * - * That's it! For many application, this will be enough. - * For special applications and requirements, have a - * closer look at the `epd_driver.h` header. - */ - - #ifdef __cplusplus - extern "C" { - #endif - -#include "epd_driver.h" - -/// Holds the internal state of the high-level API. -typedef struct { - /// The "front" framebuffer object. - uint8_t* front_fb; - /// The "back" framebuffer object. - uint8_t* back_fb; - /// Buffer for holding the interlaced difference image. - uint8_t* difference_fb; - /// Tainted lines based on the last difference calculation. - bool* dirty_lines; - /// The waveform information to use. - const EpdWaveform* waveform; -} EpdiyHighlevelState; - - -/** - * Initialize a state object. - * This allocates two framebuffers and an update buffer for - * the display in the external PSRAM. - * In order to keep things simple, a chip reset is triggered if this fails. - * - * @param waveform: The waveform to use for updates. - * If you did not create your own, this will be `EPD_BUILTIN_WAVEFORM`. - * @returns An initialized state object. - */ -EpdiyHighlevelState epd_hl_init(const EpdWaveform* waveform); - -/// Get a reference to the front framebuffer. -/// Use this to draw on the framebuffer before updating the screen with `epd_hl_update_screen()`. -uint8_t* epd_hl_get_framebuffer(EpdiyHighlevelState* state); - -/** - * Update the EPD screen to match the content of the front frame buffer. - * Prior to this, power to the display must be enabled via `epd_poweron()` - * and should be disabled afterwards if no immediate additional updates follow. - * - * @param state: A reference to the `EpdiyHighlevelState` object used. - * @param mode: The update mode to use. - * Additional mode settings like the framebuffer format or - * previous display state are determined by the driver and must not be supplied here. - * In most cases, one of `MODE_GC16` and `MODE_GL16` should be used. - * @param temperature: Environmental temperature of the display in °C. - * @returns `EPD_DRAW_SUCCESS` on sucess, a combination of error flags otherwise. - */ -enum EpdDrawError epd_hl_update_screen(EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature); - -/** - * Update an area of the screen to match the content of the front framebuffer. - * Supplying a small area to update can speed up the update process. - * Prior to this, power to the display must be enabled via `epd_poweron()` - * and should be disabled afterwards if no immediate additional updates follow. - * - * @param state: A reference to the `EpdiyHighlevelState` object used. - * @param mode: See `epd_hl_update_screen()`. - * @param temperature: Environmental temperature of the display in °C. - * @param area: Area of the screen to update. - * @returns `EPD_DRAW_SUCCESS` on sucess, a combination of error flags otherwise. - */ -enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature, EpdRect area); - -/** - * Reset the front framebuffer to a white state. - * - * @param state: A reference to the `EpdiyHighlevelState` object used. - */ -void epd_hl_set_all_white(EpdiyHighlevelState* state); - -/** - * Bring the display to a fully white state and get rid of any - * remaining artifacts. - */ -void epd_fullclear(EpdiyHighlevelState* state, int temperature); - -#ifdef __cplusplus -} -#endif diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_internals.h b/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_internals.h deleted file mode 100755 index 923430579..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/include/epd_internals.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file epd_internals.h - * @brief Internal definitions and auxiliary data types. - * - * Unless you want to extend the library itself (Which you are very welcome to do), - * you will most likely not need to know about this file. - */ - -#ifndef EPD_INTERNALS_H -#define EPD_INTERNALS_H - -#include -#include - -/// minimal draw time in ms for a frame layer, -/// which will allow all particles to set properly. -#ifndef MINIMUM_FRAME_TIME -#define MINIMUM_FRAME_TIME 12 -#endif - -/// Frame draw time for monochrome mode in 1/10 us. -#define MONOCHROME_FRAME_TIME 120 - -#if defined(CONFIG_EPD_DISPLAY_TYPE_ED097OC4) || \ - defined(CONFIG_EPD_DISPLAY_TYPE_ED097TC2) || \ - defined(CONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ) -/// Width of the display area in pixels. -#define EPD_WIDTH 1200 -/// Height of the display area in pixels. -#define EPD_HEIGHT 825 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED133UT2) -#define EPD_WIDTH 1600 -#define EPD_HEIGHT 1200 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED060SC4) -/// Width of the display area in pixels. -#define EPD_WIDTH 800 -/// Height of the display area in pixels. -#define EPD_HEIGHT 600 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED060SCT) -/// Width of the display area in pixels. -#define EPD_WIDTH 800 -/// Height of the display area in pixels. -#define EPD_HEIGHT 600 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED060XC3) -/// Width of the display area in pixels. -#define EPD_WIDTH 1024 -/// Height of the display area in pixels. -#define EPD_HEIGHT 758 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED047TC1) -/// Width of the display area in pixels. -#define EPD_WIDTH 960 -/// Height of the display area in pixels. -#define EPD_HEIGHT 540 -#else -#error "no display type defined!" -#endif - - -typedef struct { - int phases; - const uint8_t* luts; - /// If we have timing information for the individual - /// phases, this is an array of the on-times for each phase. - /// Otherwise, this is NULL. - const int* phase_times; -} EpdWaveformPhases; - -typedef struct { - uint8_t type; - uint8_t temp_ranges; - EpdWaveformPhases const **range_data; -} EpdWaveformMode; - -typedef struct { - int min; - int max; -} EpdWaveformTempInterval; - -typedef struct { - uint8_t num_modes; - uint8_t num_temp_ranges; - EpdWaveformMode const **mode_data; - EpdWaveformTempInterval const *temp_intervals; -} EpdWaveform; - - - - -extern const EpdWaveform ed047tc2; -extern const EpdWaveform epdiy_ED060SC4; -extern const EpdWaveform epdiy_ED097OC4; -extern const EpdWaveform epdiy_ED047TC1; -extern const EpdWaveform epdiy_ED097TC2; -extern const EpdWaveform epdiy_ED060XC3; -extern const EpdWaveform epdiy_ED060SCT; -extern const EpdWaveform epdiy_ED133UT2; - -#if defined(CONFIG_EPD_DISPLAY_TYPE_ED047TC1) -//#define EPD_BUILTIN_WAVEFORM &epdiy_ED047TC1 -#define EPD_BUILTIN_WAVEFORM &ed047tc2 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED060SC4) -#define EPD_BUILTIN_WAVEFORM &epdiy_ED060SC4 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED060XC3) -#define EPD_BUILTIN_WAVEFORM &epdiy_ED060XC3 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED060SCT) -#define EPD_BUILTIN_WAVEFORM &epdiy_ED060SCT -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED097OC4) || defined(CONFIG_EPD_DISPLAY_TYPE_ED097OC4_LQ) -#define EPD_BUILTIN_WAVEFORM &epdiy_ED097OC4 -#elif defined(CONFIG_EPD_DISPLAY_TYPE_ED097TC2) -#define EPD_BUILTIN_WAVEFORM &epdiy_ED097TC2 -#elif defined (CONFIG_EPD_DISPLAY_TYPE_ED133UT2) -#define EPD_BUILTIN_WAVEFORM &epdiy_ED133UT2 -#endif - -/// Font data stored PER GLYPH -typedef struct { - uint8_t width; ///< Bitmap dimensions in pixels - uint8_t height; ///< Bitmap dimensions in pixels - uint8_t advance_x; ///< Distance to advance cursor (x axis) - int16_t left; ///< X dist from cursor pos to UL corner - int16_t top; ///< Y dist from cursor pos to UL corner - uint16_t compressed_size; ///< Size of the zlib-compressed font data. - uint32_t data_offset; ///< Pointer into EpdFont->bitmap -} EpdGlyph; - -/// Glyph interval structure -typedef struct { - uint32_t first; ///< The first unicode code point of the interval - uint32_t last; ///< The last unicode code point of the interval - uint32_t offset; ///< Index of the first code point into the glyph array -} EpdUnicodeInterval; - -/// Data stored for FONT AS A WHOLE -typedef struct { - const uint8_t *bitmap; ///< Glyph bitmaps, concatenated - const EpdGlyph *glyph; ///< Glyph array - const EpdUnicodeInterval *intervals; ///< Valid unicode intervals for this font - uint32_t interval_count; ///< Number of unicode intervals. - bool compressed; ///< Does this font use compressed glyph bitmaps? - uint8_t advance_y; ///< Newline distance (y axis) - int ascender; ///< Maximal height of a glyph above the base line - int descender; ///< Maximal height of a glyph below the base line -} EpdFont; - - -#endif // EPD_INTERNALS_H diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/lut.c b/lib/libesp32_eink/epdiy/src/epd_driver/lut.c deleted file mode 100755 index bf1364e33..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/lut.c +++ /dev/null @@ -1,617 +0,0 @@ -#include "lut.h" -#include "display_ops.h" -#include "esp_log.h" -#include "freertos/task.h" -#include - -/* - * Build Lookup tables and translate via LUTs. - * WARNING: These functions must only ever write to internal memory, - * Since we disable the PSRAM workaround here for performance reasons. - */ - -/* Python script for generating the 1bpp lookup table: - * for i in range(256): - number = 0; - for b in range(8): - if not (i & (b << 1)): - number |= 1 << (2*b) - print ('0x%04x,'%number) - */ -const static uint32_t lut_1bpp_black[256] = { - 0x5555, 0x5554, 0x5551, 0x5550, 0x5545, 0x5544, 0x5541, 0x5540, 0x5515, - 0x5514, 0x5511, 0x5510, 0x5505, 0x5504, 0x5501, 0x5500, 0x5455, 0x5454, - 0x5451, 0x5450, 0x5445, 0x5444, 0x5441, 0x5440, 0x5415, 0x5414, 0x5411, - 0x5410, 0x5405, 0x5404, 0x5401, 0x5400, 0x5155, 0x5154, 0x5151, 0x5150, - 0x5145, 0x5144, 0x5141, 0x5140, 0x5115, 0x5114, 0x5111, 0x5110, 0x5105, - 0x5104, 0x5101, 0x5100, 0x5055, 0x5054, 0x5051, 0x5050, 0x5045, 0x5044, - 0x5041, 0x5040, 0x5015, 0x5014, 0x5011, 0x5010, 0x5005, 0x5004, 0x5001, - 0x5000, 0x4555, 0x4554, 0x4551, 0x4550, 0x4545, 0x4544, 0x4541, 0x4540, - 0x4515, 0x4514, 0x4511, 0x4510, 0x4505, 0x4504, 0x4501, 0x4500, 0x4455, - 0x4454, 0x4451, 0x4450, 0x4445, 0x4444, 0x4441, 0x4440, 0x4415, 0x4414, - 0x4411, 0x4410, 0x4405, 0x4404, 0x4401, 0x4400, 0x4155, 0x4154, 0x4151, - 0x4150, 0x4145, 0x4144, 0x4141, 0x4140, 0x4115, 0x4114, 0x4111, 0x4110, - 0x4105, 0x4104, 0x4101, 0x4100, 0x4055, 0x4054, 0x4051, 0x4050, 0x4045, - 0x4044, 0x4041, 0x4040, 0x4015, 0x4014, 0x4011, 0x4010, 0x4005, 0x4004, - 0x4001, 0x4000, 0x1555, 0x1554, 0x1551, 0x1550, 0x1545, 0x1544, 0x1541, - 0x1540, 0x1515, 0x1514, 0x1511, 0x1510, 0x1505, 0x1504, 0x1501, 0x1500, - 0x1455, 0x1454, 0x1451, 0x1450, 0x1445, 0x1444, 0x1441, 0x1440, 0x1415, - 0x1414, 0x1411, 0x1410, 0x1405, 0x1404, 0x1401, 0x1400, 0x1155, 0x1154, - 0x1151, 0x1150, 0x1145, 0x1144, 0x1141, 0x1140, 0x1115, 0x1114, 0x1111, - 0x1110, 0x1105, 0x1104, 0x1101, 0x1100, 0x1055, 0x1054, 0x1051, 0x1050, - 0x1045, 0x1044, 0x1041, 0x1040, 0x1015, 0x1014, 0x1011, 0x1010, 0x1005, - 0x1004, 0x1001, 0x1000, 0x0555, 0x0554, 0x0551, 0x0550, 0x0545, 0x0544, - 0x0541, 0x0540, 0x0515, 0x0514, 0x0511, 0x0510, 0x0505, 0x0504, 0x0501, - 0x0500, 0x0455, 0x0454, 0x0451, 0x0450, 0x0445, 0x0444, 0x0441, 0x0440, - 0x0415, 0x0414, 0x0411, 0x0410, 0x0405, 0x0404, 0x0401, 0x0400, 0x0155, - 0x0154, 0x0151, 0x0150, 0x0145, 0x0144, 0x0141, 0x0140, 0x0115, 0x0114, - 0x0111, 0x0110, 0x0105, 0x0104, 0x0101, 0x0100, 0x0055, 0x0054, 0x0051, - 0x0050, 0x0045, 0x0044, 0x0041, 0x0040, 0x0015, 0x0014, 0x0011, 0x0010, - 0x0005, 0x0004, 0x0001, 0x0000}; - -// Timestamp when the last frame draw was started. -// This is used to enforce a minimum frame draw time, allowing -// all pixels to set. -static uint64_t last_frame_start = 0; - -inline int min(int x, int y) { return x < y ? x : y; } -inline int max(int x, int y) { return x > y ? x : y; } - -// status tracker for row skipping -uint32_t skipping; - -// output a row to the display. -void IRAM_ATTR write_row(uint32_t output_time_dus) { - epd_output_row(output_time_dus); - skipping = 0; -} - -// skip a display row -void IRAM_ATTR skip_row(uint8_t pipeline_finish_time) { - // output previously loaded row, fill buffer with no-ops. - if (skipping < 2) { - memset(epd_get_current_buffer(), 0x00, EPD_LINE_BYTES); - epd_output_row(pipeline_finish_time); - } else { - epd_skip(); - } - skipping++; -} - -void IRAM_ATTR reorder_line_buffer(uint32_t *line_data) { - for (uint32_t i = 0; i < EPD_LINE_BYTES / 4; i++) { - uint32_t val = *line_data; - *(line_data++) = val >> 16 | ((val & 0x0000FFFF) << 16); - } -} - -static void IRAM_ATTR bit_shift_buffer_right(uint8_t *buf, uint32_t len, - int shift) { - uint8_t carry = 0xFF << (8 - shift); - for (uint32_t i = 0; i < len; i++) { - uint8_t val = buf[i]; - buf[i] = (val >> shift) | carry; - carry = val << (8 - shift); - } -} - -static void IRAM_ATTR nibble_shift_buffer_right(uint8_t *buf, uint32_t len) { - uint8_t carry = 0xF; - for (uint32_t i = 0; i < len; i++) { - uint8_t val = buf[i]; - buf[i] = (val << 4) | carry; - carry = (val & 0xF0) >> 4; - } -} - -///////////////////////////// Looking up EPD Pixels -////////////////////////////////// - -static void IRAM_ATTR calc_epd_input_1bpp(const uint32_t *line_data, - uint8_t *epd_input, - const uint8_t *lut) { - - uint32_t *wide_epd_input = (uint32_t *)epd_input; - uint8_t *data_ptr = (uint8_t *)line_data; - uint32_t *lut_32 = (uint32_t *)lut; - // this is reversed for little-endian, but this is later compensated - // through the output peripheral. - for (uint32_t j = 0; j < EPD_WIDTH / 16; j++) { - uint8_t v1 = *(data_ptr++); - uint8_t v2 = *(data_ptr++); - wide_epd_input[j] = (lut_32[v1] << 16) | lut_32[v2]; - } -} - -static void IRAM_ATTR -calc_epd_input_4bpp_lut_64k(const uint32_t *line_data, uint8_t *epd_input, - const uint8_t *conversion_lut) { - - uint32_t *wide_epd_input = (uint32_t *)epd_input; - const uint16_t *line_data_16 = (const uint16_t *)line_data; - - // this is reversed for little-endian, but this is later compensated - // through the output peripheral. - for (uint32_t j = 0; j < EPD_WIDTH / 16; j++) { - - uint16_t v1 = *(line_data_16++); - uint16_t v2 = *(line_data_16++); - uint16_t v3 = *(line_data_16++); - uint16_t v4 = *(line_data_16++); - uint32_t pixel = conversion_lut[v1] << 16 | conversion_lut[v2] << 24 | - conversion_lut[v3] | conversion_lut[v4] << 8; - wide_epd_input[j] = pixel; - } -} - -/** - * Look up 4 pixels of a differential image. - */ -static inline uint8_t -lookup_differential_pixels(uint32_t in, const uint8_t *conversion_lut) { - uint8_t out = conversion_lut[in & 0xFF]; - in = in >> 8; - out |= (conversion_lut + 0x100)[in & 0xFF]; - in = in >> 8; - out |= (conversion_lut + 0x200)[in & 0xFF]; - in = in >> 8; - out |= (conversion_lut + 0x300)[in]; - return out; -} - -/** - * Calculate EPD input for a difference image with one pixel per byte. - */ -static void IRAM_ATTR calc_epd_input_1ppB(const uint32_t *ld, - uint8_t *epd_input, - const uint8_t *conversion_lut) { - - // this is reversed for little-endian, but this is later compensated - // through the output peripheral. - for (uint32_t j = 0; j < EPD_WIDTH / 4; j += 4) { - epd_input[j + 2] = lookup_differential_pixels(*(ld++), conversion_lut); - epd_input[j + 3] = lookup_differential_pixels(*(ld++), conversion_lut); - epd_input[j + 0] = lookup_differential_pixels(*(ld++), conversion_lut); - epd_input[j + 1] = lookup_differential_pixels(*(ld++), conversion_lut); - } -} - -/** - * Look up 4 pixels in a 1K LUT with fixed "from" value. - */ -static inline uint8_t lookup_pixels_4bpp_1k(uint16_t in, - const uint8_t *conversion_lut, - uint8_t from) { - uint8_t v; - uint8_t out; - v = ((in << 4) | from); - out = conversion_lut[v & 0xFF]; - v = ((in & 0xF0) | from); - out |= (conversion_lut + 0x100)[v & 0xFF]; - in = in >> 8; - v = ((in << 4) | from); - out |= (conversion_lut + 0x200)[v & 0xFF]; - v = ((in & 0xF0) | from); - out |= (conversion_lut + 0x300)[v]; - return out; -} - -/** - * Calculate EPD input for a 4bpp buffer, but with a difference image LUT. - * This is used for small-LUT mode. - */ -static void IRAM_ATTR calc_epd_input_4bpp_1k_lut(const uint32_t *ld, - uint8_t *epd_input, - const uint8_t *conversion_lut, - uint8_t from) { - - uint16_t *ptr = (uint16_t *)ld; - // this is reversed for little-endian, but this is later compensated - // through the output peripheral. - for (uint32_t j = 0; j < EPD_WIDTH / 4; j += 4) { - epd_input[j + 2] = lookup_pixels_4bpp_1k(*(ptr++), conversion_lut, from); - epd_input[j + 3] = lookup_pixels_4bpp_1k(*(ptr++), conversion_lut, from); - epd_input[j + 0] = lookup_pixels_4bpp_1k(*(ptr++), conversion_lut, from); - epd_input[j + 1] = lookup_pixels_4bpp_1k(*(ptr++), conversion_lut, from); - } -} - -static void IRAM_ATTR calc_epd_input_4bpp_1k_lut_white( - const uint32_t *ld, uint8_t *epd_input, const uint8_t *conversion_lut) { - calc_epd_input_4bpp_1k_lut(ld, epd_input, conversion_lut, 0xF); -} - -static void IRAM_ATTR calc_epd_input_4bpp_1k_lut_black( - const uint32_t *ld, uint8_t *epd_input, const uint8_t *conversion_lut) { - calc_epd_input_4bpp_1k_lut(ld, epd_input, conversion_lut, 0x0); -} - -///////////////////////////// Calculate Lookup Tables -////////////////////////////////// - -/** - * Unpack the waveform data into a lookup table, with bit shifted copies. - */ -static void IRAM_ATTR waveform_lut(const EpdWaveform *waveform, uint8_t *lut, - uint8_t mode, int range, int frame) { - const uint8_t *p_lut = - waveform->mode_data[mode]->range_data[range]->luts + (16 * 4 * frame); - for (uint8_t to = 0; to < 16; to++) { - for (uint8_t from_packed = 0; from_packed < 4; from_packed++) { - uint8_t index = (to << 4) | (from_packed * 4); - uint8_t packed = *(p_lut++); - lut[index] = (packed >> 6) & 3; - lut[index + 1] = (packed >> 4) & 3; - lut[index + 2] = (packed >> 2) & 3; - lut[index + 3] = (packed >> 0) & 3; - // printf("%2X%2X%2X%2X (%d)", lut[index], lut[index + 1], lut[index + 2], - // lut[index + 3], index); - } - // printf("\n"); - } - uint32_t index = 0x100; - for (uint8_t s = 2; s <= 6; s += 2) { - for (int i = 0; i < 0x100; i++) { - lut[index] = lut[index % 0x100] << s; - index++; - } - } -} - -/** - * Build a 16-bit LUT from the waveform if the previous color is - * known, e.g. all white or all black. - * This LUT is use to look up 4 pixels at once, as with the epdiy LUT. - */ -static void IRAM_ATTR waveform_lut_static_from(const EpdWaveform *waveform, - uint8_t *lut, uint8_t from, - uint8_t mode, int range, - int frame) { - const uint8_t *p_lut = - waveform->mode_data[mode]->range_data[range]->luts + (16 * 4 * frame); - - /// index into the packed "from" row - uint8_t fi = from >> 2; - /// bit shift amount for the packed "from" row - uint8_t fs = 6 - 2 * (from & 3); - - // populate the first 4096 bytes - uint8_t v1 = 0; - uint32_t s1 = 0; - for (uint8_t t2 = 0; t2 < 16; t2++) { - uint8_t v2 = ((p_lut[(t2 << 2) + fi] >> fs) & 0x03) << 4; - uint32_t s2 = t2 << 8; - for (uint8_t t3 = 0; t3 < 16; t3++) { - uint8_t v3 = ((p_lut[(t3 << 2) + fi] >> fs) & 0x03) << 2; - uint32_t s3 = t3 << 4; - for (uint8_t t4 = 0; t4 < 16; t4++) { - uint8_t v4 = ((p_lut[(t4 << 2) + fi] >> fs) & 0x03) << 0; - uint32_t s4 = t4; - lut[s1 | s2 | s3 | s4] = v1 | v2 | v3 | v4; - } - } - } - - // now just copy and the first 4096 bytes and add the upper two bits - for (uint8_t t1 = 1; t1 < 16; t1++) { - memcpy(&lut[t1 << 12], lut, 1 << 12); - } - - for (int i = 0; i < 16; i++) { - uint32_t v1 = ((p_lut[(i << 2) + fi] >> fs) & 0x03); - uint32_t mask = (v1 << 30) | (v1 << 22) | (v1 << 14) | (v1 << 6); - for (int j = 0; j < 16 * 16 * 16 / 4; j++) { - ((uint32_t *)lut)[(i << 10) + j] |= mask; - } - } -} - -void IRAM_ATTR provide_out(OutputParams *params) { - while (true) { - // line must be able to hold 2-pixel-per-byte or 1-pixel-per-byte data - uint8_t line[EPD_WIDTH]; - memset(line, 255, EPD_WIDTH); - - xSemaphoreTake(params->start_smphr, portMAX_DELAY); - EpdRect area = params->area; - const uint8_t *ptr = params->data_ptr; - const bool crop = (params->crop_to.width > 0 && params->crop_to.height > 0); - - // number of pixels per byte of input data - int ppB = 0; - int bytes_per_line = 0; - int width_divider = 0; - - if (params->mode & MODE_PACKING_1PPB_DIFFERENCE) { - ppB = 1; - bytes_per_line = area.width; - width_divider = 1; - } else if (params->mode & MODE_PACKING_2PPB) { - ppB = 2; - bytes_per_line = area.width / 2 + area.width % 2; - width_divider = 2; - } else if (params->mode & MODE_PACKING_8PPB) { - ppB = 8; - bytes_per_line = (area.width / 8 + (area.width % 8 > 0)); - width_divider = 8; - } else { - params->error |= EPD_DRAW_INVALID_PACKING_MODE; - } - - int crop_x = (crop ? params->crop_to.x : 0); - int crop_y = (crop ? params->crop_to.y : 0); - int crop_w = (crop ? params->crop_to.width : 0); - int crop_h = (crop ? params->crop_to.height : 0); - - // Adjust for negative starting coordinates with optional crop - if (area.x - crop_x < 0) { - ptr += -(area.x - crop_x) / width_divider; - } - - if (area.y - crop_y < 0) { - ptr += -(area.y - crop_y) * bytes_per_line; - } - - // calculate start and end row with crop - int min_y = area.y + crop_y; - int max_y = min(min_y + (crop ? crop_h : area.height), area.height); - for (int i = 0; i < EPD_HEIGHT; i++) { - if (i < min_y || i >= max_y) { - continue; - } - if (params->drawn_lines != NULL && !params->drawn_lines[i - area.y]) { - ptr += bytes_per_line; - continue; - } - - uint32_t *lp = (uint32_t *)line; - bool shifted = false; - if (area.width == EPD_WIDTH && area.x == 0 && !crop && !params->error) { - lp = (uint32_t *)ptr; - ptr += bytes_per_line; - } else if (!params->error) { - uint8_t *buf_start = (uint8_t *)line; - uint32_t line_bytes = bytes_per_line; - - int min_x = area.x + crop_x; - if (min_x >= 0) { - buf_start += min_x / width_divider; - } else { - // reduce line_bytes to actually used bytes - // ptr was already adjusted above - line_bytes += min_x / width_divider; - } - line_bytes = min(line_bytes, EPD_WIDTH / width_divider - - (uint32_t)(buf_start - line)); - memcpy(buf_start, ptr, line_bytes); - ptr += bytes_per_line; - - int cropped_width = (crop ? crop_w : area.width); - /// consider half-byte shifts in two-pixel-per-Byte mode. - if (ppB == 2) { - // mask last nibble for uneven width - if (cropped_width % 2 == 1 && - min_x / 2 + cropped_width / 2 + 1 < EPD_WIDTH) { - *(buf_start + line_bytes - 1) |= 0xF0; - } - if (area.x % 2 == 1 && !(crop_x % 2 == 1) && min_x < EPD_WIDTH) { - shifted = true; - uint32_t remaining = - (uint32_t)line + EPD_WIDTH / 2 - (uint32_t)buf_start; - uint32_t to_shift = min(line_bytes + 1, remaining); - // shift one nibble to right - nibble_shift_buffer_right(buf_start, to_shift); - } - // consider bit shifts in bit buffers - } else if (ppB == 8) { - // mask last n bits if width is not divisible by 8 - if (cropped_width % 8 != 0 && bytes_per_line + 1 < EPD_WIDTH) { - uint8_t mask = 0; - for (int s = 0; s < cropped_width % 8; s++) { - mask = (mask << 1) | 1; - } - *(buf_start + line_bytes - 1) |= ~mask; - } - - if (min_x % 8 != 0 && min_x < EPD_WIDTH) { - // shift to right - shifted = true; - uint32_t remaining = - (uint32_t)line + EPD_WIDTH / 8 - (uint32_t)buf_start; - uint32_t to_shift = min(line_bytes + 1, remaining); - bit_shift_buffer_right(buf_start, to_shift, min_x % 8); - } - } - lp = (uint32_t *)line; - } - xQueueSendToBack(*params->output_queue, lp, portMAX_DELAY); - if (shifted) { - memset(line, 255, EPD_WIDTH / width_divider); - } - } - - xSemaphoreGive(params->done_smphr); - } -} - -/** - * Set all pixels not in [xmin,xmax) to nop in the current line buffer. - */ -static void IRAM_ATTR mask_line_buffer(int xmin, int xmax) { - // lower bound to where byte order is not an issue. - int memset_start = (xmin / 16) * 4; - int memset_end = min(((xmax + 15) / 16) * 4, EPD_LINE_BYTES); - uint8_t *lb = epd_get_current_buffer(); - - // memset the areas where order is not an issue - memset(lb, 0, memset_start); - memset(lb + memset_end, 0, EPD_LINE_BYTES - memset_end); - - const int offset_table[4] = {2, 3, 0, 1}; - - // mask unused pixels at the start of the output interval - uint8_t line_start_mask = 0xFF << (2 * (xmin % 4)); - uint8_t line_end_mask = 0xFF >> (8 - 2 * (xmax % 4)); - - // number of full bytes to mask - int lower_full_bytes = max(0, (xmin / 4 - memset_start)); - int upper_full_bytes = max(0, (memset_end - ((xmax + 3) / 4))); - assert(lower_full_bytes <= 3); - assert(upper_full_bytes <= 3); - assert(memset_end >= 4); - - // mask full bytes - for (int i = 0; i < lower_full_bytes; i++) { - lb[memset_start + offset_table[i]] = 0x0; - } - for (int i = 0; i < upper_full_bytes; i++) { - lb[memset_end - 4 + offset_table[3 - i]] = 0x0; - } - - // mask partial bytes - if ((memset_start + lower_full_bytes) * 4 < xmin) { - epd_get_current_buffer()[memset_start + offset_table[lower_full_bytes]] &= - line_start_mask; - } - if ((memset_end - upper_full_bytes) * 4 > xmax) { - epd_get_current_buffer()[memset_end - 4 + - offset_table[3 - upper_full_bytes]] &= - line_end_mask; - } -} - -void IRAM_ATTR busy_delay(uint32_t cycles); - -static enum EpdDrawError calculate_lut(OutputParams *params) { - - enum EpdDrawMode mode = params->mode; - enum EpdDrawMode selected_mode = mode & 0x3F; - - // two pixel per byte packing with only target color - if (mode & MODE_PACKING_2PPB && mode & PREVIOUSLY_WHITE && - params->conversion_lut_size == (1 << 16)) { - waveform_lut_static_from(params->waveform, params->conversion_lut, 0x0F, - params->waveform_index, params->waveform_range, - params->frame); - } else if (mode & MODE_PACKING_2PPB && mode & PREVIOUSLY_BLACK && - params->conversion_lut_size == (1 << 16)) { - waveform_lut_static_from(params->waveform, params->conversion_lut, 0x00, - params->waveform_index, params->waveform_range, - params->frame); - - // one pixel per byte with from and to colors - } else if (mode & MODE_PACKING_1PPB_DIFFERENCE || - (mode & MODE_PACKING_2PPB && - params->conversion_lut_size == (1 << 10))) { - waveform_lut(params->waveform, params->conversion_lut, - params->waveform_index, params->waveform_range, params->frame); - - // 1bit per pixel monochrome with only target color - } else if (mode & MODE_PACKING_8PPB && - selected_mode == MODE_EPDIY_MONOCHROME) { - // FIXME: Pack into waveform? - if (mode & PREVIOUSLY_WHITE) { - memcpy(params->conversion_lut, lut_1bpp_black, sizeof(lut_1bpp_black)); - } else if (mode & PREVIOUSLY_BLACK) { - // FIXME: implement! - // memcpy(params->conversion_lut, lut_1bpp_white, sizeof(lut_1bpp_white)); - return EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; - } else { - return EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; - } - - // unknown format. - } else { - return EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; - } - return EPD_DRAW_SUCCESS; -} - -void IRAM_ATTR feed_display(OutputParams *params) { - while (true) { - xSemaphoreTake(params->start_smphr, portMAX_DELAY); - - skipping = 0; - EpdRect area = params->area; - enum EpdDrawMode mode = params->mode; - int frame_time = params->frame_time; - - params->error |= calculate_lut(params); - - void (*input_calc_func)(const uint32_t *, uint8_t *, const uint8_t *) = - NULL; - if (mode & MODE_PACKING_2PPB) { - if (params->conversion_lut_size == 1024) { - if (mode & PREVIOUSLY_WHITE) { - input_calc_func = &calc_epd_input_4bpp_1k_lut_white; - } else if (mode & PREVIOUSLY_BLACK) { - input_calc_func = &calc_epd_input_4bpp_1k_lut_black; - } else { - params->error |= EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; - } - } else if (params->conversion_lut_size == (1 << 16)) { - input_calc_func = &calc_epd_input_4bpp_lut_64k; - } else { - params->error |= EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; - } - } else if (mode & MODE_PACKING_1PPB_DIFFERENCE) { - input_calc_func = &calc_epd_input_1ppB; - } else if (mode & MODE_PACKING_8PPB) { - input_calc_func = &calc_epd_input_1bpp; - } else { - params->error |= EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; - } - - // Adjust min and max row for crop. - const bool crop = (params->crop_to.width > 0 && params->crop_to.height > 0); - int crop_y = (crop ? params->crop_to.y : 0); - int min_y = area.y + crop_y; - int max_y = min(min_y + (crop ? params->crop_to.height : area.height), area.height); - - // interval of the output line that is needed - // FIXME: only lookup needed parts - int line_start_x = area.x + (crop ? params->crop_to.x : 0); - int line_end_x = line_start_x + (crop ? params->crop_to.width : area.width); - line_start_x = min(max(line_start_x, 0), EPD_WIDTH); - line_end_x = min(max(line_end_x, 0), EPD_WIDTH); - - uint64_t now = esp_timer_get_time(); - uint64_t diff = (now - last_frame_start) / 1000; - if (diff < MINIMUM_FRAME_TIME) { - vTaskDelay(MINIMUM_FRAME_TIME - diff); - } - - last_frame_start = esp_timer_get_time(); - - epd_start_frame(); - for (int i = 0; i < EPD_HEIGHT; i++) { - if (i < min_y || i >= max_y) { - skip_row(frame_time); - continue; - } - if (params->drawn_lines != NULL && !params->drawn_lines[i - area.y]) { - skip_row(frame_time); - continue; - } - - uint8_t output[EPD_WIDTH]; - xQueueReceive(*params->output_queue, output, portMAX_DELAY); - if (!params->error) { - (*input_calc_func)((uint32_t *)output, epd_get_current_buffer(), - params->conversion_lut); - if (line_start_x > 0 || line_end_x < EPD_WIDTH) { - mask_line_buffer(line_start_x, line_end_x); - } - } - write_row(frame_time); - } - if (!skipping) { - // Since we "pipeline" row output, we still have to latch out the last - // row. - write_row(frame_time); - } - epd_end_frame(); - - xSemaphoreGive(params->done_smphr); - } -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/lut.h b/lib/libesp32_eink/epdiy/src/epd_driver/lut.h deleted file mode 100755 index 0d3c6b533..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/lut.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "esp_attr.h" -#include -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/queue.h" -#include "epd_driver.h" - -// number of bytes needed for one line of EPD pixel data. -#define EPD_LINE_BYTES EPD_WIDTH / 4 - -///////////////////////////// Utils ///////////////////////////////////// - -/* - * Reorder the output buffer to account for I2S FIFO order. - */ -void IRAM_ATTR reorder_line_buffer(uint32_t *line_data); - -typedef struct { - const uint8_t *data_ptr; - EpdRect crop_to; - SemaphoreHandle_t done_smphr; - SemaphoreHandle_t start_smphr; - EpdRect area; - int frame; - /// index of the waveform mode when using vendor waveforms. - /// This is not necessarily the mode number if the waveform header - //only contains a selection of modes! - int waveform_index; - /// waveform range when using vendor waveforms - int waveform_range; - /// Draw time for the current frame in 1/10ths of us. - int frame_time; - const EpdWaveform* waveform; - enum EpdDrawMode mode; - enum EpdDrawError error; - const bool *drawn_lines; - // Queue of input data lines - QueueHandle_t* output_queue; - - // Lookup table size. - size_t conversion_lut_size; - // Lookup table space. - uint8_t* conversion_lut; -} OutputParams; - - -void IRAM_ATTR feed_display(OutputParams *params); -void IRAM_ATTR provide_out(OutputParams *params); - - -void IRAM_ATTR write_row(uint32_t output_time_dus); -void IRAM_ATTR skip_row(uint8_t pipeline_finish_time); diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/render.c b/lib/libesp32_eink/epdiy/src/epd_driver/render.c deleted file mode 100755 index d7271cce3..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/render.c +++ /dev/null @@ -1,382 +0,0 @@ -#include "epd_temperature.h" -#include "display_ops.h" -#include "epd_driver.h" -#include "include/epd_driver.h" -#include "include/epd_internals.h" -#include "lut.h" - -#include "driver/rtc_io.h" -#include "esp_types.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" -#include "freertos/task.h" -#include "xtensa/core-macros.h" -#include - -inline int min(int x, int y) { return x < y ? x : y; } -inline int max(int x, int y) { return x > y ? x : y; } - -const int clear_cycle_time = 12; - -const int DEFAULT_FRAME_TIME = 120; - -#define RTOS_ERROR_CHECK(x) \ - do { \ - esp_err_t __err_rc = (x); \ - if (__err_rc != pdPASS) { \ - abort(); \ - } \ - } while (0) - -#define CLEAR_BYTE 0B10101010 -#define DARK_BYTE 0B01010101 - -// Queue of input data lines -static QueueHandle_t output_queue; - -static OutputParams fetch_params; -static OutputParams feed_params; - -// Space to use for the EPD output lookup table, which -// is calculated for each cycle. -static uint8_t* conversion_lut; - -void epd_push_pixels(EpdRect area, short time, int color) { - - uint8_t row[EPD_LINE_BYTES] = {0}; - - const uint8_t color_choice[4] = {DARK_BYTE, CLEAR_BYTE, 0x00, 0xFF}; - for (uint32_t i = 0; i < area.width; i++) { - uint32_t position = i + area.x % 4; - uint8_t mask = color_choice[color] & (0b00000011 << (2 * (position % 4))); - row[area.x / 4 + position / 4] |= mask; - } - reorder_line_buffer((uint32_t *)row); - - epd_start_frame(); - - for (int i = 0; i < EPD_HEIGHT; i++) { - // before are of interest: skip - if (i < area.y) { - skip_row(time); - // start area of interest: set row data - } else if (i == area.y) { - 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(time * 10); - // load nop row if done with area - } else if (i >= area.y + area.height) { - skip_row(time); - // output the same as before - } else { - write_row(time * 10); - } - } - // Since we "pipeline" row output, we still have to latch out the last row. - write_row(time * 10); - - epd_end_frame(); -} - - -///////////////////////////// Coordination /////////////////////////////// - - -/** - * Find the waveform temperature range index for a given temperature in °C. - * If no range in the waveform data fits the given temperature, return the - * closest one. - * Returns -1 if the waveform does not contain any temperature range. - */ -int waveform_temp_range_index(const EpdWaveform* waveform, int temperature) { - int idx = 0; - if (waveform->num_temp_ranges == 0) { - return -1; - } - while (idx < waveform->num_temp_ranges - 1 - && waveform->temp_intervals[idx].min < temperature) { - idx++; - } - return idx; -} - -//////////////////////////////// API Procedures ////////////////////////////////// - -static int get_waveform_index(const EpdWaveform* waveform, enum EpdDrawMode mode) { - for (int i=0; i < waveform->num_modes; i++) { - if (waveform->mode_data[i]->type == (mode & 0x3F)) { - return i; - } - } - return -1; -} - -enum EpdDrawError IRAM_ATTR epd_draw_base(EpdRect area, - const uint8_t *data, - EpdRect crop_to, - enum EpdDrawMode mode, - int temperature, - const bool *drawn_lines, - const EpdWaveform *waveform) { - uint8_t line[EPD_WIDTH / 2]; - memset(line, 255, EPD_WIDTH / 2); - - int waveform_range = waveform_temp_range_index(waveform, temperature); - if (waveform_range < 0) { - return EPD_DRAW_NO_PHASES_AVAILABLE; - } - int waveform_index = 0; - uint8_t frame_count = 0; - const EpdWaveformPhases* waveform_phases = NULL; - - // no waveform required for monochrome mode - if (!(mode & MODE_EPDIY_MONOCHROME)) { - waveform_index = get_waveform_index(waveform, mode); - if (waveform_index < 0) { - return EPD_DRAW_MODE_NOT_FOUND; - } - - waveform_phases = waveform->mode_data[waveform_index] - ->range_data[waveform_range]; - // FIXME: error if not present - frame_count = waveform_phases->phases; - } else { - frame_count = 1; - } - - if (crop_to.width < 0 || crop_to.height < 0) { - return EPD_DRAW_INVALID_CROP; - } - - const bool crop = (crop_to.width > 0 && crop_to.height > 0); - if (crop && (crop_to.width > area.width - || crop_to.height > area.height - || crop_to.x > area.width - || crop_to.y > area.height)) { - return EPD_DRAW_INVALID_CROP; - } - - for (uint8_t k = 0; k < frame_count; k++) { - - int frame_time = DEFAULT_FRAME_TIME; - if (waveform_phases != NULL && waveform_phases->phase_times != NULL) { - frame_time = waveform_phases->phase_times[k]; - } - - if (mode & MODE_EPDIY_MONOCHROME) { - frame_time = MONOCHROME_FRAME_TIME; - } - - fetch_params.area = area; - // IMPORTANT: This must only ever read from PSRAM, - // Since the PSRAM workaround is disabled for lut.c - fetch_params.data_ptr = data; - fetch_params.crop_to = crop_to; - fetch_params.frame = k; - fetch_params.waveform_range = waveform_range; - fetch_params.waveform_index = waveform_index; - fetch_params.frame_time = frame_time; - fetch_params.mode = mode; - fetch_params.waveform = waveform; - fetch_params.error = EPD_DRAW_SUCCESS; - fetch_params.drawn_lines = drawn_lines; - fetch_params.output_queue = &output_queue; - - feed_params.area = area; - feed_params.data_ptr = data; - feed_params.crop_to = crop_to; - feed_params.frame = k; - feed_params.frame_time = frame_time; - feed_params.waveform_range = waveform_range; - feed_params.waveform_index = waveform_index; - feed_params.mode = mode; - feed_params.waveform = waveform; - feed_params.error = EPD_DRAW_SUCCESS; - feed_params.drawn_lines = drawn_lines; - feed_params.output_queue = &output_queue; - - xSemaphoreGive(fetch_params.start_smphr); - xSemaphoreGive(feed_params.start_smphr); - xSemaphoreTake(fetch_params.done_smphr, portMAX_DELAY); - xSemaphoreTake(feed_params.done_smphr, portMAX_DELAY); - - enum EpdDrawError all_errors = fetch_params.error | feed_params.error; - if (all_errors != EPD_DRAW_SUCCESS) { - return all_errors; - } - } - return EPD_DRAW_SUCCESS; -} - -void epd_clear_area(EpdRect area) { - epd_clear_area_cycles(area, 3, clear_cycle_time); -} - -void epd_clear_area_cycles(EpdRect area, int cycles, int cycle_time) { - const short white_time = cycle_time; - const short dark_time = cycle_time; - - for (int c = 0; c < cycles; c++) { - for (int i = 0; i < 10; i++) { - epd_push_pixels(area, dark_time, 0); - } - for (int i = 0; i < 10; i++) { - epd_push_pixels(area, white_time, 1); - } - } -} - - - -void epd_init(enum EpdInitOptions options) { - epd_base_init(EPD_WIDTH); - epd_temperature_init(); - - size_t lut_size = 0; - if (options & EPD_LUT_1K) { - lut_size = 1 << 10; - } else if ((options & EPD_LUT_64K) || (options == EPD_OPTIONS_DEFAULT)) { - lut_size = 1 << 16; - } else { - ESP_LOGE("epd", "invalid init options: %d", options); - return; - } - - conversion_lut = (uint8_t *)heap_caps_malloc(lut_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - if (conversion_lut == NULL) { - ESP_LOGE("epd", "could not allocate LUT!"); - } - assert(conversion_lut != NULL); - - fetch_params.conversion_lut = conversion_lut; - fetch_params.conversion_lut_size = lut_size; - feed_params.conversion_lut = conversion_lut; - feed_params.conversion_lut_size = lut_size; - - fetch_params.done_smphr = xSemaphoreCreateBinary(); - fetch_params.start_smphr = xSemaphoreCreateBinary(); - - feed_params.done_smphr = xSemaphoreCreateBinary(); - feed_params.start_smphr = xSemaphoreCreateBinary(); - - RTOS_ERROR_CHECK(xTaskCreatePinnedToCore((void (*)(void *))provide_out, - "epd_fetch", (1 << 12), &fetch_params, 5, - NULL, 0)); - - RTOS_ERROR_CHECK(xTaskCreatePinnedToCore((void (*)(void *))feed_display, - "epd_feed", 1 << 12, &feed_params, - 5, NULL, 1)); - - //conversion_lut = (uint8_t *)heap_caps_malloc(1 << 16, MALLOC_CAP_8BIT); - //assert(conversion_lut != NULL); - int queue_len = 32; - if (options & EPD_FEED_QUEUE_32) { - queue_len = 32; - } else if (options & EPD_FEED_QUEUE_8) { - queue_len = 8; - } - output_queue = xQueueCreate(queue_len, EPD_WIDTH); -} - -void epd_deinit() { - // FIXME: deinit processes -#if defined(CONFIG_EPD_BOARD_REVISION_V5) - gpio_reset_pin(CKH); - rtc_gpio_isolate(CKH); -#endif - epd_base_deinit(); -} - - -EpdRect epd_difference_image_base( - const uint8_t* to, - const uint8_t* from, - EpdRect crop_to, - int fb_width, - int fb_height, - uint8_t* interlaced, - bool* dirty_lines, - uint8_t* from_or, - uint8_t* from_and -) { - assert(from_or != NULL); - assert(from_and != NULL); - // OR over all pixels of the "from"-image - *from_or = 0x00; - // AND over all pixels of the "from"-image - *from_and = 0xFF; - - uint8_t dirty_cols[EPD_WIDTH] = {0}; - int x_end = min(fb_width, crop_to.x + crop_to.width); - int y_end = min(fb_height, crop_to.y + crop_to.height); - - for (int y=crop_to.y; y < y_end; y++) { - uint8_t dirty = 0; - for (int x = crop_to.x; x < x_end; x++) { - uint8_t t = *(to + y*fb_width / 2 + x / 2); - t = (x % 2) ? (t >> 4) : (t & 0x0f); - uint8_t f = *(from + y*fb_width / 2+ x / 2); - *from_or |= f; - *from_and &= f; - f = (x % 2) ? (f >> 4) : (f & 0x0f); - dirty |= (t ^ f); - dirty_cols[x] |= (t ^ f); - interlaced[y * fb_width + x] = (t << 4) | f; - } - dirty_lines[y] = dirty > 0; - } - int min_x, min_y, max_x, max_y; - for (min_x = crop_to.x; min_x < x_end; min_x++) { - if (dirty_cols[min_x] != 0) break; - } - for (max_x = x_end - 1; max_x >= crop_to.x; max_x--) { - if (dirty_cols[max_x] != 0) break; - } - for (min_y = crop_to.y; min_y < y_end; min_y++) { - if (dirty_lines[min_y] != 0) break; - } - for (max_y = y_end - 1; max_y >= crop_to.y; max_y--) { - if (dirty_lines[max_y] != 0) break; - } - EpdRect crop_rect = { - .x = min_x, - .y = min_y, - .width = max(max_x - min_x + 1, 0), - .height = max(max_y - min_y + 1, 0), - }; - return crop_rect; -} - -EpdRect epd_difference_image( - const uint8_t* to, - const uint8_t* from, - uint8_t* interlaced, - bool* dirty_lines -) { - uint8_t from_or = 0; - uint8_t from_and = 0; - return epd_difference_image_base(to, from, epd_full_screen(), EPD_WIDTH, EPD_HEIGHT, interlaced, dirty_lines, &from_or, &from_and); -} - -EpdRect epd_difference_image_cropped( - const uint8_t* to, - const uint8_t* from, - EpdRect crop_to, - uint8_t* interlaced, - bool* dirty_lines, - bool* previously_white, - bool* previously_black -) { - uint8_t from_or, from_and; - - EpdRect result = epd_difference_image_base(to, from, crop_to, EPD_WIDTH, EPD_HEIGHT, interlaced, dirty_lines, &from_or, &from_and); - - if (previously_white != NULL) *previously_white = (from_and == 0xFF); - if (previously_black != NULL) *previously_black = (from_or == 0x00); - return result; -} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.c b/lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.c deleted file mode 100755 index 8e93496f4..000000000 --- a/lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "rmt_pulse.h" -#include "driver/rmt.h" -#include "esp_system.h" - -static intr_handle_t gRMT_intr_handle = NULL; - -// the RMT channel configuration object -static rmt_config_t row_rmt_config; - -// keep track of wether the current pulse is ongoing -volatile bool rmt_tx_done = true; - -/** - * Remote peripheral interrupt. Used to signal when transmission is done. - */ -static void IRAM_ATTR rmt_interrupt_handler(void *arg) { - rmt_tx_done = true; - RMT.int_clr.val = RMT.int_st.val; -} - -void rmt_pulse_init(gpio_num_t pin) { - - row_rmt_config.rmt_mode = RMT_MODE_TX; - // currently hardcoded: use channel 0 - row_rmt_config.channel = RMT_CHANNEL_1; - - row_rmt_config.gpio_num = pin; - row_rmt_config.mem_block_num = 2; - - // Divide 80MHz APB Clock by 8 -> .1us resolution delay - row_rmt_config.clk_div = 8; - - row_rmt_config.tx_config.loop_en = false; - row_rmt_config.tx_config.carrier_en = false; - row_rmt_config.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW; - row_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; - row_rmt_config.tx_config.idle_output_en = true; - - #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0) && ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 0, 2) - #error "This driver is not compatible with IDF version 4.1.\nPlease use 4.0 or >= 4.2!" - #endif - esp_intr_alloc(ETS_RMT_INTR_SOURCE, ESP_INTR_FLAG_LEVEL3, - rmt_interrupt_handler, 0, &gRMT_intr_handle); - - rmt_config(&row_rmt_config); - rmt_set_tx_intr_en(row_rmt_config.channel, true); -} - -void IRAM_ATTR pulse_ckv_ticks(uint16_t high_time_ticks, - uint16_t low_time_ticks, bool wait) { - while (!rmt_tx_done) { - }; - volatile rmt_item32_t *rmt_mem_ptr = - &(RMTMEM.chan[row_rmt_config.channel].data32[0]); - if (high_time_ticks > 0) { - rmt_mem_ptr->level0 = 1; - rmt_mem_ptr->duration0 = high_time_ticks; - rmt_mem_ptr->level1 = 0; - rmt_mem_ptr->duration1 = low_time_ticks; - } else { - rmt_mem_ptr->level0 = 1; - rmt_mem_ptr->duration0 = low_time_ticks; - rmt_mem_ptr->level1 = 0; - rmt_mem_ptr->duration1 = 0; - } - RMTMEM.chan[row_rmt_config.channel].data32[1].val = 0; - rmt_tx_done = false; - RMT.conf_ch[row_rmt_config.channel].conf1.mem_rd_rst = 1; - RMT.conf_ch[row_rmt_config.channel].conf1.mem_owner = RMT_MEM_OWNER_TX; - RMT.conf_ch[row_rmt_config.channel].conf1.tx_start = 1; - while (wait && !rmt_tx_done) { - }; -} - -void IRAM_ATTR pulse_ckv_us(uint16_t high_time_us, uint16_t low_time_us, - bool wait) { - pulse_ckv_ticks(10 * high_time_us, 10 * low_time_us, wait); -} - -bool IRAM_ATTR rmt_busy() { return !rmt_tx_done; } diff --git a/lib/libesp32_eink/epdiy/src/epd_highlevel.h b/lib/libesp32_eink/epdiy/src/epd_highlevel.h index 092fe2556..4a253a2c2 100755 --- a/lib/libesp32_eink/epdiy/src/epd_highlevel.h +++ b/lib/libesp32_eink/epdiy/src/epd_highlevel.h @@ -1,4 +1,157 @@ +/** + * @file "epd_highlevel.h" + * @brief High-level API for drawing to e-paper displays. + * + * The functions in this library provide a simple way to manage updates of e-paper display. + * To use it, follow the steps below: + * + * 1. First, we declare a global object that manages the display state. + * + * EpdiyHighlevelState hl; + * + * 2. Then, the driver and framebuffers must be initialized. + * + * epd_init(EPD_LUT_1K); + * hl = epd_hl_init(EPD_BUILTIN_WAVEFORM); + * + * 3. Now, we can draw to the allocated framebuffer, + * using the draw and text functions defined in `epdiy.h`. + * This will not yet update the display, but only its representation in memory. + * + * // A reference to the framebuffer + * uint8_t* fb = epd_hl_get_framebuffer(&hl); + * + * // draw a black rectangle + * EpdRect some_rect = { + * .x = 100, + * .y = 100, + * .width = 100, + * .height = 100 + * }; + * epd_fill_rect(some_rect, 0x0, fb); + * + * // write a message + * int cursor_x = 100; + * int cursor_y = 300; + * epd_write_default(&FiraSans, "Hello, World!", &cursor_x, &cursor_y, fb); + * + * // finally, update the display! + * int temperature = 25; + * epd_poweron(); + * EpdDrawError err = epd_hl_update_screen(&hl, MODE_GC16, temperature); + * epd_poweroff(); + * + * That's it! For many application, this will be enough. + * For special applications and requirements, have a + * closer look at the `epdiy.h` header. + * + * Colors + * ====== + * + * Since most displays only support 16 colors, we're only using the upper 4 bits (nibble) of a byte + * to detect the color. + * + * char pixel_color = color & 0xF0; + * + * So keep in mind, when passing a color to any function, to always set the upper 4 bits, otherwise + * the color would be black. + * + * Possible colors are `0xF0` (white) through `0x80` (median gray) til `0x00` (black). + */ + +#ifdef __cplusplus +extern "C" { + +#endif #pragma once -// This file is only used in the Arduino IDE -// and just includes the IDF component header. -#include "epd_driver/include/epd_highlevel.h" +#include +#include "epdiy.h" + +#define EPD_BUILTIN_WAVEFORM NULL + +/// Holds the internal state of the high-level API. +typedef struct { + /// The "front" framebuffer object. + uint8_t* front_fb; + /// The "back" framebuffer object. + uint8_t* back_fb; + /// Buffer for holding the interlaced difference image. + uint8_t* difference_fb; + /// Tainted lines based on the last difference calculation. + bool* dirty_lines; + /// Tainted column nibbles based on the last difference calculation. + uint8_t* dirty_columns; + /// The waveform information to use. + const EpdWaveform* waveform; +} EpdiyHighlevelState; + +/** + * Initialize a state object. + * This allocates two framebuffers and an update buffer for + * the display in the external PSRAM. + * In order to keep things simple, a chip reset is triggered if this fails. + * + * @param waveform: The waveform to use for updates. + * If you did not create your own, this will be `EPD_BUILTIN_WAVEFORM`. + * @returns An initialized state object. + */ +EpdiyHighlevelState epd_hl_init(const EpdWaveform* waveform); + +/// Get a reference to the front framebuffer. +/// Use this to draw on the framebuffer before updating the screen with `epd_hl_update_screen()`. +uint8_t* epd_hl_get_framebuffer(EpdiyHighlevelState* state); + +/** + * Update the EPD screen to match the content of the front frame buffer. + * Prior to this, power to the display must be enabled via `epd_poweron()` + * and should be disabled afterwards if no immediate additional updates follow. + * + * @param state: A reference to the `EpdiyHighlevelState` object used. + * @param mode: The update mode to use. + * Additional mode settings like the framebuffer format or + * previous display state are determined by the driver and must not be supplied here. + * In most cases, one of `MODE_GC16` and `MODE_GL16` should be used. + * @param temperature: Environmental temperature of the display in °C. + * @returns `EPD_DRAW_SUCCESS` on sucess, a combination of error flags otherwise. + */ +enum EpdDrawError epd_hl_update_screen( + EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature +); + +/** + * Update an area of the screen to match the content of the front framebuffer. + * Supplying a small area to update can speed up the update process. + * Prior to this, power to the display must be enabled via `epd_poweron()` + * and should be disabled afterwards if no immediate additional updates follow. + * + * @param state: A reference to the `EpdiyHighlevelState` object used. + * @param mode: See `epd_hl_update_screen()`. + * @param temperature: Environmental temperature of the display in °C. + * @param area: Area of the screen to update. + * @returns `EPD_DRAW_SUCCESS` on sucess, a combination of error flags otherwise. + */ +enum EpdDrawError epd_hl_update_area( + EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature, EpdRect area +); + +/** + * Reset the front framebuffer to a white state. + * + * @param state: A reference to the `EpdiyHighlevelState` object used. + */ +void epd_hl_set_all_white(EpdiyHighlevelState* state); + +/** + * Bring the display to a fully white state and get rid of any + * remaining artifacts. + */ +void epd_fullclear(EpdiyHighlevelState* state, int temperature); + +/** + * Just changes the used Waveform + */ +void epd_hl_waveform(EpdiyHighlevelState* state, const EpdWaveform* waveform); + +#ifdef __cplusplus +} +#endif diff --git a/lib/libesp32_eink/epdiy/src/epd_internals.h b/lib/libesp32_eink/epdiy/src/epd_internals.h new file mode 100644 index 000000000..0cc5df3f6 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/epd_internals.h @@ -0,0 +1,89 @@ +/** + * @file epd_internals.h + * @brief Internal definitions and auxiliary data types. + * + * Unless you want to extend the library itself (Which you are very welcome to do), + * you will most likely not need to know about this file. + */ + +#ifndef EPD_INTERNALS_H +#define EPD_INTERNALS_H + +#include +#include + +/// minimal draw time in ms for a frame layer, +/// which will allow all particles to set properly. +#define MINIMUM_FRAME_TIME 12 + +/// Frame draw time for monochrome mode in 1/10 us. +#define MONOCHROME_FRAME_TIME 120 + +typedef struct { + int phases; + const uint8_t* luts; + /// If we have timing information for the individual + /// phases, this is an array of the on-times for each phase. + /// Otherwise, this is NULL. + const int* phase_times; +} EpdWaveformPhases; + +typedef struct { + uint8_t type; + uint8_t temp_ranges; + EpdWaveformPhases const** range_data; +} EpdWaveformMode; + +typedef struct { + int min; + int max; +} EpdWaveformTempInterval; + +typedef struct { + uint8_t num_modes; + uint8_t num_temp_ranges; + EpdWaveformMode const** mode_data; + EpdWaveformTempInterval const* temp_intervals; +} EpdWaveform; + +extern const EpdWaveform epdiy_ED060SC4; +extern const EpdWaveform epdiy_ED097OC4; +extern const EpdWaveform epdiy_ED047TC1; +extern const EpdWaveform epdiy_ED047TC2; +extern const EpdWaveform epdiy_ED097TC2; +extern const EpdWaveform epdiy_ED060XC3; +extern const EpdWaveform epdiy_ED060SCT; +extern const EpdWaveform epdiy_ED133UT2; +extern const EpdWaveform epdiy_NULL; + +/// Font data stored PER GLYPH +typedef struct { + uint16_t width; ///< Bitmap dimensions in pixels + uint16_t height; ///< Bitmap dimensions in pixels + uint16_t advance_x; ///< Distance to advance cursor (x axis) + int16_t left; ///< X dist from cursor pos to UL corner + int16_t top; ///< Y dist from cursor pos to UL corner + uint32_t compressed_size; ///< Size of the zlib-compressed font data. + uint32_t data_offset; ///< Pointer into EpdFont->bitmap +} EpdGlyph; + +/// Glyph interval structure +typedef struct { + uint32_t first; ///< The first unicode code point of the interval + uint32_t last; ///< The last unicode code point of the interval + uint32_t offset; ///< Index of the first code point into the glyph array +} EpdUnicodeInterval; + +/// Data stored for FONT AS A WHOLE +typedef struct { + const uint8_t* bitmap; ///< Glyph bitmaps, concatenated + const EpdGlyph* glyph; ///< Glyph array + const EpdUnicodeInterval* intervals; ///< Valid unicode intervals for this font + uint32_t interval_count; ///< Number of unicode intervals. + bool compressed; ///< Does this font use compressed glyph bitmaps? + uint16_t advance_y; ///< Newline distance (y axis) + int ascender; ///< Maximal height of a glyph above the base line + int descender; ///< Maximal height of a glyph below the base line +} EpdFont; + +#endif // EPD_INTERNALS_H diff --git a/lib/libesp32_eink/epdiy/src/epdiy.c b/lib/libesp32_eink/epdiy/src/epdiy.c new file mode 100644 index 000000000..9735df15e --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/epdiy.c @@ -0,0 +1,545 @@ +#include "epdiy.h" +#include "epd_board.h" +#include "epd_display.h" +#include "output_common/render_method.h" +#include "render.h" + +#include +#include +#include +#include + +// Simple x and y coordinate +typedef struct { + uint16_t x; + uint16_t y; +} Coord_xy; + +static const EpdDisplay_t* display = NULL; + +// Display rotation. Can be updated using epd_set_rotation(enum EpdRotation) +static enum EpdRotation display_rotation = EPD_ROT_LANDSCAPE; + +#ifndef _swap_int +#define _swap_int(a, b) \ + { \ + int t = a; \ + a = b; \ + b = t; \ + } +#endif + +EpdRect epd_full_screen() { + EpdRect area = { .x = 0, .y = 0, .width = epd_width(), .height = epd_height() }; + return area; +} + +void epd_clear() { + epd_clear_area(epd_full_screen()); +} + +void epd_draw_hline(int x, int y, int length, uint8_t color, uint8_t* framebuffer) { + for (int i = 0; i < length; i++) { + int xx = x + i; + epd_draw_pixel(xx, y, color, framebuffer); + } +} + +void epd_draw_vline(int x, int y, int length, uint8_t color, uint8_t* framebuffer) { + for (int i = 0; i < length; i++) { + int yy = y + i; + epd_draw_pixel(x, yy, color, framebuffer); + } +} + +Coord_xy _rotate(uint16_t x, uint16_t y) { + switch (display_rotation) { + case EPD_ROT_LANDSCAPE: + break; + case EPD_ROT_PORTRAIT: + _swap_int(x, y); + x = epd_width() - x - 1; + break; + case EPD_ROT_INVERTED_LANDSCAPE: + x = epd_width() - x - 1; + y = epd_height() - y - 1; + break; + case EPD_ROT_INVERTED_PORTRAIT: + _swap_int(x, y); + y = epd_height() - y - 1; + break; + } + Coord_xy coord = { x, y }; + return coord; +} + +void epd_draw_pixel(int x, int y, uint8_t color, uint8_t* framebuffer) { + // Check rotation and move pixel around if necessary + Coord_xy coord = _rotate(x, y); + x = coord.x; + y = coord.y; + + if (x < 0 || x >= epd_width()) { + return; + } + if (y < 0 || y >= epd_height()) { + return; + } + + uint8_t* buf_ptr = &framebuffer[y * epd_width() / 2 + x / 2]; + if (x % 2) { + *buf_ptr = (*buf_ptr & 0x0F) | (color & 0xF0); + } else { + *buf_ptr = (*buf_ptr & 0xF0) | (color >> 4); + } +} + +void epd_draw_circle(int x0, int y0, int r, uint8_t color, uint8_t* framebuffer) { + int f = 1 - r; + int ddF_x = 1; + int ddF_y = -2 * r; + int x = 0; + int y = r; + + epd_draw_pixel(x0, y0 + r, color, framebuffer); + epd_draw_pixel(x0, y0 - r, color, framebuffer); + epd_draw_pixel(x0 + r, y0, color, framebuffer); + epd_draw_pixel(x0 - r, y0, color, framebuffer); + + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + epd_draw_pixel(x0 + x, y0 + y, color, framebuffer); + epd_draw_pixel(x0 - x, y0 + y, color, framebuffer); + epd_draw_pixel(x0 + x, y0 - y, color, framebuffer); + epd_draw_pixel(x0 - x, y0 - y, color, framebuffer); + epd_draw_pixel(x0 + y, y0 + x, color, framebuffer); + epd_draw_pixel(x0 - y, y0 + x, color, framebuffer); + epd_draw_pixel(x0 + y, y0 - x, color, framebuffer); + epd_draw_pixel(x0 - y, y0 - x, color, framebuffer); + } +} + +void epd_fill_circle(int x0, int y0, int r, uint8_t color, uint8_t* framebuffer) { + epd_draw_vline(x0, y0 - r, 2 * r + 1, color, framebuffer); + epd_fill_circle_helper(x0, y0, r, 3, 0, color, framebuffer); +} + +void epd_fill_circle_helper( + int x0, int y0, int r, int corners, int delta, uint8_t color, uint8_t* framebuffer +) { + int f = 1 - r; + int ddF_x = 1; + int ddF_y = -2 * r; + int x = 0; + int y = r; + int px = x; + int py = y; + + delta++; // Avoid some +1's in the loop + + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + // These checks avoid double-drawing certain lines, important + // for the SSD1306 library which has an INVERT drawing mode. + if (x < (y + 1)) { + if (corners & 1) + epd_draw_vline(x0 + x, y0 - y, 2 * y + delta, color, framebuffer); + if (corners & 2) + epd_draw_vline(x0 - x, y0 - y, 2 * y + delta, color, framebuffer); + } + if (y != py) { + if (corners & 1) + epd_draw_vline(x0 + py, y0 - px, 2 * px + delta, color, framebuffer); + if (corners & 2) + epd_draw_vline(x0 - py, y0 - px, 2 * px + delta, color, framebuffer); + py = y; + } + px = x; + } +} + +void epd_draw_rect(EpdRect rect, uint8_t color, uint8_t* framebuffer) { + int x = rect.x; + int y = rect.y; + int w = rect.width; + int h = rect.height; + epd_draw_hline(x, y, w, color, framebuffer); + epd_draw_hline(x, y + h - 1, w, color, framebuffer); + epd_draw_vline(x, y, h, color, framebuffer); + epd_draw_vline(x + w - 1, y, h, color, framebuffer); +} + +void epd_fill_rect(EpdRect rect, uint8_t color, uint8_t* framebuffer) { + int x = rect.x; + int y = rect.y; + int w = rect.width; + int h = rect.height; + for (int i = y; i < y + h; i++) { + epd_draw_hline(x, i, w, color, framebuffer); + } +} + +static void epd_write_line(int x0, int y0, int x1, int y1, uint8_t color, uint8_t* framebuffer) { + int steep = abs(y1 - y0) > abs(x1 - x0); + if (steep) { + _swap_int(x0, y0); + _swap_int(x1, y1); + } + + if (x0 > x1) { + _swap_int(x0, x1); + _swap_int(y0, y1); + } + + int dx, dy; + dx = x1 - x0; + dy = abs(y1 - y0); + + int err = dx / 2; + int ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1; + } + + for (; x0 <= x1; x0++) { + if (steep) { + epd_draw_pixel(y0, x0, color, framebuffer); + } else { + epd_draw_pixel(x0, y0, color, framebuffer); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } +} + +void epd_draw_line(int x0, int y0, int x1, int y1, uint8_t color, uint8_t* framebuffer) { + // Update in subclasses if desired! + if (x0 == x1) { + if (y0 > y1) + _swap_int(y0, y1); + epd_draw_vline(x0, y0, y1 - y0 + 1, color, framebuffer); + } else if (y0 == y1) { + if (x0 > x1) + _swap_int(x0, x1); + epd_draw_hline(x0, y0, x1 - x0 + 1, color, framebuffer); + } else { + epd_write_line(x0, y0, x1, y1, color, framebuffer); + } +} + +void epd_draw_triangle( + int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, uint8_t* framebuffer +) { + epd_draw_line(x0, y0, x1, y1, color, framebuffer); + epd_draw_line(x1, y1, x2, y2, color, framebuffer); + epd_draw_line(x2, y2, x0, y0, color, framebuffer); +} + +void epd_fill_triangle( + int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, uint8_t* framebuffer +) { + int a, b, y, last; + + // Sort coordinates by Y order (y2 >= y1 >= y0) + if (y0 > y1) { + _swap_int(y0, y1); + _swap_int(x0, x1); + } + if (y1 > y2) { + _swap_int(y2, y1); + _swap_int(x2, x1); + } + if (y0 > y1) { + _swap_int(y0, y1); + _swap_int(x0, x1); + } + + if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing + a = b = x0; + if (x1 < a) + a = x1; + else if (x1 > b) + b = x1; + if (x2 < a) + a = x2; + else if (x2 > b) + b = x2; + epd_draw_hline(a, y0, b - a + 1, color, framebuffer); + return; + } + + int dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0, dx12 = x2 - x1, + dy12 = y2 - y1; + int32_t sa = 0, sb = 0; + + // For upper part of triangle, find scanline crossings for segments + // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 + // is included here (and second loop will be skipped, avoiding a /0 + // error there), otherwise scanline y1 is skipped here and handled + // in the second loop...which also avoids a /0 error here if y0=y1 + // (flat-topped triangle). + if (y1 == y2) + last = y1; // Include y1 scanline + else + last = y1 - 1; // Skip it + + for (y = y0; y <= last; y++) { + a = x0 + sa / dy01; + b = x0 + sb / dy02; + sa += dx01; + sb += dx02; + /* longhand: + a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if (a > b) + _swap_int(a, b); + epd_draw_hline(a, y, b - a + 1, color, framebuffer); + } + + // For lower part of triangle, find scanline crossings for segments + // 0-2 and 1-2. This loop is skipped if y1=y2. + sa = (int32_t)dx12 * (y - y1); + sb = (int32_t)dx02 * (y - y0); + for (; y <= y2; y++) { + a = x1 + sa / dy12; + b = x0 + sb / dy02; + sa += dx12; + sb += dx02; + /* longhand: + a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if (a > b) + _swap_int(a, b); + epd_draw_hline(a, y, b - a + 1, color, framebuffer); + } +} + +void epd_copy_to_framebuffer(EpdRect image_area, const uint8_t* image_data, uint8_t* framebuffer) { + assert(framebuffer != NULL); + + for (uint32_t i = 0; i < image_area.width * image_area.height; i++) { + uint32_t value_index = i; + // for images of uneven width, + // consume an additional nibble per row. + if (image_area.width % 2) { + value_index += i / image_area.width; + } + uint8_t val = (value_index % 2) ? (image_data[value_index / 2] & 0xF0) >> 4 + : image_data[value_index / 2] & 0x0F; + + int xx = image_area.x + i % image_area.width; + if (xx < 0 || xx >= epd_width()) { + continue; + } + int yy = image_area.y + i / image_area.width; + if (yy < 0 || yy >= epd_height()) { + continue; + } + uint8_t* buf_ptr = &framebuffer[yy * epd_width() / 2 + xx / 2]; + if (xx % 2) { + *buf_ptr = (*buf_ptr & 0x0F) | (val << 4); + } else { + *buf_ptr = (*buf_ptr & 0xF0) | val; + } + } +} + +enum EpdDrawError epd_draw_image(EpdRect area, const uint8_t* data, const EpdWaveform* waveform) { + int temperature = epd_ambient_temperature(); + assert(waveform != NULL); + EpdRect no_crop = { + .x = 0, + .y = 0, + .width = 0, + .height = 0, + }; + return epd_draw_base(area, data, no_crop, EPD_MODE_DEFAULT, temperature, NULL, NULL, waveform); +} + +void epd_set_rotation(enum EpdRotation rotation) { + display_rotation = rotation; +} + +enum EpdRotation epd_get_rotation() { + return display_rotation; +} + +int epd_rotated_display_width() { + int display_width = epd_width(); + switch (display_rotation) { + case EPD_ROT_PORTRAIT: + display_width = epd_height(); + break; + case EPD_ROT_INVERTED_PORTRAIT: + display_width = epd_height(); + break; + case EPD_ROT_INVERTED_LANDSCAPE: + case EPD_ROT_LANDSCAPE: + break; + } + return display_width; +} + +int epd_rotated_display_height() { + int display_height = epd_height(); + switch (display_rotation) { + case EPD_ROT_PORTRAIT: + display_height = epd_width(); + break; + case EPD_ROT_INVERTED_PORTRAIT: + display_height = epd_width(); + break; + case EPD_ROT_INVERTED_LANDSCAPE: + case EPD_ROT_LANDSCAPE: + break; + } + return display_height; +} + +uint8_t epd_get_pixel(int x, int y, int fb_width, int fb_height, const uint8_t* framebuffer) { + if (x < 0 || x >= fb_width) { + return 0; + } + if (y < 0 || y >= fb_height) { + return 0; + } + int fb_width_bytes = fb_width / 2 + fb_width % 2; + uint8_t buf_val = framebuffer[y * fb_width_bytes + x / 2]; + if (x % 2) { + buf_val = (buf_val & 0xF0) >> 4; + } else { + buf_val = (buf_val & 0x0F); + } + + // epd_draw_pixel needs a 0 -> 255 value + return buf_val << 4; +} + +static void draw_rotated_transparent_image( + EpdRect image_area, + const uint8_t* image_buffer, + uint8_t* framebuffer, + uint8_t* transparent_color +) { + uint16_t x_offset = 0; + uint16_t y_offset = 0; + uint8_t pixel_color; + for (uint16_t y = 0; y < image_area.height; y++) { + for (uint16_t x = 0; x < image_area.width; x++) { + x_offset = image_area.x + x; + y_offset = image_area.y + y; + if (x_offset >= epd_rotated_display_width()) + continue; + if (y_offset >= epd_rotated_display_height()) + continue; + pixel_color = epd_get_pixel(x, y, image_area.width, image_area.height, image_buffer); + if (transparent_color == NULL || pixel_color != (*transparent_color)) + epd_draw_pixel(x_offset, y_offset, pixel_color, framebuffer); + } + } +} + +void epd_draw_rotated_transparent_image( + EpdRect image_area, const uint8_t* image_buffer, uint8_t* framebuffer, uint8_t transparent_color +) { + draw_rotated_transparent_image(image_area, image_buffer, framebuffer, &transparent_color); +} + +void epd_draw_rotated_image(EpdRect image_area, const uint8_t* image_buffer, uint8_t* framebuffer) { + if (epd_get_rotation() != EPD_ROT_LANDSCAPE) { + draw_rotated_transparent_image(image_area, image_buffer, framebuffer, NULL); + } else { + epd_copy_to_framebuffer(image_area, image_buffer, framebuffer); + } +} + +void epd_poweron() { + epd_current_board()->poweron(epd_ctrl_state()); +} + +void epd_poweroff() { + epd_current_board()->poweroff(epd_ctrl_state()); +} + +void epd_init( + const EpdBoardDefinition* board, const EpdDisplay_t* disp, enum EpdInitOptions options +) { + display = disp; + epd_set_board(board); + epd_renderer_init(options); +} + +void epd_deinit() { + epd_renderer_deinit(); +} + +float epd_ambient_temperature() { + if (!epd_current_board()) { + ESP_LOGE("epdiy", "Could not read temperature: board not set!"); + return 0.0; + } + + if (!epd_current_board()->get_temperature) { + ESP_LOGW("epdiy", "No ambient temperature sensor - returning 21C"); + return 21.0; + } + return epd_current_board()->get_temperature(); +} + +void epd_set_vcom(uint16_t vcom) { + if (!epd_current_board()) { + ESP_LOGE("epdiy", "Could not set VCOM: board not set!"); + return; + } + + if (!epd_current_board()->set_vcom) { + ESP_LOGE("epdiy", "Could not set VCOM: board does not support setting VCOM in software."); + return; + } + return epd_current_board()->set_vcom(vcom); +} + +const EpdDisplay_t* epd_get_display() { + assert(display != NULL); + return display; +} + +int epd_width() { + return display->width; +} + +int epd_height() { + return display->height; +} + +void epd_set_lcd_pixel_clock_MHz(int frequency) { +#ifdef RENDER_METHOD_LCD + void epd_lcd_set_pixel_clock_MHz(int frequency); + epd_lcd_set_pixel_clock_MHz(frequency); +#else + ESP_LOGW("epdiy", "called set_lcd_pixel_clock_MHz, but LCD driver is not used!"); +#endif +} diff --git a/lib/libesp32_eink/epdiy/src/epdiy.h b/lib/libesp32_eink/epdiy/src/epdiy.h new file mode 100644 index 000000000..9f8ffa5f7 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/epdiy.h @@ -0,0 +1,605 @@ +/** + * @file epdiy.h + * A driver library for drawing to an EPD. + */ +#include "epd_display.h" +#ifdef __cplusplus +extern "C" { +#endif + +#pragma once +#include +#include +#include + +#include "epd_internals.h" + +/// An area on the display. +typedef struct { + /// Horizontal position. + int x; + /// Vertical position. + int y; + /// Area / image width, must be positive. + int width; + /// Area / image height, must be positive. + int height; +} EpdRect; + +/// Global EPD driver options. +enum EpdInitOptions { + /// Use the default options. + EPD_OPTIONS_DEFAULT = 0, + /// Use a small look-up table of 1024 bytes. + /// The EPD driver will use less space, but performance may be worse. + EPD_LUT_1K = 1, + /// Use a 64K lookup table. (default) + /// Best performance, but permanently occupies a 64k block of internal memory. + EPD_LUT_64K = 2, + + /// Use a small feed queue of 8 display lines. + /// This uses less memory, but may impact performance. + EPD_FEED_QUEUE_8 = 4, + /// Use a feed queue of 32 display lines. (default) + /// Best performance, but larger memory footprint. + EPD_FEED_QUEUE_32 = 8, +}; + +/// The image drawing mode. +enum EpdDrawMode { + /// An init waveform. + /// This is currently unused, use `epd_clear()` instead. + MODE_INIT = 0x0, + /// Direct Update: Go from any color to black for white only. + MODE_DU = 0x1, + /// Go from any grayscale value to another with a flashing update. + MODE_GC16 = 0x2, + /// Faster version of `MODE_GC16`. + /// Not available with default epdiy waveforms. + MODE_GC16_FAST = 0x3, + /// Animation Mode: Fast, monochrom updates. + /// Not available with default epdiy waveforms. + MODE_A2 = 0x4, + /// Go from any grayscale value to another with a non-flashing update. + MODE_GL16 = 0x5, + /// Faster version of `MODE_GL16`. + /// Not available with default epdiy waveforms. + MODE_GL16_FAST = 0x6, + /// A 4-grayscale version of `MODE_DU`. + /// Not available with default epdiy waveforms. + MODE_DU4 = 0x7, + /// Arbitrary transitions for 4 grayscale values. + /// Not available with default epdiy waveforms. + MODE_GL4 = 0xA, + /// Not available with default epdiy waveforms. + MODE_GL16_INV = 0xB, + + /// Go from a white screen to arbitrary grayscale, quickly. + /// Exclusively available with epdiy waveforms. + MODE_EPDIY_WHITE_TO_GL16 = 0x10, + /// Go from a black screen to arbitrary grayscale, quickly. + /// Exclusively available with epdiy waveforms. + MODE_EPDIY_BLACK_TO_GL16 = 0x11, + + /// Monochrome mode. Only supported with 1bpp buffers. + MODE_EPDIY_MONOCHROME = 0x20, + + MODE_UNKNOWN_WAVEFORM = 0x3F, + + // Framebuffer packing modes + /// 1 bit-per-pixel framebuffer with 0 = black, 1 = white. + /// MSB is left is the leftmost pixel, LSB the rightmost pixel. + MODE_PACKING_8PPB = 0x40, + /// 4 bit-per pixel framebuffer with 0x0 = black, 0xF = white. + /// The upper nibble corresponds to the left pixel. + /// A byte cannot wrap over multiple rows, images of uneven width + /// must add a padding nibble per line. + MODE_PACKING_2PPB = 0x80, + /// A difference image with one pixel per byte. + /// The upper nibble marks the "from" color, + /// the lower nibble the "to" color. + MODE_PACKING_1PPB_DIFFERENCE = 0x100, + // reserver for 4PPB mode + + /// Assert that the display has a uniform color, e.g. after initialization. + /// If `MODE_PACKING_2PPB` is specified, a optimized output calculation can be used. + /// Draw on a white background + PREVIOUSLY_WHITE = 0x200, + /// See `PREVIOUSLY_WHITE`. + /// Draw on a black background + PREVIOUSLY_BLACK = 0x400, + + /// Enforce NOT using S3 Vector extensions. + /// USed for testing. + MODE_FORCE_NO_PIE = 0x800, +}; + +/** Display software rotation. + * Sets the rotation for the purposes of the drawing and font functions + * Use epd_set_rotation(EPD_ROT_*) to set it using one of the options below + * Use epd_get_rotation() in case you need to read this value + */ +enum EpdRotation { + EPD_ROT_LANDSCAPE = 0, + EPD_ROT_PORTRAIT = 1, + EPD_ROT_INVERTED_LANDSCAPE = 2, + EPD_ROT_INVERTED_PORTRAIT = 3, +}; + +/// Possible failures when drawing. +enum EpdDrawError { + EPD_DRAW_SUCCESS = 0x0, + /// No valid framebuffer packing mode was specified. + EPD_DRAW_INVALID_PACKING_MODE = 0x1, + + /// No lookup table implementation for this mode / packing. + EPD_DRAW_LOOKUP_NOT_IMPLEMENTED = 0x2, + + /// The string to draw is invalid. + EPD_DRAW_STRING_INVALID = 0x4, + + /// The string was not empty, but no characters where drawable. + EPD_DRAW_NO_DRAWABLE_CHARACTERS = 0x8, + + /// Allocation failed + EPD_DRAW_FAILED_ALLOC = 0x10, + + /// A glyph could not be drawn, and not fallback was present. + EPD_DRAW_GLYPH_FALLBACK_FAILED = 0x20, + + /// The specified crop area is invalid. + EPD_DRAW_INVALID_CROP = 0x40, + + /// No such mode is available with the current waveform. + EPD_DRAW_MODE_NOT_FOUND = 0x80, + + /// The waveform info file contains no applicable temperature range. + EPD_DRAW_NO_PHASES_AVAILABLE = 0x100, + + /// An invalid combination of font flags was used. + EPD_DRAW_INVALID_FONT_FLAGS = 0x200, + + /// The waveform lookup could not keep up with the display output. + /// + /// Reduce the display clock speed. + EPD_DRAW_EMPTY_LINE_QUEUE = 0x400, +}; + +/// The default draw mode (non-flashy refresh, whith previously white screen). +#define EPD_MODE_DEFAULT (MODE_GL16 | PREVIOUSLY_WHITE) + +/// Font drawing flags +enum EpdFontFlags { + /// Draw a background. + /// + /// Take the background into account + /// when calculating the size. + EPD_DRAW_BACKGROUND = 0x1, + + /// Left-Align lines + EPD_DRAW_ALIGN_LEFT = 0x2, + /// Right-align lines + EPD_DRAW_ALIGN_RIGHT = 0x4, + /// Center-align lines + EPD_DRAW_ALIGN_CENTER = 0x8, +}; + +/// Font properties. +typedef struct { + /// Foreground color + uint8_t fg_color : 4; + /// Background color + uint8_t bg_color : 4; + /// Use the glyph for this codepoint for missing glyphs. + uint32_t fallback_glyph; + /// Additional flags, reserved for future use + enum EpdFontFlags flags; +} EpdFontProperties; + +#include "epd_board.h" +#include "epd_board_specific.h" +#include "epd_display.h" +#include "epd_highlevel.h" + +/** Initialize the ePaper display */ +void epd_init( + const EpdBoardDefinition* board, const EpdDisplay_t* display, enum EpdInitOptions options +); + +/** + * Get the configured display. + */ +const EpdDisplay_t* epd_get_display(); + +/** + * Get the EPD display's witdth. + */ +int epd_width(); + +/** + * Get the EPD display's height. + */ +int epd_height(); + +/** + * Set the display common voltage if supported. + * + * Voltage is set as absolute value in millivolts. + * Although VCOM is negative, this function takes a positive (absolute) value. + */ +void epd_set_vcom(uint16_t vcom); + +/** + * Get the current ambient temperature in °C, + * if the board has a sensor. + */ +float epd_ambient_temperature(); + +/** Get the display rotation value */ +enum EpdRotation epd_get_rotation(); + +/** Set the display rotation: Affects the drawing and font functions */ +void epd_set_rotation(enum EpdRotation rotation); + +/** Get screen width after rotation */ +int epd_rotated_display_width(); + +/** Get screen height after rotation */ +int epd_rotated_display_height(); + +/** Deinit the ePaper display */ +void epd_deinit(); + +/** Enable display power supply. */ +void epd_poweron(); + +/** Disable display power supply. */ +void epd_poweroff(); + +/** Clear the whole screen by flashing it. */ +void epd_clear(); + +/** + * Clear an area by flashing it. + * + * @param area: The area to clear. + */ +void epd_clear_area(EpdRect area); + +/** + * Clear an area by flashing it. + * + * @param area: The area to clear. + * @param cycles: The number of black-to-white clear cycles. + * @param cycle_time: Length of a cycle. Default: 50 (us). + */ +void epd_clear_area_cycles(EpdRect area, int cycles, int cycle_time); + +/** + * @returns Rectancle representing the whole screen area. + */ +EpdRect epd_full_screen(); + +/** + * Draw a picture to a given framebuffer. + * + * @param image_area: The area to copy to. `width` and `height` of the area + * must correspond to the image dimensions in pixels. + * @param image_data: The image data, as a buffer of 4 bit wide brightness + * values. Pixel data is packed (two pixels per byte). A byte cannot wrap over + * multiple rows, images of uneven width must add a padding nibble per line. + * @param framebuffer: The framebuffer object, + * which must be `epd_width() / 2 * epd_height()` large. + */ +void epd_copy_to_framebuffer(EpdRect image_area, const uint8_t* image_data, uint8_t* framebuffer); + +/** + * Draw a pixel a given framebuffer. + * + * @param x: Horizontal position in pixels. + * @param y: Vertical position in pixels. + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_draw_pixel(int x, int y, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a horizontal line to a given framebuffer. + * + * @param x: Horizontal start position in pixels. + * @param y: Vertical start position in pixels. + * @param length: Length of the line in pixels. + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + * which must be `epd_width() / 2 * epd_height()` bytes large. + */ +void epd_draw_hline(int x, int y, int length, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a horizontal line to a given framebuffer. + * + * @param x: Horizontal start position in pixels. + * @param y: Vertical start position in pixels. + * @param length: Length of the line in pixels. + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + * which must be `epd_width() / 2 * epd_height()` bytes large. + */ +void epd_draw_vline(int x, int y, int length, uint8_t color, uint8_t* framebuffer); + +void epd_fill_circle_helper( + int x0, int y0, int r, int corners, int delta, uint8_t color, uint8_t* framebuffer +); + +/** + * Draw a circle with given center and radius + * + * @param x: Center-point x coordinate + * @param y: Center-point y coordinate + * @param r: Radius of the circle in pixels + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_draw_circle(int x, int y, int r, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a circle with fill with given center and radius + * + * @param x: Center-point x coordinate + * @param y: Center-point y coordinate + * @param r: Radius of the circle in pixels + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_fill_circle(int x, int y, int r, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a rectanle with no fill color + * + * @param rect: The rectangle to draw. + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_draw_rect(EpdRect rect, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a rectanle with fill color + * + * @param rect: The rectangle to fill. + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_fill_rect(EpdRect rect, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a line + * + * @param x0 Start point x coordinate + * @param y0 Start point y coordinate + * @param x1 End point x coordinate + * @param y1 End point y coordinate + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_draw_line(int x0, int y0, int x1, int y1, uint8_t color, uint8_t* framebuffer); + +/** + * Draw a triangle with no fill color + * + * @param x0 Vertex #0 x coordinate + * @param y0 Vertex #0 y coordinate + * @param x1 Vertex #1 x coordinate + * @param y1 Vertex #1 y coordinate + * @param x2 Vertex #2 x coordinate + * @param y2 Vertex #2 y coordinate + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_draw_triangle( + int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, uint8_t* framebuffer +); + +/** + * Draw a triangle with color-fill + * + * @param x0 Vertex #0 x coordinate + * @param y0 Vertex #0 y coordinate + * @param x1 Vertex #1 x coordinate + * @param y1 Vertex #1 y coordinate + * @param x2 Vertex #2 x coordinate + * @param y2 Vertex #2 y coordinate + * @param color: The gray value of the line (see [Colors](#Colors)); + * @param framebuffer: The framebuffer to draw to, + */ +void epd_fill_triangle( + int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, uint8_t* framebuffer +); +/** + * Get the current ambient temperature in °C, if supported by the board. + * Requires the display to be powered on. + */ +float epd_ambient_temperature(); + +/** + * The default font properties. + */ +EpdFontProperties epd_font_properties_default(); + +/*! + * Get the text bounds for string, when drawn at (x, y). + * Set font properties to NULL to use the defaults. + */ +void epd_get_text_bounds( + const EpdFont* font, + const char* string, + const int* x, + const int* y, + int* x1, + int* y1, + int* w, + int* h, + const EpdFontProperties* props +); +/*! + * Returns a rect with the bounds of the text + * @param font : the font used to get the character sizes + * @param string: pointer to c string + * @param x : left most position of rectangle + * @param y : top most point of the rectangle + * @param margin : to be pllied to the width and height + * @returns EpdRect with x and y as per the original and height and width + * adjusted to fit the text with the margin added as well. + */ +EpdRect epd_get_string_rect( + const EpdFont* font, + const char* string, + int x, + int y, + int margin, + const EpdFontProperties* properties +); + +/** + * Write text to the EPD. + */ +enum EpdDrawError epd_write_string( + const EpdFont* font, + const char* string, + int* cursor_x, + int* cursor_y, + uint8_t* framebuffer, + const EpdFontProperties* properties +); + +/** + * Write a (multi-line) string to the EPD. + */ +enum EpdDrawError epd_write_default( + const EpdFont* font, const char* string, int* cursor_x, int* cursor_y, uint8_t* framebuffer +); + +/** + * Get the font glyph for a unicode code point. + */ +const EpdGlyph* epd_get_glyph(const EpdFont* font, uint32_t code_point); + +/** + * Darken / lighten an area for a given time. + * + * @param area: The area to darken / lighten. + * @param time: The time in us to apply voltage to each pixel. + * @param color: 1: lighten, 0: darken. + */ +void epd_push_pixels(EpdRect area, short time, int color); + +/** + * Base function for drawing an image on the screen. + * If It is very customizable, and the documentation below should be studied carefully. + * For simple applications, use the epdiy highlevel api in "epd_higlevel.h". + * + * @param area: The area of the screen to draw to. + * This can be imagined as shifting the origin of the frame buffer. + * @param data: A full framebuffer of display data. + * It's structure depends on the chosen `mode`. + * @param crop_to: Only draw a part of the frame buffer. + * Set to `epd_full_screen()` to draw the full buffer. + * @param mode: Specifies the Waveform used, the framebuffer format + * and additional information, like if the display is cleared. + * @param temperature: The temperature of the display in °C. + * Currently, this is unused by the default waveforms at can be + * set to room temperature, e.g. 20-25°C. + * @param drawn_lines: If not NULL, an array of at least the height of the + * image. Every line where the corresponding value in `lines` is `false` will be + * skipped. + * @param drawn_columns: If not NULL, an array of at least the width of the + * image / 2, 16-byte aligned. + * The image will only be updated in pixel columns where the corresponding nibbles are + * non-zero. + * @param waveform: The waveform information to use for drawing. + * If you don't have special waveforms, use `EPD_BUILTIN_WAVEFORM`. + * @returns `EPD_DRAW_SUCCESS` on sucess, a combination of error flags otherwise. + */ +enum EpdDrawError epd_draw_base( + EpdRect area, + const uint8_t* data, + EpdRect crop_to, + enum EpdDrawMode mode, + int temperature, + const bool* drawn_lines, + const uint8_t* drawn_columns, + const EpdWaveform* waveform +); +/** + * Calculate a `MODE_PACKING_1PPB_DIFFERENCE` difference image + * from two `MODE_PACKING_2PPB` (4 bit-per-pixel) buffers. + * If you're using the epdiy highlevel api, this is handled by the update functions. + * + * @param to: The goal image as 4-bpp (`MODE_PACKING_2PPB`) framebuffer. + * @param from: The previous image as 4-bpp (`MODE_PACKING_2PPB`) framebuffer. + * @param crop_to: Only calculate the difference for a crop of the input framebuffers. + * The `interlaced` will not be modified outside the crop area. + * @param interlaced: The resulting difference image in `MODE_PACKING_1PPB_DIFFERENCE` format. + * @param dirty_lines: An array of at least `epd_height()`. + * The positions corresponding to lines where `to` and `from` differ + * are set to `true`, otherwise to `false`. + * @param col_dirtyness: An array of at least `epd_width() / 2`. + * If a nibble is set to non-zero, the pixel column is marked as changed, aka "dirty." + * The buffer must be 16 byte aligned. + * @returns The smallest rectangle containing all changed pixels. + */ +EpdRect epd_difference_image_cropped( + const uint8_t* to, + const uint8_t* from, + EpdRect crop_to, + uint8_t* interlaced, + bool* dirty_lines, + uint8_t* col_dirtiness +); + +/** + * Simplified version of `epd_difference_image_cropped()`, which considers the + * whole display frame buffer. + * + * See `epd_difference_image_cropped() for details.` + */ +EpdRect epd_difference_image( + const uint8_t* to, + const uint8_t* from, + uint8_t* interlaced, + bool* dirty_lines, + uint8_t* col_dirtiness +); + +/** + * Return the pixel color of a 4 bit image array + * x,y coordinates of the image pixel + * fb_width, fb_height dimensions + * @returns uint8_t 0-255 representing the color on given coordinates (as in epd_draw_pixel) + */ +uint8_t epd_get_pixel(int x, int y, int fb_width, int fb_height, const uint8_t* framebuffer); + +/** + * Draw an image reading pixel per pixel and being rotation aware (via epd_draw_pixel) + */ +void epd_draw_rotated_image(EpdRect image_area, const uint8_t* image_buffer, uint8_t* framebuffer); + +/** + * Draw an image reading pixel per pixel and being rotation aware (via epd_draw_pixel) + * With an optional transparent color (color key transparency) + */ +void epd_draw_rotated_transparent_image( + EpdRect image_area, const uint8_t* image_buffer, uint8_t* framebuffer, uint8_t transparent_color +); + +/** + * Override the pixel clock when using the LCD driver for display output (Epdiy V7+). + * This may result in draws failing if it's set too high! + * + * This method can be used to tune your application for maximum refresh speed, + * if you can guarantee the driver can keep up. + */ +void epd_set_lcd_pixel_clock_MHz(int frequency); + +#ifdef __cplusplus +} +#endif diff --git a/lib/libesp32_eink/epdiy/src/font.c b/lib/libesp32_eink/epdiy/src/font.c new file mode 100644 index 000000000..39e41122d --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/font.c @@ -0,0 +1,434 @@ +#include +#include +#include +#include + +#include "epdiy.h" + +#include +#include +#include +#include + +typedef struct { + uint8_t mask; /* char data will be bitwise AND with this */ + uint8_t lead; /* start bytes of current char in utf-8 encoded character */ + uint32_t beg; /* beginning of codepoint range */ + uint32_t end; /* end of codepoint range */ + int bits_stored; /* the number of bits from the codepoint that fits in char */ +} utf_t; + +/* + * UTF-8 decode inspired from rosetta code + * https://rosettacode.org/wiki/UTF-8_encode_and_decode#C + */ +static utf_t* utf[] = { + /* mask lead beg end bits */ + [0] = &(utf_t){ 0b00111111, 0b10000000, 0, 0, 6 }, + [1] = &(utf_t){ 0b01111111, 0b00000000, 0000, 0177, 7 }, + [2] = &(utf_t){ 0b00011111, 0b11000000, 0200, 03777, 5 }, + [3] = &(utf_t){ 0b00001111, 0b11100000, 04000, 0177777, 4 }, + [4] = &(utf_t){ 0b00000111, 0b11110000, 0200000, 04177777, 3 }, + &(utf_t){ 0 }, +}; + +static inline int min(int x, int y) { + return x < y ? x : y; +} +static inline int max(int x, int y) { + return x > y ? x : y; +} + +static int utf8_len(const uint8_t ch) { + int len = 0; + for (utf_t** u = utf; (*u)->mask; ++u) { + if ((ch & ~(*u)->mask) == (*u)->lead) { + break; + } + ++len; + } + if (len > 4) { /* Malformed leading byte */ + assert("invalid unicode."); + } + return len; +} + +static uint32_t next_cp(const uint8_t** string) { + if (**string == 0) { + return 0; + } + int bytes = utf8_len(**string); + const uint8_t* chr = *string; + *string += bytes; + int shift = utf[0]->bits_stored * (bytes - 1); + uint32_t codep = (*chr++ & utf[bytes]->mask) << shift; + + for (int i = 1; i < bytes; ++i, ++chr) { + shift -= utf[0]->bits_stored; + codep |= ((const uint8_t)*chr & utf[0]->mask) << shift; + } + + return codep; +} + +EpdFontProperties epd_font_properties_default() { + EpdFontProperties props + = { .fg_color = 0, .bg_color = 15, .fallback_glyph = 0, .flags = EPD_DRAW_ALIGN_LEFT }; + return props; +} + +const EpdGlyph* epd_get_glyph(const EpdFont* font, uint32_t code_point) { + const EpdUnicodeInterval* intervals = font->intervals; + for (int i = 0; i < font->interval_count; i++) { + const EpdUnicodeInterval* interval = &intervals[i]; + if (code_point >= interval->first && code_point <= interval->last) { + return &font->glyph[interval->offset + (code_point - interval->first)]; + } + if (code_point < interval->first) { + return NULL; + } + } + return NULL; +} + +static int uncompress( + uint8_t* dest, size_t uncompressed_size, const uint8_t* source, size_t source_size +) { + tinfl_decompressor* decomp; + if (uncompressed_size == 0 || dest == NULL || source_size == 0 || source == NULL) { + return -1; + } + decomp = malloc(sizeof(tinfl_decompressor)); + if (!decomp) { + // Out of memory + return -1; + } + tinfl_init(decomp); + + // we know everything will fit into the buffer. + tinfl_status decomp_status = tinfl_decompress( + decomp, + source, + &source_size, + dest, + dest, + &uncompressed_size, + TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF + ); + free(decomp); + if (decomp_status != TINFL_STATUS_DONE) { + return decomp_status; + } + return 0; +} + +/*! + @brief Draw a single character to a pre-allocated buffer. +*/ +static enum EpdDrawError IRAM_ATTR draw_char( + const EpdFont* font, + uint8_t* buffer, + int* cursor_x, + int cursor_y, + uint32_t cp, + const EpdFontProperties* props +) { + assert(props != NULL); + + const EpdGlyph* glyph = epd_get_glyph(font, cp); + if (!glyph) { + glyph = epd_get_glyph(font, props->fallback_glyph); + } + + if (!glyph) { + return EPD_DRAW_GLYPH_FALLBACK_FAILED; + } + + uint32_t offset = glyph->data_offset; + uint16_t width = glyph->width, height = glyph->height; + int left = glyph->left; + + int byte_width = (width / 2 + width % 2); + unsigned long bitmap_size = byte_width * height; + const uint8_t* bitmap = NULL; + if (bitmap_size > 0 && font->compressed) { + uint8_t* tmp_bitmap = (uint8_t*)malloc(bitmap_size); + if (tmp_bitmap == NULL && bitmap_size) { + ESP_LOGE("font", "malloc failed."); + return EPD_DRAW_FAILED_ALLOC; + } + uncompress(tmp_bitmap, bitmap_size, &font->bitmap[offset], glyph->compressed_size); + bitmap = tmp_bitmap; + } else { + bitmap = &font->bitmap[offset]; + } + + uint8_t color_lut[16]; + for (int c = 0; c < 16; c++) { + int color_difference = (int)props->fg_color - (int)props->bg_color; + color_lut[c] = max(0, min(15, props->bg_color + c * color_difference / 15)); + } + bool background_needed = props->flags & EPD_DRAW_BACKGROUND; + + for (int y = 0; y < height; y++) { + int yy = cursor_y - glyph->top + y; + int start_pos = *cursor_x + left; + bool byte_complete = start_pos % 2; + int x = max(0, -start_pos); + int max_x = start_pos + width; + uint8_t color; + + for (int xx = start_pos; xx < max_x; xx++) { + uint8_t bm = bitmap[y * byte_width + x / 2]; + if ((x & 1) == 0) { + bm = bm & 0xF; + } else { + bm = bm >> 4; + } + if (background_needed || bm) { + color = color_lut[bm] << 4; + epd_draw_pixel(xx, yy, color, buffer); + } + byte_complete = !byte_complete; + x++; + } + } + if (bitmap_size > 0 && font->compressed) { + free((uint8_t*)bitmap); + } + *cursor_x += glyph->advance_x; + return EPD_DRAW_SUCCESS; +} + +/*! + * @brief Calculate the bounds of a character when drawn at (x, y), move the + * cursor (*x) forward, adjust the given bounds. + */ +static void get_char_bounds( + const EpdFont* font, + uint32_t cp, + int* x, + int* y, + int* minx, + int* miny, + int* maxx, + int* maxy, + const EpdFontProperties* props +) { + assert(props != NULL); + + const EpdGlyph* glyph = epd_get_glyph(font, cp); + + if (!glyph) { + glyph = epd_get_glyph(font, props->fallback_glyph); + } + + if (!glyph) { + return; + } + + int x1 = *x + glyph->left, y1 = *y + glyph->top - glyph->height, x2 = x1 + glyph->width, + y2 = y1 + glyph->height; + + // background needs to be taken into account + if (props->flags & EPD_DRAW_BACKGROUND) { + *minx = min(*x, min(*minx, x1)); + *maxx = max(max(*x + glyph->advance_x, x2), *maxx); + *miny = min(*y + font->descender, min(*miny, y1)); + *maxy = max(*y + font->ascender, max(*maxy, y2)); + } else { + if (x1 < *minx) + *minx = x1; + if (y1 < *miny) + *miny = y1; + if (x2 > *maxx) + *maxx = x2; + if (y2 > *maxy) + *maxy = y2; + } + *x += glyph->advance_x; +} + +EpdRect epd_get_string_rect( + const EpdFont* font, + const char* string, + int x, + int y, + int margin, + const EpdFontProperties* properties +) { + assert(properties != NULL); + EpdFontProperties props = *properties; + props.flags |= EPD_DRAW_BACKGROUND; + EpdRect temp = { .x = x, .y = y, .width = 0, .height = 0 }; + if (*string == '\0') + return temp; + int minx = 100000, miny = 100000, maxx = -1, maxy = -1; + int temp_x = x; + int temp_y = y + font->ascender; + + // Go through each line and get it's co-ordinates + uint32_t c; + while ((c = next_cp((const uint8_t**)&string))) { + if (c == 0x000A) // newline + { + temp_x = x; + temp_y += font->advance_y; + } else + get_char_bounds(font, c, &temp_x, &temp_y, &minx, &miny, &maxx, &maxy, &props); + } + temp.width = maxx - x + (margin * 2); + temp.height = maxy - miny + (margin * 2); + return temp; +} + +void epd_get_text_bounds( + const EpdFont* font, + const char* string, + const int* x, + const int* y, + int* x1, + int* y1, + int* w, + int* h, + const EpdFontProperties* properties +) { + // FIXME: Does not respect alignment! + + assert(properties != NULL); + EpdFontProperties props = *properties; + + if (*string == '\0') { + *w = 0; + *h = 0; + *y1 = *y; + *x1 = *x; + return; + } + int minx = 100000, miny = 100000, maxx = -1, maxy = -1; + int original_x = *x; + int temp_x = *x; + int temp_y = *y; + uint32_t c; + while ((c = next_cp((const uint8_t**)&string))) { + get_char_bounds(font, c, &temp_x, &temp_y, &minx, &miny, &maxx, &maxy, &props); + } + *x1 = min(original_x, minx); + *w = maxx - *x1; + *y1 = miny; + *h = maxy - miny; +} + +static enum EpdDrawError epd_write_line( + const EpdFont* font, + const char* string, + int* cursor_x, + int* cursor_y, + uint8_t* framebuffer, + const EpdFontProperties* properties +) { + assert(framebuffer != NULL); + + if (*string == '\0') { + return EPD_DRAW_SUCCESS; + } + + assert(properties != NULL); + EpdFontProperties props = *properties; + enum EpdFontFlags alignment_mask + = EPD_DRAW_ALIGN_LEFT | EPD_DRAW_ALIGN_RIGHT | EPD_DRAW_ALIGN_CENTER; + enum EpdFontFlags alignment = props.flags & alignment_mask; + + // alignments are mutually exclusive! + if ((alignment & (alignment - 1)) != 0) { + return EPD_DRAW_INVALID_FONT_FLAGS; + } + + int x1 = 0, y1 = 0, w = 0, h = 0; + int tmp_cur_x = *cursor_x; + int tmp_cur_y = *cursor_y; + epd_get_text_bounds(font, string, &tmp_cur_x, &tmp_cur_y, &x1, &y1, &w, &h, &props); + + // no printable characters + if (w < 0 || h < 0) { + return EPD_DRAW_NO_DRAWABLE_CHARACTERS; + } + + uint8_t* buffer = framebuffer; + int local_cursor_x = *cursor_x; + int local_cursor_y = *cursor_y; + uint32_t c; + + int cursor_x_init = local_cursor_x; + int cursor_y_init = local_cursor_y; + + switch (alignment) { + case EPD_DRAW_ALIGN_LEFT: { + break; + } + case EPD_DRAW_ALIGN_CENTER: { + local_cursor_x -= w / 2; + break; + } + case EPD_DRAW_ALIGN_RIGHT: { + local_cursor_x -= w; + break; + } + default: + break; + } + + uint8_t bg = props.bg_color; + if (props.flags & EPD_DRAW_BACKGROUND) { + for (int l = local_cursor_y - font->ascender; l < local_cursor_y - font->descender; l++) { + epd_draw_hline(local_cursor_x, l, w, bg << 4, buffer); + } + } + enum EpdDrawError err = EPD_DRAW_SUCCESS; + while ((c = next_cp((const uint8_t**)&string))) { + err |= draw_char(font, buffer, &local_cursor_x, local_cursor_y, c, &props); + } + + *cursor_x += local_cursor_x - cursor_x_init; + *cursor_y += local_cursor_y - cursor_y_init; + return err; +} + +enum EpdDrawError epd_write_default( + const EpdFont* font, const char* string, int* cursor_x, int* cursor_y, uint8_t* framebuffer +) { + const EpdFontProperties props = epd_font_properties_default(); + return epd_write_string(font, string, cursor_x, cursor_y, framebuffer, &props); +} + +enum EpdDrawError epd_write_string( + const EpdFont* font, + const char* string, + int* cursor_x, + int* cursor_y, + uint8_t* framebuffer, + const EpdFontProperties* properties +) { + char *token, *newstring, *tofree; + if (string == NULL) { + ESP_LOGE("font.c", "cannot draw a NULL string!"); + return EPD_DRAW_STRING_INVALID; + } + tofree = newstring = strdup(string); + if (newstring == NULL) { + ESP_LOGE("font.c", "cannot allocate string copy!"); + return EPD_DRAW_FAILED_ALLOC; + } + + enum EpdDrawError err = EPD_DRAW_SUCCESS; + // taken from the strsep manpage + int line_start = *cursor_x; + while ((token = strsep(&newstring, "\n")) != NULL) { + *cursor_x = line_start; + err |= epd_write_line(font, token, cursor_x, cursor_y, framebuffer, properties); + *cursor_y += font->advance_y; + } + + free(tofree); + return err; +} diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/hacks.cmake b/lib/libesp32_eink/epdiy/src/hacks.cmake old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/hacks.cmake rename to lib/libesp32_eink/epdiy/src/hacks.cmake diff --git a/lib/libesp32_eink/epdiy/src/highlevel.c b/lib/libesp32_eink/epdiy/src/highlevel.c new file mode 100644 index 000000000..0a82b92b4 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/highlevel.c @@ -0,0 +1,216 @@ +/** + * High-level API implementation for epdiy. + */ + +#include +#include +#include +#include +#include +#include + +#include "epd_highlevel.h" +#include "epdiy.h" + +#ifndef _swap_int +#define _swap_int(a, b) \ + { \ + int t = a; \ + a = b; \ + b = t; \ + } +#endif + +static bool already_initialized = 0; + +EpdiyHighlevelState epd_hl_init(const EpdWaveform* waveform) { + assert(!already_initialized); + if (waveform == NULL) { + waveform = epd_get_display()->default_waveform; + } + + int fb_size = epd_width() / 2 * epd_height(); + +#if !(defined(CONFIG_ESP32_SPIRAM_SUPPORT) || defined(CONFIG_ESP32S3_SPIRAM_SUPPORT)) + ESP_LOGW( + "EPDiy", "Please enable PSRAM for the ESP32 (menuconfig→ Component config→ ESP32-specific)" + ); +#endif + EpdiyHighlevelState state; + state.back_fb = heap_caps_aligned_alloc(16, fb_size, MALLOC_CAP_SPIRAM); + assert(state.back_fb != NULL); + state.front_fb = heap_caps_aligned_alloc(16, fb_size, MALLOC_CAP_SPIRAM); + assert(state.front_fb != NULL); + state.difference_fb = heap_caps_aligned_alloc(16, 2 * fb_size, MALLOC_CAP_SPIRAM); + assert(state.difference_fb != NULL); + state.dirty_lines = malloc(epd_height() * sizeof(bool)); + assert(state.dirty_lines != NULL); + state.dirty_columns + = heap_caps_aligned_alloc(16, epd_width() / 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + assert(state.dirty_columns != NULL); + state.waveform = waveform; + + memset(state.front_fb, 0xFF, fb_size); + memset(state.back_fb, 0xFF, fb_size); + + already_initialized = true; + return state; +} + +uint8_t* epd_hl_get_framebuffer(EpdiyHighlevelState* state) { + assert(state != NULL); + return state->front_fb; +} + +enum EpdDrawError epd_hl_update_screen( + EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature +) { + return epd_hl_update_area(state, mode, temperature, epd_full_screen()); +} + +EpdRect _inverse_rotated_area(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { + // If partial update uses full screen do not rotate anything + if (!(x == 0 && y == 0 && epd_width() == w && epd_height() == h)) { + // invert the current display rotation + switch (epd_get_rotation()) { + // 0 landscape: Leave it as is + case EPD_ROT_LANDSCAPE: + break; + // 1 90 ° clockwise + case EPD_ROT_PORTRAIT: + _swap_int(x, y); + _swap_int(w, h); + x = epd_width() - x - w; + break; + + case EPD_ROT_INVERTED_LANDSCAPE: + // 3 180° + x = epd_width() - x - w; + y = epd_height() - y - h; + break; + + case EPD_ROT_INVERTED_PORTRAIT: + // 3 270 ° + _swap_int(x, y); + _swap_int(w, h); + y = epd_height() - y - h; + break; + } + } + + EpdRect rotated = { x, y, w, h }; + return rotated; +} + +enum EpdDrawError epd_hl_update_area( + EpdiyHighlevelState* state, enum EpdDrawMode mode, int temperature, EpdRect area +) { + assert(state != NULL); + // Not right to rotate here since this copies part of buffer directly + + // Check rotation FIX + EpdRect rotated_area = _inverse_rotated_area(area.x, area.y, area.width, area.height); + area.x = rotated_area.x; + area.y = rotated_area.y; + area.width = rotated_area.width; + area.height = rotated_area.height; + + uint32_t ts = esp_timer_get_time() / 1000; + + // FIXME: use crop information here, if available + EpdRect diff_area = epd_difference_image_cropped( + state->front_fb, + state->back_fb, + area, + state->difference_fb, + state->dirty_lines, + state->dirty_columns + ); + + if (diff_area.height == 0 || diff_area.width == 0) { + return EPD_DRAW_SUCCESS; + } + + uint32_t t1 = esp_timer_get_time() / 1000; + + diff_area.x = 0; + diff_area.y = 0; + diff_area.width = epd_width(); + diff_area.height = epd_height(); + + enum EpdDrawError err = EPD_DRAW_SUCCESS; + err = epd_draw_base( + epd_full_screen(), + state->difference_fb, + diff_area, + MODE_PACKING_1PPB_DIFFERENCE | mode, + temperature, + state->dirty_lines, + state->dirty_columns, + state->waveform + ); + + uint32_t t2 = esp_timer_get_time() / 1000; + + diff_area.x = 0; + diff_area.y = 0; + diff_area.width = epd_width(); + diff_area.height = epd_height(); + + int buf_width = epd_width(); + + for (int l = diff_area.y; l < diff_area.y + diff_area.height; l++) { + if (state->dirty_lines[l] > 0) { + uint8_t* lfb = state->front_fb + buf_width / 2 * l; + uint8_t* lbb = state->back_fb + buf_width / 2 * l; + + int x = diff_area.x; + int x_last = diff_area.x + diff_area.width - 1; + + if (x % 2) { + *(lbb + x / 2) = (*(lfb + x / 2) & 0xF0) | (*(lbb + x / 2) & 0x0F); + x += 1; + } + + if (!(x_last % 2)) { + *(lbb + x_last / 2) = (*(lfb + x_last / 2) & 0x0F) | (*(lbb + x_last / 2) & 0xF0); + x_last -= 1; + } + + memcpy(lbb + (x / 2), lfb + (x / 2), (x_last - x + 1) / 2); + } + } + + uint32_t t3 = esp_timer_get_time() / 1000; + + ESP_LOGI( + "epdiy", + "diff: %dms, draw: %dms, buffer update: %dms, total: %dms", + t1 - ts, + t2 - t1, + t3 - t2, + t3 - ts + ); + return err; +} + +void epd_hl_set_all_white(EpdiyHighlevelState* state) { + assert(state != NULL); + int fb_size = epd_width() / 2 * epd_height(); + memset(state->front_fb, 0xFF, fb_size); +} + +void epd_fullclear(EpdiyHighlevelState* state, int temperature) { + assert(state != NULL); + epd_hl_set_all_white(state); + enum EpdDrawError err = epd_hl_update_screen(state, MODE_GC16, temperature); + assert(err == EPD_DRAW_SUCCESS); + epd_clear(); +} + +void epd_hl_waveform(EpdiyHighlevelState* state, const EpdWaveform* waveform) { + if (waveform == NULL) { + waveform = epd_get_display()->default_waveform; + } + state->waveform = waveform; +} \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/output_common/line_queue.c b/lib/libesp32_eink/epdiy/src/output_common/line_queue.c new file mode 100644 index 000000000..5a2dfa604 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/line_queue.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include + +#include "line_queue.h" +#include "render_method.h" + +static inline int ceil_div(int x, int y) { + return x / y + (x % y != 0); +} + +/// Initialize the line queue and allocate memory. +LineQueue_t lq_init(int queue_len, int element_size) { + LineQueue_t queue; + queue.element_size = element_size; + queue.size = queue_len; + queue.current = 0; + queue.last = 0; + + int elem_buf_size = ceil_div(element_size, 16) * 16; + + queue.bufs = calloc(queue.size, elem_buf_size); + assert(queue.bufs != NULL); + + for (int i = 0; i < queue.size; i++) { + queue.bufs[i] = heap_caps_aligned_alloc(16, elem_buf_size, MALLOC_CAP_INTERNAL); + assert(queue.bufs[i] != NULL); + } + + return queue; +} + +/// Deinitialize the line queue and free memory. +void lq_free(LineQueue_t* queue) { + for (int i = 0; i < queue->size; i++) { + heap_caps_free(queue->bufs[i]); + } + + free(queue->bufs); +} + +uint8_t* IRAM_ATTR lq_current(LineQueue_t* queue) { + int current = atomic_load_explicit(&queue->current, memory_order_acquire); + int last = atomic_load_explicit(&queue->last, memory_order_acquire); + + if ((current + 1) % queue->size == last) { + return NULL; + } + return queue->bufs[current]; +} + +void IRAM_ATTR lq_commit(LineQueue_t* queue) { + int current = atomic_load_explicit(&queue->current, memory_order_acquire); + + if (current == queue->size - 1) { + queue->current = 0; + } else { + atomic_fetch_add(&queue->current, 1); + } +} + +int IRAM_ATTR lq_read(LineQueue_t* queue, uint8_t* dst) { + int current = atomic_load_explicit(&queue->current, memory_order_acquire); + int last = atomic_load_explicit(&queue->last, memory_order_acquire); + + if (current == last) { + return -1; + } + + memcpy(dst, queue->bufs[last], queue->element_size); + + if (last == queue->size - 1) { + queue->last = 0; + } else { + atomic_fetch_add(&queue->last, 1); + } + return 0; +} + +void IRAM_ATTR lq_reset(LineQueue_t* queue) { + queue->current = 0; + queue->last = 0; +} diff --git a/lib/libesp32_eink/epdiy/src/output_common/line_queue.h b/lib/libesp32_eink/epdiy/src/output_common/line_queue.h new file mode 100644 index 000000000..e6fa81de2 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/line_queue.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include + +/// Circular line queue with atomic read / write operations +/// and accelerated masking on the output buffer. +typedef struct { + int size; + atomic_int current; + atomic_int last; + uint8_t** bufs; + // size of an element + size_t element_size; +} LineQueue_t; + +/// Initialize the line queue and allocate memory. +LineQueue_t lq_init(int queue_len, int element_size); + +/// Deinitialize the line queue and free memory. +void lq_free(LineQueue_t* queue); + +/// Pointer to the next empty element in the line queue. +/// +/// NULL if the queue is currently full. +uint8_t* lq_current(LineQueue_t* queue); + +/// Advance the line queue. +void lq_commit(LineQueue_t* queue); + +/// Read from the line queue. +/// +/// Returns 0 for a successful read to `dst`, -1 for a failed read (empty queue). +int lq_read(LineQueue_t* queue, uint8_t* dst); + +/// Reset the queue into an empty state. +/// This operation is *not* atomic! +void lq_reset(LineQueue_t* queue); diff --git a/lib/libesp32_eink/epdiy/src/output_common/lut.S b/lib/libesp32_eink/epdiy/src/output_common/lut.S new file mode 100644 index 000000000..3bbbaaa73 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/lut.S @@ -0,0 +1,145 @@ +#include +#include +#include "sdkconfig.h" + +#ifdef CONFIG_IDF_TARGET_ESP32S3 + +.text +.align 4 +.global calc_epd_input_1ppB_1k_S3_VE_aligned +.type calc_epd_input_1ppB_1k_S3_VE_aligned,@function + +// // CRASH AND BURN for debugging +// EE.MOVI.32.A q3, a2, 0 +// EE.MOVI.32.A q3, a3, 1 +// EE.MOVI.32.A q3, a4, 2 +// EE.MOVI.32.A q3, a5, 3 +// l8ui a10, a10, 0 + +// void calc_epd_input_1ppB_1k_S3_VE_aligned( +// const uint32_t *ld, +// uint8_t *epd_input, +// const uint8_t *conversion_lut, +// uint32_t epd_width +//); +calc_epd_input_1ppB_1k_S3_VE_aligned: +// input - a2 +// output - a3 +// lut - a4 +// len - a5 + + entry a1, 32 + + // divide by 16 and do one loop lesss, + // because the last loop is special + srli a5, a5, 4 + addi.n a5, a5, -1 + + + // bitmasks for bit shift by multiplication + movi.n a10, 0x40001000 + EE.MOVI.32.Q q4,a10,0 + movi.n a10, 0x04000100 + EE.MOVI.32.Q q4,a10,1 + movi.n a10, 0x00400010 + EE.MOVI.32.Q q4,a10,2 + movi a10, 0x00040001 + EE.MOVI.32.Q q4,a10,3 + + EE.ZERO.Q q0 + + EE.VLD.128.IP q1, a2, 16 + + // Instructions sometimes are in an unexpected order + // for best pipeline utilization + loopnez a5, .loop_end_lut_lookup + + // q1, q0 contain the input bytes, zero-extended to bits bytes + EE.VZIP.8 q1, q0 + + // load 32-bit LUT results + EE.LDXQ.32 q2, q0, a4, 0, 6 + EE.LDXQ.32 q2, q0, a4, 1, 7 + EE.LDXQ.32 q2, q0, a4, 2, 4 + EE.LDXQ.32 q2, q0, a4, 3, 5 + EE.LDXQ.32 q3, q0, a4, 0, 2 + EE.LDXQ.32 q3, q0, a4, 1, 3 + EE.LDXQ.32 q3, q0, a4, 2, 0 + EE.LDXQ.32 q3, q0, a4, 3, 1 + + EE.ZERO.ACCX + + // zip to have 16bit LUT results in q2, q3 zeroes + EE.VUNZIP.16 q2, q3 + + // combine results with using multiply-add as shift-or + EE.VMULAS.U16.ACCX q2,q4 + + // load 32-bit LUT results + EE.LDXQ.32 q2, q1, a4, 0, 6 + EE.LDXQ.32 q2, q1, a4, 1, 7 + EE.LDXQ.32 q2, q1, a4, 2, 4 + EE.LDXQ.32 q2, q1, a4, 3, 5 + EE.LDXQ.32 q0, q1, a4, 0, 2 + EE.LDXQ.32 q0, q1, a4, 1, 3 + EE.LDXQ.32 q0, q1, a4, 2, 0 + EE.LDXQ.32 q0, q1, a4, 3, 1 + + // store multiplication result in a6 + RUR.ACCX_0 a6 + s16i a6, a3, 2 + + EE.ZERO.ACCX + + // zip to have 16bit LUT results in q2, q0 zeroes + EE.VUNZIP.16 q2, q0 + + // Combine second set of results and load the next data + EE.VMULAS.U16.ACCX.LD.IP q1, a2, 16, q2, q4 + + // store result in a6 + RUR.ACCX_0 a6 + s16i a6, a3, 0 + + addi.n a3, a3, 4 +.loop_end_lut_lookup: + + // Same as above, but in the last iteration + // we do not load to not access out of bounds. + EE.VZIP.8 q1, q0 + + EE.LDXQ.32 q2, q0, a4, 0, 6 + EE.LDXQ.32 q2, q0, a4, 1, 7 + EE.LDXQ.32 q2, q0, a4, 2, 4 + EE.LDXQ.32 q2, q0, a4, 3, 5 + EE.LDXQ.32 q3, q0, a4, 0, 2 + EE.LDXQ.32 q3, q0, a4, 1, 3 + EE.LDXQ.32 q3, q0, a4, 2, 0 + EE.LDXQ.32 q3, q0, a4, 3, 1 + + EE.ZERO.ACCX + EE.VUNZIP.16 q2, q3 + EE.VMULAS.U16.ACCX q2,q4 + + EE.LDXQ.32 q2, q1, a4, 0, 6 + EE.LDXQ.32 q2, q1, a4, 1, 7 + EE.LDXQ.32 q2, q1, a4, 2, 4 + EE.LDXQ.32 q2, q1, a4, 3, 5 + EE.LDXQ.32 q0, q1, a4, 0, 2 + EE.LDXQ.32 q0, q1, a4, 1, 3 + EE.LDXQ.32 q0, q1, a4, 2, 0 + EE.LDXQ.32 q0, q1, a4, 3, 1 + + RUR.ACCX_0 a6 + s16i a6, a3, 2 + EE.ZERO.ACCX + + EE.VUNZIP.16 q2, q0 + EE.VMULAS.U16.ACCX q2, q4 + RUR.ACCX_0 a6 + s16i a6, a3, 0 + + movi.n a2, 0 // return status ESP_OK + retw.n + +#endif \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/output_common/lut.c b/lib/libesp32_eink/epdiy/src/output_common/lut.c new file mode 100644 index 000000000..f19ef135e --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/lut.c @@ -0,0 +1,495 @@ +#include "lut.h" + +#include "epdiy.h" +#include "esp_attr.h" +#include "render_context.h" +#include "render_method.h" + +#include +#include +#include + +#include "esp_timer.h" + +/* + * Build Lookup tables and translate via LUTs. + * WARNING: These functions must only ever write to internal memory, + * Since we disable the PSRAM workaround here for performance reasons. + */ + +/* Python script for generating the 8ppB, starting at white lookup table: + for i in range(256): + number = 0; + for b in range(8): + if not (i & (1 << b)): + number |= 1 << (2*b) + print ('0x%04x,'%number) + */ +const uint32_t lut_8ppB_start_at_white[256] = { + 0x5555, 0x5554, 0x5551, 0x5550, 0x5545, 0x5544, 0x5541, 0x5540, 0x5515, 0x5514, 0x5511, 0x5510, + 0x5505, 0x5504, 0x5501, 0x5500, 0x5455, 0x5454, 0x5451, 0x5450, 0x5445, 0x5444, 0x5441, 0x5440, + 0x5415, 0x5414, 0x5411, 0x5410, 0x5405, 0x5404, 0x5401, 0x5400, 0x5155, 0x5154, 0x5151, 0x5150, + 0x5145, 0x5144, 0x5141, 0x5140, 0x5115, 0x5114, 0x5111, 0x5110, 0x5105, 0x5104, 0x5101, 0x5100, + 0x5055, 0x5054, 0x5051, 0x5050, 0x5045, 0x5044, 0x5041, 0x5040, 0x5015, 0x5014, 0x5011, 0x5010, + 0x5005, 0x5004, 0x5001, 0x5000, 0x4555, 0x4554, 0x4551, 0x4550, 0x4545, 0x4544, 0x4541, 0x4540, + 0x4515, 0x4514, 0x4511, 0x4510, 0x4505, 0x4504, 0x4501, 0x4500, 0x4455, 0x4454, 0x4451, 0x4450, + 0x4445, 0x4444, 0x4441, 0x4440, 0x4415, 0x4414, 0x4411, 0x4410, 0x4405, 0x4404, 0x4401, 0x4400, + 0x4155, 0x4154, 0x4151, 0x4150, 0x4145, 0x4144, 0x4141, 0x4140, 0x4115, 0x4114, 0x4111, 0x4110, + 0x4105, 0x4104, 0x4101, 0x4100, 0x4055, 0x4054, 0x4051, 0x4050, 0x4045, 0x4044, 0x4041, 0x4040, + 0x4015, 0x4014, 0x4011, 0x4010, 0x4005, 0x4004, 0x4001, 0x4000, 0x1555, 0x1554, 0x1551, 0x1550, + 0x1545, 0x1544, 0x1541, 0x1540, 0x1515, 0x1514, 0x1511, 0x1510, 0x1505, 0x1504, 0x1501, 0x1500, + 0x1455, 0x1454, 0x1451, 0x1450, 0x1445, 0x1444, 0x1441, 0x1440, 0x1415, 0x1414, 0x1411, 0x1410, + 0x1405, 0x1404, 0x1401, 0x1400, 0x1155, 0x1154, 0x1151, 0x1150, 0x1145, 0x1144, 0x1141, 0x1140, + 0x1115, 0x1114, 0x1111, 0x1110, 0x1105, 0x1104, 0x1101, 0x1100, 0x1055, 0x1054, 0x1051, 0x1050, + 0x1045, 0x1044, 0x1041, 0x1040, 0x1015, 0x1014, 0x1011, 0x1010, 0x1005, 0x1004, 0x1001, 0x1000, + 0x0555, 0x0554, 0x0551, 0x0550, 0x0545, 0x0544, 0x0541, 0x0540, 0x0515, 0x0514, 0x0511, 0x0510, + 0x0505, 0x0504, 0x0501, 0x0500, 0x0455, 0x0454, 0x0451, 0x0450, 0x0445, 0x0444, 0x0441, 0x0440, + 0x0415, 0x0414, 0x0411, 0x0410, 0x0405, 0x0404, 0x0401, 0x0400, 0x0155, 0x0154, 0x0151, 0x0150, + 0x0145, 0x0144, 0x0141, 0x0140, 0x0115, 0x0114, 0x0111, 0x0110, 0x0105, 0x0104, 0x0101, 0x0100, + 0x0055, 0x0054, 0x0051, 0x0050, 0x0045, 0x0044, 0x0041, 0x0040, 0x0015, 0x0014, 0x0011, 0x0010, + 0x0005, 0x0004, 0x0001, 0x0000 +}; + +/* Python script for generating the 8ppB, starting at black lookup table: + for i in range(256): + number = 0; + for b in range(8): + if (i & (1 << b)): + number |= 2 << (2*b) + print ('0x%04x,'%number) + */ +const uint32_t lut_8ppB_start_at_black[256] = { + 0x0000, 0x0002, 0x0008, 0x000a, 0x0020, 0x0022, 0x0028, 0x002a, 0x0080, 0x0082, 0x0088, 0x008a, + 0x00a0, 0x00a2, 0x00a8, 0x00aa, 0x0200, 0x0202, 0x0208, 0x020a, 0x0220, 0x0222, 0x0228, 0x022a, + 0x0280, 0x0282, 0x0288, 0x028a, 0x02a0, 0x02a2, 0x02a8, 0x02aa, 0x0800, 0x0802, 0x0808, 0x080a, + 0x0820, 0x0822, 0x0828, 0x082a, 0x0880, 0x0882, 0x0888, 0x088a, 0x08a0, 0x08a2, 0x08a8, 0x08aa, + 0x0a00, 0x0a02, 0x0a08, 0x0a0a, 0x0a20, 0x0a22, 0x0a28, 0x0a2a, 0x0a80, 0x0a82, 0x0a88, 0x0a8a, + 0x0aa0, 0x0aa2, 0x0aa8, 0x0aaa, 0x2000, 0x2002, 0x2008, 0x200a, 0x2020, 0x2022, 0x2028, 0x202a, + 0x2080, 0x2082, 0x2088, 0x208a, 0x20a0, 0x20a2, 0x20a8, 0x20aa, 0x2200, 0x2202, 0x2208, 0x220a, + 0x2220, 0x2222, 0x2228, 0x222a, 0x2280, 0x2282, 0x2288, 0x228a, 0x22a0, 0x22a2, 0x22a8, 0x22aa, + 0x2800, 0x2802, 0x2808, 0x280a, 0x2820, 0x2822, 0x2828, 0x282a, 0x2880, 0x2882, 0x2888, 0x288a, + 0x28a0, 0x28a2, 0x28a8, 0x28aa, 0x2a00, 0x2a02, 0x2a08, 0x2a0a, 0x2a20, 0x2a22, 0x2a28, 0x2a2a, + 0x2a80, 0x2a82, 0x2a88, 0x2a8a, 0x2aa0, 0x2aa2, 0x2aa8, 0x2aaa, 0x8000, 0x8002, 0x8008, 0x800a, + 0x8020, 0x8022, 0x8028, 0x802a, 0x8080, 0x8082, 0x8088, 0x808a, 0x80a0, 0x80a2, 0x80a8, 0x80aa, + 0x8200, 0x8202, 0x8208, 0x820a, 0x8220, 0x8222, 0x8228, 0x822a, 0x8280, 0x8282, 0x8288, 0x828a, + 0x82a0, 0x82a2, 0x82a8, 0x82aa, 0x8800, 0x8802, 0x8808, 0x880a, 0x8820, 0x8822, 0x8828, 0x882a, + 0x8880, 0x8882, 0x8888, 0x888a, 0x88a0, 0x88a2, 0x88a8, 0x88aa, 0x8a00, 0x8a02, 0x8a08, 0x8a0a, + 0x8a20, 0x8a22, 0x8a28, 0x8a2a, 0x8a80, 0x8a82, 0x8a88, 0x8a8a, 0x8aa0, 0x8aa2, 0x8aa8, 0x8aaa, + 0xa000, 0xa002, 0xa008, 0xa00a, 0xa020, 0xa022, 0xa028, 0xa02a, 0xa080, 0xa082, 0xa088, 0xa08a, + 0xa0a0, 0xa0a2, 0xa0a8, 0xa0aa, 0xa200, 0xa202, 0xa208, 0xa20a, 0xa220, 0xa222, 0xa228, 0xa22a, + 0xa280, 0xa282, 0xa288, 0xa28a, 0xa2a0, 0xa2a2, 0xa2a8, 0xa2aa, 0xa800, 0xa802, 0xa808, 0xa80a, + 0xa820, 0xa822, 0xa828, 0xa82a, 0xa880, 0xa882, 0xa888, 0xa88a, 0xa8a0, 0xa8a2, 0xa8a8, 0xa8aa, + 0xaa00, 0xaa02, 0xaa08, 0xaa0a, 0xaa20, 0xaa22, 0xaa28, 0xaa2a, 0xaa80, 0xaa82, 0xaa88, 0xaa8a, + 0xaaa0, 0xaaa2, 0xaaa8, 0xaaaa, +}; + +static inline int min(int x, int y) { + return x < y ? x : y; +} +static inline int max(int x, int y) { + return x > y ? x : y; +} + +// status tracker for row skipping +uint32_t skipping; + +__attribute__((optimize("O3"))) void IRAM_ATTR +reorder_line_buffer(uint32_t* line_data, int buf_len) { + for (uint32_t i = 0; i < buf_len / 4; i++) { + uint32_t val = *line_data; + *(line_data++) = val >> 16 | ((val & 0x0000FFFF) << 16); + } +} + +__attribute__((optimize("O3"))) void IRAM_ATTR +bit_shift_buffer_right(uint8_t* buf, uint32_t len, int shift) { + uint8_t carry = 0xFF << (8 - shift); + for (uint32_t i = 0; i < len; i++) { + uint8_t val = buf[i]; + buf[i] = (val >> shift) | carry; + carry = val << (8 - shift); + } +} + +__attribute__((optimize("O3"))) void IRAM_ATTR +nibble_shift_buffer_right(uint8_t* buf, uint32_t len) { + uint8_t carry = 0xF; + for (uint32_t i = 0; i < len; i++) { + uint8_t val = buf[i]; + buf[i] = (val << 4) | carry; + carry = (val & 0xF0) >> 4; + } +} + +__attribute__((optimize("O3"))) void IRAM_ATTR calc_epd_input_8ppB( + const uint32_t* line_data, uint8_t* epd_input, const uint8_t* lut, uint32_t epd_width +) { + uint32_t* wide_epd_input = (uint32_t*)epd_input; + uint8_t* data_ptr = (uint8_t*)line_data; + uint32_t* lut_32 = (uint32_t*)lut; + // this is reversed for little-endian, but this is later compensated + // through the output peripheral. + for (int j = 0; j < epd_width / 16; j++) { + uint8_t v1 = *(data_ptr++); + uint8_t v2 = *(data_ptr++); + wide_epd_input[j] = (lut_32[v2] << 16) | lut_32[v1]; + } + + // Account for missing line end if epd_width is not divisible by 16. + // We assume divisibility by 4. + for (int j = 0; j < (epd_width % 16) / 4; j++) { + uint8_t nibble = *data_ptr; + if (j % 2 == 1) { + nibble = nibble >> 4; + data_ptr++; + } else { + nibble = nibble & 0xF; + } + epd_input[(epd_width / 16) * 4 + j] = lut_32[nibble]; + } +} + +/** + * Look up 4 pixels of a differential image in a LUT constructed for use with vector extensions. + */ +__attribute__((optimize("O3"))) static inline uint8_t lookup_pixels_in_VE_LUT( + const uint32_t in, const uint8_t* conversion_lut +) { + uint32_t* padded_lut = (uint32_t*)conversion_lut; + uint8_t out = padded_lut[(in >> 24) & 0xFF] << 6; + out |= padded_lut[(in >> 16) & 0xFF] << 4; + out |= padded_lut[(in >> 8) & 0xFF] << 2; + out |= padded_lut[(in >> 0) & 0xFF]; + return out; +} + +/** + * Lookup accelerated by the S3 Vector Extensions. + * Expects aligned buffers and a length that is divisible by 16. + */ +void IRAM_ATTR calc_epd_input_1ppB_1k_S3_VE_aligned( + const uint32_t* ld, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +); + +#ifdef RENDER_METHOD_I2S +void calc_epd_input_1ppB_1k_S3_VE_aligned( + const uint32_t* ld, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +) { + // dummy implementation, should never be called. + abort(); +} +#endif + +/** + * Lookup accelerated by the S3 Vector Extensions. + * Uses a 1K padded LUT (each entry takes up 32 bits) + */ +void IRAM_ATTR calc_epd_input_1ppB_1k_S3_VE( + const uint32_t* ld, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +) { + // alignment boundaries in pixels + int unaligned_len_front = (16 - (uint32_t)ld % 16) % 16; + int unaligned_len_back = ((uint32_t)ld + epd_width) % 16; + int aligned_len = epd_width - unaligned_len_front - unaligned_len_back; + + if (unaligned_len_front) { + for (int i = 0; i < unaligned_len_front / 4; i++) { + (*epd_input++) = lookup_pixels_in_VE_LUT((*ld++), conversion_lut); + } + } + calc_epd_input_1ppB_1k_S3_VE_aligned(ld, epd_input, conversion_lut, aligned_len); + + ld += aligned_len / 4; + epd_input += aligned_len / 4; + + if (unaligned_len_back) { + for (int i = 0; i < unaligned_len_back / 4; i++) { + (*epd_input++) = lookup_pixels_in_VE_LUT((*ld++), conversion_lut); + } + } +} + +/** + * Calculate EPD input for a difference image with one pixel per byte. + */ +__attribute__((optimize("O3"))) void IRAM_ATTR calc_epd_input_1ppB_64k( + const uint32_t* ld, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +) { + const uint16_t* lp = (uint16_t*)ld; + for (uint32_t j = 0; j < epd_width / 4; j++) { + epd_input[j] = (conversion_lut[lp[2 * j + 1]] << 4) | conversion_lut[lp[2 * j]]; + } +} + +__attribute__((optimize("O3"))) void IRAM_ATTR calc_epd_input_2ppB_lut_64k( + const uint32_t* line_data, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +) { + const uint16_t* line_data_16 = (const uint16_t*)line_data; + + for (uint32_t j = 0; j < epd_width / 4; j++) { + epd_input[j] = conversion_lut[*(line_data_16++)]; + } +} + +/** + * Look up 4 pixels in a 1K LUT with fixed "from" value. + */ +__attribute__((optimize("O3"))) static uint8_t lookup_pixels_2ppB_1k( + uint16_t in, const uint8_t* conversion_lut, uint8_t from +) { + uint8_t v; + uint8_t out; + + v = ((in << 4) | from); + out = conversion_lut[v & 0xFF]; + v = ((in & 0xF0) | from); + out |= (conversion_lut + 0x100)[v & 0xFF]; + in = in >> 8; + v = ((in << 4) | from); + out |= (conversion_lut + 0x200)[v & 0xFF]; + v = ((in & 0xF0) | from); + out |= (conversion_lut + 0x300)[v]; + return out; +} + +/** + * Calculate EPD input for a 2ppB buffer, but with a difference image LUT. + * This is used for small-LUT mode. + */ +__attribute__((optimize("O3"))) void IRAM_ATTR calc_epd_input_2ppB_1k_lut( + const uint32_t* ld, + uint8_t* epd_input, + const uint8_t* conversion_lut, + uint8_t from, + uint32_t epd_width +) { + const uint16_t* line_data_16 = (const uint16_t*)ld; + + for (uint32_t j = 0; j < epd_width / 4; j++) { + epd_input[j] = lookup_pixels_2ppB_1k(*(line_data_16++), conversion_lut, from); + }; +} + +__attribute__((optimize("O3"))) void IRAM_ATTR calc_epd_input_2ppB_1k_lut_white( + const uint32_t* ld, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +) { + calc_epd_input_2ppB_1k_lut(ld, epd_input, conversion_lut, 0xF, epd_width); +} + +__attribute__((optimize("O3"))) void IRAM_ATTR calc_epd_input_2ppB_1k_lut_black( + const uint32_t* ld, uint8_t* epd_input, const uint8_t* conversion_lut, uint32_t epd_width +) { + calc_epd_input_2ppB_1k_lut(ld, epd_input, conversion_lut, 0x0, epd_width); +} + +///////////////////////////// Calculate Lookup Tables +////////////////////////////////// + +/** + * Unpack the waveform data into a lookup table, with bit shifted copies. + */ +__attribute__((optimize("O3"))) static void IRAM_ATTR +build_2ppB_lut_1k(uint8_t* lut, const EpdWaveformPhases* phases, int frame) { + const uint8_t* p_lut = phases->luts + (16 * 4 * frame); + for (uint8_t to = 0; to < 16; to++) { + for (uint8_t from_packed = 0; from_packed < 4; from_packed++) { + uint8_t index = (to << 4) | (from_packed * 4); + uint8_t packed = *(p_lut++); + lut[index] = (packed >> 6) & 3; + lut[index + 1] = (packed >> 4) & 3; + lut[index + 2] = (packed >> 2) & 3; + lut[index + 3] = (packed >> 0) & 3; + // printf("%2X%2X%2X%2X (%d)", lut[index], lut[index + 1], lut[index + 2], + // lut[index + 3], index); + } + // printf("\n"); + } + uint32_t index = 0x100; + for (uint8_t s = 2; s <= 6; s += 2) { + for (int i = 0; i < 0x100; i++) { + lut[index] = lut[index % 0x100] << s; + index++; + } + } +} + +/** + * Unpack the waveform data into a lookup table, + * 64k to loop up two bytes at once + */ +__attribute__((optimize("O3"))) static void IRAM_ATTR +build_1ppB_lut_64k(uint8_t* lut, const EpdWaveformPhases* phases, int frame) { + const uint8_t* p_lut = phases->luts + (16 * 4 * frame); + for (uint8_t to = 0; to < 16; to++) { + for (uint8_t from_packed = 0; from_packed < 4; from_packed++) { + uint8_t index = (to << 4) | (from_packed * 4); + uint8_t packed = *(p_lut++); + lut[index] = (packed >> 6) & 3; + lut[index + 1] = (packed >> 4) & 3; + lut[index + 2] = (packed >> 2) & 3; + lut[index + 3] = (packed >> 0) & 3; + // printf("%2X%2X%2X%2X (%d)", lut[index], lut[index + 1], lut[index + 2], + // lut[index + 3], index); + } + // printf("\n"); + } + + for (int outer = 0xFF; outer >= 0; outer--) { + uint32_t outer_result = lut[outer] << 2; + outer_result |= (outer_result << 16); + outer_result |= (outer_result << 8); + uint32_t* lut_section = (uint32_t*)(&lut[outer << 8]); + memcpy(lut_section, lut, 0x100); + for (int i = 0; i < 0x100 / 4; i++) { + lut_section[i] = lut_section[i] | outer_result; + } + } +} + +/** + * A 32bit aligned lookup table for lookup using the ESP32-S3 vector extensions. + */ +__attribute__((optimize("O3"))) static void IRAM_ATTR +build_1ppB_lut_S3_VE_1k(uint8_t* lut, const EpdWaveformPhases* phases, int frame) { + uint32_t* lut32 = (uint32_t*)lut; + const uint8_t* p_lut = phases->luts + (16 * 4 * frame); + for (uint8_t to = 0; to < 16; to++) { + for (uint8_t from_packed = 0; from_packed < 4; from_packed++) { + uint8_t index = (to << 4) | (from_packed * 4); + uint8_t packed = *(p_lut++); + lut32[index] = (packed >> 6) & 3; + lut32[index + 1] = (packed >> 4) & 3; + lut32[index + 2] = (packed >> 2) & 3; + lut32[index + 3] = (packed >> 0) & 3; + } + } +} + +/** + * Build a 16-bit LUT from the waveform if the previous color is + * known, e.g. all white or all black. + * This LUT is use to look up 4 pixels at once, as with the epdiy LUT. + */ +__attribute__((optimize("O3"))) static void build_2ppB_lut_64k_static_from( + uint8_t* lut, const EpdWaveformPhases* phases, uint8_t from, int frame +) { + const uint8_t* p_lut = phases->luts + (16 * 4 * frame); + + /// index into the packed "from" row + uint8_t fi = from >> 2; + /// bit shift amount for the packed "from" row + uint8_t fs = 6 - 2 * (from & 3); + + // populate the first 4096 bytes + uint8_t v1 = 0; + uint32_t s1 = 0; + for (uint8_t t2 = 0; t2 < 16; t2++) { + uint8_t v2 = ((p_lut[(t2 << 2) + fi] >> fs) & 0x03) << 4; + uint32_t s2 = t2 << 8; + for (uint8_t t3 = 0; t3 < 16; t3++) { + uint8_t v3 = ((p_lut[(t3 << 2) + fi] >> fs) & 0x03) << 2; + uint32_t s3 = t3 << 4; + for (uint8_t t4 = 0; t4 < 16; t4++) { + uint8_t v4 = ((p_lut[(t4 << 2) + fi] >> fs) & 0x03) << 0; + uint32_t s4 = t4; + lut[s1 | s2 | s3 | s4] = v1 | v2 | v3 | v4; + } + } + } + + // now just copy and the first 4096 bytes and add the upper two bits + for (uint8_t t1 = 1; t1 < 16; t1++) { + memcpy(&lut[t1 << 12], lut, 1 << 12); + } + + for (int i = 0; i < 16; i++) { + uint32_t v1 = ((p_lut[(i << 2) + fi] >> fs) & 0x03); + uint32_t mask = (v1 << 30) | (v1 << 22) | (v1 << 14) | (v1 << 6); + for (int j = 0; j < 16 * 16 * 16 / 4; j++) { + ((uint32_t*)lut)[(i << 10) + j] |= mask; + } + } +} + +static void build_2ppB_lut_64k_from_0(uint8_t* lut, const EpdWaveformPhases* phases, int frame) { + build_2ppB_lut_64k_static_from(lut, phases, 0, frame); +} + +static void build_2ppB_lut_64k_from_15(uint8_t* lut, const EpdWaveformPhases* phases, int frame) { + build_2ppB_lut_64k_static_from(lut, phases, 0xF, frame); +} + +static void build_8ppB_lut_256b_from_white( + uint8_t* lut, const EpdWaveformPhases* phases, int frame +) { + memcpy(lut, lut_8ppB_start_at_white, sizeof(lut_8ppB_start_at_white)); +} + +static void build_8ppB_lut_256b_from_black( + uint8_t* lut, const EpdWaveformPhases* phases, int frame +) { + memcpy(lut, lut_8ppB_start_at_black, sizeof(lut_8ppB_start_at_black)); +} + +void IRAM_ATTR epd_apply_line_mask(uint8_t* buf, const uint8_t* mask, int len) { + for (int i = 0; i < len / 4; i++) { + ((uint32_t*)buf)[i] &= ((uint32_t*)mask)[i]; + } +} + +LutFunctionPair find_lut_functions(enum EpdDrawMode mode, uint32_t lut_size) { + LutFunctionPair pair; + pair.build_func = NULL; + pair.lookup_func = NULL; + + if (mode & MODE_PACKING_1PPB_DIFFERENCE) { + if (EPD_CURRENT_RENDER_METHOD == RENDER_METHOD_LCD && !(mode & MODE_FORCE_NO_PIE) + && lut_size >= 1024) { + pair.build_func = &build_1ppB_lut_S3_VE_1k; + pair.lookup_func = &calc_epd_input_1ppB_1k_S3_VE; + return pair; + } else if (lut_size >= 1 << 16) { + pair.build_func = &build_1ppB_lut_64k; + pair.lookup_func = &calc_epd_input_1ppB_64k; + return pair; + } + } else if (mode & MODE_PACKING_2PPB) { + if (lut_size >= 1 << 16) { + if (mode & PREVIOUSLY_WHITE) { + pair.build_func = &build_2ppB_lut_64k_from_15; + pair.lookup_func = &calc_epd_input_2ppB_lut_64k; + return pair; + } else if (mode & PREVIOUSLY_BLACK) { + pair.build_func = &build_2ppB_lut_64k_from_0; + pair.lookup_func = &calc_epd_input_2ppB_lut_64k; + return pair; + } + } else if (lut_size >= 1024) { + if (mode & PREVIOUSLY_WHITE) { + pair.build_func = &build_2ppB_lut_1k; + pair.lookup_func = &calc_epd_input_2ppB_1k_lut_white; + return pair; + } else if (mode & PREVIOUSLY_BLACK) { + pair.build_func = &build_2ppB_lut_1k; + pair.lookup_func = &calc_epd_input_2ppB_1k_lut_black; + return pair; + } + } + } else if (mode & MODE_PACKING_8PPB) { + if (lut_size < sizeof(lut_8ppB_start_at_white)) { + return pair; + } + + if (mode & PREVIOUSLY_WHITE) { + pair.build_func = &build_8ppB_lut_256b_from_white; + pair.lookup_func = &calc_epd_input_8ppB; + return pair; + } else if (mode & PREVIOUSLY_BLACK) { + pair.build_func = &build_8ppB_lut_256b_from_black; + pair.lookup_func = &calc_epd_input_8ppB; + return pair; + } + } + + return pair; +} diff --git a/lib/libesp32_eink/epdiy/src/output_common/lut.h b/lib/libesp32_eink/epdiy/src/output_common/lut.h new file mode 100644 index 000000000..364636e4a --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/lut.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include "epdiy.h" + +// Make a block of 4 pixels lighter on the EPD. +#define CLEAR_BYTE 0B10101010 +// Make a block of 4 pixels darker on the EPD. +#define DARK_BYTE 0B01010101 + +/** + * Type signature of a framebuffer to display output lookup function. + */ +typedef void (*lut_func_t)( + const uint32_t* line_buffer, uint8_t* epd_input, const uint8_t* lut, uint32_t epd_width +); + +/** + * Type signature of a LUT preparation function. + */ +typedef void (*lut_build_func_t)(uint8_t* lut, const EpdWaveformPhases* phases, int frame); + +typedef struct { + lut_build_func_t build_func; + lut_func_t lookup_func; +} LutFunctionPair; + +/** + * Select the appropriate LUT building and lookup function + * for the selected draw mode and allocated LUT size. + */ +LutFunctionPair find_lut_functions(enum EpdDrawMode mode, uint32_t lut_size); + +/* + * Reorder the output buffer to account for I2S FIFO order. + */ +void reorder_line_buffer(uint32_t* line_data, int buf_len); + +/** + * Apply a mask to a line buffer. + * `len` must be divisible by 4. + */ +void epd_apply_line_mask(uint8_t* buf, const uint8_t* mask, int len); + +// legacy functions +void bit_shift_buffer_right(uint8_t* buf, uint32_t len, int shift); +void nibble_shift_buffer_right(uint8_t* buf, uint32_t len); diff --git a/lib/libesp32_eink/epdiy/src/output_common/render_context.c b/lib/libesp32_eink/epdiy/src/output_common/render_context.c new file mode 100644 index 000000000..bb1890eaf --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/render_context.c @@ -0,0 +1,106 @@ +#include "render_context.h" + +#include +#include "esp_log.h" + +#include "../epdiy.h" +#include "lut.h" +#include "render_method.h" + +/// For waveforms without timing and the I2S diving method, +/// the default hold time for each line is 12us +const static int DEFAULT_FRAME_TIME = 120; + +static inline int min(int x, int y) { + return x < y ? x : y; +} + +void get_buffer_params( + RenderContext_t* ctx, + int* bytes_per_line, + const uint8_t** start_ptr, + int* min_y, + int* max_y, + int* pixels_per_byte +) { + EpdRect area = ctx->area; + + enum EpdDrawMode mode = ctx->mode; + const EpdRect crop_to = ctx->crop_to; + const bool horizontally_cropped = !(crop_to.x == 0 && crop_to.width == area.width); + const bool vertically_cropped = !(crop_to.y == 0 && crop_to.height == area.height); + + // number of pixels per byte of input data + int width_divider = 0; + + if (mode & MODE_PACKING_1PPB_DIFFERENCE) { + *bytes_per_line = area.width; + width_divider = 1; + } else if (mode & MODE_PACKING_2PPB) { + *bytes_per_line = area.width / 2 + area.width % 2; + width_divider = 2; + } else if (mode & MODE_PACKING_8PPB) { + *bytes_per_line = (area.width / 8 + (area.width % 8 > 0)); + width_divider = 8; + } else { + ctx->error |= EPD_DRAW_INVALID_PACKING_MODE; + } + + int crop_x = (horizontally_cropped ? crop_to.x : 0); + int crop_y = (vertically_cropped ? crop_to.y : 0); + int crop_h = (vertically_cropped ? crop_to.height : 0); + + const uint8_t* ptr_start = ctx->data_ptr; + + // Adjust for negative starting coordinates with optional crop + if (area.x - crop_x < 0) { + ptr_start += -(area.x - crop_x) / width_divider; + } + + if (area.y - crop_y < 0) { + ptr_start += -(area.y - crop_y) * *bytes_per_line; + } + + // calculate start and end row with crop + *min_y = area.y + crop_y; + *max_y = min(*min_y + (vertically_cropped ? crop_h : area.height), area.height); + *start_ptr = ptr_start; + *pixels_per_byte = width_divider; +} + +void IRAM_ATTR prepare_context_for_next_frame(RenderContext_t* ctx) { + int frame_time = DEFAULT_FRAME_TIME; + if (ctx->phase_times != NULL) { + frame_time = ctx->phase_times[ctx->current_frame]; + } + + if (ctx->mode & MODE_EPDIY_MONOCHROME) { + frame_time = MONOCHROME_FRAME_TIME; + } + ctx->frame_time = frame_time; + + const EpdWaveformPhases* phases + = ctx->waveform->mode_data[ctx->waveform_index]->range_data[ctx->waveform_range]; + + assert(ctx->lut_build_func != NULL); + ctx->lut_build_func(ctx->conversion_lut, phases, ctx->current_frame); + + ctx->lines_prepared = 0; + ctx->lines_consumed = 0; +} + +void epd_populate_line_mask(uint8_t* line_mask, const uint8_t* dirty_columns, int mask_len) { + if (dirty_columns == NULL) { + memset(line_mask, 0xFF, mask_len); + } else { + int pixels = mask_len * 4; + for (int c = 0; c < pixels / 2; c += 2) { + uint8_t mask = 0; + mask |= (dirty_columns[c + 1] & 0xF0) != 0 ? 0xC0 : 0x00; + mask |= (dirty_columns[c + 1] & 0x0F) != 0 ? 0x30 : 0x00; + mask |= (dirty_columns[c] & 0xF0) != 0 ? 0x0C : 0x00; + mask |= (dirty_columns[c] & 0x0F) != 0 ? 0x03 : 0x00; + line_mask[c / 2] = mask; + } + } +} \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/output_common/render_context.h b/lib/libesp32_eink/epdiy/src/output_common/render_context.h new file mode 100644 index 000000000..47f8ddbc4 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/render_context.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "../epdiy.h" +#include "line_queue.h" +#include "lut.h" + +#define NUM_RENDER_THREADS 2 + +typedef struct { + EpdRect area; + EpdRect crop_to; + const bool* drawn_lines; + const uint8_t* data_ptr; + + /// The display width for quick access. + int display_width; + /// The display height for quick access. + int display_height; + + /// index of the next line of data to process + atomic_int lines_prepared; + volatile int lines_consumed; + int lines_total; + + /// frame currently in the current update cycle + int current_frame; + /// number of frames in the current update cycle + int cycle_frames; + + TaskHandle_t feed_tasks[NUM_RENDER_THREADS]; + SemaphoreHandle_t feed_done_smphr[NUM_RENDER_THREADS]; + SemaphoreHandle_t frame_done; + /// Line buffers for feed tasks + uint8_t* feed_line_buffers[NUM_RENDER_THREADS]; + + /// index of the waveform mode when using vendor waveforms. + /// This is not necessarily the mode number if the waveform header + // only contains a selection of modes! + int waveform_index; + /// waveform range when using vendor waveforms + int waveform_range; + /// Draw time for the current frame in 1/10ths of us. + int frame_time; + + const int* phase_times; + + const EpdWaveform* waveform; + enum EpdDrawMode mode; + enum EpdDrawError error; + + // Lookup table size. + size_t conversion_lut_size; + // Lookup table space. + uint8_t* conversion_lut; + + /// LUT lookup function. Must not be NULL. + lut_func_t lut_lookup_func; + /// LUT building function. Must not be NULL + lut_build_func_t lut_build_func; + + /// Queue of lines prepared for output to the display, + /// one for each thread. + LineQueue_t line_queues[NUM_RENDER_THREADS]; + uint8_t* line_threads; + + // Output line mask + uint8_t* line_mask; + + /// track line skipping when working in old i2s mode + int skipping; + + /// line buffer when using epd_push_pixels + uint8_t* static_line_buffer; +} RenderContext_t; + +/** + * Based on the render context, assign the bytes per line, + * framebuffer start pointer, min and max vertical positions and the pixels per byte. + */ +void get_buffer_params( + RenderContext_t* ctx, + int* bytes_per_line, + const uint8_t** start_ptr, + int* min_y, + int* max_y, + int* pixels_per_byte +); + +/** + * Prepare the render context for drawing the next frame. + * + * (Reset counters, etc) + */ +void prepare_context_for_next_frame(RenderContext_t* ctx); + +/** + * Populate an output line mask from line dirtyness with two bits per pixel. + * If the dirtyness data is NULL, set the mask to neutral. + * + * don't inline for to ensure availability in tests. + */ +void __attribute__((noinline)) epd_populate_line_mask( + uint8_t* line_mask, const uint8_t* dirty_columns, int mask_len +); \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/output_common/render_method.c b/lib/libesp32_eink/epdiy/src/output_common/render_method.c new file mode 100644 index 000000000..5404b7ee1 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/render_method.c @@ -0,0 +1,10 @@ +#include "render_method.h" +#include "sdkconfig.h" + +#ifdef CONFIG_IDF_TARGET_ESP32 +const enum EpdRenderMethod EPD_CURRENT_RENDER_METHOD = RENDER_METHOD_I2S; +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +const enum EpdRenderMethod EPD_CURRENT_RENDER_METHOD = RENDER_METHOD_LCD; +#else +#error "unknown chip, cannot choose render method!" +#endif \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/output_common/render_method.h b/lib/libesp32_eink/epdiy/src/output_common/render_method.h new file mode 100644 index 000000000..217b41004 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_common/render_method.h @@ -0,0 +1,29 @@ +#pragma once + +#include "sdkconfig.h" + +/** + * Rendering Method / Hardware to use. + */ +enum EpdRenderMethod { + /// Use the I2S peripheral on ESP32 chips. + RENDER_METHOD_I2S = 1, + /// Use the CAM/LCD peripheral in ESP32-S3 chips. + RENDER_METHOD_LCD = 2, +}; + +extern const enum EpdRenderMethod EPD_CURRENT_RENDER_METHOD; + +#ifdef CONFIG_IDF_TARGET_ESP32 +#define RENDER_METHOD_I2S 1 +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +#define RENDER_METHOD_LCD 1 +#else +#error "unknown chip, cannot choose render method!" +#endif + +#ifdef __clang__ +#define IRAM_ATTR +// define this if we're using clangd to make it accept the GCC builtin +void __assert_func(const char* file, int line, const char* func, const char* failedexpr); +#endif \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.c b/lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.c new file mode 100644 index 000000000..6c63b10c5 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.c @@ -0,0 +1,303 @@ +#include "i2s_data_bus.h" + +#include "esp_intr_alloc.h" +#include "sdkconfig.h" + +// the I2S driver is based on ESP32 registers and won't compile on the S3 +#ifdef CONFIG_IDF_TARGET_ESP32 + +#include "driver/rtc_io.h" +#include "esp_system.h" +#if ESP_IDF_VERSION < (4, 0, 0) || ARDUINO_ARCH_ESP32 +#include "rom/gpio.h" +#include "rom/lldesc.h" +#else +#include "esp32/rom/gpio.h" +#include "esp32/rom/lldesc.h" +#endif +#include "esp_heap_caps.h" +#include "soc/i2s_reg.h" +#include "soc/i2s_struct.h" +#include "soc/rtc.h" + +#include "esp_system.h" // for ESP_IDF_VERSION_VAL +#include "esp_private/periph_ctrl.h" + +/// DMA descriptors for front and back line buffer. +/// We use two buffers, so one can be filled while the other +/// is transmitted. +typedef struct { + volatile lldesc_t* dma_desc_a; + volatile lldesc_t* dma_desc_b; + + /// Front and back line buffer. + uint8_t* buf_a; + uint8_t* buf_b; +} i2s_parallel_state_t; + +/// Indicates which line buffer is currently back / front. +static int current_buffer = 0; + +/// The I2S state instance. +static i2s_parallel_state_t i2s_state; + +static intr_handle_t gI2S_intr_handle = NULL; + +/// Indicates the device has finished its transmission and is ready again. +static volatile bool output_done = true; +/// The start pulse pin extracted from the configuration for use in the "done" +/// interrupt. +static gpio_num_t start_pulse_pin; + +/// Initializes a DMA descriptor. +static void fill_dma_desc( + volatile lldesc_t* dmadesc, uint8_t* buf, uint32_t buf_size, uint32_t buf_length +) { + assert(buf_length % 4 == 0); // Must be word aligned + dmadesc->size = buf_size; + dmadesc->length = buf_length; + dmadesc->buf = buf; + dmadesc->eof = 1; + dmadesc->sosf = 1; + dmadesc->owner = 1; + dmadesc->qe.stqe_next = 0; + dmadesc->offset = 0; +} + +/// Address of the currently front DMA descriptor, +/// which uses only the lower 20bits (according to TRM) +uint32_t dma_desc_addr() { + return (uint32_t)(current_buffer ? i2s_state.dma_desc_a : i2s_state.dma_desc_b) & 0x000FFFFF; +} + +// Helper function to help align values +static size_t align_up(size_t x, size_t a) { + return (size_t)(x + ((size_t)a - 1)) & ~(size_t)(a - 1); +} + +/// Set up a GPIO as output and route it to a signal. +static void gpio_setup_out(int gpio, int sig, bool invert) { + if (gpio == -1) + return; + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); + gpio_set_direction(gpio, GPIO_MODE_DEF_OUTPUT); + gpio_matrix_out(gpio, sig, invert, false); +} + +/// Resets "Start Pulse" signal when the current row output is done. +static void IRAM_ATTR i2s_int_hdl(void* arg) { + i2s_dev_t* dev = &I2S1; + if (dev->int_st.out_done) { + // gpio_set_level(start_pulse_pin, 1); + // gpio_set_level(GPIO_NUM_26, 0); + output_done = true; + } + // Clear the interrupt. Otherwise, the whole device would hang. + dev->int_clr.val = dev->int_raw.val; +} + +uint8_t* IRAM_ATTR i2s_get_current_buffer() { + return (uint8_t*)(current_buffer ? i2s_state.dma_desc_a->buf : i2s_state.dma_desc_b->buf); +} + +bool IRAM_ATTR i2s_is_busy() { + // DMA and FIFO must be done + return !output_done || !I2S1.state.tx_idle; +} + +void IRAM_ATTR i2s_switch_buffer() { + // either device is done transmitting or the switch must be away from the + // buffer currently used by the DMA engine. + while (i2s_is_busy() && dma_desc_addr() != I2S1.out_link.addr) { + }; + current_buffer = !current_buffer; +} + +void IRAM_ATTR i2s_start_line_output() { + output_done = false; + + i2s_dev_t* dev = &I2S1; + dev->conf.tx_start = 0; + dev->conf.tx_reset = 1; + dev->conf.tx_fifo_reset = 1; + dev->conf.rx_fifo_reset = 1; + dev->conf.tx_reset = 0; + dev->conf.tx_fifo_reset = 0; + dev->conf.rx_fifo_reset = 0; + dev->out_link.addr = dma_desc_addr(); + dev->out_link.start = 1; + + // sth is pulled up through peripheral interrupt + // This is timing-critical! + gpio_set_level(start_pulse_pin, 0); + dev->conf.tx_start = 1; +} + +void i2s_gpio_attach(i2s_bus_config* cfg) { + gpio_num_t I2S_GPIO_BUS[] = { cfg->data_6, cfg->data_7, cfg->data_4, cfg->data_5, + cfg->data_2, cfg->data_3, cfg->data_0, cfg->data_1 }; + + gpio_set_direction(cfg->start_pulse, GPIO_MODE_OUTPUT); + gpio_set_level(cfg->start_pulse, 1); + // Use I2S1 with no signal offset (for some reason the offset seems to be + // needed in 16-bit mode, but not in 8 bit mode. + int signal_base = I2S1O_DATA_OUT0_IDX; + + // Setup and route GPIOS + for (int x = 0; x < 8; x++) { + gpio_setup_out(I2S_GPIO_BUS[x], signal_base + x, false); + } + + // Free CKH after wakeup + gpio_hold_dis(cfg->clock); + // Invert word select signal + gpio_setup_out(cfg->clock, I2S1O_WS_OUT_IDX, true); +} + +void i2s_gpio_detach(i2s_bus_config* cfg) { + gpio_set_direction(cfg->data_0, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_1, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_2, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_3, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_4, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_5, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_6, GPIO_MODE_INPUT); + gpio_set_direction(cfg->data_7, GPIO_MODE_INPUT); + gpio_set_direction(cfg->start_pulse, GPIO_MODE_INPUT); + gpio_set_direction(cfg->clock, GPIO_MODE_INPUT); + + gpio_reset_pin(cfg->clock); + if (cfg->clock != 5) { + rtc_gpio_isolate(cfg->clock); + } +} + +void i2s_bus_init(i2s_bus_config* cfg, uint32_t epd_row_width) { + i2s_gpio_attach(cfg); + + // store pin in global variable for use in interrupt. + start_pulse_pin = cfg->start_pulse; + + periph_module_enable(PERIPH_I2S1_MODULE); + + i2s_dev_t* dev = &I2S1; + + // Initialize device + dev->conf.tx_reset = 1; + dev->conf.tx_reset = 0; + + // Reset DMA + dev->lc_conf.in_rst = 1; + dev->lc_conf.in_rst = 0; + dev->lc_conf.out_rst = 1; + dev->lc_conf.out_rst = 0; + + // Setup I2S config. See section 12 of Technical Reference Manual + // Enable LCD mode + dev->conf2.val = 0; + dev->conf2.lcd_en = 1; + + // Enable FRAME1-Mode (See technical reference manual) + dev->conf2.lcd_tx_wrx2_en = 1; + dev->conf2.lcd_tx_sdx2_en = 0; + + // Set to 8 bit parallel output + dev->sample_rate_conf.val = 0; + dev->sample_rate_conf.tx_bits_mod = 8; + + // Half speed of bit clock in LCD mode. + // (Smallest possible divider according to the spec). + dev->sample_rate_conf.tx_bck_div_num = 2; + + // Initialize Audio Clock (APLL) + rtc_clk_apll_enable(true); + rtc_clk_apll_coeff_set(0, 0, 0, 8); + + // Set Audio Clock Dividers + dev->clkm_conf.val = 0; + dev->clkm_conf.clka_en = 1; + dev->clkm_conf.clkm_div_a = 1; + dev->clkm_conf.clkm_div_b = 0; + // 2 is the smallest possible divider according to the spec. + dev->clkm_conf.clkm_div_num = 2; + + // Set up FIFO + dev->fifo_conf.val = 0; + dev->fifo_conf.tx_fifo_mod_force_en = 1; + dev->fifo_conf.tx_fifo_mod = 1; + dev->fifo_conf.tx_data_num = 32; + dev->fifo_conf.dscr_en = 1; + + // Stop after transmission complete + dev->conf1.val = 0; + dev->conf1.tx_stop_en = 0; + dev->conf1.tx_pcm_bypass = 1; + + // Configure TX channel + dev->conf_chan.val = 0; + dev->conf_chan.tx_chan_mod = 1; + dev->conf.tx_right_first = 1; + + dev->timing.val = 0; + + // Allocate DMA descriptors + const size_t buf_size = align_up(epd_row_width / 4, 4); // Buf size must be word aligned + i2s_state.buf_a = heap_caps_malloc(buf_size, MALLOC_CAP_DMA); + i2s_state.buf_b = heap_caps_malloc(buf_size, MALLOC_CAP_DMA); + i2s_state.dma_desc_a = heap_caps_malloc(sizeof(lldesc_t), MALLOC_CAP_DMA); + i2s_state.dma_desc_b = heap_caps_malloc(sizeof(lldesc_t), MALLOC_CAP_DMA); + + // and fill them + fill_dma_desc(i2s_state.dma_desc_a, i2s_state.buf_a, epd_row_width / 4, buf_size); + fill_dma_desc(i2s_state.dma_desc_b, i2s_state.buf_b, epd_row_width / 4, buf_size); + + // enable "done" interrupt + SET_PERI_REG_BITS(I2S_INT_ENA_REG(1), I2S_OUT_DONE_INT_ENA_V, 1, I2S_OUT_DONE_INT_ENA_S); + // register interrupt + esp_intr_alloc(ETS_I2S1_INTR_SOURCE, 0, i2s_int_hdl, 0, &gI2S_intr_handle); + + // Reset FIFO/DMA + dev->lc_conf.in_rst = 1; + dev->lc_conf.out_rst = 1; + dev->lc_conf.ahbm_rst = 1; + dev->lc_conf.ahbm_fifo_rst = 1; + dev->lc_conf.in_rst = 0; + dev->lc_conf.out_rst = 0; + dev->lc_conf.ahbm_rst = 0; + dev->lc_conf.ahbm_fifo_rst = 0; + dev->conf.tx_reset = 1; + dev->conf.tx_fifo_reset = 1; + dev->conf.rx_fifo_reset = 1; + dev->conf.tx_reset = 0; + dev->conf.tx_fifo_reset = 0; + dev->conf.rx_fifo_reset = 0; + + // Start dma on front buffer + dev->lc_conf.val = I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN; + dev->out_link.addr = ((uint32_t)(i2s_state.dma_desc_a)); + dev->out_link.start = 1; + + dev->int_clr.val = dev->int_raw.val; + + dev->int_ena.val = 0; + dev->int_ena.out_done = 1; + + dev->conf.tx_start = 0; +} + +void i2s_bus_deinit() { + esp_intr_disable(gI2S_intr_handle); + esp_intr_free(gI2S_intr_handle); + + free(i2s_state.buf_a); + free(i2s_state.buf_b); + free((void*)i2s_state.dma_desc_a); + free((void*)i2s_state.dma_desc_b); + + rtc_clk_apll_coeff_set(0, 0, 0, 8); + rtc_clk_apll_enable(true); + + periph_module_disable(PERIPH_I2S1_MODULE); +} + +#endif diff --git a/lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.h b/lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.h new file mode 100644 index 000000000..2aeb1f0e8 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_i2s/i2s_data_bus.h @@ -0,0 +1,77 @@ +/** + * Implements a 8bit parallel interface to transmit pixel + * data to the display, based on the I2S peripheral. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +/** + * I2S bus configuration parameters. + */ +typedef struct { + // GPIO numbers of the parallel bus pins. + gpio_num_t data_0; + gpio_num_t data_1; + gpio_num_t data_2; + gpio_num_t data_3; + gpio_num_t data_4; + gpio_num_t data_5; + gpio_num_t data_6; + gpio_num_t data_7; + + // Data clock pin. + gpio_num_t clock; + + // "Start Pulse", enabling data input on the slave device (active low) + gpio_num_t start_pulse; +} i2s_bus_config; + +/** + * Initialize the I2S data bus for communication + * with a 8bit parallel display interface. + */ +void i2s_bus_init(i2s_bus_config* cfg, uint32_t epd_row_width); + +/** + * Attach I2S to gpio's + */ +void i2s_gpio_attach(i2s_bus_config* cfg); + +/** + * Detach I2S from gpio's + */ +void i2s_gpio_detach(i2s_bus_config* cfg); + +/** + * Get the currently writable line buffer. + */ +uint8_t* i2s_get_current_buffer(); + +/** + * Switches front and back line buffer. + * If the switched-to line buffer is currently in use, + * this function blocks until transmission is done. + */ +void i2s_switch_buffer(); + +/** + * Start transmission of the current back buffer. + */ +void i2s_start_line_output(); + +/** + * Returns true if there is an ongoing transmission. + */ +bool i2s_is_busy(); + +/** + * Give up allocated resources. + */ +void i2s_bus_deinit(); diff --git a/lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.c b/lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.c new file mode 100644 index 000000000..08db81062 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.c @@ -0,0 +1,402 @@ +#include "render_i2s.h" + +#include "../output_common/render_method.h" + +#ifdef RENDER_METHOD_I2S +#include +#include + +#include + +#include "epd_internals.h" +#include "epdiy.h" + +// output a row to the display. +#include "../output_common/lut.h" +#include "../output_common/render_context.h" +#include "i2s_data_bus.h" +#include "rmt_pulse.h" + +static const epd_ctrl_state_t NoChangeState = { 0 }; + +/** + * Waits until all previously submitted data has been written. + * Then, the following operations are initiated: + * + * - Previously submitted data is latched to the output register. + * - The RMT peripheral is set up to pulse the vertical (gate) driver for + * `output_time_dus` / 10 microseconds. + * - The I2S peripheral starts transmission of the current buffer to + * the source driver. + * - The line buffers are switched. + * + * This sequence of operations allows for pipelining data preparation and + * transfer, reducing total refresh times. + */ +static void IRAM_ATTR i2s_output_row(uint32_t output_time_dus) { + while (i2s_is_busy() || rmt_busy()) { + }; + + const EpdBoardDefinition* epd_board = epd_current_board(); + epd_ctrl_state_t* ctrl_state = epd_ctrl_state(); + epd_ctrl_state_t mask = NoChangeState; + + ctrl_state->ep_sth = true; + ctrl_state->ep_latch_enable = true; + mask.ep_sth = true; + mask.ep_latch_enable = true; + epd_board->set_ctrl(ctrl_state, &mask); + + mask = NoChangeState; + ctrl_state->ep_latch_enable = false; + mask.ep_latch_enable = true; + epd_board->set_ctrl(ctrl_state, &mask); + + if (epd_get_display()->display_type == DISPLAY_TYPE_ED097TC2) { + pulse_ckv_ticks(output_time_dus, 1, false); + } else { + pulse_ckv_ticks(output_time_dus, 50, false); + } + + i2s_start_line_output(); + i2s_switch_buffer(); +} + +/** Line i2s_output_row, but resets skip indicator. */ +static void IRAM_ATTR i2s_write_row(RenderContext_t* ctx, uint32_t output_time_dus) { + i2s_output_row(output_time_dus); + ctx->skipping = 0; +} + +/** Skip a row without writing to it. */ +static void IRAM_ATTR i2s_skip_row(RenderContext_t* ctx, uint8_t pipeline_finish_time) { + int line_bytes = ctx->display_width / 4; + // output previously loaded row, fill buffer with no-ops. + if (ctx->skipping < 2) { + memset((void*)i2s_get_current_buffer(), 0x00, line_bytes); + i2s_output_row(pipeline_finish_time); + } else { + if (epd_get_display()->display_type == DISPLAY_TYPE_ED097TC2) { + pulse_ckv_ticks(5, 5, false); + } else { + // According to the spec, the OC4 maximum CKV frequency is 200kHz. + pulse_ckv_ticks(45, 5, false); + } + } + ctx->skipping++; +} + +/** + * Start a draw cycle. + */ +static void i2s_start_frame() { + while (i2s_is_busy() || rmt_busy()) { + }; + + const EpdBoardDefinition* epd_board = epd_current_board(); + epd_ctrl_state_t* ctrl_state = epd_ctrl_state(); + epd_ctrl_state_t mask = NoChangeState; + + ctrl_state->ep_mode = true; + mask.ep_mode = true; + epd_board->set_ctrl(ctrl_state, &mask); + + pulse_ckv_us(1, 1, true); + + // This is very timing-sensitive! + mask = NoChangeState; + ctrl_state->ep_stv = false; + mask.ep_stv = true; + epd_board->set_ctrl(ctrl_state, &mask); + // busy_delay(240); + pulse_ckv_us(1000, 100, false); + mask = NoChangeState; + ctrl_state->ep_stv = true; + mask.ep_stv = true; + epd_board->set_ctrl(ctrl_state, &mask); + // pulse_ckv_us(0, 10, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + + mask = NoChangeState; + ctrl_state->ep_output_enable = true; + mask.ep_output_enable = true; + epd_board->set_ctrl(ctrl_state, &mask); +} + +/** + * End a draw cycle. + */ +static void i2s_end_frame() { + const EpdBoardDefinition* epd_board = epd_current_board(); + epd_ctrl_state_t* ctrl_state = epd_ctrl_state(); + epd_ctrl_state_t mask = NoChangeState; + + ctrl_state->ep_stv = false; + mask.ep_stv = true; + epd_board->set_ctrl(ctrl_state, &mask); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + mask = NoChangeState; + ctrl_state->ep_mode = false; + mask.ep_mode = true; + epd_board->set_ctrl(ctrl_state, &mask); + pulse_ckv_us(0, 10, true); + mask = NoChangeState; + ctrl_state->ep_output_enable = false; + mask.ep_output_enable = true; + epd_board->set_ctrl(ctrl_state, &mask); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); + pulse_ckv_us(1, 1, true); +} + +void i2s_do_update(RenderContext_t* ctx) { + for (uint8_t k = 0; k < ctx->cycle_frames; k++) { + prepare_context_for_next_frame(ctx); + + // start both feeder tasks + xTaskNotifyGive(ctx->feed_tasks[!xPortGetCoreID()]); + xTaskNotifyGive(ctx->feed_tasks[xPortGetCoreID()]); + + // transmission is started in renderer threads, now wait util it's done + xSemaphoreTake(ctx->frame_done, portMAX_DELAY); + + for (int i = 0; i < NUM_RENDER_THREADS; i++) { + xSemaphoreTake(ctx->feed_done_smphr[i], portMAX_DELAY); + } + + ctx->current_frame++; + + // make the watchdog happy. + if (k % 10 == 0) { + vTaskDelay(0); + } + } +} + +void IRAM_ATTR epd_push_pixels_i2s(RenderContext_t* ctx, EpdRect area, short time, int color) { + int line_bytes = ctx->display_width / 4; + uint8_t row[line_bytes]; + memset(row, 0, line_bytes); + + const uint8_t color_choice[4] = { DARK_BYTE, CLEAR_BYTE, 0x00, 0xFF }; + for (uint32_t i = 0; i < area.width; i++) { + uint32_t position = i + area.x % 4; + uint8_t mask = color_choice[color] & (0b00000011 << (2 * (position % 4))); + row[area.x / 4 + position / 4] |= mask; + } + reorder_line_buffer((uint32_t*)row, line_bytes); + + i2s_start_frame(); + + for (int i = 0; i < ctx->display_height; i++) { + // before are of interest: skip + if (i < area.y) { + i2s_skip_row(ctx, time); + // start area of interest: set row data + } else if (i == area.y) { + i2s_switch_buffer(); + memcpy((void*)i2s_get_current_buffer(), row, line_bytes); + i2s_switch_buffer(); + memcpy((void*)i2s_get_current_buffer(), row, line_bytes); + + i2s_write_row(ctx, time * 10); + // load nop row if done with area + } else if (i >= area.y + area.height) { + i2s_skip_row(ctx, time); + // output the same as before + } else { + i2s_write_row(ctx, time * 10); + } + } + // Since we "pipeline" row output, we still have to latch out the last row. + i2s_write_row(ctx, time * 10); + + i2s_end_frame(); +} + +void IRAM_ATTR i2s_output_frame(RenderContext_t* ctx, int thread_id) { + uint8_t* line_buf = ctx->feed_line_buffers[thread_id]; + + ctx->skipping = 0; + EpdRect area = ctx->area; + int frame_time = ctx->frame_time; + + i2s_start_frame(); + for (int i = 0; i < ctx->display_height; i++) { + LineQueue_t* lq = &ctx->line_queues[0]; + + memset(line_buf, 0, ctx->display_width); + while (lq_read(lq, line_buf) < 0) { + }; + + ctx->lines_consumed += 1; + + if (ctx->drawn_lines != NULL && !ctx->drawn_lines[i - area.y]) { + i2s_skip_row(ctx, frame_time); + continue; + } + + // lookup pixel actions in the waveform LUT + ctx->lut_lookup_func( + (uint32_t*)line_buf, + (uint8_t*)i2s_get_current_buffer(), + ctx->conversion_lut, + ctx->display_width + ); + + // apply the line mask + epd_apply_line_mask(i2s_get_current_buffer(), ctx->line_mask, ctx->display_width / 4); + + reorder_line_buffer((uint32_t*)i2s_get_current_buffer(), ctx->display_width / 4); + i2s_write_row(ctx, frame_time); + } + if (!ctx->skipping) { + // Since we "pipeline" row output, we still have to latch out the + // last row. + i2s_write_row(ctx, frame_time); + } + i2s_end_frame(); + + xSemaphoreGive(ctx->feed_done_smphr[thread_id]); + xSemaphoreGive(ctx->frame_done); +} + +static inline int min(int x, int y) { + return x < y ? x : y; +} +static inline int max(int x, int y) { + return x > y ? x : y; +} + +void IRAM_ATTR i2s_fetch_frame_data(RenderContext_t* ctx, int thread_id) { + uint8_t* input_line = ctx->feed_line_buffers[thread_id]; + + // line must be able to hold 2-pixel-per-byte or 1-pixel-per-byte data + memset(input_line, 0x00, ctx->display_width); + + LineQueue_t* lq = &ctx->line_queues[thread_id]; + + EpdRect area = ctx->area; + + int min_y, max_y, bytes_per_line, pixels_per_byte; + const uint8_t* ptr_start; + get_buffer_params(ctx, &bytes_per_line, &ptr_start, &min_y, &max_y, &pixels_per_byte); + + const EpdRect crop_to = ctx->crop_to; + const bool horizontally_cropped = !(crop_to.x == 0 && crop_to.width == area.width); + int crop_x = (horizontally_cropped ? crop_to.x : 0); + int crop_w = (horizontally_cropped ? crop_to.width : 0); + + // interval of the output line that is needed + // FIXME: only lookup needed parts + int line_start_x = area.x + (horizontally_cropped ? crop_to.x : 0); + int line_end_x = line_start_x + (horizontally_cropped ? crop_to.width : area.width); + line_start_x = min(max(line_start_x, 0), ctx->display_width); + line_end_x = min(max(line_end_x, 0), ctx->display_width); + + int l = 0; + while (l = atomic_fetch_add(&ctx->lines_prepared, 1), l < ctx->display_height) { + // if (thread_id) gpio_set_level(15, 0); + ctx->line_threads[l] = thread_id; + + if (l < min_y || l >= max_y + || (ctx->drawn_lines != NULL && !ctx->drawn_lines[l - area.y])) { + uint8_t* buf = NULL; + while (buf == NULL) + buf = lq_current(lq); + memset(buf, 0x00, lq->element_size); + lq_commit(lq); + continue; + } + + uint32_t* lp = (uint32_t*)input_line; + bool shifted = false; + const uint8_t* ptr = ptr_start + bytes_per_line * (l - min_y); + + if (area.width == ctx->display_width && area.x == 0 && !ctx->error) { + lp = (uint32_t*)ptr; + } else if (!ctx->error) { + uint8_t* buf_start = (uint8_t*)input_line; + uint32_t line_bytes = bytes_per_line; + + int min_x = area.x + crop_x; + if (min_x >= 0) { + buf_start += min_x / pixels_per_byte; + } else { + // reduce line_bytes to actually used bytes + // ptr was already adjusted above + line_bytes += min_x / pixels_per_byte; + } + line_bytes = min( + line_bytes, + ctx->display_width / pixels_per_byte - (uint32_t)(buf_start - input_line) + ); + + memcpy(buf_start, ptr, line_bytes); + + int cropped_width = (horizontally_cropped ? crop_w : area.width); + /// consider half-byte shifts in two-pixel-per-Byte mode. + if (pixels_per_byte == 2) { + // mask last nibble for uneven width + if (cropped_width % 2 == 1 + && min_x / 2 + cropped_width / 2 + 1 < ctx->display_width) { + *(buf_start + line_bytes - 1) |= 0xF0; + } + if (area.x % 2 == 1 && !(crop_x % 2 == 1) && min_x < ctx->display_width) { + shifted = true; + uint32_t remaining + = (uint32_t)input_line + ctx->display_width / 2 - (uint32_t)buf_start; + uint32_t to_shift = min(line_bytes + 1, remaining); + // shift one nibble to right + nibble_shift_buffer_right(buf_start, to_shift); + } + // consider bit shifts in bit buffers + } else if (pixels_per_byte == 8) { + // mask last n bits if width is not divisible by 8 + if (cropped_width % 8 != 0 && bytes_per_line + 1 < ctx->display_width) { + uint8_t mask = 0; + for (int s = 0; s < cropped_width % 8; s++) { + mask = (mask << 1) | 1; + } + *(buf_start + line_bytes - 1) |= ~mask; + } + + if (min_x % 8 != 0 && min_x < ctx->display_width) { + // shift to right + shifted = true; + uint32_t remaining + = (uint32_t)input_line + ctx->display_width / 8 - (uint32_t)buf_start; + uint32_t to_shift = min(line_bytes + 1, remaining); + bit_shift_buffer_right(buf_start, to_shift, min_x % 8); + } + } + lp = (uint32_t*)input_line; + } + + uint8_t* buf = NULL; + while (buf == NULL) + buf = lq_current(lq); + + memcpy(buf, lp, lq->element_size); + + lq_commit(lq); + + if (shifted) { + memset(input_line, 255, ctx->display_width / pixels_per_byte); + } + } +} + +void i2s_deinit() { + rmt_pulse_deinit(); + i2s_bus_deinit(); +} + +#endif diff --git a/lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.h b/lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.h new file mode 100644 index 000000000..ec16c825c --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_i2s/render_i2s.h @@ -0,0 +1,59 @@ +#include "epdiy.h" + +#include +#include +#include +#include +#include + +#include "../output_common/render_context.h" +#include "sdkconfig.h" + +/** + * Lighten / darken picels using the I2S driving method. + */ +void epd_push_pixels_i2s(RenderContext_t* ctx, EpdRect area, short time, int color); + +/** + * Do a full update cycle with a configured context. + */ +void i2s_do_update(RenderContext_t* ctx); + +/** + * Worker to fetch framebuffer data and write into a queue for processing. + */ +void i2s_fetch_frame_data(RenderContext_t* ctx, int thread_id); + +/** + * Worker to output frame data to the display. + */ +void i2s_output_frame(RenderContext_t* ctx, int thread_id); + +/** + * Deinitialize the I2S peripheral for low power consumption. + */ +void i2s_deinit(); + +/* + * Write bits directly using the registers in the ESP32. + * Won't work for some pins (>= 32). + */ +inline void fast_gpio_set_hi(gpio_num_t gpio_num) { +#ifdef CONFIG_IDF_TARGET_ESP32 + gpio_dev_t* device = GPIO_LL_GET_HW(GPIO_PORT_0); + device->out_w1ts = (1 << gpio_num); +#else + // not supportd on non ESP32 chips + assert(false); +#endif +} + +inline void fast_gpio_set_lo(gpio_num_t gpio_num) { +#ifdef CONFIG_IDF_TARGET_ESP32 + gpio_dev_t* device = GPIO_LL_GET_HW(GPIO_PORT_0); + device->out_w1tc = (1 << gpio_num); +#else + // not supportd on non ESP32 chips + assert(false); +#endif +} diff --git a/lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.c b/lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.c new file mode 100644 index 000000000..f5ca71b49 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.c @@ -0,0 +1,97 @@ +#include "../output_common/render_method.h" +#include "esp_intr_alloc.h" + +#ifdef RENDER_METHOD_I2S + +#include "driver/rmt.h" +#include "rmt_pulse.h" + +#include "soc/rmt_struct.h" + +static intr_handle_t gRMT_intr_handle = NULL; + +// the RMT channel configuration object +static rmt_config_t row_rmt_config; + +// keep track of wether the current pulse is ongoing +volatile bool rmt_tx_done = true; + +/** + * Remote peripheral interrupt. Used to signal when transmission is done. + */ +static void IRAM_ATTR rmt_interrupt_handler(void* arg) { + rmt_tx_done = true; + RMT.int_clr.val = RMT.int_st.val; +} + +// The extern line is declared in esp-idf/components/driver/deprecated/rmt_legacy.c. It has access +// to RMTMEM through the rmt_private.h header which we can't access outside the sdk. Declare our own +// extern here to properly use the RMTMEM smybol defined in +// components/soc/[target]/ld/[target].peripherals.ld Also typedef the new rmt_mem_t struct to the +// old rmt_block_mem_t struct. Same data fields, different names +typedef rmt_mem_t rmt_block_mem_t; +extern rmt_block_mem_t RMTMEM; + +void rmt_pulse_init(gpio_num_t pin) { + row_rmt_config.rmt_mode = RMT_MODE_TX; + // currently hardcoded: use channel 0 + row_rmt_config.channel = RMT_CHANNEL_1; + + row_rmt_config.gpio_num = pin; + row_rmt_config.mem_block_num = 2; + + // Divide 80MHz APB Clock by 8 -> .1us resolution delay + row_rmt_config.clk_div = 8; + + row_rmt_config.tx_config.loop_en = false; + row_rmt_config.tx_config.carrier_en = false; + row_rmt_config.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW; + row_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; + row_rmt_config.tx_config.idle_output_en = true; + + esp_intr_alloc( + ETS_RMT_INTR_SOURCE, ESP_INTR_FLAG_LEVEL3, rmt_interrupt_handler, 0, &gRMT_intr_handle + ); + + rmt_config(&row_rmt_config); + rmt_set_tx_intr_en(row_rmt_config.channel, true); +} + +void rmt_pulse_deinit() { + esp_intr_disable(gRMT_intr_handle); + esp_intr_free(gRMT_intr_handle); +} + +void IRAM_ATTR pulse_ckv_ticks(uint16_t high_time_ticks, uint16_t low_time_ticks, bool wait) { + while (!rmt_tx_done) { + }; + volatile rmt_item32_t* rmt_mem_ptr = &(RMTMEM.chan[row_rmt_config.channel].data32[0]); + if (high_time_ticks > 0) { + rmt_mem_ptr->level0 = 1; + rmt_mem_ptr->duration0 = high_time_ticks; + rmt_mem_ptr->level1 = 0; + rmt_mem_ptr->duration1 = low_time_ticks; + } else { + rmt_mem_ptr->level0 = 1; + rmt_mem_ptr->duration0 = low_time_ticks; + rmt_mem_ptr->level1 = 0; + rmt_mem_ptr->duration1 = 0; + } + RMTMEM.chan[row_rmt_config.channel].data32[1].val = 0; + rmt_tx_done = false; + RMT.conf_ch[row_rmt_config.channel].conf1.mem_rd_rst = 1; + RMT.conf_ch[row_rmt_config.channel].conf1.mem_owner = RMT_MEM_OWNER_TX; + RMT.conf_ch[row_rmt_config.channel].conf1.tx_start = 1; + while (wait && !rmt_tx_done) { + }; +} + +void IRAM_ATTR pulse_ckv_us(uint16_t high_time_us, uint16_t low_time_us, bool wait) { + pulse_ckv_ticks(10 * high_time_us, 10 * low_time_us, wait); +} + +bool IRAM_ATTR rmt_busy() { + return !rmt_tx_done; +} + +#endif diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.h b/lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.h old mode 100755 new mode 100644 similarity index 78% rename from lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.h rename to lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.h index c55a8084d..263c48066 --- a/lib/libesp32_eink/epdiy/src/epd_driver/rmt_pulse.h +++ b/lib/libesp32_eink/epdiy/src/output_i2s/rmt_pulse.h @@ -3,9 +3,9 @@ */ #pragma once +#include #include "driver/gpio.h" #include "esp_attr.h" -#include /** * Initializes RMT Channel 0 with a pin for RMT pulsing. @@ -13,6 +13,11 @@ */ void rmt_pulse_init(gpio_num_t pin); +/** + * Resets the pin and RMT peripheral, frees associated resources. + */ +void rmt_pulse_deinit(); + /** * Outputs a single pulse (high -> low) on the configured pin. * This function will always wait for a previous call to finish. @@ -21,12 +26,11 @@ void rmt_pulse_init(gpio_num_t pin); * @param: low_time_us Pulse low time in us. * @param: wait Block until the pulse is finished. */ -void IRAM_ATTR pulse_ckv_us(uint16_t high_time_us, uint16_t low_time_us, - bool wait); +void pulse_ckv_us(uint16_t high_time_us, uint16_t low_time_us, bool wait); /** * Indicates if the rmt is currently sending a pulse. */ -bool IRAM_ATTR rmt_busy(); +bool rmt_busy(); /** * Outputs a single pulse (high -> low) on the configured pin. @@ -36,5 +40,4 @@ bool IRAM_ATTR rmt_busy(); * @param: low_time_us Pulse low time in clock ticks. * @param: wait Block until the pulse is finished. */ -void IRAM_ATTR pulse_ckv_ticks(uint16_t high_time_us, uint16_t low_time_us, - bool wait); +void pulse_ckv_ticks(uint16_t high_time_us, uint16_t low_time_us, bool wait); diff --git a/lib/libesp32_eink/epdiy/src/output_lcd/idf-4-backports.h b/lib/libesp32_eink/epdiy/src/output_lcd/idf-4-backports.h new file mode 100644 index 000000000..916789a8d --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_lcd/idf-4-backports.h @@ -0,0 +1,22 @@ +/** + * Backported functions to make the LCD-based driver compile with IDF < 5.0 + */ + +#define RMT_BASECLK_DEFAULT RMT_BASECLK_APB +typedef int rmt_clock_source_t; + +static inline void rmt_ll_enable_periph_clock(rmt_dev_t* dev, bool enable) { + dev->sys_conf.clk_en = enable; // register clock gating + dev->sys_conf.mem_clk_force_on = enable; // memory clock gating +} + +static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t* dev, bool enable) { + dev->sys_conf.apb_fifo_mask = enable; +} + +__attribute__((always_inline)) static inline void rmt_ll_tx_fix_idle_level( + rmt_dev_t* dev, uint32_t channel, uint8_t level, bool enable +) { + dev->chnconf0[channel].idle_out_en_n = enable; + dev->chnconf0[channel].idle_out_lv_n = level; +} diff --git a/lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.c b/lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.c new file mode 100644 index 000000000..ae5c833a3 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.c @@ -0,0 +1,706 @@ +#include "lcd_driver.h" +#include "epdiy.h" + +#include "../output_common/render_method.h" +#include "esp_heap_caps.h" +#include "esp_intr_alloc.h" +#include "hal/gpio_types.h" + +#ifdef RENDER_METHOD_LCD + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hal/gpio_hal.h" + +gpio_hal_context_t hal = { .dev = GPIO_HAL_GET_HW(GPIO_PORT_0) }; + +#define TAG "epdiy" + +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 2) +#define LCD_PERIPH_SIGNALS lcd_periph_signals +#else +#define LCD_PERIPH_SIGNALS lcd_periph_rgb_signals +#endif + +static inline int min(int x, int y) { + return x < y ? x : y; +} +static inline int max(int x, int y) { + return x > y ? x : y; +} + +#define S3_LCD_PIN_NUM_BK_LIGHT -1 +// #define S3_LCD_PIN_NUM_MODE 4 + +#define LINE_BATCH 1000 +#define BOUNCE_BUF_LINES 4 + +#define RMT_CKV_CHAN RMT_CHANNEL_1 + +// The extern line is declared in esp-idf/components/driver/deprecated/rmt_legacy.c. It has access +// to RMTMEM through the rmt_private.h header which we can't access outside the sdk. Declare our own +// extern here to properly use the RMTMEM smybol defined in +// components/soc/[target]/ld/[target].peripherals.ld Also typedef the new rmt_mem_t struct to the +// old rmt_block_mem_t struct. Same data fields, different names +typedef rmt_mem_t rmt_block_mem_t; +extern rmt_block_mem_t RMTMEM; + +// spinlock for protecting the critical section at frame start +static portMUX_TYPE frame_start_spinlock = portMUX_INITIALIZER_UNLOCKED; + +typedef struct { + lcd_hal_context_t hal; + intr_handle_t vsync_intr; + intr_handle_t done_intr; + + frame_done_func_t frame_done_cb; + line_cb_func_t line_source_cb; + void* line_cb_payload; + void* frame_cb_payload; + + int line_length_us; + int line_cycles; + int lcd_res_h; + + LcdEpdConfig_t config; + + uint8_t* bounce_buffer[2]; + // size of a single bounce buffer + size_t bb_size; + size_t batches; + + // Number of DMA descriptors that used to carry the frame buffer + size_t num_dma_nodes; + // DMA channel handle + gdma_channel_handle_t dma_chan; + // DMA descriptors pool + dma_descriptor_t* dma_nodes; + + /// The number of bytes in a horizontal display register line. + int line_bytes; + + // With 8 bit bus width, we need a dummy cycle before the actual data, + // because the LCD peripheral behaves weirdly. + // Also see: + // https://blog.adafruit.com/2022/06/14/esp32uesday-hacking-the-esp32-s3-lcd-peripheral/ + int dummy_bytes; + + /// The number of lines of the display + int display_lines; +} s3_lcd_t; + +static s3_lcd_t lcd = { 0 }; + +void IRAM_ATTR epd_lcd_line_source_cb(line_cb_func_t line_source, void* payload) { + lcd.line_source_cb = line_source; + lcd.line_cb_payload = payload; +} + +void IRAM_ATTR epd_lcd_frame_done_cb(frame_done_func_t cb, void* payload) { + lcd.frame_done_cb = cb; + lcd.frame_cb_payload = payload; +} + +static IRAM_ATTR bool fill_bounce_buffer(uint8_t* buffer) { + bool task_awoken = false; + + for (int i = 0; i < BOUNCE_BUF_LINES; i++) { + if (lcd.line_source_cb != NULL) { + // this is strange, with 16 bit need a dummy cycle. But still, the first byte in the + // FIFO is correct. So we only need a true dummy byte in the FIFO in the 8 bit + // configuration. + int buffer_offset = i * (lcd.line_bytes + lcd.dummy_bytes) + (lcd.dummy_bytes % 2); + task_awoken |= lcd.line_source_cb(lcd.line_cb_payload, &buffer[buffer_offset]); + } else { + memset(&buffer[i * lcd.line_bytes], 0x00, lcd.line_bytes); + } + } + return task_awoken; +} + +static void start_ckv_cycles(int cycles) { + rmt_ll_tx_enable_loop_count(&RMT, RMT_CKV_CHAN, true); + rmt_ll_tx_enable_loop_autostop(&RMT, RMT_CKV_CHAN, true); + rmt_ll_tx_set_loop_count(&RMT, RMT_CKV_CHAN, cycles); + rmt_ll_tx_reset_pointer(&RMT, RMT_CKV_CHAN); + rmt_ll_tx_start(&RMT, RMT_CKV_CHAN); +} + +/** + * Build the RMT signal according to the timing set in the lcd object. + */ +static void ckv_rmt_build_signal() { + int low_time = (lcd.line_length_us * 10 - lcd.config.ckv_high_time); + volatile rmt_item32_t* rmt_mem_ptr = &(RMTMEM.chan[RMT_CKV_CHAN].data32[0]); + rmt_mem_ptr->duration0 = lcd.config.ckv_high_time; + rmt_mem_ptr->level0 = 1; + rmt_mem_ptr->duration1 = low_time; + rmt_mem_ptr->level1 = 0; + rmt_mem_ptr[1].val = 0; +} + +/** + * Configure the RMT peripheral for use as the CKV clock. + */ +static void init_ckv_rmt() { + periph_module_reset(PERIPH_RMT_MODULE); + periph_module_enable(PERIPH_RMT_MODULE); + + rmt_ll_enable_periph_clock(&RMT, true); + + // Divide 80MHz APB Clock by 8 -> .1us resolution delay + // idf >= 5.0 calculates the clock divider differently + rmt_ll_set_group_clock_src(&RMT, RMT_CKV_CHAN, RMT_CLK_SRC_DEFAULT, 1, 0, 0); + rmt_ll_tx_set_channel_clock_div(&RMT, RMT_CKV_CHAN, 8); + rmt_ll_tx_set_mem_blocks(&RMT, RMT_CKV_CHAN, 2); + rmt_ll_enable_mem_access_nonfifo(&RMT, true); + rmt_ll_tx_fix_idle_level(&RMT, RMT_CKV_CHAN, RMT_IDLE_LEVEL_LOW, true); + rmt_ll_tx_enable_carrier_modulation(&RMT, RMT_CKV_CHAN, false); + + rmt_ll_tx_enable_loop(&RMT, RMT_CKV_CHAN, true); + + gpio_hal_func_sel(&hal, lcd.config.bus.ckv, PIN_FUNC_GPIO); + gpio_set_direction(lcd.config.bus.ckv, GPIO_MODE_OUTPUT); + esp_rom_gpio_connect_out_signal( + lcd.config.bus.ckv, rmt_periph_signals.groups[0].channels[RMT_CKV_CHAN].tx_sig, false, 0 + ); + + ckv_rmt_build_signal(); +} + +/** + * Reset the CKV RMT configuration. + */ +static void deinit_ckv_rmt() { + periph_module_reset(PERIPH_RMT_MODULE); + periph_module_disable(PERIPH_RMT_MODULE); + + gpio_reset_pin(lcd.config.bus.ckv); +} + +__attribute__((optimize("O3"))) IRAM_ATTR static void lcd_isr_vsync(void* args) { + bool need_yield = false; + + uint32_t intr_status = lcd_ll_get_interrupt_status(lcd.hal.dev); + lcd_ll_clear_interrupt_status(lcd.hal.dev, intr_status); + + if (intr_status & LCD_LL_EVENT_VSYNC_END) { + int batches_needed = lcd.display_lines / LINE_BATCH; + if (lcd.batches >= batches_needed) { + lcd_ll_stop(lcd.hal.dev); + if (lcd.frame_done_cb != NULL) { + (*lcd.frame_done_cb)(lcd.frame_cb_payload); + } + } else { + int ckv_cycles = 0; + // last batch + if (lcd.batches == batches_needed - 1) { + lcd_ll_enable_auto_next_frame(lcd.hal.dev, false); + lcd_ll_set_vertical_timing(lcd.hal.dev, 1, 0, lcd.display_lines % LINE_BATCH, 10); + ckv_cycles = lcd.display_lines % LINE_BATCH + 10; + } else { + lcd_ll_set_vertical_timing(lcd.hal.dev, 1, 0, LINE_BATCH, 1); + ckv_cycles = LINE_BATCH + 1; + } + // apparently, this is needed for the new timing to take effect. + lcd_ll_start(lcd.hal.dev); + + // skip the LCD front porch line, which is not actual data + esp_rom_delay_us(lcd.line_length_us); + start_ckv_cycles(ckv_cycles); + } + + lcd.batches += 1; + } + + if (need_yield) { + portYIELD_FROM_ISR(); + } +}; + +// ISR handling bounce buffer refill +static IRAM_ATTR bool lcd_rgb_panel_eof_handler( + gdma_channel_handle_t dma_chan, gdma_event_data_t* event_data, void* user_data +) { + dma_descriptor_t* desc = (dma_descriptor_t*)event_data->tx_eof_desc_addr; + // Figure out which bounce buffer to write to. + // Note: what we receive is the *last* descriptor of this bounce buffer. + int bb = (desc == &lcd.dma_nodes[0]) ? 0 : 1; + return fill_bounce_buffer(lcd.bounce_buffer[bb]); +} + +static esp_err_t init_dma_trans_link() { + lcd.dma_nodes[0].dw0.suc_eof = 1; + lcd.dma_nodes[0].dw0.size = lcd.bb_size; + lcd.dma_nodes[0].dw0.length = lcd.bb_size; + lcd.dma_nodes[0].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_CPU; + lcd.dma_nodes[0].buffer = lcd.bounce_buffer[0]; + + lcd.dma_nodes[1].dw0.suc_eof = 1; + lcd.dma_nodes[1].dw0.size = lcd.bb_size; + lcd.dma_nodes[1].dw0.length = lcd.bb_size; + lcd.dma_nodes[1].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_CPU; + lcd.dma_nodes[1].buffer = lcd.bounce_buffer[1]; + + // loop end back to start + lcd.dma_nodes[0].next = &lcd.dma_nodes[1]; + lcd.dma_nodes[1].next = &lcd.dma_nodes[0]; + + // alloc DMA channel and connect to LCD peripheral + gdma_channel_alloc_config_t dma_chan_config = { + .direction = GDMA_CHANNEL_DIRECTION_TX, + }; + ESP_RETURN_ON_ERROR( + gdma_new_channel(&dma_chan_config, &lcd.dma_chan), TAG, "alloc DMA channel failed" + ); + gdma_trigger_t trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0); + ESP_RETURN_ON_ERROR(gdma_connect(lcd.dma_chan, trigger), TAG, "dma connect error"); + gdma_transfer_ability_t ability = { + .psram_trans_align = 64, + .sram_trans_align = 4, + }; + ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(lcd.dma_chan, &ability), TAG, "dma setup error"); + + gdma_tx_event_callbacks_t cbs = { + .on_trans_eof = lcd_rgb_panel_eof_handler, + }; + ESP_RETURN_ON_ERROR( + gdma_register_tx_event_callbacks(lcd.dma_chan, &cbs, NULL), TAG, "dma setup error" + ); + + return ESP_OK; +} + +void deinit_dma_trans_link() { + gdma_reset(lcd.dma_chan); + gdma_disconnect(lcd.dma_chan); + gdma_del_channel(lcd.dma_chan); +} + +/** + * Configure LCD peripheral and auxiliary GPIOs + */ +static esp_err_t init_bus_gpio() { + const int DATA_LINES[16] = { + lcd.config.bus.data[14], lcd.config.bus.data[15], lcd.config.bus.data[12], + lcd.config.bus.data[13], lcd.config.bus.data[10], lcd.config.bus.data[11], + lcd.config.bus.data[8], lcd.config.bus.data[9], lcd.config.bus.data[6], + lcd.config.bus.data[7], lcd.config.bus.data[4], lcd.config.bus.data[5], + lcd.config.bus.data[2], lcd.config.bus.data[3], lcd.config.bus.data[0], + lcd.config.bus.data[1], + }; + + // connect peripheral signals via GPIO matrix + for (size_t i = (16 - lcd.config.bus_width); i < 16; i++) { + gpio_hal_func_sel(&hal, DATA_LINES[i], PIN_FUNC_GPIO); + gpio_set_direction(DATA_LINES[i], GPIO_MODE_OUTPUT); + esp_rom_gpio_connect_out_signal( + DATA_LINES[i], LCD_PERIPH_SIGNALS.panels[0].data_sigs[i], false, false + ); + } + gpio_hal_func_sel(&hal, lcd.config.bus.leh, PIN_FUNC_GPIO); + gpio_set_direction(lcd.config.bus.leh, GPIO_MODE_OUTPUT); + gpio_hal_func_sel(&hal, lcd.config.bus.clock, PIN_FUNC_GPIO); + gpio_set_direction(lcd.config.bus.clock, GPIO_MODE_OUTPUT); + gpio_hal_func_sel(&hal, lcd.config.bus.start_pulse, PIN_FUNC_GPIO); + gpio_set_direction(lcd.config.bus.start_pulse, GPIO_MODE_OUTPUT); + + esp_rom_gpio_connect_out_signal( + lcd.config.bus.leh, LCD_PERIPH_SIGNALS.panels[0].hsync_sig, false, false + ); + esp_rom_gpio_connect_out_signal( + lcd.config.bus.clock, LCD_PERIPH_SIGNALS.panels[0].pclk_sig, false, false + ); + esp_rom_gpio_connect_out_signal( + lcd.config.bus.start_pulse, LCD_PERIPH_SIGNALS.panels[0].de_sig, false, false + ); + + gpio_config_t vsync_gpio_conf = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ull << lcd.config.bus.stv, + }; + gpio_config(&vsync_gpio_conf); + gpio_set_level(lcd.config.bus.stv, 1); + return ESP_OK; +} + +/** + * Reset bus GPIO pin functions. + */ +static void deinit_bus_gpio() { + for (size_t i = (16 - lcd.config.bus_width); i < 16; i++) { + gpio_reset_pin(lcd.config.bus.data[i]); + } + + gpio_reset_pin(lcd.config.bus.leh); + gpio_reset_pin(lcd.config.bus.clock); + gpio_reset_pin(lcd.config.bus.start_pulse); + gpio_reset_pin(lcd.config.bus.stv); +} + +/** + * Check if the PSRAM cache is properly configured. + */ +static void check_cache_configuration() { + if (CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE < 64) { + ESP_LOGE( + "epdiy", + "cache line size is set to %d (< 64B)! This will degrade performance, please update " + "this option in menuconfig.", + CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE + ); + ESP_LOGE( + "epdiy", + "If you are on arduino, you can't set this option yourself, you'll need to use a lower " + "speed." + ); + ESP_LOGE( + "epdiy", + "Reducing the pixel clock from %d MHz to %d MHz for now!", + lcd.config.pixel_clock / 1000 / 1000, + lcd.config.pixel_clock / 1000 / 1000 / 2 + ); + lcd.config.pixel_clock = lcd.config.pixel_clock / 2; + + // fixme: this would be nice, but doesn't work :( + // uint32_t d_autoload = Cache_Suspend_DCache(); + /// Cache_Set_DCache_Mode(CACHE_SIZE_FULL, CACHE_4WAYS_ASSOC, CACHE_LINE_SIZE_32B); + // Cache_Invalidate_DCache_All(); + // Cache_Resume_DCache(d_autoload); + } +} + +/** + * Assign LCD configuration parameters from a given configuration, without allocating memory or + * touching the LCD peripheral config. + */ +static void assign_lcd_parameters_from_config( + const LcdEpdConfig_t* config, int display_width, int display_height +) { + // copy over the configuraiton object + memcpy(&lcd.config, config, sizeof(LcdEpdConfig_t)); + + // Make sure the bounce buffers divide the display height evenly. + lcd.display_lines = (((display_height + 7) / 8) * 8); + + lcd.line_bytes = display_width / 4; + lcd.lcd_res_h = lcd.line_bytes / (lcd.config.bus_width / 8); + + // With 8 bit bus width, we need a dummy cycle before the actual data, + // because the LCD peripheral behaves weirdly. + // Also see: + // https://blog.adafruit.com/2022/06/14/esp32uesday-hacking-the-esp32-s3-lcd-peripheral/ + lcd.dummy_bytes = lcd.config.bus_width / 8; + + // each bounce buffer holds a number of lines with data + dummy bytes each + lcd.bb_size = BOUNCE_BUF_LINES * (lcd.line_bytes + lcd.dummy_bytes); + + check_cache_configuration(); + + ESP_LOGI(TAG, "using resolution %dx%d", lcd.lcd_res_h, lcd.display_lines); +} + +/** + * Allocate buffers for LCD driver operation. + */ +static esp_err_t allocate_lcd_buffers() { + uint32_t dma_flags = MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + + // allocate bounce buffers + for (int i = 0; i < 2; i++) { + lcd.bounce_buffer[i] = heap_caps_aligned_calloc(4, 1, lcd.bb_size, dma_flags); + ESP_RETURN_ON_FALSE(lcd.bounce_buffer[i], ESP_ERR_NO_MEM, TAG, "install interrupt failed"); + } + + // So far, I haven't seen any displays with > 4096 pixels per line, + // so we only need one DMA node for now. + assert(lcd.bb_size < DMA_DESCRIPTOR_BUFFER_MAX_SIZE); + lcd.dma_nodes = heap_caps_calloc(1, sizeof(dma_descriptor_t) * 2, dma_flags); + ESP_RETURN_ON_FALSE(lcd.dma_nodes, ESP_ERR_NO_MEM, TAG, "no mem for dma nodes"); + return ESP_OK; +} + +static void free_lcd_buffers() { + for (int i = 0; i < 2; i++) { + uint8_t* buf = lcd.bounce_buffer[i]; + if (buf != NULL) { + heap_caps_free(buf); + lcd.bounce_buffer[i] = NULL; + } + } + + if (lcd.dma_nodes != NULL) { + heap_caps_free(lcd.dma_nodes); + lcd.dma_nodes = NULL; + } +} + +/** + * Initialize the LCD peripheral itself and install interrupts. + */ +static esp_err_t init_lcd_peripheral() { + esp_err_t ret = ESP_OK; + + // enable APB to access LCD registers + periph_module_enable(PERIPH_LCD_CAM_MODULE); + periph_module_reset(PERIPH_LCD_CAM_MODULE); + + lcd_hal_init(&lcd.hal, 0); + lcd_ll_enable_clock(lcd.hal.dev, true); + lcd_ll_select_clk_src(lcd.hal.dev, LCD_CLK_SRC_PLL240M); + ESP_RETURN_ON_ERROR(ret, TAG, "set source clock failed"); + + // install interrupt service, (LCD peripheral shares the interrupt source with Camera by + // different mask) + int flags = ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED + | ESP_INTR_FLAG_LOWMED; + + int source = LCD_PERIPH_SIGNALS.panels[0].irq_id; + uint32_t status = (uint32_t)lcd_ll_get_interrupt_status_reg(lcd.hal.dev); + ret = esp_intr_alloc_intrstatus( + source, flags, status, LCD_LL_EVENT_VSYNC_END, lcd_isr_vsync, NULL, &lcd.vsync_intr + ); + ESP_RETURN_ON_ERROR(ret, TAG, "install interrupt failed"); + + status = (uint32_t)lcd_ll_get_interrupt_status_reg(lcd.hal.dev); + ret = esp_intr_alloc_intrstatus( + source, flags, status, LCD_LL_EVENT_TRANS_DONE, lcd_isr_vsync, NULL, &lcd.done_intr + ); + ESP_RETURN_ON_ERROR(ret, TAG, "install interrupt failed"); + + lcd_ll_fifo_reset(lcd.hal.dev); + lcd_ll_reset(lcd.hal.dev); + + // pixel clock phase and polarity + lcd_ll_set_clock_idle_level(lcd.hal.dev, false); + lcd_ll_set_pixel_clock_edge(lcd.hal.dev, false); + + // enable RGB mode and set data width + lcd_ll_enable_rgb_mode(lcd.hal.dev, true); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) + lcd_ll_set_dma_read_stride(lcd.hal.dev, lcd.config.bus_width); + lcd_ll_set_data_wire_width(lcd.hal.dev, lcd.config.bus_width); +#else + lcd_ll_set_data_width(lcd.hal.dev, lcd.config.bus_width); +#endif + lcd_ll_set_phase_cycles(lcd.hal.dev, 0, (lcd.dummy_bytes > 0), 1); // enable data phase only + lcd_ll_enable_output_hsync_in_porch_region(lcd.hal.dev, false); // enable data phase only + + // number of data cycles is controlled by DMA buffer size + lcd_ll_enable_output_always_on(lcd.hal.dev, false); + lcd_ll_set_idle_level(lcd.hal.dev, false, true, true); + + // configure blank region timing + // RGB panel always has a front and back blank (porch region) + lcd_ll_set_blank_cycles(lcd.hal.dev, 1, 1); + + // output hsync even in porch region? + lcd_ll_enable_output_hsync_in_porch_region(lcd.hal.dev, false); + // send next frame automatically in stream mode + lcd_ll_enable_auto_next_frame(lcd.hal.dev, false); + + lcd_ll_enable_interrupt(lcd.hal.dev, LCD_LL_EVENT_VSYNC_END, true); + lcd_ll_enable_interrupt(lcd.hal.dev, LCD_LL_EVENT_TRANS_DONE, true); + + // enable intr + esp_intr_enable(lcd.vsync_intr); + esp_intr_enable(lcd.done_intr); + return ret; +} + +static void deinit_lcd_peripheral() { + // disable and free interrupts + esp_intr_disable(lcd.vsync_intr); + esp_intr_disable(lcd.done_intr); + esp_intr_free(lcd.vsync_intr); + esp_intr_free(lcd.done_intr); + + lcd_ll_fifo_reset(lcd.hal.dev); + lcd_ll_reset(lcd.hal.dev); + + periph_module_reset(PERIPH_LCD_CAM_MODULE); + periph_module_disable(PERIPH_LCD_CAM_MODULE); +} + +/** + * Configure the LCD driver for epdiy. + */ +void epd_lcd_init(const LcdEpdConfig_t* config, int display_width, int display_height) { + esp_err_t ret = ESP_OK; + assign_lcd_parameters_from_config(config, display_width, display_height); + + check_cache_configuration(); + + ret = allocate_lcd_buffers(); + ESP_GOTO_ON_ERROR(ret, err, TAG, "lcd buffer allocation failed"); + + ret = init_lcd_peripheral(); + ESP_GOTO_ON_ERROR(ret, err, TAG, "lcd peripheral init failed"); + + ret = init_dma_trans_link(); + ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed"); + + ret = init_bus_gpio(); + ESP_GOTO_ON_ERROR(ret, err, TAG, "configure GPIO failed"); + + init_ckv_rmt(); + + // setup driver state + epd_lcd_set_pixel_clock_MHz(lcd.config.pixel_clock / 1000 / 1000); + epd_lcd_line_source_cb(NULL, NULL); + + ESP_LOGI(TAG, "LCD init done."); + return; +err: + ESP_LOGE(TAG, "LCD initialization failed!"); + abort(); +} + +/** + * Deinitializue the LCD driver, i.e., free resources and peripherals. + */ +void epd_lcd_deinit() { + epd_lcd_line_source_cb(NULL, NULL); + + deinit_bus_gpio(); + deinit_lcd_peripheral(); + deinit_dma_trans_link(); + free_lcd_buffers(); + deinit_ckv_rmt(); + + ESP_LOGI(TAG, "LCD deinitialized."); +} + +void epd_lcd_set_pixel_clock_MHz(int frequency) { + lcd.config.pixel_clock = frequency * 1000 * 1000; + + // set pclk + int flags = 0; + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) + hal_utils_clk_div_t clk_div = {}; +/** + * There was a change in the parameters of this function in this commit: + * https://github.com/espressif/esp-idf/commit/d39388fe4f4c5bfb0b52df9177307b1688f41016#diff-2df607d77e3f6e350bab8eb31cfd914500ae42744564e1640cec47006cc17a9c + * There are different builds with the same IDF minor version, some with, some without the commit. + * So we try to select the correct one by checking if the flag value is defined. + */ +#ifdef LCD_HAL_PCLK_FLAG_ALLOW_EQUAL_SYSCLK + uint32_t freq + = lcd_hal_cal_pclk_freq(&lcd.hal, 240000000, lcd.config.pixel_clock, flags, &clk_div); +#else + uint32_t freq = lcd_hal_cal_pclk_freq(&lcd.hal, 240000000, lcd.config.pixel_clock, &clk_div); +#endif + lcd_ll_set_group_clock_coeff( + &LCD_CAM, (int)clk_div.integer, (int)clk_div.denominator, (int)clk_div.numerator + ); +#else + uint32_t freq = lcd_hal_cal_pclk_freq(&lcd.hal, 240000000, lcd.config.pixel_clock, flags); +#endif + + ESP_LOGI(TAG, "pclk freq: %d Hz", freq); + lcd.line_length_us = (lcd.lcd_res_h + lcd.config.le_high_time + lcd.config.line_front_porch - 1) + * 1000000 / lcd.config.pixel_clock + + 1; + lcd.line_cycles = lcd.line_length_us * lcd.config.pixel_clock / 1000000; + ESP_LOGI(TAG, "line width: %dus, %d cylces", lcd.line_length_us, lcd.line_cycles); + + ckv_rmt_build_signal(); +} + +void IRAM_ATTR epd_lcd_start_frame() { + int initial_lines = min(LINE_BATCH, lcd.display_lines); + + // hsync: pulse with, back porch, active width, front porch + int end_line + = lcd.line_cycles - lcd.lcd_res_h - lcd.config.le_high_time - lcd.config.line_front_porch; + lcd_ll_set_horizontal_timing( + lcd.hal.dev, + lcd.config.le_high_time - (lcd.dummy_bytes > 0), + lcd.config.line_front_porch, + // a dummy byte is neeed in 8 bit mode to work around LCD peculiarities + lcd.lcd_res_h + (lcd.dummy_bytes > 0), + end_line + ); + lcd_ll_set_vertical_timing(lcd.hal.dev, 1, 0, initial_lines, 1); + + // generate the hsync at the very beginning of line + lcd_ll_set_hsync_position(lcd.hal.dev, 1); + + // reset FIFO of DMA and LCD, incase there remains old frame data + gdma_reset(lcd.dma_chan); + lcd_ll_stop(lcd.hal.dev); + lcd_ll_fifo_reset(lcd.hal.dev); + lcd_ll_enable_auto_next_frame(lcd.hal.dev, true); + + lcd.batches = 0; + fill_bounce_buffer(lcd.bounce_buffer[0]); + fill_bounce_buffer(lcd.bounce_buffer[1]); + + // the start of DMA should be prior to the start of LCD engine + gdma_start(lcd.dma_chan, (intptr_t)&lcd.dma_nodes[0]); + + // enter a critical section to ensure the frame start timing is correct + taskENTER_CRITICAL(&frame_start_spinlock); + + // delay 1us is sufficient for DMA to pass data to LCD FIFO + // in fact, this is only needed when LCD pixel clock is set too high + gpio_set_level(lcd.config.bus.stv, 0); + // esp_rom_delay_us(1); + // for picture clarity, it seems to be important to start CKV at a "good" + // time, seemingly start or towards end of line. + start_ckv_cycles(initial_lines + 5); + esp_rom_delay_us(lcd.line_length_us); + gpio_set_level(lcd.config.bus.stv, 1); + esp_rom_delay_us(lcd.line_length_us); + esp_rom_delay_us(lcd.config.ckv_high_time / 10); + + // start LCD engine + lcd_ll_start(lcd.hal.dev); + + taskEXIT_CRITICAL(&frame_start_spinlock); +} + +#else + +/// Dummy implementation to link on the old ESP32 +void epd_lcd_init(const LcdEpdConfig_t* config, int display_width, int display_height) { + assert(false); +} + +#endif // S3 Target diff --git a/lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.h b/lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.h new file mode 100644 index 000000000..34c453aab --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_lcd/lcd_driver.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include +#include + +/** + * LCD bus configuration parameters. + */ +typedef struct { + // GPIO numbers of the parallel bus pins. + gpio_num_t data[16]; + + // horizontal clock pin. + gpio_num_t clock; + // vertical clock pin + gpio_num_t ckv; + + // horizontal "Start Pulse", enabling data input on the line shift register + gpio_num_t start_pulse; + // latch enable + gpio_num_t leh; + // vertical start pulse, resetting the vertical line shift register. + gpio_num_t stv; +} lcd_bus_config_t; + +/// Configuration structure for the LCD-based Epd driver. +typedef struct { + // high time for CKV in 1/10us. + size_t pixel_clock; // = 12000000 + int ckv_high_time; // = 70 + int line_front_porch; // = 4 + int le_high_time; // = 4 + int bus_width; // = 16 + lcd_bus_config_t bus; +} LcdEpdConfig_t; + +typedef bool (*line_cb_func_t)(void*, uint8_t*); +typedef void (*frame_done_func_t)(void*); + +void epd_lcd_init(const LcdEpdConfig_t* config, int display_width, int display_height); +void epd_lcd_deinit(); +void epd_lcd_frame_done_cb(frame_done_func_t, void* payload); +void epd_lcd_line_source_cb(line_cb_func_t, void* payload); +void epd_lcd_start_frame(); +/** + * Set the LCD pixel clock frequency in MHz. + */ +void epd_lcd_set_pixel_clock_MHz(int frequency); diff --git a/lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.c b/lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.c new file mode 100644 index 000000000..c5229d3d9 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.c @@ -0,0 +1,246 @@ +#include +#include + +#include "../output_common/render_method.h" + +#ifdef RENDER_METHOD_LCD + +#include +#include + +#include "../epd_internals.h" +#include "../output_common/line_queue.h" +#include "../output_common/lut.h" +#include "../output_common/render_context.h" +#include "epd_board.h" +#include "epdiy.h" +#include "lcd_driver.h" +#include "render_lcd.h" + +// declare vector optimized line mask application. +void epd_apply_line_mask_VE(uint8_t* line, const uint8_t* mask, int mask_len); + +__attribute__((optimize("O3"))) static bool IRAM_ATTR +retrieve_line_isr(RenderContext_t* ctx, uint8_t* buf) { + if (ctx->lines_consumed >= ctx->lines_total) { + return false; + } + int thread = ctx->line_threads[ctx->lines_consumed]; + assert(thread < NUM_RENDER_THREADS); + + LineQueue_t* lq = &ctx->line_queues[thread]; + + BaseType_t awoken = pdFALSE; + + if (lq_read(lq, buf) != 0) { + ctx->error |= EPD_DRAW_EMPTY_LINE_QUEUE; + memset(buf, 0x00, ctx->display_width / 4); + } + + if (ctx->lines_consumed >= ctx->display_height) { + memset(buf, 0x00, ctx->display_width / 4); + } + ctx->lines_consumed += 1; + return awoken; +} + +/// start the next frame in the current update cycle +static void IRAM_ATTR handle_lcd_frame_done(RenderContext_t* ctx) { + epd_lcd_frame_done_cb(NULL, NULL); + epd_lcd_line_source_cb(NULL, NULL); + + BaseType_t task_awoken = pdFALSE; + xSemaphoreGiveFromISR(ctx->frame_done, &task_awoken); + + portYIELD_FROM_ISR(); +} + +void lcd_do_update(RenderContext_t* ctx) { + epd_set_mode(1); + + for (uint8_t k = 0; k < ctx->cycle_frames; k++) { + epd_lcd_frame_done_cb((frame_done_func_t)handle_lcd_frame_done, ctx); + prepare_context_for_next_frame(ctx); + + // start both feeder tasks + xTaskNotifyGive(ctx->feed_tasks[!xPortGetCoreID()]); + xTaskNotifyGive(ctx->feed_tasks[xPortGetCoreID()]); + + // transmission is started in renderer threads, now wait util it's done + xSemaphoreTake(ctx->frame_done, portMAX_DELAY); + + for (int i = 0; i < NUM_RENDER_THREADS; i++) { + xSemaphoreTake(ctx->feed_done_smphr[i], portMAX_DELAY); + } + + ctx->current_frame++; + + // make the watchdog happy. + vTaskDelay(0); + } + + epd_lcd_line_source_cb(NULL, NULL); + epd_lcd_frame_done_cb(NULL, NULL); + + epd_set_mode(0); +} + +__attribute__((optimize("O3"))) static bool IRAM_ATTR +push_pixels_isr(RenderContext_t* ctx, uint8_t* buf) { + // Output no-op outside of drawn area + if (ctx->lines_consumed < ctx->area.y) { + memset(buf, 0, ctx->display_width / 4); + } else if (ctx->lines_consumed >= ctx->area.y + ctx->area.height) { + memset(buf, 0, ctx->display_width / 4); + } else { + memcpy(buf, ctx->static_line_buffer, ctx->display_width / 4); + } + ctx->lines_consumed += 1; + return pdFALSE; +} + +/** + * Populate the line mask for use in epd_push_pixels. + */ +static void push_pixels_populate_line(RenderContext_t* ctx, int color) { + // Select fill pattern by draw color + int fill_byte = 0; + switch (color) { + case 0: + fill_byte = DARK_BYTE; + break; + case 1: + fill_byte = CLEAR_BYTE; + break; + default: + fill_byte = 0x00; + } + + // Compute a line mask based on the drawn area + uint8_t* dirtyness = malloc(ctx->display_width / 2); + assert(dirtyness != NULL); + + memset(dirtyness, 0, ctx->display_width / 2); + + for (int i = 0; i < ctx->display_width; i++) { + if ((i >= ctx->area.x) && (i < ctx->area.x + ctx->area.width)) { + dirtyness[i / 2] |= i % 2 ? 0xF0 : 0x0F; + } + } + epd_populate_line_mask(ctx->line_mask, dirtyness, ctx->display_width / 4); + + // mask the line pattern with the populated mask + memset(ctx->static_line_buffer, fill_byte, ctx->display_width / 4); + epd_apply_line_mask(ctx->static_line_buffer, ctx->line_mask, ctx->display_width / 4); + + free(dirtyness); +} + +void epd_push_pixels_lcd(RenderContext_t* ctx, short time, int color) { + ctx->current_frame = 0; + ctx->lines_total = ctx->display_height; + ctx->lines_consumed = 0; + ctx->static_line_buffer = malloc(ctx->display_width / 4); + assert(ctx->static_line_buffer != NULL); + + push_pixels_populate_line(ctx, color); + epd_lcd_frame_done_cb((frame_done_func_t)handle_lcd_frame_done, ctx); + epd_lcd_line_source_cb((line_cb_func_t)&push_pixels_isr, ctx); + + epd_set_mode(1); + epd_lcd_start_frame(); + xSemaphoreTake(ctx->frame_done, portMAX_DELAY); + epd_set_mode(0); + + free(ctx->static_line_buffer); + ctx->static_line_buffer = NULL; +} + +#define int_min(a, b) (((a) < (b)) ? (a) : (b)) +__attribute__((optimize("O3"))) void IRAM_ATTR +lcd_calculate_frame(RenderContext_t* ctx, int thread_id) { + assert(ctx->lut_lookup_func != NULL); + uint8_t* input_line = ctx->feed_line_buffers[thread_id]; + + LineQueue_t* lq = &ctx->line_queues[thread_id]; + int l = 0; + + // if there is an error, start the frame but don't feed data. + if (ctx->error) { + memset(ctx->line_threads, 0, ctx->lines_total); + epd_lcd_line_source_cb((line_cb_func_t)&retrieve_line_isr, ctx); + epd_lcd_start_frame(); + ESP_LOGW("epd_lcd", "draw frame draw initiated, but an error flag is set: %X", ctx->error); + return; + } + + // line must be able to hold 2-pixel-per-byte or 1-pixel-per-byte data + memset(input_line, 0x00, ctx->display_width); + + EpdRect area = ctx->area; + int min_y, max_y, bytes_per_line, _ppB; + const uint8_t* ptr_start; + get_buffer_params(ctx, &bytes_per_line, &ptr_start, &min_y, &max_y, &_ppB); + + assert(area.width == ctx->display_width && area.x == 0 && !ctx->error); + + // index of the line that triggers the frame output when processed + int trigger_line = int_min(63, max_y - min_y); + + while (l = atomic_fetch_add(&ctx->lines_prepared, 1), l < ctx->lines_total) { + ctx->line_threads[l] = thread_id; + + // queue is sufficiently filled to fill both bounce buffers, frame + // can begin + if (l - min_y == trigger_line) { + epd_lcd_line_source_cb((line_cb_func_t)&retrieve_line_isr, ctx); + epd_lcd_start_frame(); + } + + if (l < min_y || l >= max_y + || (ctx->drawn_lines != NULL && !ctx->drawn_lines[l - area.y])) { + uint8_t* buf = NULL; + while (buf == NULL) { + // break in case of errors + if (ctx->error & EPD_DRAW_EMPTY_LINE_QUEUE) { + printf("on err 1: %d %d\n", ctx->lines_prepared, ctx->lines_consumed); + lq_reset(lq); + return; + }; + + buf = lq_current(lq); + } + memset(buf, 0x00, lq->element_size); + lq_commit(lq); + continue; + } + + uint32_t* lp = (uint32_t*)input_line; + const uint8_t* ptr = ptr_start + bytes_per_line * (l - min_y); + + Cache_Start_DCache_Preload((uint32_t)ptr, ctx->display_width, 0); + + lp = (uint32_t*)ptr; + + uint8_t* buf = NULL; + while (buf == NULL) { + // break in case of errors + if (ctx->error & EPD_DRAW_EMPTY_LINE_QUEUE) { + lq_reset(lq); + printf("on err 2: %d %d\n", ctx->lines_prepared, ctx->lines_consumed); + return; + }; + + buf = lq_current(lq); + } + + ctx->lut_lookup_func(lp, buf, ctx->conversion_lut, ctx->display_width); + + // apply the line mask + epd_apply_line_mask_VE(buf, ctx->line_mask, ctx->display_width / 4); + + lq_commit(lq); + } +} + +#endif diff --git a/lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.h b/lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.h new file mode 100644 index 000000000..3c521e856 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/output_lcd/render_lcd.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../output_common/render_context.h" + +/** + * Lighten / darken picels using the LCD driving method. + */ +void epd_push_pixels_lcd(RenderContext_t* ctx, short time, int color); + +/** + * Do a full update cycle with a configured context. + */ +void lcd_do_update(RenderContext_t* ctx); + +/** + * Worker thread for output calculation. + * In LCD mode, both threads do the same thing. + */ +void lcd_calculate_frame(RenderContext_t* ctx, int thread_id); diff --git a/lib/libesp32_eink/epdiy/src/render.c b/lib/libesp32_eink/epdiy/src/render.c new file mode 100644 index 000000000..eaba217d8 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/render.c @@ -0,0 +1,526 @@ +#include "render.h" + +#include "epd_board.h" +#include "epd_internals.h" +#include "epdiy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "esp_heap_caps.h" +#include "output_common/line_queue.h" +#include "output_common/lut.h" +#include "output_common/render_context.h" +#include "output_common/render_method.h" +#include "output_i2s/render_i2s.h" +#include "output_lcd/render_lcd.h" + +static inline int min(int x, int y) { + return x < y ? x : y; +} +static inline int max(int x, int y) { + return x > y ? x : y; +} + +const int clear_cycle_time = 12; + +#define RTOS_ERROR_CHECK(x) \ + do { \ + esp_err_t __err_rc = (x); \ + if (__err_rc != pdPASS) { \ + abort(); \ + } \ + } while (0) + +static RenderContext_t render_context; + +void epd_push_pixels(EpdRect area, short time, int color) { + render_context.area = area; +#ifdef RENDER_METHOD_LCD + epd_push_pixels_lcd(&render_context, time, color); +#else + epd_push_pixels_i2s(&render_context, area, time, color); +#endif +} + +///////////////////////////// Coordination /////////////////////////////// + +/** + * Find the waveform temperature range index for a given temperature in °C. + * If no range in the waveform data fits the given temperature, return the + * closest one. + * Returns -1 if the waveform does not contain any temperature range. + */ +int waveform_temp_range_index(const EpdWaveform* waveform, int temperature) { + int idx = 0; + if (waveform->num_temp_ranges == 0) { + return -1; + } + while (idx < waveform->num_temp_ranges - 1 && waveform->temp_intervals[idx].min < temperature) { + idx++; + } + return idx; +} + +static int get_waveform_index(const EpdWaveform* waveform, enum EpdDrawMode mode) { + for (int i = 0; i < waveform->num_modes; i++) { + if (waveform->mode_data[i]->type == (mode & 0x3F)) { + return i; + } + } + return -1; +} + +///////////////////////////// API Procedures ////////////////////////////////// + +/// Rounded up display height for even division into multi-line buffers. +static inline int rounded_display_height() { + return (((epd_height() + 7) / 8) * 8); +} + +// FIXME: fix misleading naming: +// area -> buffer dimensions +// crop -> area taken out of buffer +enum EpdDrawError IRAM_ATTR epd_draw_base( + EpdRect area, + const uint8_t* data, + EpdRect crop_to, + enum EpdDrawMode mode, + int temperature, + const bool* drawn_lines, + const uint8_t* drawn_columns, + const EpdWaveform* waveform +) { + if (waveform == NULL) { + return EPD_DRAW_NO_PHASES_AVAILABLE; + } + int waveform_range = waveform_temp_range_index(waveform, temperature); + if (waveform_range < 0) { + return EPD_DRAW_NO_PHASES_AVAILABLE; + } + int waveform_index = 0; + uint8_t frame_count = 0; + const EpdWaveformPhases* waveform_phases = NULL; + + // no waveform required for monochrome mode + if (!(mode & MODE_EPDIY_MONOCHROME)) { + waveform_index = get_waveform_index(waveform, mode); + if (waveform_index < 0) { + return EPD_DRAW_MODE_NOT_FOUND; + } + + waveform_phases = waveform->mode_data[waveform_index]->range_data[waveform_range]; + // FIXME: error if not present + frame_count = waveform_phases->phases; + } else { + frame_count = 1; + } + + if (crop_to.width < 0 || crop_to.height < 0) { + return EPD_DRAW_INVALID_CROP; + } + + const bool crop = (crop_to.width > 0 && crop_to.height > 0); + if (crop + && (crop_to.width > area.width || crop_to.height > area.height || crop_to.x > area.width + || crop_to.y > area.height)) { + return EPD_DRAW_INVALID_CROP; + } + +#ifdef RENDER_METHOD_LCD + if (mode & MODE_PACKING_1PPB_DIFFERENCE && render_context.conversion_lut_size > 1 << 10) { + ESP_LOGI( + "epdiy", + "Using optimized vector implementation on the ESP32-S3, only 1k of %d LUT in use!", + render_context.conversion_lut_size + ); + } +#endif + + LutFunctionPair lut_functions = find_lut_functions(mode, render_context.conversion_lut_size); + if (lut_functions.build_func == NULL || lut_functions.lookup_func == NULL) { + ESP_LOGE("epdiy", "no output lookup method found for your mode and LUT size!"); + return EPD_DRAW_LOOKUP_NOT_IMPLEMENTED; + } + + render_context.area = area; + render_context.crop_to = crop_to; + render_context.waveform_range = waveform_range; + render_context.waveform_index = waveform_index; + render_context.mode = mode; + render_context.waveform = waveform; + render_context.error = EPD_DRAW_SUCCESS; + render_context.drawn_lines = drawn_lines; + render_context.data_ptr = data; + render_context.lut_build_func = lut_functions.build_func; + render_context.lut_lookup_func = lut_functions.lookup_func; + + render_context.lines_prepared = 0; + render_context.lines_consumed = 0; + render_context.lines_total = rounded_display_height(); + render_context.current_frame = 0; + render_context.cycle_frames = frame_count; + render_context.phase_times = NULL; + if (waveform_phases != NULL && waveform_phases->phase_times != NULL) { + render_context.phase_times = waveform_phases->phase_times; + } + + epd_populate_line_mask( + render_context.line_mask, drawn_columns, render_context.display_width / 4 + ); + +#ifdef RENDER_METHOD_I2S + i2s_do_update(&render_context); +#elif defined(RENDER_METHOD_LCD) + lcd_do_update(&render_context); +#endif + + if (render_context.error & EPD_DRAW_EMPTY_LINE_QUEUE) { + ESP_LOGE("epdiy", "line buffer underrun occurred!"); + } + + if (render_context.error != EPD_DRAW_SUCCESS) { + return render_context.error; + } + return EPD_DRAW_SUCCESS; +} + +static void IRAM_ATTR render_thread(void* arg) { + int thread_id = (int)arg; + + while (true) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + +#ifdef RENDER_METHOD_LCD + lcd_calculate_frame(&render_context, thread_id); +#elif defined(RENDER_METHOD_I2S) + if (thread_id == 0) { + i2s_fetch_frame_data(&render_context, thread_id); + } else { + i2s_output_frame(&render_context, thread_id); + } +#endif + + xSemaphoreGive(render_context.feed_done_smphr[thread_id]); + } +} + +void epd_clear_area(EpdRect area) { + epd_clear_area_cycles(area, 3, clear_cycle_time); +} + +void epd_clear_area_cycles(EpdRect area, int cycles, int cycle_time) { + const short white_time = cycle_time; + const short dark_time = cycle_time; + + for (int c = 0; c < cycles; c++) { + for (int i = 0; i < 10; i++) { + epd_push_pixels(area, dark_time, 0); + } + for (int i = 0; i < 10; i++) { + epd_push_pixels(area, white_time, 1); + } + for (int i = 0; i < 2; i++) { + epd_push_pixels(area, white_time, 2); + } + } +} + +void epd_renderer_init(enum EpdInitOptions options) { + // Either the board should be set in menuconfig or the epd_set_board() must + // be called before epd_init() + assert((epd_current_board() != NULL)); + + epd_current_board()->init(epd_width()); + epd_control_reg_init(); + + render_context.display_width = epd_width(); + render_context.display_height = epd_height(); + + size_t lut_size = 0; + if (options & EPD_LUT_1K) { + lut_size = 1 << 10; + } else if (options & EPD_LUT_64K) { + lut_size = 1 << 16; + } else if (options == EPD_OPTIONS_DEFAULT) { +#ifdef RENDER_METHOD_LCD + lut_size = 1 << 10; +#else + lut_size = 1 << 16; +#endif + } else { + ESP_LOGE("epd", "invalid init options: %d", options); + return; + } + + ESP_LOGI("epd", "Space used for waveform LUT: %dK", lut_size / 1024); + render_context.conversion_lut + = (uint8_t*)heap_caps_malloc(lut_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + if (render_context.conversion_lut == NULL) { + ESP_LOGE("epd", "could not allocate LUT!"); + abort(); + } + render_context.conversion_lut_size = lut_size; + render_context.static_line_buffer = NULL; + + render_context.frame_done = xSemaphoreCreateBinary(); + + for (int i = 0; i < NUM_RENDER_THREADS; i++) { + render_context.feed_done_smphr[i] = xSemaphoreCreateBinary(); + } + + // When using the LCD peripheral, we may need padding lines to + // satisfy the bounce buffer size requirements + render_context.line_threads = (uint8_t*)heap_caps_malloc( + rounded_display_height(), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL + ); + + int queue_len = 32; + if (options & EPD_FEED_QUEUE_32) { + queue_len = 32; + } else if (options & EPD_FEED_QUEUE_8) { + queue_len = 8; + } + + if (render_context.conversion_lut == NULL) { + ESP_LOGE("epd", "could not allocate line mask!"); + abort(); + } + + render_context.line_mask + = heap_caps_aligned_alloc(16, epd_width() / 4, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + assert(render_context.line_mask != NULL); + +#ifdef RENDER_METHOD_LCD + size_t queue_elem_size = render_context.display_width / 4; +#elif defined(RENDER_METHOD_I2S) + size_t queue_elem_size = render_context.display_width; +#endif + + for (int i = 0; i < NUM_RENDER_THREADS; i++) { + render_context.line_queues[i] = lq_init(queue_len, queue_elem_size); + render_context.feed_line_buffers[i] = (uint8_t*)heap_caps_malloc( + render_context.display_width, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL + ); + assert(render_context.feed_line_buffers[i] != NULL); + RTOS_ERROR_CHECK(xTaskCreatePinnedToCore( + render_thread, + "epd_prep", + 1 << 12, + (void*)i, + configMAX_PRIORITIES - 1, + &render_context.feed_tasks[i], + i + )); + } +} + +void epd_renderer_deinit() { + const EpdBoardDefinition* epd_board = epd_current_board(); + + epd_board->poweroff(epd_ctrl_state()); + + for (int i = 0; i < NUM_RENDER_THREADS; i++) { + vTaskDelete(render_context.feed_tasks[i]); + lq_free(&render_context.line_queues[i]); + heap_caps_free(render_context.feed_line_buffers[i]); + vSemaphoreDelete(render_context.feed_done_smphr[i]); + } + +#ifdef RENDER_METHOD_I2S + i2s_deinit(); +#endif + + epd_control_reg_deinit(); + + if (epd_board->deinit) { + epd_board->deinit(); + } + + heap_caps_free(render_context.conversion_lut); + heap_caps_free(render_context.line_threads); + heap_caps_free(render_context.line_mask); + vSemaphoreDelete(render_context.frame_done); +} + +#ifdef RENDER_METHOD_LCD +uint32_t epd_interlace_4bpp_line_VE( + const uint8_t* to, + const uint8_t* from, + uint8_t* interlaced, + uint8_t* col_dirtyness, + int fb_width +); +#endif + +/** + * Interlaces `len` nibbles from the buffers `to` and `from` into `interlaced`. + * In the process, tracks which nibbles differ in `col_dirtyness`. + * Returns `1` if there are differences, `0` otherwise. + * Does not require special alignment of the buffers beyond 32 bit alignment. + */ +__attribute__((optimize("O3"))) static inline int _interlace_line_unaligned( + const uint8_t* to, const uint8_t* from, uint8_t* interlaced, uint8_t* col_dirtyness, int len +) { + int dirty = 0; + for (int x = 0; x < len; x++) { + uint8_t t = *(to + x / 2); + uint8_t f = *(from + x / 2); + t = (x % 2) ? (t >> 4) : (t & 0x0f); + f = (x % 2) ? (f >> 4) : (f & 0x0f); + col_dirtyness[x / 2] |= (t ^ f) << (4 * (x % 2)); + dirty |= (t ^ f); + interlaced[x] = (t << 4) | f; + } + return dirty; +} + +/** + * Interlaces the lines at `to`, `from` into `interlaced`. + * returns `1` if there are differences, `0` otherwise. + */ +__attribute__((optimize("O3"))) bool _epd_interlace_line( + const uint8_t* to, + const uint8_t* from, + uint8_t* interlaced, + uint8_t* col_dirtyness, + int fb_width +) { +#ifdef RENDER_METHOD_I2S + return _interlace_line_unaligned(to, from, interlaced, col_dirtyness, fb_width) > 0; +#elif defined(RENDER_METHOD_LCD) + // Use Vector Extensions with the ESP32-S3. + // Both input buffers should have the same alignment w.r.t. 16 bytes, + // as asserted in epd_difference_image_base. + uint32_t dirty = 0; + + // alignment boundaries in pixels + int unaligned_len_front_px = ((16 - (uint32_t)to % 16) * 2) % 32; + int unaligned_len_back_px = (((uint32_t)to + fb_width / 2) % 16) * 2; + int unaligned_back_start_px = fb_width - unaligned_len_back_px; + int aligned_len_px = fb_width - unaligned_len_front_px - unaligned_len_back_px; + + dirty |= _interlace_line_unaligned(to, from, interlaced, col_dirtyness, unaligned_len_front_px); + dirty |= epd_interlace_4bpp_line_VE( + to + unaligned_len_front_px / 2, + from + unaligned_len_front_px / 2, + interlaced + unaligned_len_front_px, + col_dirtyness + unaligned_len_front_px / 2, + aligned_len_px + ); + dirty |= _interlace_line_unaligned( + to + unaligned_back_start_px / 2, + from + unaligned_back_start_px / 2, + interlaced + unaligned_back_start_px, + col_dirtyness + unaligned_back_start_px / 2, + unaligned_len_back_px + ); + return dirty; +#endif +} + +EpdRect epd_difference_image_base( + const uint8_t* to, + const uint8_t* from, + EpdRect crop_to, + int fb_width, + int fb_height, + uint8_t* interlaced, + bool* dirty_lines, + uint8_t* col_dirtyness +) { + assert(fb_width % 8 == 0); + assert(col_dirtyness != NULL); + + // these buffers should be allocated 16 byte aligned + assert((uint32_t)to % 16 == 0); + assert((uint32_t)from % 16 == 0); + assert((uint32_t)col_dirtyness % 16 == 0); + assert((uint32_t)interlaced % 16 == 0); + + memset(col_dirtyness, 0, fb_width / 2); + memset(dirty_lines, 0, sizeof(bool) * fb_height); + + int x_end = min(fb_width, crop_to.x + crop_to.width); + int y_end = min(fb_height, crop_to.y + crop_to.height); + + for (int y = crop_to.y; y < y_end; y++) { + uint32_t offset = y * fb_width / 2; + int dirty = _epd_interlace_line( + to + offset, from + offset, interlaced + offset * 2, col_dirtyness, fb_width + ); + dirty_lines[y] = dirty; + } + + int min_x, min_y, max_x, max_y; + for (min_x = crop_to.x; min_x < x_end; min_x++) { + uint8_t mask = min_x % 2 ? 0xF0 : 0x0F; + if ((col_dirtyness[min_x / 2] & mask) != 0) + break; + } + for (max_x = x_end - 1; max_x >= crop_to.x; max_x--) { + uint8_t mask = min_x % 2 ? 0xF0 : 0x0F; + if ((col_dirtyness[max_x / 2] & mask) != 0) + break; + } + for (min_y = crop_to.y; min_y < y_end; min_y++) { + if (dirty_lines[min_y] != 0) + break; + } + for (max_y = y_end - 1; max_y >= crop_to.y; max_y--) { + if (dirty_lines[max_y] != 0) + break; + } + + EpdRect crop_rect = { + .x = min_x, + .y = min_y, + .width = max(max_x - min_x + 1, 0), + .height = max(max_y - min_y + 1, 0), + }; + + return crop_rect; +} + +EpdRect epd_difference_image( + const uint8_t* to, + const uint8_t* from, + uint8_t* interlaced, + bool* dirty_lines, + uint8_t* col_dirtyness +) { + return epd_difference_image_base( + to, + from, + epd_full_screen(), + epd_width(), + epd_height(), + interlaced, + dirty_lines, + col_dirtyness + ); +} + +EpdRect epd_difference_image_cropped( + const uint8_t* to, + const uint8_t* from, + EpdRect crop_to, + uint8_t* interlaced, + bool* dirty_lines, + uint8_t* col_dirtyness +) { + EpdRect result = epd_difference_image_base( + to, from, crop_to, epd_width(), epd_height(), interlaced, dirty_lines, col_dirtyness + ); + return result; +} diff --git a/lib/libesp32_eink/epdiy/src/render.h b/lib/libesp32_eink/epdiy/src/render.h new file mode 100644 index 000000000..9a0810e62 --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/render.h @@ -0,0 +1,12 @@ +#pragma once + +#include "epdiy.h" +/** + * Initialize the EPD renderer and its render context. + */ +void epd_renderer_init(enum EpdInitOptions options); + +/** + * Deinitialize the EPD renderer and free up its resources. + */ +void epd_renderer_deinit(); diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED047TC1.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED047TC1.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED047TC1.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED047TC1.h diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/ED047TC2.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED047TC2.h similarity index 98% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/ED047TC2.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED047TC2.h index d213dd2f4..18eb71948 100644 --- a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/ED047TC2.h +++ b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED047TC2.h @@ -1,52 +1,52 @@ #include -const uint8_t epd_wp_ed047tc2_1_5_data[25][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x80,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x00,0x15,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa0}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_5 = { .phases = 25, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_5_data[0] }; -const uint8_t epd_wp_ed047tc2_1_6_data[22][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x84,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x84,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x04}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x04}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x04}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x18}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x18}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x98}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_6 = { .phases = 22, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_6_data[0] }; -const uint8_t epd_wp_ed047tc2_1_7_data[22][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x00}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x00}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x90}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa0}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_7 = { .phases = 22, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_7_data[0] }; -const uint8_t epd_wp_ed047tc2_1_8_data[22][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x00,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_8 = { .phases = 22, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_8_data[0] }; -const uint8_t epd_wp_ed047tc2_1_9_data[18][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x00}},{{0x00,0x00,0x15,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x80,0x00}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x84}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_9 = { .phases = 18, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_9_data[0] }; -const uint8_t epd_wp_ed047tc2_1_10_data[17][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x90,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x90,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa4,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x00}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x40}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x40}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x90}},{{0x00,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa0}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa4}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_10 = { .phases = 17, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_10_data[0] }; -const uint8_t epd_wp_ed047tc2_1_11_data[15][16][4] = {{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x54}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x54}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x00,0x00,0x54}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x54}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x90,0x00,0x54}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x54}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x54}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x40,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x85,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_1_11 = { .phases = 15, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_1_11_data[0] }; -const EpdWaveformPhases* epd_wm_ed047tc2_1_ranges[7] = { &epd_wp_ed047tc2_1_5,&epd_wp_ed047tc2_1_6,&epd_wp_ed047tc2_1_7,&epd_wp_ed047tc2_1_8,&epd_wp_ed047tc2_1_9,&epd_wp_ed047tc2_1_10,&epd_wp_ed047tc2_1_11 }; +const uint8_t epd_wp_ED047TC2_1_5_data[25][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x80,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x00,0x15,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa0}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_5 = { .phases = 25, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_5_data[0] }; +const uint8_t epd_wp_ED047TC2_1_6_data[22][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x84,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x84,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x04}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x04}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x04}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x18}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x18}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x98}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_6 = { .phases = 22, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_6_data[0] }; +const uint8_t epd_wp_ED047TC2_1_7_data[22][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x00}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x00}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x80}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x90}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa0}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_7 = { .phases = 22, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_7_data[0] }; +const uint8_t epd_wp_ED047TC2_1_8_data[22][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x00,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x04}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x00,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x88}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x01,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_8 = { .phases = 22, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_8_data[0] }; +const uint8_t epd_wp_ED047TC2_1_9_data[18][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x15},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa8,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x00}},{{0x00,0x00,0x15,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x80,0x00}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x01,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x00}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x04}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x84}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_9 = { .phases = 18, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_9_data[0] }; +const uint8_t epd_wp_ED047TC2_1_10_data[17][16][4] = {{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x90,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x01},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x90,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa4,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa8,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x00}},{{0x00,0x00,0x01,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x00}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x00,0x00}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa0,0x40}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x40}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0x90}},{{0x00,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa0}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa4}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_10 = { .phases = 17, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_10_data[0] }; +const uint8_t epd_wp_ED047TC2_1_11_data[15][16][4] = {{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x54}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xa0,0x00,0x00,0x54}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x00,0x00,0x54}},{{0x00,0x00,0x00,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x80,0x00,0x54}},{{0x00,0x00,0x05,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x90,0x00,0x54}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x54}},{{0x00,0x00,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xa0,0x00,0x54}},{{0x00,0x05,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x40,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0x85,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x15,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_1_11 = { .phases = 15, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_1_11_data[0] }; +const EpdWaveformPhases* epd_wm_ed047tc2_1_ranges[7] = { &epd_wp_ED047TC2_1_5,&epd_wp_ED047TC2_1_6,&epd_wp_ED047TC2_1_7,&epd_wp_ED047TC2_1_8,&epd_wp_ED047TC2_1_9,&epd_wp_ED047TC2_1_10,&epd_wp_ED047TC2_1_11 }; const EpdWaveformMode epd_wm_ed047tc2_1 = { .type = 1, .temp_ranges = 7, .range_data = &epd_wm_ed047tc2_1_ranges[0] }; -const uint8_t epd_wp_ed047tc2_2_5_data[46][16][4] = {{{0x00,0x00,0x00,0x00},{0x20,0x88,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x80,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x08,0x00},{0x00,0x02,0x00,0x80},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa2,0x88,0x20,0x88},{0x22,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x00,0x44,0x08,0x00},{0xa0,0x02,0x20,0xa8},{0x08,0x62,0x88,0x80},{0x00,0x00,0x00,0x08},{0x08,0x22,0x88,0x80},{0x00,0x80,0x00,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x24,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x80,0x82,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x84,0x84,0x28,0x80},{0xa0,0x02,0x20,0xaa},{0xa8,0xaa,0x8a,0x80},{0x22,0x84,0x00,0x28},{0x2a,0xaa,0xaa,0xa0},{0x00,0x80,0x28,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x08,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x00,0x20,0x02},{0x00,0x00,0x00,0x02},{0x84,0x88,0x2a,0xa2},{0xa0,0xaa,0xa8,0xa8},{0xa8,0xaa,0x8a,0x80},{0x2a,0xaa,0x08,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x08}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0x24,0x80,0x00},{0x00,0x00,0x00,0x00},{0x29,0x80,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x02,0xa0,0x00},{0x02,0x00,0x00,0x81},{0x88,0xa8,0xaa,0xa9},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0x8a,0x81},{0x2a,0xaa,0x2a,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x04}},{{0xaa,0xaa,0xa8,0xa4},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0xa8,0x80,0x00},{0x00,0x20,0x00,0x00},{0x2a,0x84,0xa0,0x08},{0x2a,0x68,0x20,0x80},{0x80,0xa2,0xa2,0xa8},{0x80,0x02,0xa0,0x01},{0x02,0x80,0x00,0xa9},{0x9a,0xa8,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x89},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x8a,0x28,0x04}},{{0xaa,0xaa,0xa8,0x64},{0x2a,0xaa,0xaa,0x01},{0x00,0x88,0x02,0x00},{0x29,0xa8,0x80,0x00},{0x00,0x28,0x08,0x02},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xa2,0xa2,0xa9},{0x80,0x02,0xa0,0x01},{0x02,0xa0,0x00,0xa9},{0x9a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0x8a,0xa8,0x84}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x00,0x8a,0x02,0x08},{0x2a,0xa8,0x88,0x00},{0x00,0x28,0x8a,0x01},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xaa,0xaa,0xa9},{0x80,0x02,0xa0,0x01},{0x0a,0xaa,0x80,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x8a,0xaa,0x56}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x20,0x8a,0x0a,0x08},{0x2a,0xa8,0xaa,0x00},{0x00,0x2a,0x8a,0x01},{0x2a,0xaa,0xa8,0x08},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x80,0x02,0xa0,0x81},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x59},{0x69,0x8a,0xaa,0x56}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa0,0x8a,0x0a,0x0a},{0xaa,0xaa,0xaa,0x02},{0x08,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x09},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x82,0x82,0xa0,0xa1},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0x59,0x8a,0xaa,0x55}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa2,0x8a,0x2a,0x09},{0xaa,0xaa,0xaa,0x09},{0x28,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x89},{0x2a,0xaa,0xa8,0xa1},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0xa0,0xa9},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x55}},{{0xaa,0xaa,0xaa,0x58},{0x2a,0xaa,0xa5,0x05},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x01},{0x2a,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x01},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x55}},{{0xaa,0xaa,0x96,0xa8},{0xaa,0xaa,0x55,0x09},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x98,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa4,0x55},{0xaa,0xa8,0x8a,0x55},{0xaa,0xaa,0xa5,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x54,0xaa,0xaa,0x55}},{{0xaa,0xa5,0x96,0xa8},{0xaa,0xa5,0x55,0xa9},{0xaa,0xaa,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x90,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0xaa,0x55},{0xa6,0x99,0x55,0x55},{0x94,0xaa,0xa6,0x51}},{{0xaa,0xa5,0x56,0xa8},{0xaa,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x15,0x55},{0x92,0x95,0x65,0x55},{0xaa,0xaa,0xa5,0x55},{0x95,0x95,0x55,0x55},{0x94,0xaa,0x96,0x01}},{{0xa9,0x55,0x56,0xa8},{0xa9,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa5},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x9a,0x85,0x55,0x55},{0x94,0x95,0x55,0x55},{0x99,0xa9,0x95,0x55},{0x95,0x55,0x55,0x55},{0x94,0xaa,0x96,0x01}},{{0x95,0x55,0x56,0xa8},{0xa5,0x55,0x5a,0xa5},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0xa5},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0x96,0x65},{0xaa,0xaa,0x1a,0x59},{0xaa,0x59,0x51,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xa8,0x55,0x55,0x55},{0x98,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x94,0x6a,0x96,0x01}},{{0x95,0x55,0x55,0x94},{0x95,0x55,0xaa,0x95},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0x95},{0x2a,0xaa,0xa5,0x55},{0x9a,0x6a,0x55,0x55},{0xaa,0x85,0x5a,0x55},{0xaa,0x59,0x55,0x55},{0xaa,0xa9,0x5a,0x55},{0xa8,0xaa,0x00,0x55},{0xa8,0x55,0x55,0x55},{0x91,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x90,0x69,0x95,0x01}},{{0x55,0x55,0x55,0x54},{0x96,0x5a,0xaa,0x15},{0xaa,0xa6,0xa9,0x05},{0xaa,0x9a,0x65,0x55},{0x2a,0x96,0x65,0x55},{0x96,0x65,0x55,0x55},{0xa1,0x95,0x56,0x55},{0x28,0x55,0x55,0x55},{0xaa,0xa9,0x52,0x55},{0xa9,0x01,0x05,0x55},{0x25,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x01}},{{0x55,0x55,0x69,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa6,0xa5,0x85},{0x9a,0x56,0x55,0x55},{0xaa,0x95,0x65,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0xa1,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x01}},{{0x55,0x5a,0xa9,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa5,0xa5,0x85},{0x92,0x55,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x15,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x01}},{{0x56,0xaa,0xa9,0x55},{0x99,0xaa,0xa1,0x55},{0xaa,0x65,0x95,0x45},{0x95,0x55,0x55,0x55},{0xa6,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x54,0x55},{0x55,0x55,0x55,0x55},{0x05,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x01}},{{0x6a,0xaa,0xaa,0x55},{0x95,0xaa,0x15,0x55},{0x9a,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x01}},{{0xaa,0xaa,0xaa,0x55},{0x95,0xa5,0x55,0x55},{0x99,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x01}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x15,0x65,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x55,0x01}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x41,0x01}},{{0xaa,0xaa,0x56,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x56},{0x55,0x55,0x55,0x55},{0x69,0x55,0x55,0x55},{0xaa,0x55,0x41,0x01}},{{0xa9,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x55,0x55,0x96},{0x65,0x55,0x55,0x56},{0x6a,0x65,0x55,0xa6},{0xaa,0x94,0x49,0x02}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x6a,0x2a,0x8a,0xaa},{0x6a,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x51,0x56},{0x65,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x40,0xaa},{0x55,0x54,0x45,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x56,0xa6,0x50},{0x55,0x56,0x95,0x56},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x95,0x55,0x55},{0x55,0x55,0x95,0x04},{0x45,0x05,0x55,0xaa},{0x55,0x55,0x55,0xaa},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x45,0x48,0x58,0x50},{0x55,0x55,0x41,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x54,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x54},{0x41,0x04,0x44,0x12},{0x6a,0x2a,0x21,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x69},{0x55,0x55,0x55,0x54},{0x45,0x05,0x15,0x16},{0x41,0x41,0x15,0x02},{0x6a,0x00,0xa0,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x66},{0x55,0x59,0x59,0xa6},{0x60,0x00,0x00,0x0a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x6a,0x59,0x51,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x50,0x55,0x55,0x52},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x6a,0x55,0x55,0x02},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xa5,0x96,0xa6,0x5a},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_5 = { .phases = 46, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_5_data[0] }; -const uint8_t epd_wp_ed047tc2_2_6_data[43][16][4] = {{{0x02,0xaa,0x00,0x00},{0x20,0x22,0xa8,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x22,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xa8,0x20},{0x00,0x00,0x00,0x00},{0x20,0x02,0x08,0x80},{0x00,0x80,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x2a,0xaa,0x00,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x28},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xaa,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x20},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa0,0x20,0x2a},{0x28,0x22,0xa8,0xa8},{0x28,0x00,0x00,0x00}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa8,0x22,0x2a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x80}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0xa2,0x82,0x08,0x80},{0x08,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x42}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x20,0x00,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0xa8},{0x00,0x00,0x00,0x00},{0xaa,0x82,0x88,0xa0},{0x8a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0x94},{0x24,0x00,0x28,0x42}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x20,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0x8a,0x8a,0xa0},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x24,0x00,0x28,0x42}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x22,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0xa0,0xa0,0xa8,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa5},{0xa6,0xaa,0xaa,0x95},{0x24,0x00,0x26,0x41}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x42},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xa2,0xa8,0xaa,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xa8},{0x08,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa6,0x55},{0x56,0x02,0x95,0x55}},{{0xaa,0xaa,0xa0,0x04},{0x20,0xaa,0xa5,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x26},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0x98},{0x88,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xa5,0xa9,0x65,0x55},{0x56,0x0a,0x95,0x55}},{{0xaa,0xa9,0xa0,0x24},{0x20,0xa9,0x55,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x25},{0x2a,0x80,0x00,0x02},{0x20,0xa0,0x28,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x80},{0xa0,0x00,0x00,0x01},{0x20,0xa2,0xa8,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xa2,0xa8,0xaa},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xa5,0x95,0x55,0x55},{0x56,0x0a,0x95,0x55}},{{0xaa,0x95,0xa8,0xa4},{0x20,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x29},{0xa2,0x88,0x00,0x15},{0x2a,0x80,0x00,0x01},{0x20,0xa8,0x28,0x14},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x81},{0xa0,0x00,0x00,0x01},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x56,0x89,0x55,0x55}},{{0xaa,0x95,0x98,0x94},{0xa0,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x25},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0x20,0xaa,0xa8,0x94},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0xa1},{0xa0,0x22,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x94},{0xa8,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0xa9,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x15}},{{0xa9,0x55,0x9a,0x98},{0xa8,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0xa2,0xaa,0xaa,0x94},{0xaa,0xaa,0xaa,0x89},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x2a,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x56},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0x95,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x15}},{{0xa5,0x55,0x5a,0xa8},{0xa8,0x95,0x55,0x45},{0xa0,0x82,0x20,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x85,0x69},{0xaa,0x2a,0xa8,0x29},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xa9,0xa9,0xa5,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0xa5,0x41,0x15}},{{0x95,0x55,0x6a,0x68},{0xa8,0x55,0x55,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xa9,0x55,0x69},{0xaa,0x2a,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0x99,0xa9,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x65,0x40,0x15}},{{0x95,0x55,0x66,0x58},{0xa8,0x55,0x5a,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0xa8,0xa0,0x15},{0xaa,0x62,0xa8,0x19},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x95},{0xaa,0x95,0x55,0x55},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa9,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x65,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x91,0x55,0x40,0x15}},{{0x95,0x56,0xa5,0x94},{0xa8,0x56,0xaa,0x85},{0xa8,0xaa,0xa0,0x95},{0xaa,0xa8,0xa0,0x15},{0xaa,0x6a,0xaa,0x15},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x55,0x55},{0x89,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0x99,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x50,0x00,0x15}},{{0x55,0x6a,0x89,0x94},{0x98,0x6a,0xaa,0x85},{0xaa,0xaa,0xa0,0x95},{0xaa,0xa6,0xa0,0x15},{0x8a,0x6a,0xaa,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xaa,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x89,0x50,0x00,0x15}},{{0x56,0xaa,0x9a,0x14},{0x98,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xa2,0x15},{0x99,0x6a,0xaa,0x95},{0xaa,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xa9,0x10,0x00,0x05}},{{0x5a,0xaa,0x12,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0xa9,0x10,0x00,0x05}},{{0x6a,0xaa,0x55,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0x9a,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x8a,0x55,0x55,0x55},{0xaa,0x00,0x00,0x01}},{{0x6a,0xaa,0x55,0x55},{0x9a,0x96,0xaa,0x41},{0x6a,0xaa,0xaa,0x55},{0x99,0x66,0xaa,0x95},{0x95,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x59,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0x99,0x65},{0xaa,0x00,0x00,0x01}},{{0xaa,0xaa,0x55,0x55},{0x96,0x56,0xa5,0x51},{0x6a,0x69,0x8a,0x55},{0x95,0x66,0xaa,0x95},{0x95,0x69,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x01}},{{0xaa,0xa8,0x55,0x55},{0x96,0x55,0x55,0x55},{0x6a,0x65,0x58,0x55},{0x95,0x66,0x59,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x01}},{{0xa9,0x45,0x55,0x45},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xa5,0x55,0x55,0x41},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x5a,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x95,0x55,0x55,0x41},{0x56,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x45,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x56,0x59,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x2a},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x51},{0x59,0x55,0x55,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x56},{0x55,0x15,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x15},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x10,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x42},{0x6a,0x95,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x59},{0x15,0x55,0x55,0x82},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x55},{0x99,0x50,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0xaa,0x99,0x55,0x6a},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_6 = { .phases = 43, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_6_data[0] }; -const uint8_t epd_wp_ed047tc2_2_7_data[40][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x0a,0x08,0x80},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa0,0x80,0x00,0x00},{0x08,0x80,0x20,0x00},{0x00,0x12,0x22,0x00},{0x00,0x00,0x00,0x00},{0x1a,0x20,0x00,0x00},{0x01,0x80,0x00,0x00},{0x88,0x00,0x00,0x00},{0x00,0x10,0x80,0x00},{0x20,0x0a,0x88,0x82},{0x80,0x00,0x05,0x08},{0x0a,0xa0,0x00,0x20},{0x20,0x00,0x00,0x20},{0x00,0x80,0x00,0x08},{0x80,0x28,0x08,0x80},{0x2a,0x80,0xa0,0x28},{0x20,0x00,0x80,0x04}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x11,0x22,0xa2,0x00},{0x04,0x04,0x00,0x00},{0x2a,0xa0,0x20,0x00},{0x22,0xa0,0x00,0x00},{0x98,0x12,0x00,0x0a},{0x18,0xa0,0x80,0x00},{0x28,0x0a,0x8a,0x82},{0x88,0x88,0x09,0x28},{0x0a,0xa2,0x20,0x20},{0x20,0x00,0x02,0xa0},{0x00,0xa4,0x00,0x08},{0xa8,0xa8,0xa8,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x20,0x02,0x88,0x84}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x22,0x22,0xa2,0x28},{0x04,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x20,0x0a},{0x98,0x56,0x02,0x8a},{0xa8,0xa4,0x80,0x00},{0x28,0x0a,0xaa,0x82},{0x88,0xaa,0x0a,0x28},{0x2a,0xaa,0xa8,0x22},{0x20,0x40,0xa2,0xa2},{0x12,0xa8,0xa0,0x28},{0xa8,0xaa,0xaa,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x28,0x82,0xa8,0x85}},{{0xa8,0xa0,0x00,0x00},{0x08,0xa0,0x20,0x00},{0x26,0x22,0xa2,0x28},{0x05,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x28,0x0a},{0x99,0xaa,0x82,0x8a},{0xaa,0xa8,0xa2,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0x28},{0x2a,0xaa,0xa8,0xa2},{0x20,0xa6,0xa2,0xa2},{0x92,0xaa,0xa8,0x28},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x98},{0x58,0x8a,0xa8,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xa0,0x20,0x00},{0x2a,0x66,0xa2,0x28},{0x09,0x0a,0x00,0x00},{0x2a,0xa2,0x28,0x00},{0x2a,0xa0,0xa8,0x0a},{0xa9,0xaa,0x82,0x8a},{0xaa,0xaa,0xaa,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa2},{0x25,0xa6,0xaa,0xa2},{0xaa,0xaa,0xa8,0x2a},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x58,0x8a,0xaa,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0x20,0x80},{0x2a,0xa6,0xa2,0x28},{0x19,0x0a,0x00,0x00},{0x2a,0xa2,0xa8,0x00},{0x2a,0xaa,0xa8,0x89},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x02},{0x2a,0x8a,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x81},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa0,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0x2a,0xaa,0xa8,0x04},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x82},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa4},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0xaa,0xaa,0xa8,0x88},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x96},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x95},{0x5a,0xaa,0xa9,0x55}},{{0xa8,0xa0,0x00,0x14},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xaa,0x28},{0xaa,0x2a,0x00,0x00},{0xaa,0xaa,0xaa,0x99},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x5a,0xaa,0x69,0x55}},{{0xa8,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x16},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0xa9,0xa5,0x55,0x55},{0x9a,0xaa,0x65,0x51}},{{0x98,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x15},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x64,0x51}},{{0x98,0x50,0x00,0x28},{0x8a,0x6a,0x9a,0x41},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x18,0x80},{0xaa,0xaa,0x96,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xaa,0xa5,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x80,0x55},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x54,0x51}},{{0x94,0x50,0x00,0x28},{0xa6,0x55,0x55,0x61},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x28,0x80},{0xa9,0x9a,0x96,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0xa9,0x69,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xa5,0x65,0x55},{0xaa,0xa6,0x25,0x55},{0xaa,0x01,0x55,0x55},{0xaa,0xaa,0x59,0x55},{0xaa,0x55,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0xa5,0x54,0x41}},{{0x94,0xa0,0x00,0x28},{0xa5,0x55,0x55,0x51},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0xa1},{0xa5,0x59,0x55,0x55},{0xaa,0x5a,0x55,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0xa5,0x15,0x55},{0xa9,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x65,0x54,0x41}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x55,0x59},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0x95},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xaa,0xa5,0x65,0x55},{0xaa,0x55,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa8,0x65,0x54,0x41}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x55},{0x8a,0x99,0x59,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0xa5,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x92,0x25,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x95},{0x89,0x99,0x55,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x25,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0x50,0x80,0x15},{0xa5,0x95,0x65,0x95},{0x99,0x95,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x58,0x5a,0x80,0x15},{0xa9,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x98,0x5a,0x80,0x15},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x2a,0x95,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa6,0x54,0x14,0x00}},{{0x98,0x5a,0x48,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x25,0x95,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0x55,0x55,0x65},{0xa6,0x54,0x10,0x00}},{{0x9a,0x55,0x68,0x55},{0x6a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x25,0x55,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x25,0x55,0x55,0x66},{0x2a,0xaa,0xaa,0x6a},{0xa6,0x10,0x00,0x00}},{{0x9a,0x55,0x64,0x41},{0x5a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0xa6,0x10,0x08,0x00}},{{0x9a,0x55,0x94,0x81},{0x5a,0x6a,0x9a,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x46,0x0a,0x9a,0x81},{0xa6,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x0a,0xa9,0x41},{0xa5,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x15,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x44,0x85,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x0a,0x65,0x41},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x55,0x55,0x69},{0x55,0x55,0x55,0x69},{0x55,0x56,0x11,0x59},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x66},{0x65,0x44,0x42,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x51},{0x55,0xaa,0xaa,0x54},{0x45,0x55,0x55,0x56},{0x59,0x59,0x11,0x56},{0x55,0x55,0x14,0x52},{0x55,0x55,0x55,0x55},{0x55,0x51,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x61},{0x40,0x55,0x55,0x80},{0x6a,0xaa,0xaa,0xaa},{0x55,0x04,0x02,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x59,0x55,0x65,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x40,0x00,0x00,0x42},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x64,0x0a,0x9a,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x59},{0x65,0x55,0x55,0x55},{0x55,0x64,0x55,0x41},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x6a,0x2a,0x82,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x45},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x44},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x95,0x55,0x51,0x42},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x50,0x50,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_7 = { .phases = 40, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_7_data[0] }; -const uint8_t epd_wp_ed047tc2_2_8_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x80,0x08,0x82},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x08},{0x00,0x00,0x00,0x00},{0x02,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0x20,0x00,0x00,0x08},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x20},{0x80,0x00,0x00,0x00},{0xaa,0x08,0xaa,0x08},{0x00,0x00,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x20,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0xa0,0x00,0x00,0x0a},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x2a},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa8},{0x00,0x20,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x81},{0xa0,0x00,0x00,0x05},{0x20,0x00,0x00,0x01},{0x02,0x82,0x00,0xa9},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa4},{0x12,0x28,0xaa,0x01}},{{0xa8,0x00,0x0a,0x00},{0x88,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x82,0xa8,0x08,0x81},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x08},{0x00,0x02,0x0a,0x80},{0x88,0x00,0x02,0x81},{0xa0,0x00,0x00,0x25},{0x28,0x00,0x00,0x21},{0x22,0x82,0x00,0xa5},{0x80,0x00,0x00,0x21},{0xaa,0xaa,0xaa,0xa4},{0x19,0x2a,0xaa,0x81}},{{0xa8,0x00,0x0a,0x00},{0x8a,0xa8,0x8a,0x0a},{0x00,0x20,0x00,0x28},{0x80,0x00,0x00,0x00},{0x20,0x00,0x00,0x0a},{0x82,0xaa,0x08,0x81},{0x08,0x20,0x02,0x02},{0x08,0x00,0x00,0x08},{0x28,0x02,0x0a,0x80},{0x88,0x08,0x0a,0x81},{0xa0,0x00,0x08,0x25},{0x2a,0x00,0x0a,0x21},{0x22,0xa2,0x00,0x95},{0x80,0x02,0x00,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x19,0xaa,0xaa,0x81}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0x8a,0x0a},{0x02,0x20,0x00,0x28},{0x88,0x00,0x00,0x02},{0x20,0x00,0x00,0x09},{0xa2,0xaa,0xa8,0x85},{0x8a,0x28,0x0a,0x09},{0x88,0x00,0x00,0x08},{0x28,0x02,0x8a,0x80},{0x88,0x0a,0x0a,0x81},{0xa8,0x02,0x08,0x25},{0xaa,0xaa,0x0a,0x21},{0x2a,0xaa,0x2a,0x95},{0xa0,0x02,0x82,0x81},{0xaa,0xaa,0xaa,0x95},{0x19,0xaa,0xaa,0x81}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0xaa,0x09},{0x02,0x20,0x08,0x04},{0x88,0x00,0x00,0x21},{0x28,0x00,0x00,0x09},{0xaa,0xaa,0xa8,0x85},{0x8a,0xaa,0x0a,0x09},{0x88,0x08,0x00,0x04},{0xaa,0x82,0x8a,0x82},{0xaa,0xaa,0xaa,0x81},{0xa8,0x22,0xa8,0x15},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0x2a,0x95},{0xa0,0x22,0x82,0x91},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xaa,0x85}},{{0xa8,0x00,0x05,0x10},{0x8a,0xaa,0xaa,0x09},{0x22,0x20,0x28,0x14},{0x88,0x00,0x00,0x25},{0x28,0x00,0x00,0x05},{0xaa,0xaa,0xa8,0x45},{0xaa,0xaa,0xaa,0x05},{0x88,0x0a,0x00,0x85},{0xaa,0xa2,0x8a,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa2,0x2a,0x8a,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xa6,0x85}},{{0xa8,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x09},{0xaa,0x22,0xaa,0x15},{0x88,0x00,0x00,0x25},{0xa8,0x00,0x00,0x25},{0xaa,0xaa,0xa8,0x65},{0xaa,0xaa,0xaa,0x25},{0xa8,0x2a,0x80,0xa5},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa2,0xaa,0x8a,0x95},{0xa9,0xaa,0x66,0x55},{0x15,0x6a,0x56,0x45}},{{0x94,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x29},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x08,0x00,0x25},{0xaa,0xaa,0xa6,0x65},{0xaa,0xaa,0xaa,0x25},{0xaa,0x2a,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x45},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0x29,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xa9,0xa9,0x55,0x55},{0x25,0x6a,0x55,0x55}},{{0x94,0x00,0x0a,0x64},{0x8a,0xaa,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x0a,0x0a,0x15},{0xaa,0x6a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa9,0x69,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x99,0xa5,0x55,0x55},{0x21,0x15,0x55,0x55}},{{0x94,0x00,0x0a,0x64},{0xaa,0x9a,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x8a,0x00,0x00,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x5a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0x55},{0x9a,0xaa,0xa6,0x55},{0x9a,0xaa,0xa5,0x55},{0xa9,0x69,0xaa,0x55},{0xaa,0xa9,0x6a,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x55}},{{0x94,0x00,0x0a,0xa5},{0xaa,0x5a,0x65,0x15},{0xaa,0x22,0xaa,0x95},{0xaa,0xa0,0x08,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x55,0x56,0x55},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x9a,0xa9,0x56,0x55},{0x9a,0xa1,0x55,0x55},{0xa9,0x69,0x95,0x55},{0xaa,0xa9,0x69,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x55}},{{0x68,0x00,0x0a,0x95},{0xa6,0x55,0x55,0x15},{0xaa,0x12,0x8a,0x15},{0xaa,0xa0,0x28,0x15},{0xa8,0x2a,0x8a,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0xaa,0xa5,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0xa5,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0x91,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x9a,0xa9,0x65,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x55}},{{0x68,0x00,0x0a,0x55},{0xa6,0x55,0x9a,0x15},{0xaa,0x12,0x06,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x99,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x55}},{{0x68,0x00,0x05,0x55},{0xa5,0x55,0x9a,0x25},{0xa9,0x91,0x55,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x95},{0x59,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa5,0x6a,0x55},{0xaa,0xa9,0x65,0x55},{0xa4,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x55}},{{0x68,0x00,0x05,0x55},{0xa5,0x65,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xaa,0xaa,0xa8,0x95},{0x9a,0x25,0x65,0x95},{0x51,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xa6,0x85,0x65,0x55},{0x9a,0x29,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x55}},{{0x54,0x00,0x05,0x55},{0xa9,0xa5,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xa6,0xaa,0xaa,0x95},{0x96,0xa5,0x65,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x85,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x55,0x55,0x55},{0xaa,0x95,0x11,0x56}},{{0x94,0x00,0x05,0x55},{0x69,0xaa,0xaa,0x25},{0x95,0x99,0x55,0x55},{0xa6,0xaa,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x56},{0xa6,0x55,0x55,0x59},{0xaa,0x95,0x21,0x56}},{{0x94,0x00,0x85,0x51},{0x6a,0xaa,0xaa,0xa5},{0x95,0x99,0x55,0x55},{0x65,0x59,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x66},{0xaa,0x56,0x99,0x6a},{0xaa,0xaa,0xaa,0xaa}},{{0x94,0x22,0x85,0x51},{0x6a,0xaa,0x20,0x95},{0x55,0x59,0x55,0x55},{0x55,0x55,0x56,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x66,0x56,0x95,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x96,0x2a,0x65,0x01},{0xa2,0x8a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x96,0xa9,0x50,0x01},{0xa6,0x0a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x45,0x55,0x55,0x4a},{0x55,0x55,0x55,0x55},{0x66,0x96,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x42,0x95,0x90,0x01},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x52},{0x65,0x54,0x01,0x2a},{0x65,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x56,0xa0,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x64},{0x66,0x6a,0xa9,0x50},{0x55,0x55,0x55,0x64},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x45,0x50,0x00,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x6a,0x60,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x56},{0x55,0x5a,0x95,0x5a},{0x55,0x15,0x55,0x20},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0xa9,0x50,0x05},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x59,0x65,0x6a,0xa6},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x41,0x50,0x15,0x6a},{0x45,0x54,0x55,0x91},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0x95,0x50,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x65,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x54,0x10,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x55,0x50,0x15},{0x55,0x55,0x55,0x55},{0x6a,0xa2,0xaa,0xa2},{0x52,0xa6,0x65,0x92},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xa2},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x84,0x50,0x05,0x0a},{0x40,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xa5,0x50,0x15,0x48},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x45},{0x00,0x00,0x00,0x00},{0x81,0x51,0x11,0x68},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x45,0x55,0x55,0x44},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_8 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_8_data[0] }; -const uint8_t epd_wp_ed047tc2_2_9_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x0a,0x82,0x02,0x00},{0x40,0x00,0x00,0x00},{0x00,0x80,0x02,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x0a,0x8a,0x82,0x00},{0x40,0x08,0x00,0x40},{0x00,0x80,0x22,0x08},{0x00,0x08,0x08,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x04,0x00,0x00},{0x11,0x40,0x20,0x00},{0x81,0x00,0x00,0x20},{0x28,0x08,0x00,0x82},{0x00,0x20,0x80,0x80},{0x00,0x00,0x02,0x80}},{{0x80,0x00,0x00,0x00},{0x6a,0x8a,0x8a,0x00},{0x90,0x08,0x01,0x40},{0x00,0x80,0x22,0x08},{0x00,0x28,0x88,0x0a},{0x80,0x08,0x00,0x00},{0x00,0x08,0x02,0x00},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x80,0x00},{0x14,0x14,0x00,0x00},{0x21,0x50,0x20,0x80},{0x81,0x18,0x00,0xa0},{0x29,0x0a,0x02,0x81},{0x2a,0xa2,0xaa,0xa0},{0x00,0x2a,0x02,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xa0,0x08,0x02,0x80},{0x80,0x88,0x22,0x08},{0x20,0xa8,0x89,0x0a},{0x80,0xa8,0x00,0x02},{0xaa,0x8a,0x0a,0x08},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x02},{0x08,0x08,0x80,0x00},{0x24,0x54,0x22,0x80},{0x25,0x52,0x2a,0xa0},{0x86,0xa8,0x20,0xa8},{0xaa,0x2a,0x82,0x81},{0x2a,0xaa,0xaa,0xa0},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xaa,0x8a,0x2a,0x80},{0x80,0x88,0x22,0x08},{0x22,0xaa,0x8a,0x0a},{0x82,0xa8,0x00,0x02},{0xaa,0xaa,0x0a,0x0a},{0x00,0x08,0x02,0x28},{0x00,0x00,0x00,0x02},{0x2a,0x8a,0x80,0x00},{0xa5,0xaa,0xa2,0xa0},{0x26,0x96,0xaa,0xa0},{0x8a,0xa8,0xa0,0xa8},{0xaa,0x2a,0x8a,0x81},{0x2a,0xaa,0xaa,0xa8},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x0a},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0x2a,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x00,0x02},{0x2a,0xaa,0x80,0x00},{0xa9,0xaa,0xa2,0xa0},{0x26,0xa6,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0x2a,0x8a,0x41},{0xaa,0xaa,0xaa,0xa8},{0x08,0xaa,0x12,0x41}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x29},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0xaa,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x08,0x80},{0x2a,0xaa,0x8a,0x22},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x12,0x41}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x02},{0xaa,0xaa,0xaa,0x09},{0x20,0x08,0x02,0x28},{0x00,0x02,0x0a,0xa0},{0x2a,0xaa,0x8a,0x2a},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x11,0x45}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x81,0x88,0xa2,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0x8a,0x02,0x28},{0x00,0x82,0xaa,0xa1},{0x2a,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0x91,0x45}},{{0x80,0x00,0x00,0x20},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0x80},{0x82,0x88,0xaa,0x24},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x82,0x04},{0x20,0xa2,0xaa,0xa1},{0x2a,0xaa,0xaa,0x29},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x55},{0x96,0xa5,0x65,0x55},{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0x91,0x45}},{{0x80,0x00,0x00,0x10},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x9a,0x14},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x21},{0xaa,0xaa,0xaa,0x85},{0x2a,0xaa,0x8a,0x15},{0x20,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0x25},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0xaa,0x55},{0x96,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x56},{0x2a,0x99,0x91,0x45}},{{0x80,0x00,0x00,0x94},{0xaa,0xa9,0x45,0x44},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x99,0x16},{0xaa,0xa6,0xa6,0x95},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa9,0xa5},{0xaa,0xaa,0xa9,0x95},{0x2a,0xaa,0xaa,0x69},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0x55,0x56},{0x1a,0x95,0x99,0x05}},{{0x80,0x00,0x00,0x64},{0xa9,0x65,0x45,0x48},{0xaa,0xaa,0xa9,0xa2},{0xa2,0x6a,0x99,0x15},{0xaa,0xa5,0x65,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa5,0xa5},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x59},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x99,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x99,0x55,0x55},{0x19,0x55,0x89,0x05}},{{0x40,0x00,0x00,0xa4},{0xa5,0x65,0x45,0x4a},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x6a,0x99,0x15},{0xa9,0x95,0x65,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa5,0x95,0xa5},{0xaa,0xa6,0xa9,0x95},{0xaa,0xaa,0xa6,0x55},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x59,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x99,0x55,0x55},{0x15,0x55,0x49,0x15}},{{0x40,0x00,0x00,0x54},{0xa5,0x65,0x45,0x88},{0xaa,0xaa,0xa9,0xa1},{0xaa,0x66,0x11,0x15},{0xa9,0x55,0x65,0x55},{0xaa,0x96,0xa9,0x95},{0xa5,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x15},{0xaa,0xaa,0x95,0x55},{0x26,0xa5,0x65,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x45,0x15}},{{0x40,0x00,0x00,0x55},{0xa5,0x55,0x46,0x89},{0xaa,0xa6,0xa5,0x61},{0xaa,0x66,0x51,0x15},{0x95,0x55,0x55,0x55},{0x28,0x56,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x55},{0xaa,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x15}},{{0xa0,0x00,0x00,0x55},{0x95,0x56,0x8a,0x99},{0xaa,0xaa,0x9a,0x51},{0xaa,0x66,0x55,0x95},{0x95,0x55,0x55,0x55},{0x29,0x55,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa5,0x45,0x55},{0xaa,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x16}},{{0xa0,0x00,0x00,0x55},{0x9a,0x9a,0x8a,0x65},{0xaa,0xa5,0x56,0x51},{0x6a,0x56,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x96},{0x95,0x55,0x55,0x55},{0x05,0x55,0x45,0x16}},{{0xa0,0x00,0x20,0x51},{0x5a,0xaa,0x8a,0x65},{0xa5,0x65,0x56,0x59},{0x69,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x85,0x55,0x45,0x12}},{{0x60,0x28,0xa0,0x51},{0x6a,0xaa,0x8a,0x65},{0x95,0x55,0x56,0x55},{0x59,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x84,0x55,0x44,0x12}},{{0x6a,0xaa,0xa8,0x11},{0x6a,0xaa,0x8a,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x45,0x44,0x12}},{{0x5a,0xaa,0x64,0x01},{0xa6,0x99,0x45,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x44,0x46,0x12}},{{0x5a,0x95,0x56,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x99,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x56,0x5a,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x95},{0x95,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x65,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x25,0x6a,0x99,0x01},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x65},{0x56,0x5a,0x56,0x56},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x65},{0x95,0x55,0x41,0x56},{0x95,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x5a,0x66,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0xaa,0x56,0x05},{0x55,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x95,0x61},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x45},{0x55,0x55,0x55,0x59},{0x55,0x55,0x54,0x55},{0x55,0x54,0x00,0x15},{0x91,0x55,0x15,0x42},{0x55,0x55,0x24,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0x95,0x56,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x65,0x49,0x91},{0x55,0x55,0x54,0x44},{0x55,0x55,0x55,0x49},{0x15,0x55,0x55,0x54},{0x55,0x51,0x54,0x0a},{0x55,0x04,0x00,0x2a},{0xaa,0xaa,0xaa,0xaa},{0x55,0x54,0x10,0x55},{0x65,0x56,0x9a,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xa2,0x1a,0x06,0x50},{0x68,0xa0,0xa8,0xaa},{0x55,0x45,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x04,0x00,0xaa},{0x55,0x55,0x65,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x51,0x05,0x01,0x02},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x6a,0xaa,0xa9,0xa4},{0x55,0x55,0x55,0x00},{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_9 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_9_data[0] }; -const uint8_t epd_wp_ed047tc2_2_10_data[44][16][4] = {{{0x00,0x00,0x00,0x00},{0x80,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x00},{0x00,0x80,0x00,0x00},{0x80,0x00,0x08,0x02},{0x00,0x80,0x00,0x08},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x02,0x00,0x00,0x00},{0xa2,0x88,0x20,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x80,0x20,0x00},{0x00,0x80,0x00,0x00},{0x00,0x82,0x00,0x00},{0xa8,0x00,0x08,0x82},{0x00,0x80,0x20,0x0a},{0x92,0x00,0x00,0x8a},{0x2a,0x20,0xa2,0xa8},{0x00,0x00,0x00,0x08}},{{0x02,0x00,0x00,0x00},{0xa2,0x8a,0x20,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x08,0x05,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x00,0x80,0x20,0x00},{0x02,0xa0,0xa0,0x00},{0x00,0x82,0x00,0x02},{0xaa,0x20,0x08,0x82},{0x84,0x80,0xa0,0x0a},{0xa2,0x84,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x08}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa0,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x15,0x42,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xa0,0x20,0x80},{0x02,0xaa,0xa8,0x00},{0x00,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x82},{0x9a,0x90,0xa8,0x0a},{0xa6,0xa8,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x00,0x80,0x2a}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x1a,0x46,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xaa,0x28,0x80},{0x2a,0xaa,0xa8,0x00},{0x02,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0x08,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x8a,0x88,0x26}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x90},{0x02,0xa0,0x08,0x02},{0x2a,0x2a,0x86,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x80},{0x2a,0xaa,0xa8,0x20},{0x02,0x82,0x00,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0x8a,0x8a,0xa6}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x0a},{0x80,0x00,0x00,0x90},{0x02,0xaa,0x2a,0x02},{0x2a,0xaa,0x8a,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xa2,0xa2,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0xaa,0x4a,0x55}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0x90},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa0},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x16,0xaa,0x46,0x55}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa4},{0x15,0x9a,0x65,0x55}},{{0x82,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0x80,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0x15,0x95,0x65,0x55}},{{0x81,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0xa2,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x8a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x02,0x82,0x20},{0x00,0x0a,0x00,0x09},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0x15,0x55,0x55,0x55}},{{0x81,0x00,0x80,0xa8},{0xaa,0xaa,0x9a,0x2a},{0xa2,0xa2,0x02,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x82,0x82,0xa0},{0x00,0x8a,0x80,0x09},{0x2a,0xaa,0xaa,0x22},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0x21},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xa9,0x55},{0x15,0x55,0x55,0x55}},{{0x81,0x00,0x80,0xa8},{0xaa,0x66,0x9a,0x2a},{0xa2,0xa2,0x22,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0x2a,0xa2,0xa0,0x80},{0x02,0x8a,0x80,0x05},{0x2a,0xaa,0x8a,0x20},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xa0,0x61},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x81,0x00,0x80,0x94},{0xaa,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x82},{0x02,0x8a,0x82,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xa8,0xaa,0xa1},{0xaa,0xaa,0xa0,0x65},{0xaa,0xaa,0x20,0x85},{0xaa,0xaa,0xaa,0x65},{0xaa,0x95,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x41,0x00,0x40,0x94},{0x69,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xa2,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0x9a},{0xaa,0x28,0xaa,0xa9},{0xaa,0xaa,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x42,0x00,0x48,0xa4},{0x59,0x55,0x55,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xaa,0x25},{0x2a,0xaa,0xaa,0x9a},{0xa8,0x80,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x8a,0x29},{0x2a,0xaa,0x56,0x99},{0xaa,0x28,0xa8,0xa9},{0xaa,0x82,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x42,0x00,0x48,0x64},{0x59,0x59,0x65,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xa0,0x65},{0x2a,0xaa,0xa9,0x56},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0xa9,0x8a},{0xaa,0xaa,0xaa,0x05},{0xaa,0x2a,0x86,0x69},{0x2a,0x55,0x55,0x99},{0xaa,0x69,0x89,0xa9},{0x96,0x82,0x00,0x45},{0xaa,0x22,0x10,0x05},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x62,0x00,0x4a,0x54},{0x59,0x9a,0xa9,0x95},{0xaa,0xaa,0x22,0x65},{0x82,0xaa,0xa5,0x45},{0x26,0xaa,0xa9,0x55},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0x29,0x89},{0xaa,0xaa,0xaa,0x85},{0xaa,0x55,0x54,0x69},{0x21,0x55,0x55,0x55},{0xaa,0x69,0x45,0xa9},{0x95,0x55,0x55,0x55},{0xaa,0x22,0x10,0x05},{0x89,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0xa2,0x00,0x8a,0x54},{0x66,0xaa,0xaa,0x95},{0xaa,0xaa,0x22,0x55},{0x82,0x95,0x55,0x55},{0x16,0xa5,0x55,0x55},{0xa2,0xa0,0x20,0x09},{0xaa,0xa9,0x29,0x09},{0xaa,0xaa,0xaa,0x85},{0xa9,0x55,0x55,0x59},{0x11,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa1,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x55}},{{0xa2,0x00,0x86,0x54},{0xa6,0xaa,0xaa,0xa5},{0xaa,0xaa,0x22,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x5a,0xa9,0x55},{0xa2,0xaa,0x28,0x01},{0xaa,0xa9,0x29,0x55},{0xaa,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x55,0x55,0x55}},{{0xa1,0x00,0x85,0x54},{0xaa,0xa2,0xaa,0x65},{0xaa,0xaa,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x15,0xa5,0x55,0x55},{0xa2,0xaa,0xa8,0x01},{0xaa,0xa9,0x69,0x55},{0xaa,0xa5,0x69,0xa5},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x45,0x55,0x55}},{{0xa1,0x00,0x85,0x54},{0x9a,0x95,0x55,0x55},{0xaa,0x99,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa2,0xa9,0x55,0x55},{0xaa,0xa5,0x69,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x85,0x55}},{{0x61,0x00,0x45,0x54},{0x95,0x55,0x55,0x55},{0xaa,0x99,0x61,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa5,0x55,0x55,0x55},{0xaa,0x65,0x55,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x89,0x95}},{{0x61,0x00,0x45,0x50},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0xaa,0x8a,0xa9}},{{0x61,0x00,0x45,0x10},{0x15,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xa9}},{{0x51,0x20,0x41,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x16,0x6a,0x94,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x50,0x2a,0x40,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x2a,0x00,0x01},{0x55,0x55,0x55,0x55},{0x51,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0xaa}},{{0x28,0xa9,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x28,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x24,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x99},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x99},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x9a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x14,0x6a,0x20,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x65},{0x55,0x14,0x54,0x56},{0x41,0x55,0x55,0x56},{0x55,0x55,0x55,0x5a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x14,0x6a,0x10,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x11},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x15},{0x6a,0xaa,0xaa,0x99},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x96,0x10,0x05},{0x55,0x55,0x55,0x19},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x21},{0xa9,0x55,0x56,0xa5},{0x55,0x55,0x55,0x55},{0x66,0xa9,0x69,0x54},{0x55,0x50,0x14,0x1a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x95,0x10,0x45},{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x65},{0x6a,0x6a,0x9a,0x11},{0x95,0x55,0x55,0x55},{0x69,0x55,0x55,0x59},{0x51,0x56,0x16,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x55,0x10,0x55},{0x00,0x00,0x00,0x00},{0x55,0x65,0x56,0x54},{0x55,0x15,0x45,0x02},{0x80,0x00,0x00,0x0a},{0x55,0x55,0x55,0x16},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x15,0x55,0x15,0x55},{0x00,0x00,0x00,0x00},{0x59,0x55,0x55,0x14},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x65,0x45,0x54,0x0a},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_10 = { .phases = 44, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_10_data[0] }; -const uint8_t epd_wp_ed047tc2_2_11_data[57][16][4] = {{{0x20,0x8a,0x80,0x00},{0x15,0x55,0x5a,0xa4},{0x44,0x10,0x0a,0x41},{0x40,0x00,0x09,0x54},{0x10,0x50,0x00,0x00},{0x00,0x00,0x04,0x28},{0x40,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x40,0x00},{0x00,0x00,0x00,0x00},{0x00,0x40,0x00,0x68},{0x00,0x00,0x40,0x00},{0x00,0x00,0x0a,0x54},{0x00,0x0a,0x80,0x00},{0x10,0x09,0x60,0x00},{0x00,0x00,0x00,0x50}},{{0xaa,0xaa,0x8a,0x00},{0x0a,0x60,0x0a,0xa8},{0x54,0x54,0x8a,0x41},{0x41,0x02,0x09,0x54},{0x15,0x50,0x06,0x24},{0x00,0x08,0xa4,0x28},{0x44,0x00,0x09,0xa8},{0x05,0x00,0x2a,0xa8},{0x01,0x10,0x46,0xa8},{0x04,0x00,0x00,0xa8},{0x00,0x40,0x00,0x54},{0x04,0x00,0x44,0xa8},{0x00,0x00,0x8a,0x54},{0x00,0x0a,0x8a,0x58},{0x50,0x19,0x65,0x54},{0x00,0x00,0x00,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x6a,0xaa,0xa8},{0x55,0x94,0x89,0x55},{0x41,0x02,0x09,0x54},{0x15,0x50,0x66,0x24},{0x40,0x04,0xa4,0x68},{0x44,0x0a,0x09,0x54},{0x05,0x08,0x55,0x54},{0x11,0x14,0x56,0x54},{0x04,0x40,0x00,0x58},{0x01,0x40,0x0a,0x54},{0x04,0x0a,0x44,0xa8},{0x01,0x00,0x8a,0x54},{0x00,0x0a,0x6a,0x54},{0x50,0x19,0x65,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x2a,0xaa,0xa8},{0x96,0x95,0x55,0x55},{0x51,0x0a,0x05,0x54},{0x15,0x50,0x66,0xa4},{0x40,0x04,0x54,0x54},{0x44,0x05,0x09,0x54},{0x05,0x18,0x55,0x54},{0x51,0x14,0x56,0x54},{0x04,0x40,0x02,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x58},{0x01,0x0a,0x85,0x54},{0x01,0x05,0x65,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x96,0xa5,0x55,0x55},{0x51,0x09,0x05,0x55},{0x15,0x50,0x65,0x94},{0x44,0x14,0x54,0x54},{0x54,0x15,0x95,0x54},{0x05,0x56,0x55,0x54},{0x51,0x14,0x55,0x54},{0x14,0x40,0x82,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x54},{0x01,0x0a,0x45,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x49,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x14,0x55,0x55},{0x14,0x40,0x8a,0x54},{0x01,0x40,0x85,0x54},{0x04,0x15,0x44,0x54},{0x01,0x0a,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x55,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0xa9,0x54},{0x01,0x40,0x45,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0x69,0x55},{0x01,0x40,0x65,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x55,0x54},{0x01,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x52,0x55,0x54},{0x54,0x14,0x56,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x65,0x55},{0x01,0x50,0x65,0x55},{0x04,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x92,0x55,0x55},{0x55,0x14,0x56,0x54},{0x54,0x55,0x55,0x55},{0x45,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x91,0x55,0x15,0x55},{0x16,0x92,0x55,0x55},{0x55,0x14,0x56,0x55},{0x54,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0x92,0x55,0x95,0x55},{0x6a,0x91,0x55,0x55},{0x55,0x54,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x05,0x15,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0x91,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x4a,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x4a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0xa1,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa9,0x15,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0xa5,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x95,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0x99,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0x56,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x55,0x55,0x55},{0x15,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x05,0x55,0x55},{0xa9,0x66,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x55},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0xa9,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x15,0x45,0x55,0x55},{0x11,0x55,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x15,0x55,0x55},{0xa9,0x66,0x95,0x55},{0x00,0x10,0x55,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x96},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x55,0x55,0x55},{0x5a,0x95,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x19,0x45,0x55,0x55},{0x11,0x95,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x66,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x9a,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x96},{0xaa,0xa6,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x5a,0xa5,0x55,0x55},{0xaa,0x65,0x55,0x55},{0x29,0x85,0x55,0x55},{0x12,0x95,0x55,0x55},{0x59,0x55,0x56,0x55},{0x56,0x15,0x55,0x55},{0xa6,0x15,0x55,0x55},{0xaa,0x6a,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x95,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x9a,0xa5,0x55,0x55},{0xaa,0x69,0x95,0x55},{0x2a,0x85,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x55,0x95,0x55},{0x56,0x15,0x55,0x55},{0xaa,0x1a,0x95,0x55},{0xaa,0x6a,0xaa,0xa9},{0x00,0x15,0x55,0x54}},{{0x55,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0xa9},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0xa9,0x55},{0xa9,0xaa,0x56,0x55},{0xaa,0xa5,0x95,0x55},{0xaa,0x69,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x1a,0xaa,0xa5},{0xaa,0xaa,0xaa,0xa9},{0x20,0x95,0x55,0x54}},{{0x55,0x55,0x8a,0x00},{0xaa,0xaa,0xa5,0x5a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0x99,0x59},{0xaa,0xa8,0xa9,0x55},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0x6a,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0xa6,0x15,0x55,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x5a,0x8a,0x00},{0xaa,0xaa,0x55,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0x9a,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x6a,0x8a,0x00},{0xaa,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xa9,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0xa5,0x55,0x95},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0xaa,0x8a,0x00},{0xa9,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x95,0x55,0x55},{0x66,0xa5,0x55,0xa9},{0xaa,0xaa,0x99,0x55},{0xaa,0x2a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x12,0x45,0x55,0x54}},{{0x6a,0xaa,0x8a,0x00},{0xa5,0x55,0xa5,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0x95,0x55,0xa5},{0xa6,0xa5,0x9a,0xa9},{0xaa,0xaa,0x99,0xa5},{0xaa,0x2a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x41,0x55,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x95,0x6a,0xa5,0x56},{0xaa,0x69,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0x96,0xa9},{0xa6,0xa5,0xaa,0xaa},{0xaa,0xaa,0x99,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x85,0x00},{0x55,0x6a,0xa5,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xa9,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0xaa,0xaa},{0xaa,0xa5,0xaa,0xaa},{0xaa,0xaa,0xa9,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x45,0x00},{0x5a,0x6a,0x55,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x99,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x40,0x02,0xa0}},{{0xaa,0xa5,0x45,0x00},{0x6a,0x55,0x55,0x56},{0x69,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x40,0x02,0xa8}},{{0xaa,0x55,0x45,0x00},{0x6a,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0xa5,0x55,0x45,0x00},{0x66,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x55,0x95,0x55,0x55},{0x55,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x5a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x99,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x55,0x69},{0x69,0x6a,0xaa,0xaa},{0xaa,0x5a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0xa9,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x5a,0xa9,0xaa},{0xa5,0x6a,0xaa,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x0a,0xa9}},{{0x55,0x55,0x40,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0xa9,0xaa},{0x95,0x6a,0x66,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa9}},{{0x55,0x50,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x99,0xaa},{0x55,0x46,0x66,0xaa},{0xa8,0x6a,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa9}},{{0x50,0x00,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x95,0x56},{0x55,0x45,0x55,0xa6},{0x65,0x96,0x96,0xaa},{0x26,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x08,0x28,0xaa,0xa9}},{{0x00,0x00,0x00,0x60},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x55,0xa6},{0x55,0x96,0x66,0xaa},{0x2a,0x4a,0xaa,0xaa},{0xaa,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x88,0x2a,0xaa,0xa8}},{{0x00,0x00,0x20,0x50},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x66,0x6a},{0x12,0x86,0xaa,0xaa},{0x85,0x4a,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0xa8,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x61,0x09,0x55,0x55},{0x45,0x55,0x55,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x98,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x99,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x56,0xaa},{0x94,0x6a,0xaa,0xaa},{0x56,0x65,0x55,0x55},{0xa6,0x55,0x66,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x00,0x00,0x25,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x95,0x55,0x55},{0xa9,0x8a,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x00,0x05,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xa4,0x6a,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x05,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x01,0x50,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_2_11 = { .phases = 57, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_2_11_data[0] }; -const EpdWaveformPhases* epd_wm_ed047tc2_2_ranges[7] = { &epd_wp_ed047tc2_2_5,&epd_wp_ed047tc2_2_6,&epd_wp_ed047tc2_2_7,&epd_wp_ed047tc2_2_8,&epd_wp_ed047tc2_2_9,&epd_wp_ed047tc2_2_10,&epd_wp_ed047tc2_2_11 }; +const uint8_t epd_wp_ED047TC2_2_5_data[46][16][4] = {{{0x00,0x00,0x00,0x00},{0x20,0x88,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x80,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x08,0x00},{0x00,0x02,0x00,0x80},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa2,0x88,0x20,0x88},{0x22,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x00,0x44,0x08,0x00},{0xa0,0x02,0x20,0xa8},{0x08,0x62,0x88,0x80},{0x00,0x00,0x00,0x08},{0x08,0x22,0x88,0x80},{0x00,0x80,0x00,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x24,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x80,0x82,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x84,0x84,0x28,0x80},{0xa0,0x02,0x20,0xaa},{0xa8,0xaa,0x8a,0x80},{0x22,0x84,0x00,0x28},{0x2a,0xaa,0xaa,0xa0},{0x00,0x80,0x28,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x08,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x00,0x20,0x02},{0x00,0x00,0x00,0x02},{0x84,0x88,0x2a,0xa2},{0xa0,0xaa,0xa8,0xa8},{0xa8,0xaa,0x8a,0x80},{0x2a,0xaa,0x08,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x08}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0x24,0x80,0x00},{0x00,0x00,0x00,0x00},{0x29,0x80,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x02,0xa0,0x00},{0x02,0x00,0x00,0x81},{0x88,0xa8,0xaa,0xa9},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0x8a,0x81},{0x2a,0xaa,0x2a,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x04}},{{0xaa,0xaa,0xa8,0xa4},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0xa8,0x80,0x00},{0x00,0x20,0x00,0x00},{0x2a,0x84,0xa0,0x08},{0x2a,0x68,0x20,0x80},{0x80,0xa2,0xa2,0xa8},{0x80,0x02,0xa0,0x01},{0x02,0x80,0x00,0xa9},{0x9a,0xa8,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x89},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x8a,0x28,0x04}},{{0xaa,0xaa,0xa8,0x64},{0x2a,0xaa,0xaa,0x01},{0x00,0x88,0x02,0x00},{0x29,0xa8,0x80,0x00},{0x00,0x28,0x08,0x02},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xa2,0xa2,0xa9},{0x80,0x02,0xa0,0x01},{0x02,0xa0,0x00,0xa9},{0x9a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0x8a,0xa8,0x84}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x00,0x8a,0x02,0x08},{0x2a,0xa8,0x88,0x00},{0x00,0x28,0x8a,0x01},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xaa,0xaa,0xa9},{0x80,0x02,0xa0,0x01},{0x0a,0xaa,0x80,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x8a,0xaa,0x56}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x20,0x8a,0x0a,0x08},{0x2a,0xa8,0xaa,0x00},{0x00,0x2a,0x8a,0x01},{0x2a,0xaa,0xa8,0x08},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x80,0x02,0xa0,0x81},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x59},{0x69,0x8a,0xaa,0x56}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa0,0x8a,0x0a,0x0a},{0xaa,0xaa,0xaa,0x02},{0x08,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x09},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x82,0x82,0xa0,0xa1},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0x59,0x8a,0xaa,0x55}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa2,0x8a,0x2a,0x09},{0xaa,0xaa,0xaa,0x09},{0x28,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x89},{0x2a,0xaa,0xa8,0xa1},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0xa0,0xa9},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x55}},{{0xaa,0xaa,0xaa,0x58},{0x2a,0xaa,0xa5,0x05},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x01},{0x2a,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x01},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x55}},{{0xaa,0xaa,0x96,0xa8},{0xaa,0xaa,0x55,0x09},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x98,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa4,0x55},{0xaa,0xa8,0x8a,0x55},{0xaa,0xaa,0xa5,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x54,0xaa,0xaa,0x55}},{{0xaa,0xa5,0x96,0xa8},{0xaa,0xa5,0x55,0xa9},{0xaa,0xaa,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x90,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0xaa,0x55},{0xa6,0x99,0x55,0x55},{0x94,0xaa,0xa6,0x51}},{{0xaa,0xa5,0x56,0xa8},{0xaa,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x15,0x55},{0x92,0x95,0x65,0x55},{0xaa,0xaa,0xa5,0x55},{0x95,0x95,0x55,0x55},{0x94,0xaa,0x96,0x01}},{{0xa9,0x55,0x56,0xa8},{0xa9,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa5},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x9a,0x85,0x55,0x55},{0x94,0x95,0x55,0x55},{0x99,0xa9,0x95,0x55},{0x95,0x55,0x55,0x55},{0x94,0xaa,0x96,0x01}},{{0x95,0x55,0x56,0xa8},{0xa5,0x55,0x5a,0xa5},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0xa5},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0x96,0x65},{0xaa,0xaa,0x1a,0x59},{0xaa,0x59,0x51,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xa8,0x55,0x55,0x55},{0x98,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x94,0x6a,0x96,0x01}},{{0x95,0x55,0x55,0x94},{0x95,0x55,0xaa,0x95},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0x95},{0x2a,0xaa,0xa5,0x55},{0x9a,0x6a,0x55,0x55},{0xaa,0x85,0x5a,0x55},{0xaa,0x59,0x55,0x55},{0xaa,0xa9,0x5a,0x55},{0xa8,0xaa,0x00,0x55},{0xa8,0x55,0x55,0x55},{0x91,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x90,0x69,0x95,0x01}},{{0x55,0x55,0x55,0x54},{0x96,0x5a,0xaa,0x15},{0xaa,0xa6,0xa9,0x05},{0xaa,0x9a,0x65,0x55},{0x2a,0x96,0x65,0x55},{0x96,0x65,0x55,0x55},{0xa1,0x95,0x56,0x55},{0x28,0x55,0x55,0x55},{0xaa,0xa9,0x52,0x55},{0xa9,0x01,0x05,0x55},{0x25,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x01}},{{0x55,0x55,0x69,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa6,0xa5,0x85},{0x9a,0x56,0x55,0x55},{0xaa,0x95,0x65,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0xa1,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x01}},{{0x55,0x5a,0xa9,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa5,0xa5,0x85},{0x92,0x55,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x15,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x01}},{{0x56,0xaa,0xa9,0x55},{0x99,0xaa,0xa1,0x55},{0xaa,0x65,0x95,0x45},{0x95,0x55,0x55,0x55},{0xa6,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x54,0x55},{0x55,0x55,0x55,0x55},{0x05,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x01}},{{0x6a,0xaa,0xaa,0x55},{0x95,0xaa,0x15,0x55},{0x9a,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x01}},{{0xaa,0xaa,0xaa,0x55},{0x95,0xa5,0x55,0x55},{0x99,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x01}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x15,0x65,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x55,0x01}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x41,0x01}},{{0xaa,0xaa,0x56,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x56},{0x55,0x55,0x55,0x55},{0x69,0x55,0x55,0x55},{0xaa,0x55,0x41,0x01}},{{0xa9,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x55,0x55,0x96},{0x65,0x55,0x55,0x56},{0x6a,0x65,0x55,0xa6},{0xaa,0x94,0x49,0x02}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x6a,0x2a,0x8a,0xaa},{0x6a,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x51,0x56},{0x65,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x40,0xaa},{0x55,0x54,0x45,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x56,0xa6,0x50},{0x55,0x56,0x95,0x56},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x95,0x55,0x55},{0x55,0x55,0x95,0x04},{0x45,0x05,0x55,0xaa},{0x55,0x55,0x55,0xaa},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x45,0x48,0x58,0x50},{0x55,0x55,0x41,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x54,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x54},{0x41,0x04,0x44,0x12},{0x6a,0x2a,0x21,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x69},{0x55,0x55,0x55,0x54},{0x45,0x05,0x15,0x16},{0x41,0x41,0x15,0x02},{0x6a,0x00,0xa0,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x66},{0x55,0x59,0x59,0xa6},{0x60,0x00,0x00,0x0a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x6a,0x59,0x51,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x50,0x55,0x55,0x52},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x6a,0x55,0x55,0x02},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xa5,0x96,0xa6,0x5a},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_5 = { .phases = 46, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_5_data[0] }; +const uint8_t epd_wp_ED047TC2_2_6_data[43][16][4] = {{{0x02,0xaa,0x00,0x00},{0x20,0x22,0xa8,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x22,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xa8,0x20},{0x00,0x00,0x00,0x00},{0x20,0x02,0x08,0x80},{0x00,0x80,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x2a,0xaa,0x00,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x28},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xaa,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x20},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa0,0x20,0x2a},{0x28,0x22,0xa8,0xa8},{0x28,0x00,0x00,0x00}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa8,0x22,0x2a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x80}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0xa2,0x82,0x08,0x80},{0x08,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x42}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x20,0x00,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0xa8},{0x00,0x00,0x00,0x00},{0xaa,0x82,0x88,0xa0},{0x8a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0x94},{0x24,0x00,0x28,0x42}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x20,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0x8a,0x8a,0xa0},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x24,0x00,0x28,0x42}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x22,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0xa0,0xa0,0xa8,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa5},{0xa6,0xaa,0xaa,0x95},{0x24,0x00,0x26,0x41}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x42},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xa2,0xa8,0xaa,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xa8},{0x08,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa6,0x55},{0x56,0x02,0x95,0x55}},{{0xaa,0xaa,0xa0,0x04},{0x20,0xaa,0xa5,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x26},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0x98},{0x88,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xa5,0xa9,0x65,0x55},{0x56,0x0a,0x95,0x55}},{{0xaa,0xa9,0xa0,0x24},{0x20,0xa9,0x55,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x25},{0x2a,0x80,0x00,0x02},{0x20,0xa0,0x28,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x80},{0xa0,0x00,0x00,0x01},{0x20,0xa2,0xa8,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xa2,0xa8,0xaa},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xa5,0x95,0x55,0x55},{0x56,0x0a,0x95,0x55}},{{0xaa,0x95,0xa8,0xa4},{0x20,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x29},{0xa2,0x88,0x00,0x15},{0x2a,0x80,0x00,0x01},{0x20,0xa8,0x28,0x14},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x81},{0xa0,0x00,0x00,0x01},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x56,0x89,0x55,0x55}},{{0xaa,0x95,0x98,0x94},{0xa0,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x25},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0x20,0xaa,0xa8,0x94},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0xa1},{0xa0,0x22,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x94},{0xa8,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0xa9,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x15}},{{0xa9,0x55,0x9a,0x98},{0xa8,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0xa2,0xaa,0xaa,0x94},{0xaa,0xaa,0xaa,0x89},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x2a,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x56},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0x95,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x15}},{{0xa5,0x55,0x5a,0xa8},{0xa8,0x95,0x55,0x45},{0xa0,0x82,0x20,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x85,0x69},{0xaa,0x2a,0xa8,0x29},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xa9,0xa9,0xa5,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0xa5,0x41,0x15}},{{0x95,0x55,0x6a,0x68},{0xa8,0x55,0x55,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xa9,0x55,0x69},{0xaa,0x2a,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0x99,0xa9,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x65,0x40,0x15}},{{0x95,0x55,0x66,0x58},{0xa8,0x55,0x5a,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0xa8,0xa0,0x15},{0xaa,0x62,0xa8,0x19},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x95},{0xaa,0x95,0x55,0x55},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa9,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x65,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x91,0x55,0x40,0x15}},{{0x95,0x56,0xa5,0x94},{0xa8,0x56,0xaa,0x85},{0xa8,0xaa,0xa0,0x95},{0xaa,0xa8,0xa0,0x15},{0xaa,0x6a,0xaa,0x15},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x55,0x55},{0x89,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0x99,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x50,0x00,0x15}},{{0x55,0x6a,0x89,0x94},{0x98,0x6a,0xaa,0x85},{0xaa,0xaa,0xa0,0x95},{0xaa,0xa6,0xa0,0x15},{0x8a,0x6a,0xaa,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xaa,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x89,0x50,0x00,0x15}},{{0x56,0xaa,0x9a,0x14},{0x98,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xa2,0x15},{0x99,0x6a,0xaa,0x95},{0xaa,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xa9,0x10,0x00,0x05}},{{0x5a,0xaa,0x12,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0xa9,0x10,0x00,0x05}},{{0x6a,0xaa,0x55,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0x9a,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x8a,0x55,0x55,0x55},{0xaa,0x00,0x00,0x01}},{{0x6a,0xaa,0x55,0x55},{0x9a,0x96,0xaa,0x41},{0x6a,0xaa,0xaa,0x55},{0x99,0x66,0xaa,0x95},{0x95,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x59,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0x99,0x65},{0xaa,0x00,0x00,0x01}},{{0xaa,0xaa,0x55,0x55},{0x96,0x56,0xa5,0x51},{0x6a,0x69,0x8a,0x55},{0x95,0x66,0xaa,0x95},{0x95,0x69,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x01}},{{0xaa,0xa8,0x55,0x55},{0x96,0x55,0x55,0x55},{0x6a,0x65,0x58,0x55},{0x95,0x66,0x59,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x01}},{{0xa9,0x45,0x55,0x45},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xa5,0x55,0x55,0x41},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x5a,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x95,0x55,0x55,0x41},{0x56,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x45,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x56,0x59,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x2a},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x51},{0x59,0x55,0x55,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x56},{0x55,0x15,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x00,0x15},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x10,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x42},{0x6a,0x95,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x59},{0x15,0x55,0x55,0x82},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x55},{0x99,0x50,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0xaa,0x99,0x55,0x6a},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_6 = { .phases = 43, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_6_data[0] }; +const uint8_t epd_wp_ED047TC2_2_7_data[40][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x0a,0x08,0x80},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa0,0x80,0x00,0x00},{0x08,0x80,0x20,0x00},{0x00,0x12,0x22,0x00},{0x00,0x00,0x00,0x00},{0x1a,0x20,0x00,0x00},{0x01,0x80,0x00,0x00},{0x88,0x00,0x00,0x00},{0x00,0x10,0x80,0x00},{0x20,0x0a,0x88,0x82},{0x80,0x00,0x05,0x08},{0x0a,0xa0,0x00,0x20},{0x20,0x00,0x00,0x20},{0x00,0x80,0x00,0x08},{0x80,0x28,0x08,0x80},{0x2a,0x80,0xa0,0x28},{0x20,0x00,0x80,0x04}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x11,0x22,0xa2,0x00},{0x04,0x04,0x00,0x00},{0x2a,0xa0,0x20,0x00},{0x22,0xa0,0x00,0x00},{0x98,0x12,0x00,0x0a},{0x18,0xa0,0x80,0x00},{0x28,0x0a,0x8a,0x82},{0x88,0x88,0x09,0x28},{0x0a,0xa2,0x20,0x20},{0x20,0x00,0x02,0xa0},{0x00,0xa4,0x00,0x08},{0xa8,0xa8,0xa8,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x20,0x02,0x88,0x84}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x22,0x22,0xa2,0x28},{0x04,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x20,0x0a},{0x98,0x56,0x02,0x8a},{0xa8,0xa4,0x80,0x00},{0x28,0x0a,0xaa,0x82},{0x88,0xaa,0x0a,0x28},{0x2a,0xaa,0xa8,0x22},{0x20,0x40,0xa2,0xa2},{0x12,0xa8,0xa0,0x28},{0xa8,0xaa,0xaa,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x28,0x82,0xa8,0x85}},{{0xa8,0xa0,0x00,0x00},{0x08,0xa0,0x20,0x00},{0x26,0x22,0xa2,0x28},{0x05,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x28,0x0a},{0x99,0xaa,0x82,0x8a},{0xaa,0xa8,0xa2,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0x28},{0x2a,0xaa,0xa8,0xa2},{0x20,0xa6,0xa2,0xa2},{0x92,0xaa,0xa8,0x28},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x98},{0x58,0x8a,0xa8,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xa0,0x20,0x00},{0x2a,0x66,0xa2,0x28},{0x09,0x0a,0x00,0x00},{0x2a,0xa2,0x28,0x00},{0x2a,0xa0,0xa8,0x0a},{0xa9,0xaa,0x82,0x8a},{0xaa,0xaa,0xaa,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa2},{0x25,0xa6,0xaa,0xa2},{0xaa,0xaa,0xa8,0x2a},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x58,0x8a,0xaa,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0x20,0x80},{0x2a,0xa6,0xa2,0x28},{0x19,0x0a,0x00,0x00},{0x2a,0xa2,0xa8,0x00},{0x2a,0xaa,0xa8,0x89},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x02},{0x2a,0x8a,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x81},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa0,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0x2a,0xaa,0xa8,0x04},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x82},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa4},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x95}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0xaa,0xaa,0xa8,0x88},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x96},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x95},{0x5a,0xaa,0xa9,0x55}},{{0xa8,0xa0,0x00,0x14},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xaa,0x28},{0xaa,0x2a,0x00,0x00},{0xaa,0xaa,0xaa,0x99},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x5a,0xaa,0x69,0x55}},{{0xa8,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x16},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0xa9,0xa5,0x55,0x55},{0x9a,0xaa,0x65,0x51}},{{0x98,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x15},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x64,0x51}},{{0x98,0x50,0x00,0x28},{0x8a,0x6a,0x9a,0x41},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x18,0x80},{0xaa,0xaa,0x96,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xaa,0xa5,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x80,0x55},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x54,0x51}},{{0x94,0x50,0x00,0x28},{0xa6,0x55,0x55,0x61},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x28,0x80},{0xa9,0x9a,0x96,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0xa9,0x69,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xa5,0x65,0x55},{0xaa,0xa6,0x25,0x55},{0xaa,0x01,0x55,0x55},{0xaa,0xaa,0x59,0x55},{0xaa,0x55,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0xa5,0x54,0x41}},{{0x94,0xa0,0x00,0x28},{0xa5,0x55,0x55,0x51},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0xa1},{0xa5,0x59,0x55,0x55},{0xaa,0x5a,0x55,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0xa5,0x15,0x55},{0xa9,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x65,0x54,0x41}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x55,0x59},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0x95},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xaa,0xa5,0x65,0x55},{0xaa,0x55,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa8,0x65,0x54,0x41}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x55},{0x8a,0x99,0x59,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0xa5,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x92,0x25,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x95},{0x89,0x99,0x55,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x25,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0x50,0x80,0x15},{0xa5,0x95,0x65,0x95},{0x99,0x95,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x58,0x5a,0x80,0x15},{0xa9,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x98,0x5a,0x80,0x15},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x2a,0x95,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa6,0x54,0x14,0x00}},{{0x98,0x5a,0x48,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x25,0x95,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0x55,0x55,0x65},{0xa6,0x54,0x10,0x00}},{{0x9a,0x55,0x68,0x55},{0x6a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x25,0x55,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x25,0x55,0x55,0x66},{0x2a,0xaa,0xaa,0x6a},{0xa6,0x10,0x00,0x00}},{{0x9a,0x55,0x64,0x41},{0x5a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0xa6,0x10,0x08,0x00}},{{0x9a,0x55,0x94,0x81},{0x5a,0x6a,0x9a,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x46,0x0a,0x9a,0x81},{0xa6,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x0a,0xa9,0x41},{0xa5,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x15,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x44,0x85,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x0a,0x65,0x41},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x55,0x55,0x69},{0x55,0x55,0x55,0x69},{0x55,0x56,0x11,0x59},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x66},{0x65,0x44,0x42,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x51},{0x55,0xaa,0xaa,0x54},{0x45,0x55,0x55,0x56},{0x59,0x59,0x11,0x56},{0x55,0x55,0x14,0x52},{0x55,0x55,0x55,0x55},{0x55,0x51,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x61},{0x40,0x55,0x55,0x80},{0x6a,0xaa,0xaa,0xaa},{0x55,0x04,0x02,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x59,0x55,0x65,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x40,0x00,0x00,0x42},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x64,0x0a,0x9a,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x59},{0x65,0x55,0x55,0x55},{0x55,0x64,0x55,0x41},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x6a,0x2a,0x82,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x45},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x44},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x95,0x55,0x51,0x42},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x50,0x50,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_7 = { .phases = 40, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_7_data[0] }; +const uint8_t epd_wp_ED047TC2_2_8_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x80,0x08,0x82},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x08},{0x00,0x00,0x00,0x00},{0x02,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0x20,0x00,0x00,0x08},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x20},{0x80,0x00,0x00,0x00},{0xaa,0x08,0xaa,0x08},{0x00,0x00,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x20,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0xa0,0x00,0x00,0x0a},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x2a},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa8},{0x00,0x20,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x81},{0xa0,0x00,0x00,0x05},{0x20,0x00,0x00,0x01},{0x02,0x82,0x00,0xa9},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa4},{0x12,0x28,0xaa,0x01}},{{0xa8,0x00,0x0a,0x00},{0x88,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x82,0xa8,0x08,0x81},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x08},{0x00,0x02,0x0a,0x80},{0x88,0x00,0x02,0x81},{0xa0,0x00,0x00,0x25},{0x28,0x00,0x00,0x21},{0x22,0x82,0x00,0xa5},{0x80,0x00,0x00,0x21},{0xaa,0xaa,0xaa,0xa4},{0x19,0x2a,0xaa,0x81}},{{0xa8,0x00,0x0a,0x00},{0x8a,0xa8,0x8a,0x0a},{0x00,0x20,0x00,0x28},{0x80,0x00,0x00,0x00},{0x20,0x00,0x00,0x0a},{0x82,0xaa,0x08,0x81},{0x08,0x20,0x02,0x02},{0x08,0x00,0x00,0x08},{0x28,0x02,0x0a,0x80},{0x88,0x08,0x0a,0x81},{0xa0,0x00,0x08,0x25},{0x2a,0x00,0x0a,0x21},{0x22,0xa2,0x00,0x95},{0x80,0x02,0x00,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x19,0xaa,0xaa,0x81}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0x8a,0x0a},{0x02,0x20,0x00,0x28},{0x88,0x00,0x00,0x02},{0x20,0x00,0x00,0x09},{0xa2,0xaa,0xa8,0x85},{0x8a,0x28,0x0a,0x09},{0x88,0x00,0x00,0x08},{0x28,0x02,0x8a,0x80},{0x88,0x0a,0x0a,0x81},{0xa8,0x02,0x08,0x25},{0xaa,0xaa,0x0a,0x21},{0x2a,0xaa,0x2a,0x95},{0xa0,0x02,0x82,0x81},{0xaa,0xaa,0xaa,0x95},{0x19,0xaa,0xaa,0x81}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0xaa,0x09},{0x02,0x20,0x08,0x04},{0x88,0x00,0x00,0x21},{0x28,0x00,0x00,0x09},{0xaa,0xaa,0xa8,0x85},{0x8a,0xaa,0x0a,0x09},{0x88,0x08,0x00,0x04},{0xaa,0x82,0x8a,0x82},{0xaa,0xaa,0xaa,0x81},{0xa8,0x22,0xa8,0x15},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0x2a,0x95},{0xa0,0x22,0x82,0x91},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xaa,0x85}},{{0xa8,0x00,0x05,0x10},{0x8a,0xaa,0xaa,0x09},{0x22,0x20,0x28,0x14},{0x88,0x00,0x00,0x25},{0x28,0x00,0x00,0x05},{0xaa,0xaa,0xa8,0x45},{0xaa,0xaa,0xaa,0x05},{0x88,0x0a,0x00,0x85},{0xaa,0xa2,0x8a,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa2,0x2a,0x8a,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xa6,0x85}},{{0xa8,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x09},{0xaa,0x22,0xaa,0x15},{0x88,0x00,0x00,0x25},{0xa8,0x00,0x00,0x25},{0xaa,0xaa,0xa8,0x65},{0xaa,0xaa,0xaa,0x25},{0xa8,0x2a,0x80,0xa5},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa2,0xaa,0x8a,0x95},{0xa9,0xaa,0x66,0x55},{0x15,0x6a,0x56,0x45}},{{0x94,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x29},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x08,0x00,0x25},{0xaa,0xaa,0xa6,0x65},{0xaa,0xaa,0xaa,0x25},{0xaa,0x2a,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x45},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0x29,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xa9,0xa9,0x55,0x55},{0x25,0x6a,0x55,0x55}},{{0x94,0x00,0x0a,0x64},{0x8a,0xaa,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x0a,0x0a,0x15},{0xaa,0x6a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa9,0x69,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x99,0xa5,0x55,0x55},{0x21,0x15,0x55,0x55}},{{0x94,0x00,0x0a,0x64},{0xaa,0x9a,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x8a,0x00,0x00,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x5a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0x55},{0x9a,0xaa,0xa6,0x55},{0x9a,0xaa,0xa5,0x55},{0xa9,0x69,0xaa,0x55},{0xaa,0xa9,0x6a,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x55}},{{0x94,0x00,0x0a,0xa5},{0xaa,0x5a,0x65,0x15},{0xaa,0x22,0xaa,0x95},{0xaa,0xa0,0x08,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x55,0x56,0x55},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x9a,0xa9,0x56,0x55},{0x9a,0xa1,0x55,0x55},{0xa9,0x69,0x95,0x55},{0xaa,0xa9,0x69,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x55}},{{0x68,0x00,0x0a,0x95},{0xa6,0x55,0x55,0x15},{0xaa,0x12,0x8a,0x15},{0xaa,0xa0,0x28,0x15},{0xa8,0x2a,0x8a,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0xaa,0xa5,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0xa5,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0x91,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x9a,0xa9,0x65,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x55}},{{0x68,0x00,0x0a,0x55},{0xa6,0x55,0x9a,0x15},{0xaa,0x12,0x06,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x99,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x55}},{{0x68,0x00,0x05,0x55},{0xa5,0x55,0x9a,0x25},{0xa9,0x91,0x55,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x95},{0x59,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa5,0x6a,0x55},{0xaa,0xa9,0x65,0x55},{0xa4,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x55}},{{0x68,0x00,0x05,0x55},{0xa5,0x65,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xaa,0xaa,0xa8,0x95},{0x9a,0x25,0x65,0x95},{0x51,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xa6,0x85,0x65,0x55},{0x9a,0x29,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x55}},{{0x54,0x00,0x05,0x55},{0xa9,0xa5,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xa6,0xaa,0xaa,0x95},{0x96,0xa5,0x65,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x85,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x55,0x55,0x55},{0xaa,0x95,0x11,0x56}},{{0x94,0x00,0x05,0x55},{0x69,0xaa,0xaa,0x25},{0x95,0x99,0x55,0x55},{0xa6,0xaa,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x56},{0xa6,0x55,0x55,0x59},{0xaa,0x95,0x21,0x56}},{{0x94,0x00,0x85,0x51},{0x6a,0xaa,0xaa,0xa5},{0x95,0x99,0x55,0x55},{0x65,0x59,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x66},{0xaa,0x56,0x99,0x6a},{0xaa,0xaa,0xaa,0xaa}},{{0x94,0x22,0x85,0x51},{0x6a,0xaa,0x20,0x95},{0x55,0x59,0x55,0x55},{0x55,0x55,0x56,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x66,0x56,0x95,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x96,0x2a,0x65,0x01},{0xa2,0x8a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x96,0xa9,0x50,0x01},{0xa6,0x0a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x45,0x55,0x55,0x4a},{0x55,0x55,0x55,0x55},{0x66,0x96,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x42,0x95,0x90,0x01},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x52},{0x65,0x54,0x01,0x2a},{0x65,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x56,0xa0,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x64},{0x66,0x6a,0xa9,0x50},{0x55,0x55,0x55,0x64},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x45,0x50,0x00,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x6a,0x60,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x56},{0x55,0x5a,0x95,0x5a},{0x55,0x15,0x55,0x20},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0xa9,0x50,0x05},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x59,0x65,0x6a,0xa6},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x41,0x50,0x15,0x6a},{0x45,0x54,0x55,0x91},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0x95,0x50,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x65,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x54,0x10,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x55,0x50,0x15},{0x55,0x55,0x55,0x55},{0x6a,0xa2,0xaa,0xa2},{0x52,0xa6,0x65,0x92},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x41,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xa2},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x84,0x50,0x05,0x0a},{0x40,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xa5,0x50,0x15,0x48},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x45},{0x00,0x00,0x00,0x00},{0x81,0x51,0x11,0x68},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x45,0x55,0x55,0x44},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_8 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_8_data[0] }; +const uint8_t epd_wp_ED047TC2_2_9_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x0a,0x82,0x02,0x00},{0x40,0x00,0x00,0x00},{0x00,0x80,0x02,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x0a,0x8a,0x82,0x00},{0x40,0x08,0x00,0x40},{0x00,0x80,0x22,0x08},{0x00,0x08,0x08,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x04,0x00,0x00},{0x11,0x40,0x20,0x00},{0x81,0x00,0x00,0x20},{0x28,0x08,0x00,0x82},{0x00,0x20,0x80,0x80},{0x00,0x00,0x02,0x80}},{{0x80,0x00,0x00,0x00},{0x6a,0x8a,0x8a,0x00},{0x90,0x08,0x01,0x40},{0x00,0x80,0x22,0x08},{0x00,0x28,0x88,0x0a},{0x80,0x08,0x00,0x00},{0x00,0x08,0x02,0x00},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x80,0x00},{0x14,0x14,0x00,0x00},{0x21,0x50,0x20,0x80},{0x81,0x18,0x00,0xa0},{0x29,0x0a,0x02,0x81},{0x2a,0xa2,0xaa,0xa0},{0x00,0x2a,0x02,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xa0,0x08,0x02,0x80},{0x80,0x88,0x22,0x08},{0x20,0xa8,0x89,0x0a},{0x80,0xa8,0x00,0x02},{0xaa,0x8a,0x0a,0x08},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x02},{0x08,0x08,0x80,0x00},{0x24,0x54,0x22,0x80},{0x25,0x52,0x2a,0xa0},{0x86,0xa8,0x20,0xa8},{0xaa,0x2a,0x82,0x81},{0x2a,0xaa,0xaa,0xa0},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xaa,0x8a,0x2a,0x80},{0x80,0x88,0x22,0x08},{0x22,0xaa,0x8a,0x0a},{0x82,0xa8,0x00,0x02},{0xaa,0xaa,0x0a,0x0a},{0x00,0x08,0x02,0x28},{0x00,0x00,0x00,0x02},{0x2a,0x8a,0x80,0x00},{0xa5,0xaa,0xa2,0xa0},{0x26,0x96,0xaa,0xa0},{0x8a,0xa8,0xa0,0xa8},{0xaa,0x2a,0x8a,0x81},{0x2a,0xaa,0xaa,0xa8},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x0a},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0x2a,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x00,0x02},{0x2a,0xaa,0x80,0x00},{0xa9,0xaa,0xa2,0xa0},{0x26,0xa6,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0x2a,0x8a,0x41},{0xaa,0xaa,0xaa,0xa8},{0x08,0xaa,0x12,0x41}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x29},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0xaa,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x08,0x80},{0x2a,0xaa,0x8a,0x22},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x12,0x41}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x02},{0xaa,0xaa,0xaa,0x09},{0x20,0x08,0x02,0x28},{0x00,0x02,0x0a,0xa0},{0x2a,0xaa,0x8a,0x2a},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x11,0x45}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x81,0x88,0xa2,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0x8a,0x02,0x28},{0x00,0x82,0xaa,0xa1},{0x2a,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0x91,0x45}},{{0x80,0x00,0x00,0x20},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0x80},{0x82,0x88,0xaa,0x24},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x82,0x04},{0x20,0xa2,0xaa,0xa1},{0x2a,0xaa,0xaa,0x29},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x55},{0x96,0xa5,0x65,0x55},{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0x91,0x45}},{{0x80,0x00,0x00,0x10},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x9a,0x14},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x21},{0xaa,0xaa,0xaa,0x85},{0x2a,0xaa,0x8a,0x15},{0x20,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0x25},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0xaa,0x55},{0x96,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x56},{0x2a,0x99,0x91,0x45}},{{0x80,0x00,0x00,0x94},{0xaa,0xa9,0x45,0x44},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x99,0x16},{0xaa,0xa6,0xa6,0x95},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa9,0xa5},{0xaa,0xaa,0xa9,0x95},{0x2a,0xaa,0xaa,0x69},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0x55,0x56},{0x1a,0x95,0x99,0x05}},{{0x80,0x00,0x00,0x64},{0xa9,0x65,0x45,0x48},{0xaa,0xaa,0xa9,0xa2},{0xa2,0x6a,0x99,0x15},{0xaa,0xa5,0x65,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa5,0xa5},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x59},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x99,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x99,0x55,0x55},{0x19,0x55,0x89,0x05}},{{0x40,0x00,0x00,0xa4},{0xa5,0x65,0x45,0x4a},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x6a,0x99,0x15},{0xa9,0x95,0x65,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa5,0x95,0xa5},{0xaa,0xa6,0xa9,0x95},{0xaa,0xaa,0xa6,0x55},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x59,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x99,0x55,0x55},{0x15,0x55,0x49,0x15}},{{0x40,0x00,0x00,0x54},{0xa5,0x65,0x45,0x88},{0xaa,0xaa,0xa9,0xa1},{0xaa,0x66,0x11,0x15},{0xa9,0x55,0x65,0x55},{0xaa,0x96,0xa9,0x95},{0xa5,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x15},{0xaa,0xaa,0x95,0x55},{0x26,0xa5,0x65,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x45,0x15}},{{0x40,0x00,0x00,0x55},{0xa5,0x55,0x46,0x89},{0xaa,0xa6,0xa5,0x61},{0xaa,0x66,0x51,0x15},{0x95,0x55,0x55,0x55},{0x28,0x56,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x55},{0xaa,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x15}},{{0xa0,0x00,0x00,0x55},{0x95,0x56,0x8a,0x99},{0xaa,0xaa,0x9a,0x51},{0xaa,0x66,0x55,0x95},{0x95,0x55,0x55,0x55},{0x29,0x55,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa5,0x45,0x55},{0xaa,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x16}},{{0xa0,0x00,0x00,0x55},{0x9a,0x9a,0x8a,0x65},{0xaa,0xa5,0x56,0x51},{0x6a,0x56,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x96},{0x95,0x55,0x55,0x55},{0x05,0x55,0x45,0x16}},{{0xa0,0x00,0x20,0x51},{0x5a,0xaa,0x8a,0x65},{0xa5,0x65,0x56,0x59},{0x69,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x85,0x55,0x45,0x12}},{{0x60,0x28,0xa0,0x51},{0x6a,0xaa,0x8a,0x65},{0x95,0x55,0x56,0x55},{0x59,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x84,0x55,0x44,0x12}},{{0x6a,0xaa,0xa8,0x11},{0x6a,0xaa,0x8a,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x45,0x44,0x12}},{{0x5a,0xaa,0x64,0x01},{0xa6,0x99,0x45,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x44,0x46,0x12}},{{0x5a,0x95,0x56,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x99,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x56,0x5a,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x95},{0x95,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x65,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x25,0x6a,0x99,0x01},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x65},{0x56,0x5a,0x56,0x56},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x65},{0x95,0x55,0x41,0x56},{0x95,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x5a,0x66,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0xaa,0x56,0x05},{0x55,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x95,0x61},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x45},{0x55,0x55,0x55,0x59},{0x55,0x55,0x54,0x55},{0x55,0x54,0x00,0x15},{0x91,0x55,0x15,0x42},{0x55,0x55,0x24,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0x95,0x56,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x65,0x49,0x91},{0x55,0x55,0x54,0x44},{0x55,0x55,0x55,0x49},{0x15,0x55,0x55,0x54},{0x55,0x51,0x54,0x0a},{0x55,0x04,0x00,0x2a},{0xaa,0xaa,0xaa,0xaa},{0x55,0x54,0x10,0x55},{0x65,0x56,0x9a,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xa2,0x1a,0x06,0x50},{0x68,0xa0,0xa8,0xaa},{0x55,0x45,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x04,0x00,0xaa},{0x55,0x55,0x65,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x51,0x05,0x01,0x02},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x6a,0xaa,0xa9,0xa4},{0x55,0x55,0x55,0x00},{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_9 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_9_data[0] }; +const uint8_t epd_wp_ED047TC2_2_10_data[44][16][4] = {{{0x00,0x00,0x00,0x00},{0x80,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x00},{0x00,0x80,0x00,0x00},{0x80,0x00,0x08,0x02},{0x00,0x80,0x00,0x08},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x02,0x00,0x00,0x00},{0xa2,0x88,0x20,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x80,0x20,0x00},{0x00,0x80,0x00,0x00},{0x00,0x82,0x00,0x00},{0xa8,0x00,0x08,0x82},{0x00,0x80,0x20,0x0a},{0x92,0x00,0x00,0x8a},{0x2a,0x20,0xa2,0xa8},{0x00,0x00,0x00,0x08}},{{0x02,0x00,0x00,0x00},{0xa2,0x8a,0x20,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x08,0x05,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x00,0x80,0x20,0x00},{0x02,0xa0,0xa0,0x00},{0x00,0x82,0x00,0x02},{0xaa,0x20,0x08,0x82},{0x84,0x80,0xa0,0x0a},{0xa2,0x84,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x08}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa0,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x15,0x42,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xa0,0x20,0x80},{0x02,0xaa,0xa8,0x00},{0x00,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x82},{0x9a,0x90,0xa8,0x0a},{0xa6,0xa8,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x00,0x80,0x2a}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x1a,0x46,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xaa,0x28,0x80},{0x2a,0xaa,0xa8,0x00},{0x02,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0x08,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x8a,0x88,0x26}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x90},{0x02,0xa0,0x08,0x02},{0x2a,0x2a,0x86,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x80},{0x2a,0xaa,0xa8,0x20},{0x02,0x82,0x00,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0x8a,0x8a,0xa6}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x0a},{0x80,0x00,0x00,0x90},{0x02,0xaa,0x2a,0x02},{0x2a,0xaa,0x8a,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xa2,0xa2,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0xaa,0x4a,0x55}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0x90},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa0},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x16,0xaa,0x46,0x55}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa4},{0x15,0x9a,0x65,0x55}},{{0x82,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0x80,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0x15,0x95,0x65,0x55}},{{0x81,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0xa2,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x8a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x02,0x82,0x20},{0x00,0x0a,0x00,0x09},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0x15,0x55,0x55,0x55}},{{0x81,0x00,0x80,0xa8},{0xaa,0xaa,0x9a,0x2a},{0xa2,0xa2,0x02,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x82,0x82,0xa0},{0x00,0x8a,0x80,0x09},{0x2a,0xaa,0xaa,0x22},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0x21},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xa9,0x55},{0x15,0x55,0x55,0x55}},{{0x81,0x00,0x80,0xa8},{0xaa,0x66,0x9a,0x2a},{0xa2,0xa2,0x22,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0x2a,0xa2,0xa0,0x80},{0x02,0x8a,0x80,0x05},{0x2a,0xaa,0x8a,0x20},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xa0,0x61},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x81,0x00,0x80,0x94},{0xaa,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x82},{0x02,0x8a,0x82,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xa8,0xaa,0xa1},{0xaa,0xaa,0xa0,0x65},{0xaa,0xaa,0x20,0x85},{0xaa,0xaa,0xaa,0x65},{0xaa,0x95,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x41,0x00,0x40,0x94},{0x69,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xa2,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0x9a},{0xaa,0x28,0xaa,0xa9},{0xaa,0xaa,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x42,0x00,0x48,0xa4},{0x59,0x55,0x55,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xaa,0x25},{0x2a,0xaa,0xaa,0x9a},{0xa8,0x80,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x8a,0x29},{0x2a,0xaa,0x56,0x99},{0xaa,0x28,0xa8,0xa9},{0xaa,0x82,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x42,0x00,0x48,0x64},{0x59,0x59,0x65,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xa0,0x65},{0x2a,0xaa,0xa9,0x56},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0xa9,0x8a},{0xaa,0xaa,0xaa,0x05},{0xaa,0x2a,0x86,0x69},{0x2a,0x55,0x55,0x99},{0xaa,0x69,0x89,0xa9},{0x96,0x82,0x00,0x45},{0xaa,0x22,0x10,0x05},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0x62,0x00,0x4a,0x54},{0x59,0x9a,0xa9,0x95},{0xaa,0xaa,0x22,0x65},{0x82,0xaa,0xa5,0x45},{0x26,0xaa,0xa9,0x55},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0x29,0x89},{0xaa,0xaa,0xaa,0x85},{0xaa,0x55,0x54,0x69},{0x21,0x55,0x55,0x55},{0xaa,0x69,0x45,0xa9},{0x95,0x55,0x55,0x55},{0xaa,0x22,0x10,0x05},{0x89,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55}},{{0xa2,0x00,0x8a,0x54},{0x66,0xaa,0xaa,0x95},{0xaa,0xaa,0x22,0x55},{0x82,0x95,0x55,0x55},{0x16,0xa5,0x55,0x55},{0xa2,0xa0,0x20,0x09},{0xaa,0xa9,0x29,0x09},{0xaa,0xaa,0xaa,0x85},{0xa9,0x55,0x55,0x59},{0x11,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa1,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x55}},{{0xa2,0x00,0x86,0x54},{0xa6,0xaa,0xaa,0xa5},{0xaa,0xaa,0x22,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x5a,0xa9,0x55},{0xa2,0xaa,0x28,0x01},{0xaa,0xa9,0x29,0x55},{0xaa,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x55,0x55,0x55}},{{0xa1,0x00,0x85,0x54},{0xaa,0xa2,0xaa,0x65},{0xaa,0xaa,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x15,0xa5,0x55,0x55},{0xa2,0xaa,0xa8,0x01},{0xaa,0xa9,0x69,0x55},{0xaa,0xa5,0x69,0xa5},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x45,0x55,0x55}},{{0xa1,0x00,0x85,0x54},{0x9a,0x95,0x55,0x55},{0xaa,0x99,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa2,0xa9,0x55,0x55},{0xaa,0xa5,0x69,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x85,0x55}},{{0x61,0x00,0x45,0x54},{0x95,0x55,0x55,0x55},{0xaa,0x99,0x61,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa5,0x55,0x55,0x55},{0xaa,0x65,0x55,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x89,0x95}},{{0x61,0x00,0x45,0x50},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0xaa,0x8a,0xa9}},{{0x61,0x00,0x45,0x10},{0x15,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xa9}},{{0x51,0x20,0x41,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x16,0x6a,0x94,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x50,0x2a,0x40,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x2a,0x00,0x01},{0x55,0x55,0x55,0x55},{0x51,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0xaa}},{{0x28,0xa9,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x28,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x24,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x99},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x99},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x9a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x14,0x6a,0x20,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x65},{0x55,0x14,0x54,0x56},{0x41,0x55,0x55,0x56},{0x55,0x55,0x55,0x5a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x14,0x6a,0x10,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x11},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x15},{0x6a,0xaa,0xaa,0x99},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x96,0x10,0x05},{0x55,0x55,0x55,0x19},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x21},{0xa9,0x55,0x56,0xa5},{0x55,0x55,0x55,0x55},{0x66,0xa9,0x69,0x54},{0x55,0x50,0x14,0x1a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x95,0x10,0x45},{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x65},{0x6a,0x6a,0x9a,0x11},{0x95,0x55,0x55,0x55},{0x69,0x55,0x55,0x59},{0x51,0x56,0x16,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x18,0x55,0x10,0x55},{0x00,0x00,0x00,0x00},{0x55,0x65,0x56,0x54},{0x55,0x15,0x45,0x02},{0x80,0x00,0x00,0x0a},{0x55,0x55,0x55,0x16},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x15,0x55,0x15,0x55},{0x00,0x00,0x00,0x00},{0x59,0x55,0x55,0x14},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x65,0x45,0x54,0x0a},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_10 = { .phases = 44, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_10_data[0] }; +const uint8_t epd_wp_ED047TC2_2_11_data[57][16][4] = {{{0x20,0x8a,0x80,0x00},{0x15,0x55,0x5a,0xa4},{0x44,0x10,0x0a,0x41},{0x40,0x00,0x09,0x54},{0x10,0x50,0x00,0x00},{0x00,0x00,0x04,0x28},{0x40,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x40,0x00},{0x00,0x00,0x00,0x00},{0x00,0x40,0x00,0x68},{0x00,0x00,0x40,0x00},{0x00,0x00,0x0a,0x54},{0x00,0x0a,0x80,0x00},{0x10,0x09,0x60,0x00},{0x00,0x00,0x00,0x50}},{{0xaa,0xaa,0x8a,0x00},{0x0a,0x60,0x0a,0xa8},{0x54,0x54,0x8a,0x41},{0x41,0x02,0x09,0x54},{0x15,0x50,0x06,0x24},{0x00,0x08,0xa4,0x28},{0x44,0x00,0x09,0xa8},{0x05,0x00,0x2a,0xa8},{0x01,0x10,0x46,0xa8},{0x04,0x00,0x00,0xa8},{0x00,0x40,0x00,0x54},{0x04,0x00,0x44,0xa8},{0x00,0x00,0x8a,0x54},{0x00,0x0a,0x8a,0x58},{0x50,0x19,0x65,0x54},{0x00,0x00,0x00,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x6a,0xaa,0xa8},{0x55,0x94,0x89,0x55},{0x41,0x02,0x09,0x54},{0x15,0x50,0x66,0x24},{0x40,0x04,0xa4,0x68},{0x44,0x0a,0x09,0x54},{0x05,0x08,0x55,0x54},{0x11,0x14,0x56,0x54},{0x04,0x40,0x00,0x58},{0x01,0x40,0x0a,0x54},{0x04,0x0a,0x44,0xa8},{0x01,0x00,0x8a,0x54},{0x00,0x0a,0x6a,0x54},{0x50,0x19,0x65,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x2a,0xaa,0xa8},{0x96,0x95,0x55,0x55},{0x51,0x0a,0x05,0x54},{0x15,0x50,0x66,0xa4},{0x40,0x04,0x54,0x54},{0x44,0x05,0x09,0x54},{0x05,0x18,0x55,0x54},{0x51,0x14,0x56,0x54},{0x04,0x40,0x02,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x58},{0x01,0x0a,0x85,0x54},{0x01,0x05,0x65,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x96,0xa5,0x55,0x55},{0x51,0x09,0x05,0x55},{0x15,0x50,0x65,0x94},{0x44,0x14,0x54,0x54},{0x54,0x15,0x95,0x54},{0x05,0x56,0x55,0x54},{0x51,0x14,0x55,0x54},{0x14,0x40,0x82,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x54},{0x01,0x0a,0x45,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x49,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x14,0x55,0x55},{0x14,0x40,0x8a,0x54},{0x01,0x40,0x85,0x54},{0x04,0x15,0x44,0x54},{0x01,0x0a,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x55,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0xa9,0x54},{0x01,0x40,0x45,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0x69,0x55},{0x01,0x40,0x65,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x55,0x54},{0x01,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x52,0x55,0x54},{0x54,0x14,0x56,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x65,0x55},{0x01,0x50,0x65,0x55},{0x04,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x92,0x55,0x55},{0x55,0x14,0x56,0x54},{0x54,0x55,0x55,0x55},{0x45,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x91,0x55,0x15,0x55},{0x16,0x92,0x55,0x55},{0x55,0x14,0x56,0x55},{0x54,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0x92,0x55,0x95,0x55},{0x6a,0x91,0x55,0x55},{0x55,0x54,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x05,0x15,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0x91,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x4a,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x4a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0xa1,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa9,0x15,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0xa5,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x95,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0x99,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0x56,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x55,0x55,0x55},{0x15,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x05,0x55,0x55},{0xa9,0x66,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x55},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0xa9,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x15,0x45,0x55,0x55},{0x11,0x55,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x15,0x55,0x55},{0xa9,0x66,0x95,0x55},{0x00,0x10,0x55,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x96},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x55,0x55,0x55},{0x5a,0x95,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x19,0x45,0x55,0x55},{0x11,0x95,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x66,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x9a,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x96},{0xaa,0xa6,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x5a,0xa5,0x55,0x55},{0xaa,0x65,0x55,0x55},{0x29,0x85,0x55,0x55},{0x12,0x95,0x55,0x55},{0x59,0x55,0x56,0x55},{0x56,0x15,0x55,0x55},{0xa6,0x15,0x55,0x55},{0xaa,0x6a,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x95,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x9a,0xa5,0x55,0x55},{0xaa,0x69,0x95,0x55},{0x2a,0x85,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x55,0x95,0x55},{0x56,0x15,0x55,0x55},{0xaa,0x1a,0x95,0x55},{0xaa,0x6a,0xaa,0xa9},{0x00,0x15,0x55,0x54}},{{0x55,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0xa9},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0xa9,0x55},{0xa9,0xaa,0x56,0x55},{0xaa,0xa5,0x95,0x55},{0xaa,0x69,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x1a,0xaa,0xa5},{0xaa,0xaa,0xaa,0xa9},{0x20,0x95,0x55,0x54}},{{0x55,0x55,0x8a,0x00},{0xaa,0xaa,0xa5,0x5a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0x99,0x59},{0xaa,0xa8,0xa9,0x55},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0x6a,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0xa6,0x15,0x55,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x5a,0x8a,0x00},{0xaa,0xaa,0x55,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0x9a,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x6a,0x8a,0x00},{0xaa,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xa9,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0xa5,0x55,0x95},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0xaa,0x8a,0x00},{0xa9,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x95,0x55,0x55},{0x66,0xa5,0x55,0xa9},{0xaa,0xaa,0x99,0x55},{0xaa,0x2a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x12,0x45,0x55,0x54}},{{0x6a,0xaa,0x8a,0x00},{0xa5,0x55,0xa5,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0x95,0x55,0xa5},{0xa6,0xa5,0x9a,0xa9},{0xaa,0xaa,0x99,0xa5},{0xaa,0x2a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x41,0x55,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x95,0x6a,0xa5,0x56},{0xaa,0x69,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0x96,0xa9},{0xa6,0xa5,0xaa,0xaa},{0xaa,0xaa,0x99,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x85,0x00},{0x55,0x6a,0xa5,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xa9,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0xaa,0xaa},{0xaa,0xa5,0xaa,0xaa},{0xaa,0xaa,0xa9,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x45,0x00},{0x5a,0x6a,0x55,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x99,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x40,0x02,0xa0}},{{0xaa,0xa5,0x45,0x00},{0x6a,0x55,0x55,0x56},{0x69,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x40,0x02,0xa8}},{{0xaa,0x55,0x45,0x00},{0x6a,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0xa5,0x55,0x45,0x00},{0x66,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x55,0x95,0x55,0x55},{0x55,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x5a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x99,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x55,0x69},{0x69,0x6a,0xaa,0xaa},{0xaa,0x5a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0xa9,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x0a,0xa9}},{{0x55,0x55,0x45,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x5a,0xa9,0xaa},{0xa5,0x6a,0xaa,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x0a,0xa9}},{{0x55,0x55,0x40,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0xa9,0xaa},{0x95,0x6a,0x66,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa9}},{{0x55,0x50,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x99,0xaa},{0x55,0x46,0x66,0xaa},{0xa8,0x6a,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa9}},{{0x50,0x00,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x95,0x56},{0x55,0x45,0x55,0xa6},{0x65,0x96,0x96,0xaa},{0x26,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x08,0x28,0xaa,0xa9}},{{0x00,0x00,0x00,0x60},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x55,0xa6},{0x55,0x96,0x66,0xaa},{0x2a,0x4a,0xaa,0xaa},{0xaa,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x88,0x2a,0xaa,0xa8}},{{0x00,0x00,0x20,0x50},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x66,0x6a},{0x12,0x86,0xaa,0xaa},{0x85,0x4a,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0xa8,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x61,0x09,0x55,0x55},{0x45,0x55,0x55,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x98,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x99,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x56,0xaa},{0x94,0x6a,0xaa,0xaa},{0x56,0x65,0x55,0x55},{0xa6,0x55,0x66,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x00,0x00,0x25,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x95,0x55,0x55},{0xa9,0x8a,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x00,0x05,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xa4,0x6a,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa}},{{0x05,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x01,0x50,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_2_11 = { .phases = 57, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_2_11_data[0] }; +const EpdWaveformPhases* epd_wm_ed047tc2_2_ranges[7] = { &epd_wp_ED047TC2_2_5,&epd_wp_ED047TC2_2_6,&epd_wp_ED047TC2_2_7,&epd_wp_ED047TC2_2_8,&epd_wp_ED047TC2_2_9,&epd_wp_ED047TC2_2_10,&epd_wp_ED047TC2_2_11 }; const EpdWaveformMode epd_wm_ed047tc2_2 = { .type = 2, .temp_ranges = 7, .range_data = &epd_wm_ed047tc2_2_ranges[0] }; -const uint8_t epd_wp_ed047tc2_5_5_data[46][16][4] = {{{0x00,0x00,0x00,0x00},{0x20,0x88,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x80,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x08,0x00},{0x00,0x02,0x00,0x80},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa2,0x88,0x20,0x88},{0x22,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x00,0x44,0x08,0x00},{0xa0,0x02,0x20,0xa8},{0x08,0x62,0x88,0x80},{0x00,0x00,0x00,0x08},{0x08,0x22,0x88,0x80},{0x00,0x80,0x00,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x24,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x80,0x82,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x84,0x84,0x28,0x80},{0xa0,0x02,0x20,0xaa},{0xa8,0xaa,0x8a,0x80},{0x22,0x84,0x00,0x28},{0x2a,0xaa,0xaa,0xa0},{0x00,0x80,0x28,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x08,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x00,0x20,0x02},{0x00,0x00,0x00,0x02},{0x84,0x88,0x2a,0xa2},{0xa0,0xaa,0xa8,0xa8},{0xa8,0xaa,0x8a,0x80},{0x2a,0xaa,0x08,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x08}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0x24,0x80,0x00},{0x00,0x00,0x00,0x00},{0x29,0x80,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x02,0xa0,0x00},{0x02,0x00,0x00,0x81},{0x88,0xa8,0xaa,0xa9},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0x8a,0x81},{0x2a,0xaa,0x2a,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x04}},{{0xaa,0xaa,0xa8,0xa4},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0xa8,0x80,0x00},{0x00,0x20,0x00,0x00},{0x2a,0x84,0xa0,0x08},{0x2a,0x68,0x20,0x80},{0x80,0xa2,0xa2,0xa8},{0x80,0x02,0xa0,0x01},{0x02,0x80,0x00,0xa9},{0x9a,0xa8,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x89},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x8a,0x28,0x04}},{{0xaa,0xaa,0xa8,0x64},{0x2a,0xaa,0xaa,0x01},{0x00,0x88,0x02,0x00},{0x29,0xa8,0x80,0x00},{0x00,0x28,0x08,0x02},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xa2,0xa2,0xa9},{0x80,0x02,0xa0,0x01},{0x02,0xa0,0x00,0xa9},{0x9a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0x8a,0xa8,0x84}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x00,0x8a,0x02,0x08},{0x2a,0xa8,0x88,0x00},{0x00,0x28,0x8a,0x01},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xaa,0xaa,0xa9},{0x80,0x02,0xa0,0x01},{0x0a,0xaa,0x80,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x8a,0xaa,0x54}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x20,0x8a,0x0a,0x08},{0x2a,0xa8,0xaa,0x00},{0x00,0x2a,0x8a,0x01},{0x2a,0xaa,0xa8,0x08},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x80,0x02,0xa0,0x81},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x59},{0x69,0x8a,0xaa,0x54}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa0,0x8a,0x0a,0x0a},{0xaa,0xaa,0xaa,0x02},{0x08,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x09},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x82,0x82,0xa0,0xa1},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0x59,0x8a,0xaa,0x54}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa2,0x8a,0x2a,0x09},{0xaa,0xaa,0xaa,0x09},{0x28,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x89},{0x2a,0xaa,0xa8,0xa1},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0xa0,0xa9},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x54}},{{0xaa,0xaa,0xaa,0x58},{0x2a,0xaa,0xa5,0x05},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x01},{0x2a,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x01},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x54}},{{0xaa,0xaa,0x96,0xa8},{0xaa,0xaa,0x55,0x09},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x98,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa4,0x55},{0xaa,0xa8,0x8a,0x55},{0xaa,0xaa,0xa5,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x54,0xaa,0xaa,0x54}},{{0xaa,0xa5,0x96,0xa8},{0xaa,0xa5,0x55,0xa9},{0xaa,0xaa,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x90,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0xaa,0x55},{0xa6,0x99,0x55,0x55},{0x94,0xaa,0xa6,0x50}},{{0xaa,0xa5,0x56,0xa8},{0xaa,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x15,0x55},{0x92,0x95,0x65,0x55},{0xaa,0xaa,0xa5,0x55},{0x95,0x95,0x55,0x55},{0x94,0xaa,0x96,0x00}},{{0xa9,0x55,0x56,0xa8},{0xa9,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa5},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x9a,0x85,0x55,0x55},{0x94,0x95,0x55,0x55},{0x99,0xa9,0x95,0x55},{0x95,0x55,0x55,0x55},{0x94,0xaa,0x96,0x00}},{{0x95,0x55,0x56,0xa8},{0xa5,0x55,0x5a,0xa5},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0xa5},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0x96,0x65},{0xaa,0xaa,0x1a,0x59},{0xaa,0x59,0x51,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xa8,0x55,0x55,0x55},{0x98,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x94,0x6a,0x96,0x00}},{{0x95,0x55,0x55,0x94},{0x95,0x55,0xaa,0x95},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0x95},{0x2a,0xaa,0xa5,0x55},{0x9a,0x6a,0x55,0x55},{0xaa,0x85,0x5a,0x55},{0xaa,0x59,0x55,0x55},{0xaa,0xa9,0x5a,0x55},{0xa8,0xaa,0x00,0x55},{0xa8,0x55,0x55,0x55},{0x91,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x90,0x69,0x95,0x00}},{{0x55,0x55,0x55,0x54},{0x96,0x5a,0xaa,0x15},{0xaa,0xa6,0xa9,0x05},{0xaa,0x9a,0x65,0x55},{0x2a,0x96,0x65,0x55},{0x96,0x65,0x55,0x55},{0xa1,0x95,0x56,0x55},{0x28,0x55,0x55,0x55},{0xaa,0xa9,0x52,0x55},{0xa9,0x01,0x05,0x55},{0x25,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x00}},{{0x55,0x55,0x69,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa6,0xa5,0x85},{0x9a,0x56,0x55,0x55},{0xaa,0x95,0x65,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0xa1,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x00}},{{0x55,0x5a,0xa9,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa5,0xa5,0x85},{0x92,0x55,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x15,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x00}},{{0x56,0xaa,0xa9,0x55},{0x99,0xaa,0xa1,0x55},{0xaa,0x65,0x95,0x45},{0x95,0x55,0x55,0x55},{0xa6,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x54,0x55},{0x55,0x55,0x55,0x55},{0x05,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x00}},{{0x6a,0xaa,0xaa,0x55},{0x95,0xaa,0x15,0x55},{0x9a,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x00}},{{0xaa,0xaa,0xaa,0x55},{0x95,0xa5,0x55,0x55},{0x99,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x00}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x15,0x65,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x55,0x00}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x41,0x00}},{{0xaa,0xaa,0x56,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x56},{0x55,0x55,0x55,0x55},{0x69,0x55,0x55,0x55},{0xaa,0x55,0x41,0x00}},{{0xa9,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x55,0x55,0x96},{0x65,0x55,0x55,0x56},{0x6a,0x65,0x55,0xa6},{0xaa,0x94,0x49,0x00}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x6a,0x2a,0x8a,0xaa},{0x6a,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x51,0x56},{0x65,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x40,0xaa},{0x55,0x54,0x45,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x56,0xa6,0x50},{0x55,0x56,0x95,0x56},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x95,0x55,0x55},{0x55,0x55,0x95,0x04},{0x45,0x05,0x55,0xaa},{0x55,0x55,0x55,0xaa},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x45,0x48,0x58,0x50},{0x55,0x55,0x41,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x54,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x54},{0x41,0x04,0x44,0x12},{0x6a,0x2a,0x21,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x69},{0x55,0x55,0x55,0x54},{0x45,0x05,0x15,0x16},{0x41,0x41,0x15,0x02},{0x6a,0x00,0xa0,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x66},{0x55,0x59,0x59,0xa6},{0x60,0x00,0x00,0x0a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x6a,0x59,0x51,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x50,0x55,0x55,0x52},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x6a,0x55,0x55,0x02},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xa5,0x96,0xa6,0x5a},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_5 = { .phases = 46, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_5_data[0] }; -const uint8_t epd_wp_ed047tc2_5_6_data[43][16][4] = {{{0x02,0xaa,0x00,0x00},{0x20,0x22,0xa8,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x22,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xa8,0x20},{0x00,0x00,0x00,0x00},{0x20,0x02,0x08,0x80},{0x00,0x80,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x2a,0xaa,0x00,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x28},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xaa,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x20},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa0,0x20,0x2a},{0x28,0x22,0xa8,0xa8},{0x28,0x00,0x00,0x00}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa8,0x22,0x2a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x80}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0xa2,0x82,0x08,0x80},{0x08,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x40}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x20,0x00,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0xa8},{0x00,0x00,0x00,0x00},{0xaa,0x82,0x88,0xa0},{0x8a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0x94},{0x24,0x00,0x28,0x40}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x20,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0x8a,0x8a,0xa0},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x24,0x00,0x28,0x40}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x22,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0xa0,0xa0,0xa8,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa5},{0xa6,0xaa,0xaa,0x95},{0x24,0x00,0x26,0x40}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x42},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xa2,0xa8,0xaa,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xa8},{0x08,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa6,0x55},{0x56,0x02,0x95,0x54}},{{0xaa,0xaa,0xa0,0x04},{0x20,0xaa,0xa5,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x26},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0x98},{0x88,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xa5,0xa9,0x65,0x55},{0x56,0x0a,0x95,0x54}},{{0xaa,0xa9,0xa0,0x24},{0x20,0xa9,0x55,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x25},{0x2a,0x80,0x00,0x02},{0x20,0xa0,0x28,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x80},{0xa0,0x00,0x00,0x01},{0x20,0xa2,0xa8,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xa2,0xa8,0xaa},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xa5,0x95,0x55,0x55},{0x56,0x0a,0x95,0x54}},{{0xaa,0x95,0xa8,0xa4},{0x20,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x29},{0xa2,0x88,0x00,0x15},{0x2a,0x80,0x00,0x01},{0x20,0xa8,0x28,0x14},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x81},{0xa0,0x00,0x00,0x01},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x56,0x89,0x55,0x54}},{{0xaa,0x95,0x98,0x94},{0xa0,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x25},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0x20,0xaa,0xa8,0x94},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0xa1},{0xa0,0x22,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x94},{0xa8,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0xa9,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x14}},{{0xa9,0x55,0x9a,0x98},{0xa8,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0xa2,0xaa,0xaa,0x94},{0xaa,0xaa,0xaa,0x89},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x2a,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x56},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0x95,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x14}},{{0xa5,0x55,0x5a,0xa8},{0xa8,0x95,0x55,0x45},{0xa0,0x82,0x20,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x85,0x69},{0xaa,0x2a,0xa8,0x29},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xa9,0xa9,0xa5,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0xa5,0x41,0x14}},{{0x95,0x55,0x6a,0x68},{0xa8,0x55,0x55,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xa9,0x55,0x69},{0xaa,0x2a,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0x99,0xa9,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x65,0x40,0x14}},{{0x95,0x55,0x66,0x58},{0xa8,0x55,0x5a,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0xa8,0xa0,0x15},{0xaa,0x62,0xa8,0x19},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x95},{0xaa,0x95,0x55,0x55},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa9,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x65,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x91,0x55,0x40,0x14}},{{0x95,0x56,0xa5,0x94},{0xa8,0x56,0xaa,0x85},{0xa8,0xaa,0xa0,0x95},{0xaa,0xa8,0xa0,0x15},{0xaa,0x6a,0xaa,0x15},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x55,0x55},{0x89,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0x99,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x50,0x00,0x14}},{{0x55,0x6a,0x89,0x94},{0x98,0x6a,0xaa,0x85},{0xaa,0xaa,0xa0,0x95},{0xaa,0xa6,0xa0,0x15},{0x8a,0x6a,0xaa,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xaa,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x89,0x50,0x00,0x14}},{{0x56,0xaa,0x9a,0x14},{0x98,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xa2,0x15},{0x99,0x6a,0xaa,0x95},{0xaa,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xa9,0x10,0x00,0x04}},{{0x5a,0xaa,0x12,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0xa9,0x10,0x00,0x04}},{{0x6a,0xaa,0x55,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0x9a,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x8a,0x55,0x55,0x55},{0xaa,0x00,0x00,0x00}},{{0x6a,0xaa,0x55,0x55},{0x9a,0x96,0xaa,0x41},{0x6a,0xaa,0xaa,0x55},{0x99,0x66,0xaa,0x95},{0x95,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x59,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0x99,0x65},{0xaa,0x00,0x00,0x00}},{{0xaa,0xaa,0x55,0x55},{0x96,0x56,0xa5,0x51},{0x6a,0x69,0x8a,0x55},{0x95,0x66,0xaa,0x95},{0x95,0x69,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xaa,0xa8,0x55,0x55},{0x96,0x55,0x55,0x55},{0x6a,0x65,0x58,0x55},{0x95,0x66,0x59,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xa9,0x45,0x55,0x45},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xa5,0x55,0x55,0x41},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x5a,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x95,0x55,0x55,0x41},{0x56,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x45,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x56,0x59,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x2a},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x51},{0x59,0x55,0x55,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x56},{0x55,0x15,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x15},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x10,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x42},{0x6a,0x95,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x59},{0x15,0x55,0x55,0x82},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x55},{0x99,0x50,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0xaa,0x99,0x55,0x6a},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_6 = { .phases = 43, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_6_data[0] }; -const uint8_t epd_wp_ed047tc2_5_7_data[40][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x0a,0x08,0x80},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa0,0x80,0x00,0x00},{0x08,0x80,0x20,0x00},{0x00,0x12,0x22,0x00},{0x00,0x00,0x00,0x00},{0x1a,0x20,0x00,0x00},{0x01,0x80,0x00,0x00},{0x88,0x00,0x00,0x00},{0x00,0x10,0x80,0x00},{0x20,0x0a,0x88,0x82},{0x80,0x00,0x05,0x08},{0x0a,0xa0,0x00,0x20},{0x20,0x00,0x00,0x20},{0x00,0x80,0x00,0x08},{0x80,0x28,0x08,0x80},{0x2a,0x80,0xa0,0x28},{0x20,0x00,0x80,0x04}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x11,0x22,0xa2,0x00},{0x04,0x04,0x00,0x00},{0x2a,0xa0,0x20,0x00},{0x22,0xa0,0x00,0x00},{0x98,0x12,0x00,0x0a},{0x18,0xa0,0x80,0x00},{0x28,0x0a,0x8a,0x82},{0x88,0x88,0x09,0x28},{0x0a,0xa2,0x20,0x20},{0x20,0x00,0x02,0xa0},{0x00,0xa4,0x00,0x08},{0xa8,0xa8,0xa8,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x20,0x02,0x88,0x84}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x22,0x22,0xa2,0x28},{0x04,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x20,0x0a},{0x98,0x56,0x02,0x8a},{0xa8,0xa4,0x80,0x00},{0x28,0x0a,0xaa,0x82},{0x88,0xaa,0x0a,0x28},{0x2a,0xaa,0xa8,0x22},{0x20,0x40,0xa2,0xa2},{0x12,0xa8,0xa0,0x28},{0xa8,0xaa,0xaa,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x28,0x82,0xa8,0x84}},{{0xa8,0xa0,0x00,0x00},{0x08,0xa0,0x20,0x00},{0x26,0x22,0xa2,0x28},{0x05,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x28,0x0a},{0x99,0xaa,0x82,0x8a},{0xaa,0xa8,0xa2,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0x28},{0x2a,0xaa,0xa8,0xa2},{0x20,0xa6,0xa2,0xa2},{0x92,0xaa,0xa8,0x28},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x98},{0x58,0x8a,0xa8,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xa0,0x20,0x00},{0x2a,0x66,0xa2,0x28},{0x09,0x0a,0x00,0x00},{0x2a,0xa2,0x28,0x00},{0x2a,0xa0,0xa8,0x0a},{0xa9,0xaa,0x82,0x8a},{0xaa,0xaa,0xaa,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa2},{0x25,0xa6,0xaa,0xa2},{0xaa,0xaa,0xa8,0x2a},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x58,0x8a,0xaa,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0x20,0x80},{0x2a,0xa6,0xa2,0x28},{0x19,0x0a,0x00,0x00},{0x2a,0xa2,0xa8,0x00},{0x2a,0xaa,0xa8,0x89},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x02},{0x2a,0x8a,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x81},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa0,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0x2a,0xaa,0xa8,0x04},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x82},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa4},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0xaa,0xaa,0xa8,0x88},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x96},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x95},{0x5a,0xaa,0xa9,0x54}},{{0xa8,0xa0,0x00,0x14},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xaa,0x28},{0xaa,0x2a,0x00,0x00},{0xaa,0xaa,0xaa,0x99},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x5a,0xaa,0x69,0x54}},{{0xa8,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x16},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0xa9,0xa5,0x55,0x55},{0x9a,0xaa,0x65,0x50}},{{0x98,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x15},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x64,0x50}},{{0x98,0x50,0x00,0x28},{0x8a,0x6a,0x9a,0x41},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x18,0x80},{0xaa,0xaa,0x96,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xaa,0xa5,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x80,0x55},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x54,0x50}},{{0x94,0x50,0x00,0x28},{0xa6,0x55,0x55,0x61},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x28,0x80},{0xa9,0x9a,0x96,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0xa9,0x69,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xa5,0x65,0x55},{0xaa,0xa6,0x25,0x55},{0xaa,0x01,0x55,0x55},{0xaa,0xaa,0x59,0x55},{0xaa,0x55,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0xa5,0x54,0x40}},{{0x94,0xa0,0x00,0x28},{0xa5,0x55,0x55,0x51},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0xa1},{0xa5,0x59,0x55,0x55},{0xaa,0x5a,0x55,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0xa5,0x15,0x55},{0xa9,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x65,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x55,0x59},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0x95},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xaa,0xa5,0x65,0x55},{0xaa,0x55,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa8,0x65,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x55},{0x8a,0x99,0x59,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0xa5,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x92,0x25,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x95},{0x89,0x99,0x55,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x25,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0x50,0x80,0x15},{0xa5,0x95,0x65,0x95},{0x99,0x95,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x58,0x5a,0x80,0x15},{0xa9,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x98,0x5a,0x80,0x15},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x2a,0x95,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa6,0x54,0x14,0x00}},{{0x98,0x5a,0x48,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x25,0x95,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0x55,0x55,0x65},{0xa6,0x54,0x10,0x00}},{{0x9a,0x55,0x68,0x55},{0x6a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x25,0x55,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x25,0x55,0x55,0x66},{0x2a,0xaa,0xaa,0x6a},{0xa6,0x10,0x00,0x00}},{{0x9a,0x55,0x64,0x41},{0x5a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0xa6,0x10,0x08,0x00}},{{0x9a,0x55,0x94,0x81},{0x5a,0x6a,0x9a,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x46,0x0a,0x9a,0x81},{0xa6,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x0a,0xa9,0x41},{0xa5,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x15,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x44,0x85,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x0a,0x65,0x41},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x55,0x55,0x69},{0x55,0x55,0x55,0x69},{0x55,0x56,0x11,0x59},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x66},{0x65,0x44,0x42,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x51},{0x55,0xaa,0xaa,0x54},{0x45,0x55,0x55,0x56},{0x59,0x59,0x11,0x56},{0x55,0x55,0x14,0x52},{0x55,0x55,0x55,0x55},{0x55,0x51,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x61},{0x40,0x55,0x55,0x80},{0x6a,0xaa,0xaa,0xaa},{0x55,0x04,0x02,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x59,0x55,0x65,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x40,0x00,0x00,0x42},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x64,0x0a,0x9a,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x59},{0x65,0x55,0x55,0x55},{0x55,0x64,0x55,0x41},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x6a,0x2a,0x82,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x45},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x44},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x95,0x55,0x51,0x42},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x50,0x50,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_7 = { .phases = 40, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_7_data[0] }; -const uint8_t epd_wp_ed047tc2_5_8_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x80,0x08,0x82},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x08},{0x00,0x00,0x00,0x00},{0x02,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0x20,0x00,0x00,0x08},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x20},{0x80,0x00,0x00,0x00},{0xaa,0x08,0xaa,0x08},{0x00,0x00,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x20,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0xa0,0x00,0x00,0x0a},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x2a},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa8},{0x00,0x20,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x81},{0xa0,0x00,0x00,0x05},{0x20,0x00,0x00,0x01},{0x02,0x82,0x00,0xa9},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa4},{0x12,0x28,0xaa,0x00}},{{0xa8,0x00,0x0a,0x00},{0x88,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x82,0xa8,0x08,0x81},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x08},{0x00,0x02,0x0a,0x80},{0x88,0x00,0x02,0x81},{0xa0,0x00,0x00,0x25},{0x28,0x00,0x00,0x21},{0x22,0x82,0x00,0xa5},{0x80,0x00,0x00,0x21},{0xaa,0xaa,0xaa,0xa4},{0x19,0x2a,0xaa,0x80}},{{0xa8,0x00,0x0a,0x00},{0x8a,0xa8,0x8a,0x0a},{0x00,0x20,0x00,0x28},{0x80,0x00,0x00,0x00},{0x20,0x00,0x00,0x0a},{0x82,0xaa,0x08,0x81},{0x08,0x20,0x02,0x02},{0x08,0x00,0x00,0x08},{0x28,0x02,0x0a,0x80},{0x88,0x08,0x0a,0x81},{0xa0,0x00,0x08,0x25},{0x2a,0x00,0x0a,0x21},{0x22,0xa2,0x00,0x95},{0x80,0x02,0x00,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x19,0xaa,0xaa,0x80}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0x8a,0x0a},{0x02,0x20,0x00,0x28},{0x88,0x00,0x00,0x02},{0x20,0x00,0x00,0x09},{0xa2,0xaa,0xa8,0x85},{0x8a,0x28,0x0a,0x09},{0x88,0x00,0x00,0x08},{0x28,0x02,0x8a,0x80},{0x88,0x0a,0x0a,0x81},{0xa8,0x02,0x08,0x25},{0xaa,0xaa,0x0a,0x21},{0x2a,0xaa,0x2a,0x95},{0xa0,0x02,0x82,0x81},{0xaa,0xaa,0xaa,0x95},{0x19,0xaa,0xaa,0x80}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0xaa,0x09},{0x02,0x20,0x08,0x04},{0x88,0x00,0x00,0x21},{0x28,0x00,0x00,0x09},{0xaa,0xaa,0xa8,0x85},{0x8a,0xaa,0x0a,0x09},{0x88,0x08,0x00,0x04},{0xaa,0x82,0x8a,0x82},{0xaa,0xaa,0xaa,0x81},{0xa8,0x22,0xa8,0x15},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0x2a,0x95},{0xa0,0x22,0x82,0x91},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xaa,0x84}},{{0xa8,0x00,0x05,0x10},{0x8a,0xaa,0xaa,0x09},{0x22,0x20,0x28,0x14},{0x88,0x00,0x00,0x25},{0x28,0x00,0x00,0x05},{0xaa,0xaa,0xa8,0x45},{0xaa,0xaa,0xaa,0x05},{0x88,0x0a,0x00,0x85},{0xaa,0xa2,0x8a,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa2,0x2a,0x8a,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xa6,0x84}},{{0xa8,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x09},{0xaa,0x22,0xaa,0x15},{0x88,0x00,0x00,0x25},{0xa8,0x00,0x00,0x25},{0xaa,0xaa,0xa8,0x65},{0xaa,0xaa,0xaa,0x25},{0xa8,0x2a,0x80,0xa5},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa2,0xaa,0x8a,0x95},{0xa9,0xaa,0x66,0x55},{0x15,0x6a,0x56,0x44}},{{0x94,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x29},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x08,0x00,0x25},{0xaa,0xaa,0xa6,0x65},{0xaa,0xaa,0xaa,0x25},{0xaa,0x2a,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x45},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0x29,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xa9,0xa9,0x55,0x55},{0x25,0x6a,0x55,0x54}},{{0x94,0x00,0x0a,0x64},{0x8a,0xaa,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x0a,0x0a,0x15},{0xaa,0x6a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa9,0x69,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x99,0xa5,0x55,0x55},{0x21,0x15,0x55,0x54}},{{0x94,0x00,0x0a,0x64},{0xaa,0x9a,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x8a,0x00,0x00,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x5a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0x55},{0x9a,0xaa,0xa6,0x55},{0x9a,0xaa,0xa5,0x55},{0xa9,0x69,0xaa,0x55},{0xaa,0xa9,0x6a,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x54}},{{0x94,0x00,0x0a,0xa5},{0xaa,0x5a,0x65,0x15},{0xaa,0x22,0xaa,0x95},{0xaa,0xa0,0x08,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x55,0x56,0x55},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x9a,0xa9,0x56,0x55},{0x9a,0xa1,0x55,0x55},{0xa9,0x69,0x95,0x55},{0xaa,0xa9,0x69,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x54}},{{0x68,0x00,0x0a,0x95},{0xa6,0x55,0x55,0x15},{0xaa,0x12,0x8a,0x15},{0xaa,0xa0,0x28,0x15},{0xa8,0x2a,0x8a,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0xaa,0xa5,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0xa5,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0x91,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x9a,0xa9,0x65,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x54}},{{0x68,0x00,0x0a,0x55},{0xa6,0x55,0x9a,0x15},{0xaa,0x12,0x06,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x99,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x54}},{{0x68,0x00,0x05,0x55},{0xa5,0x55,0x9a,0x25},{0xa9,0x91,0x55,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x95},{0x59,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa5,0x6a,0x55},{0xaa,0xa9,0x65,0x55},{0xa4,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x54}},{{0x68,0x00,0x05,0x55},{0xa5,0x65,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xaa,0xaa,0xa8,0x95},{0x9a,0x25,0x65,0x95},{0x51,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xa6,0x85,0x65,0x55},{0x9a,0x29,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x54}},{{0x54,0x00,0x05,0x55},{0xa9,0xa5,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xa6,0xaa,0xaa,0x95},{0x96,0xa5,0x65,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x85,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x55,0x55,0x55},{0xaa,0x95,0x11,0x54}},{{0x94,0x00,0x05,0x55},{0x69,0xaa,0xaa,0x25},{0x95,0x99,0x55,0x55},{0xa6,0xaa,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x56},{0xa6,0x55,0x55,0x59},{0xaa,0x95,0x21,0x54}},{{0x94,0x00,0x85,0x51},{0x6a,0xaa,0xaa,0xa5},{0x95,0x99,0x55,0x55},{0x65,0x59,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x66},{0xaa,0x56,0x99,0x6a},{0xaa,0xaa,0xaa,0xa8}},{{0x94,0x22,0x85,0x51},{0x6a,0xaa,0x20,0x95},{0x55,0x59,0x55,0x55},{0x55,0x55,0x56,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x66,0x56,0x95,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x96,0x2a,0x65,0x01},{0xa2,0x8a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x96,0xa9,0x50,0x01},{0xa6,0x0a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x45,0x55,0x55,0x4a},{0x55,0x55,0x55,0x55},{0x66,0x96,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0x95,0x90,0x01},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x52},{0x65,0x54,0x01,0x2a},{0x65,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x56,0xa0,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x64},{0x66,0x6a,0xa9,0x50},{0x55,0x55,0x55,0x64},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x45,0x50,0x00,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x6a,0x60,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x56},{0x55,0x5a,0x95,0x5a},{0x55,0x15,0x55,0x20},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0xa9,0x50,0x05},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x59,0x65,0x6a,0xa6},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x41,0x50,0x15,0x6a},{0x45,0x54,0x55,0x91},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0x95,0x50,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x65,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x54,0x10,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x55,0x50,0x15},{0x55,0x55,0x55,0x55},{0x6a,0xa2,0xaa,0xa2},{0x52,0xa6,0x65,0x92},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xa2},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x84,0x50,0x05,0x0a},{0x40,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xa5,0x50,0x15,0x48},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x45},{0x00,0x00,0x00,0x00},{0x81,0x51,0x11,0x68},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x45,0x55,0x55,0x44},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_8 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_8_data[0] }; -const uint8_t epd_wp_ed047tc2_5_9_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x0a,0x82,0x02,0x00},{0x40,0x00,0x00,0x00},{0x00,0x80,0x02,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x0a,0x8a,0x82,0x00},{0x40,0x08,0x00,0x40},{0x00,0x80,0x22,0x08},{0x00,0x08,0x08,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x04,0x00,0x00},{0x11,0x40,0x20,0x00},{0x81,0x00,0x00,0x20},{0x28,0x08,0x00,0x82},{0x00,0x20,0x80,0x80},{0x00,0x00,0x02,0x80}},{{0x80,0x00,0x00,0x00},{0x6a,0x8a,0x8a,0x00},{0x90,0x08,0x01,0x40},{0x00,0x80,0x22,0x08},{0x00,0x28,0x88,0x0a},{0x80,0x08,0x00,0x00},{0x00,0x08,0x02,0x00},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x80,0x00},{0x14,0x14,0x00,0x00},{0x21,0x50,0x20,0x80},{0x81,0x18,0x00,0xa0},{0x29,0x0a,0x02,0x81},{0x2a,0xa2,0xaa,0xa0},{0x00,0x2a,0x02,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xa0,0x08,0x02,0x80},{0x80,0x88,0x22,0x08},{0x20,0xa8,0x89,0x0a},{0x80,0xa8,0x00,0x02},{0xaa,0x8a,0x0a,0x08},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x02},{0x08,0x08,0x80,0x00},{0x24,0x54,0x22,0x80},{0x25,0x52,0x2a,0xa0},{0x86,0xa8,0x20,0xa8},{0xaa,0x2a,0x82,0x81},{0x2a,0xaa,0xaa,0xa0},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xaa,0x8a,0x2a,0x80},{0x80,0x88,0x22,0x08},{0x22,0xaa,0x8a,0x0a},{0x82,0xa8,0x00,0x02},{0xaa,0xaa,0x0a,0x0a},{0x00,0x08,0x02,0x28},{0x00,0x00,0x00,0x02},{0x2a,0x8a,0x80,0x00},{0xa5,0xaa,0xa2,0xa0},{0x26,0x96,0xaa,0xa0},{0x8a,0xa8,0xa0,0xa8},{0xaa,0x2a,0x8a,0x81},{0x2a,0xaa,0xaa,0xa8},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x0a},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0x2a,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x00,0x02},{0x2a,0xaa,0x80,0x00},{0xa9,0xaa,0xa2,0xa0},{0x26,0xa6,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0x2a,0x8a,0x41},{0xaa,0xaa,0xaa,0xa8},{0x08,0xaa,0x12,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x29},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0xaa,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x08,0x80},{0x2a,0xaa,0x8a,0x22},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x12,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x02},{0xaa,0xaa,0xaa,0x09},{0x20,0x08,0x02,0x28},{0x00,0x02,0x0a,0xa0},{0x2a,0xaa,0x8a,0x2a},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x11,0x44}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x81,0x88,0xa2,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0x8a,0x02,0x28},{0x00,0x82,0xaa,0xa1},{0x2a,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0x91,0x44}},{{0x80,0x00,0x00,0x20},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0x80},{0x82,0x88,0xaa,0x24},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x82,0x04},{0x20,0xa2,0xaa,0xa1},{0x2a,0xaa,0xaa,0x29},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x55},{0x96,0xa5,0x65,0x55},{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0x91,0x44}},{{0x80,0x00,0x00,0x10},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x9a,0x14},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x21},{0xaa,0xaa,0xaa,0x85},{0x2a,0xaa,0x8a,0x15},{0x20,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0x25},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0xaa,0x55},{0x96,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x56},{0x2a,0x99,0x91,0x44}},{{0x80,0x00,0x00,0x94},{0xaa,0xa9,0x45,0x44},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x99,0x16},{0xaa,0xa6,0xa6,0x95},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa9,0xa5},{0xaa,0xaa,0xa9,0x95},{0x2a,0xaa,0xaa,0x69},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0x55,0x56},{0x1a,0x95,0x99,0x04}},{{0x80,0x00,0x00,0x64},{0xa9,0x65,0x45,0x48},{0xaa,0xaa,0xa9,0xa2},{0xa2,0x6a,0x99,0x15},{0xaa,0xa5,0x65,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa5,0xa5},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x59},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x99,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x99,0x55,0x55},{0x19,0x55,0x89,0x04}},{{0x40,0x00,0x00,0xa4},{0xa5,0x65,0x45,0x4a},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x6a,0x99,0x15},{0xa9,0x95,0x65,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa5,0x95,0xa5},{0xaa,0xa6,0xa9,0x95},{0xaa,0xaa,0xa6,0x55},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x59,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x99,0x55,0x55},{0x15,0x55,0x49,0x14}},{{0x40,0x00,0x00,0x54},{0xa5,0x65,0x45,0x88},{0xaa,0xaa,0xa9,0xa1},{0xaa,0x66,0x11,0x15},{0xa9,0x55,0x65,0x55},{0xaa,0x96,0xa9,0x95},{0xa5,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x15},{0xaa,0xaa,0x95,0x55},{0x26,0xa5,0x65,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x45,0x14}},{{0x40,0x00,0x00,0x55},{0xa5,0x55,0x46,0x89},{0xaa,0xa6,0xa5,0x61},{0xaa,0x66,0x51,0x15},{0x95,0x55,0x55,0x55},{0x28,0x56,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x55},{0xaa,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x14}},{{0xa0,0x00,0x00,0x55},{0x95,0x56,0x8a,0x99},{0xaa,0xaa,0x9a,0x51},{0xaa,0x66,0x55,0x95},{0x95,0x55,0x55,0x55},{0x29,0x55,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa5,0x45,0x55},{0xaa,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x14}},{{0xa0,0x00,0x00,0x55},{0x9a,0x9a,0x8a,0x65},{0xaa,0xa5,0x56,0x51},{0x6a,0x56,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x96},{0x95,0x55,0x55,0x55},{0x05,0x55,0x45,0x14}},{{0xa0,0x00,0x20,0x51},{0x5a,0xaa,0x8a,0x65},{0xa5,0x65,0x56,0x59},{0x69,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x85,0x55,0x45,0x10}},{{0x60,0x28,0xa0,0x51},{0x6a,0xaa,0x8a,0x65},{0x95,0x55,0x56,0x55},{0x59,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x84,0x55,0x44,0x10}},{{0x6a,0xaa,0xa8,0x11},{0x6a,0xaa,0x8a,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x45,0x44,0x10}},{{0x5a,0xaa,0x64,0x01},{0xa6,0x99,0x45,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x44,0x46,0x10}},{{0x5a,0x95,0x56,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x99,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x56,0x5a,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x95},{0x95,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x65,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x25,0x6a,0x99,0x01},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x65},{0x56,0x5a,0x56,0x56},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x65},{0x95,0x55,0x41,0x56},{0x95,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x5a,0x66,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0xaa,0x56,0x05},{0x55,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x95,0x61},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x45},{0x55,0x55,0x55,0x59},{0x55,0x55,0x54,0x55},{0x55,0x54,0x00,0x15},{0x91,0x55,0x15,0x42},{0x55,0x55,0x24,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0x95,0x56,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x65,0x49,0x91},{0x55,0x55,0x54,0x44},{0x55,0x55,0x55,0x49},{0x15,0x55,0x55,0x54},{0x55,0x51,0x54,0x0a},{0x55,0x04,0x00,0x2a},{0xaa,0xaa,0xaa,0xaa},{0x55,0x54,0x10,0x55},{0x65,0x56,0x9a,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xa2,0x1a,0x06,0x50},{0x68,0xa0,0xa8,0xaa},{0x55,0x45,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x04,0x00,0xaa},{0x55,0x55,0x65,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x51,0x05,0x01,0x02},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x6a,0xaa,0xa9,0xa4},{0x55,0x55,0x55,0x00},{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_9 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_9_data[0] }; -const uint8_t epd_wp_ed047tc2_5_10_data[44][16][4] = {{{0x00,0x00,0x00,0x00},{0x80,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x00},{0x00,0x80,0x00,0x00},{0x80,0x00,0x08,0x02},{0x00,0x80,0x00,0x08},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x02,0x00,0x00,0x00},{0xa2,0x88,0x20,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x80,0x20,0x00},{0x00,0x80,0x00,0x00},{0x00,0x82,0x00,0x00},{0xa8,0x00,0x08,0x82},{0x00,0x80,0x20,0x0a},{0x92,0x00,0x00,0x8a},{0x2a,0x20,0xa2,0xa8},{0x00,0x00,0x00,0x08}},{{0x02,0x00,0x00,0x00},{0xa2,0x8a,0x20,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x08,0x05,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x00,0x80,0x20,0x00},{0x02,0xa0,0xa0,0x00},{0x00,0x82,0x00,0x02},{0xaa,0x20,0x08,0x82},{0x84,0x80,0xa0,0x0a},{0xa2,0x84,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x08}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa0,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x15,0x42,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xa0,0x20,0x80},{0x02,0xaa,0xa8,0x00},{0x00,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x82},{0x9a,0x90,0xa8,0x0a},{0xa6,0xa8,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x00,0x80,0x28}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x1a,0x46,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xaa,0x28,0x80},{0x2a,0xaa,0xa8,0x00},{0x02,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0x08,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x8a,0x88,0x24}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x90},{0x02,0xa0,0x08,0x02},{0x2a,0x2a,0x86,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x80},{0x2a,0xaa,0xa8,0x20},{0x02,0x82,0x00,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0x8a,0x8a,0xa4}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x0a},{0x80,0x00,0x00,0x90},{0x02,0xaa,0x2a,0x02},{0x2a,0xaa,0x8a,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xa2,0xa2,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0xaa,0x4a,0x54}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0x90},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa0},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x16,0xaa,0x46,0x54}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa4},{0x15,0x9a,0x65,0x54}},{{0x82,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0x80,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0x15,0x95,0x65,0x54}},{{0x81,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0xa2,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x8a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x02,0x82,0x20},{0x00,0x0a,0x00,0x09},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0x15,0x55,0x55,0x54}},{{0x81,0x00,0x80,0xa8},{0xaa,0xaa,0x9a,0x2a},{0xa2,0xa2,0x02,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x82,0x82,0xa0},{0x00,0x8a,0x80,0x09},{0x2a,0xaa,0xaa,0x22},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0x21},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xa9,0x55},{0x15,0x55,0x55,0x54}},{{0x81,0x00,0x80,0xa8},{0xaa,0x66,0x9a,0x2a},{0xa2,0xa2,0x22,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0x2a,0xa2,0xa0,0x80},{0x02,0x8a,0x80,0x05},{0x2a,0xaa,0x8a,0x20},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xa0,0x61},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x81,0x00,0x80,0x94},{0xaa,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x82},{0x02,0x8a,0x82,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xa8,0xaa,0xa1},{0xaa,0xaa,0xa0,0x65},{0xaa,0xaa,0x20,0x85},{0xaa,0xaa,0xaa,0x65},{0xaa,0x95,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x41,0x00,0x40,0x94},{0x69,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xa2,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0x9a},{0xaa,0x28,0xaa,0xa9},{0xaa,0xaa,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x42,0x00,0x48,0xa4},{0x59,0x55,0x55,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xaa,0x25},{0x2a,0xaa,0xaa,0x9a},{0xa8,0x80,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x8a,0x29},{0x2a,0xaa,0x56,0x99},{0xaa,0x28,0xa8,0xa9},{0xaa,0x82,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x42,0x00,0x48,0x64},{0x59,0x59,0x65,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xa0,0x65},{0x2a,0xaa,0xa9,0x56},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0xa9,0x8a},{0xaa,0xaa,0xaa,0x05},{0xaa,0x2a,0x86,0x69},{0x2a,0x55,0x55,0x99},{0xaa,0x69,0x89,0xa9},{0x96,0x82,0x00,0x45},{0xaa,0x22,0x10,0x05},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x62,0x00,0x4a,0x54},{0x59,0x9a,0xa9,0x95},{0xaa,0xaa,0x22,0x65},{0x82,0xaa,0xa5,0x45},{0x26,0xaa,0xa9,0x55},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0x29,0x89},{0xaa,0xaa,0xaa,0x85},{0xaa,0x55,0x54,0x69},{0x21,0x55,0x55,0x55},{0xaa,0x69,0x45,0xa9},{0x95,0x55,0x55,0x55},{0xaa,0x22,0x10,0x05},{0x89,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0xa2,0x00,0x8a,0x54},{0x66,0xaa,0xaa,0x95},{0xaa,0xaa,0x22,0x55},{0x82,0x95,0x55,0x55},{0x16,0xa5,0x55,0x55},{0xa2,0xa0,0x20,0x09},{0xaa,0xa9,0x29,0x09},{0xaa,0xaa,0xaa,0x85},{0xa9,0x55,0x55,0x59},{0x11,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa1,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x54}},{{0xa2,0x00,0x86,0x54},{0xa6,0xaa,0xaa,0xa5},{0xaa,0xaa,0x22,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x5a,0xa9,0x55},{0xa2,0xaa,0x28,0x01},{0xaa,0xa9,0x29,0x55},{0xaa,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x55,0x55,0x54}},{{0xa1,0x00,0x85,0x54},{0xaa,0xa2,0xaa,0x65},{0xaa,0xaa,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x15,0xa5,0x55,0x55},{0xa2,0xaa,0xa8,0x01},{0xaa,0xa9,0x69,0x55},{0xaa,0xa5,0x69,0xa5},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x45,0x55,0x54}},{{0xa1,0x00,0x85,0x54},{0x9a,0x95,0x55,0x55},{0xaa,0x99,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa2,0xa9,0x55,0x55},{0xaa,0xa5,0x69,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x85,0x54}},{{0x61,0x00,0x45,0x54},{0x95,0x55,0x55,0x55},{0xaa,0x99,0x61,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa5,0x55,0x55,0x55},{0xaa,0x65,0x55,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x89,0x94}},{{0x61,0x00,0x45,0x50},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0xaa,0x8a,0xa8}},{{0x61,0x00,0x45,0x10},{0x15,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xa8}},{{0x51,0x20,0x41,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x16,0x6a,0x94,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x50,0x2a,0x40,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x2a,0x00,0x01},{0x55,0x55,0x55,0x55},{0x51,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0xa8}},{{0x28,0xa9,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x28,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x24,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x99},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x99},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x9a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x14,0x6a,0x20,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x65},{0x55,0x14,0x54,0x56},{0x41,0x55,0x55,0x56},{0x55,0x55,0x55,0x5a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x14,0x6a,0x10,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x11},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x15},{0x6a,0xaa,0xaa,0x99},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x96,0x10,0x05},{0x55,0x55,0x55,0x19},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x21},{0xa9,0x55,0x56,0xa5},{0x55,0x55,0x55,0x55},{0x66,0xa9,0x69,0x54},{0x55,0x50,0x14,0x1a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x95,0x10,0x45},{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x65},{0x6a,0x6a,0x9a,0x11},{0x95,0x55,0x55,0x55},{0x69,0x55,0x55,0x59},{0x51,0x56,0x16,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x55,0x10,0x55},{0x00,0x00,0x00,0x00},{0x55,0x65,0x56,0x54},{0x55,0x15,0x45,0x02},{0x80,0x00,0x00,0x0a},{0x55,0x55,0x55,0x16},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x15,0x55},{0x00,0x00,0x00,0x00},{0x59,0x55,0x55,0x14},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x65,0x45,0x54,0x0a},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_10 = { .phases = 44, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_10_data[0] }; -const uint8_t epd_wp_ed047tc2_5_11_data[57][16][4] = {{{0x20,0x8a,0x80,0x00},{0x15,0x55,0x5a,0xa4},{0x44,0x10,0x0a,0x41},{0x40,0x00,0x09,0x54},{0x10,0x50,0x00,0x00},{0x00,0x00,0x04,0x28},{0x40,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x40,0x00},{0x00,0x00,0x00,0x00},{0x00,0x40,0x00,0x68},{0x00,0x00,0x40,0x00},{0x00,0x00,0x0a,0x54},{0x00,0x0a,0x80,0x00},{0x10,0x09,0x60,0x00},{0x00,0x00,0x00,0x50}},{{0xaa,0xaa,0x8a,0x00},{0x0a,0x60,0x0a,0xa8},{0x54,0x54,0x8a,0x41},{0x41,0x02,0x09,0x54},{0x15,0x50,0x06,0x24},{0x00,0x08,0xa4,0x28},{0x44,0x00,0x09,0xa8},{0x05,0x00,0x2a,0xa8},{0x01,0x10,0x46,0xa8},{0x04,0x00,0x00,0xa8},{0x00,0x40,0x00,0x54},{0x04,0x00,0x44,0xa8},{0x00,0x00,0x8a,0x54},{0x00,0x0a,0x8a,0x58},{0x50,0x19,0x65,0x54},{0x00,0x00,0x00,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x6a,0xaa,0xa8},{0x55,0x94,0x89,0x55},{0x41,0x02,0x09,0x54},{0x15,0x50,0x66,0x24},{0x40,0x04,0xa4,0x68},{0x44,0x0a,0x09,0x54},{0x05,0x08,0x55,0x54},{0x11,0x14,0x56,0x54},{0x04,0x40,0x00,0x58},{0x01,0x40,0x0a,0x54},{0x04,0x0a,0x44,0xa8},{0x01,0x00,0x8a,0x54},{0x00,0x0a,0x6a,0x54},{0x50,0x19,0x65,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x2a,0xaa,0xa8},{0x96,0x95,0x55,0x55},{0x51,0x0a,0x05,0x54},{0x15,0x50,0x66,0xa4},{0x40,0x04,0x54,0x54},{0x44,0x05,0x09,0x54},{0x05,0x18,0x55,0x54},{0x51,0x14,0x56,0x54},{0x04,0x40,0x02,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x58},{0x01,0x0a,0x85,0x54},{0x01,0x05,0x65,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x96,0xa5,0x55,0x55},{0x51,0x09,0x05,0x55},{0x15,0x50,0x65,0x94},{0x44,0x14,0x54,0x54},{0x54,0x15,0x95,0x54},{0x05,0x56,0x55,0x54},{0x51,0x14,0x55,0x54},{0x14,0x40,0x82,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x54},{0x01,0x0a,0x45,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x49,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x14,0x55,0x55},{0x14,0x40,0x8a,0x54},{0x01,0x40,0x85,0x54},{0x04,0x15,0x44,0x54},{0x01,0x0a,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x55,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0xa9,0x54},{0x01,0x40,0x45,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0x69,0x55},{0x01,0x40,0x65,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x55,0x54},{0x01,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x52,0x55,0x54},{0x54,0x14,0x56,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x65,0x55},{0x01,0x50,0x65,0x55},{0x04,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x92,0x55,0x55},{0x55,0x14,0x56,0x54},{0x54,0x55,0x55,0x55},{0x45,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x91,0x55,0x15,0x55},{0x16,0x92,0x55,0x55},{0x55,0x14,0x56,0x55},{0x54,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0x92,0x55,0x95,0x55},{0x6a,0x91,0x55,0x55},{0x55,0x54,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x05,0x15,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0x91,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x4a,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x4a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0xa1,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa9,0x15,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0xa5,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x95,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0x99,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0x56,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x55,0x55,0x55},{0x15,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x05,0x55,0x55},{0xa9,0x66,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x55},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0xa9,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x15,0x45,0x55,0x55},{0x11,0x55,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x15,0x55,0x55},{0xa9,0x66,0x95,0x55},{0x00,0x10,0x55,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x96},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x55,0x55,0x55},{0x5a,0x95,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x19,0x45,0x55,0x55},{0x11,0x95,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x66,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x9a,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x96},{0xaa,0xa6,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x5a,0xa5,0x55,0x55},{0xaa,0x65,0x55,0x55},{0x29,0x85,0x55,0x55},{0x12,0x95,0x55,0x55},{0x59,0x55,0x56,0x55},{0x56,0x15,0x55,0x55},{0xa6,0x15,0x55,0x55},{0xaa,0x6a,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x95,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x9a,0xa5,0x55,0x55},{0xaa,0x69,0x95,0x55},{0x2a,0x85,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x55,0x95,0x55},{0x56,0x15,0x55,0x55},{0xaa,0x1a,0x95,0x55},{0xaa,0x6a,0xaa,0xa9},{0x00,0x15,0x55,0x54}},{{0x55,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0xa9},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0xa9,0x55},{0xa9,0xaa,0x56,0x55},{0xaa,0xa5,0x95,0x55},{0xaa,0x69,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x1a,0xaa,0xa5},{0xaa,0xaa,0xaa,0xa9},{0x20,0x95,0x55,0x54}},{{0x55,0x55,0x8a,0x00},{0xaa,0xaa,0xa5,0x5a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0x99,0x59},{0xaa,0xa8,0xa9,0x55},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0x6a,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0xa6,0x15,0x55,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x5a,0x8a,0x00},{0xaa,0xaa,0x55,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0x9a,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x6a,0x8a,0x00},{0xaa,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xa9,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0xa5,0x55,0x95},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0xaa,0x8a,0x00},{0xa9,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x95,0x55,0x55},{0x66,0xa5,0x55,0xa9},{0xaa,0xaa,0x99,0x55},{0xaa,0x2a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x12,0x45,0x55,0x54}},{{0x6a,0xaa,0x8a,0x00},{0xa5,0x55,0xa5,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0x95,0x55,0xa5},{0xa6,0xa5,0x9a,0xa9},{0xaa,0xaa,0x99,0xa5},{0xaa,0x2a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x41,0x55,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x95,0x6a,0xa5,0x56},{0xaa,0x69,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0x96,0xa9},{0xa6,0xa5,0xaa,0xaa},{0xaa,0xaa,0x99,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x85,0x00},{0x55,0x6a,0xa5,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xa9,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0xaa,0xaa},{0xaa,0xa5,0xaa,0xaa},{0xaa,0xaa,0xa9,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x45,0x00},{0x5a,0x6a,0x55,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x99,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x40,0x02,0xa0}},{{0xaa,0xa5,0x45,0x00},{0x6a,0x55,0x55,0x56},{0x69,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x40,0x02,0xa8}},{{0xaa,0x55,0x45,0x00},{0x6a,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0xa5,0x55,0x45,0x00},{0x66,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x55,0x95,0x55,0x55},{0x55,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x5a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x99,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x55,0x69},{0x69,0x6a,0xaa,0xaa},{0xaa,0x5a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0xa9,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x5a,0xa9,0xaa},{0xa5,0x6a,0xaa,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x0a,0xa8}},{{0x55,0x55,0x40,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0xa9,0xaa},{0x95,0x6a,0x66,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa8}},{{0x55,0x50,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x99,0xaa},{0x55,0x46,0x66,0xaa},{0xa8,0x6a,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa8}},{{0x50,0x00,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x95,0x56},{0x55,0x45,0x55,0xa6},{0x65,0x96,0x96,0xaa},{0x26,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x08,0x28,0xaa,0xa8}},{{0x00,0x00,0x00,0x60},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x55,0xa6},{0x55,0x96,0x66,0xaa},{0x2a,0x4a,0xaa,0xaa},{0xaa,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x88,0x2a,0xaa,0xa8}},{{0x00,0x00,0x20,0x50},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x66,0x6a},{0x12,0x86,0xaa,0xaa},{0x85,0x4a,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0xa8,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x61,0x09,0x55,0x55},{0x45,0x55,0x55,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x98,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x99,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x56,0xaa},{0x94,0x6a,0xaa,0xaa},{0x56,0x65,0x55,0x55},{0xa6,0x55,0x66,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x25,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x95,0x55,0x55},{0xa9,0x8a,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x05,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xa4,0x6a,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x01,0x50,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; -const EpdWaveformPhases epd_wp_ed047tc2_5_11 = { .phases = 57, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ed047tc2_5_11_data[0] }; -const EpdWaveformPhases* epd_wm_ed047tc2_5_ranges[7] = { &epd_wp_ed047tc2_5_5,&epd_wp_ed047tc2_5_6,&epd_wp_ed047tc2_5_7,&epd_wp_ed047tc2_5_8,&epd_wp_ed047tc2_5_9,&epd_wp_ed047tc2_5_10,&epd_wp_ed047tc2_5_11 }; +const uint8_t epd_wp_ED047TC2_5_5_data[46][16][4] = {{{0x00,0x00,0x00,0x00},{0x20,0x88,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x80,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x08,0x00},{0x00,0x02,0x00,0x80},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa2,0x88,0x20,0x88},{0x22,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x00,0x44,0x08,0x00},{0xa0,0x02,0x20,0xa8},{0x08,0x62,0x88,0x80},{0x00,0x00,0x00,0x08},{0x08,0x22,0x88,0x80},{0x00,0x80,0x00,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x04,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x24,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x80,0x82,0xa2,0x08},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x02},{0x84,0x84,0x28,0x80},{0xa0,0x02,0x20,0xaa},{0xa8,0xaa,0x8a,0x80},{0x22,0x84,0x00,0x28},{0x2a,0xaa,0xaa,0xa0},{0x00,0x80,0x28,0x00}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x08,0x00,0x80,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x00,0x20,0x02},{0x00,0x00,0x00,0x02},{0x84,0x88,0x2a,0xa2},{0xa0,0xaa,0xa8,0xa8},{0xa8,0xaa,0x8a,0x80},{0x2a,0xaa,0x08,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x08}},{{0xaa,0xaa,0xa8,0xa8},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0x24,0x80,0x00},{0x00,0x00,0x00,0x00},{0x29,0x80,0x00,0x00},{0x00,0x40,0x20,0x00},{0x80,0xa2,0xa2,0x88},{0x00,0x02,0xa0,0x00},{0x02,0x00,0x00,0x81},{0x88,0xa8,0xaa,0xa9},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0x8a,0x81},{0x2a,0xaa,0x2a,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x80,0x28,0x04}},{{0xaa,0xaa,0xa8,0xa4},{0x2a,0xaa,0xaa,0x02},{0x00,0x08,0x00,0x00},{0x28,0xa8,0x80,0x00},{0x00,0x20,0x00,0x00},{0x2a,0x84,0xa0,0x08},{0x2a,0x68,0x20,0x80},{0x80,0xa2,0xa2,0xa8},{0x80,0x02,0xa0,0x01},{0x02,0x80,0x00,0xa9},{0x9a,0xa8,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x89},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xa8},{0x22,0x8a,0x28,0x04}},{{0xaa,0xaa,0xa8,0x64},{0x2a,0xaa,0xaa,0x01},{0x00,0x88,0x02,0x00},{0x29,0xa8,0x80,0x00},{0x00,0x28,0x08,0x02},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xa2,0xa2,0xa9},{0x80,0x02,0xa0,0x01},{0x02,0xa0,0x00,0xa9},{0x9a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x2a,0x8a,0xa8,0x84}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x00,0x8a,0x02,0x08},{0x2a,0xa8,0x88,0x00},{0x00,0x28,0x8a,0x01},{0x2a,0x88,0xa8,0x08},{0x2a,0xaa,0xa0,0xa0},{0xaa,0xaa,0xaa,0xa9},{0x80,0x02,0xa0,0x01},{0x0a,0xaa,0x80,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x8a,0xaa,0x54}},{{0xaa,0xaa,0xa8,0x54},{0x2a,0xaa,0xaa,0x01},{0x20,0x8a,0x0a,0x08},{0x2a,0xa8,0xaa,0x00},{0x00,0x2a,0x8a,0x01},{0x2a,0xaa,0xa8,0x08},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x80,0x02,0xa0,0x81},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x59},{0x69,0x8a,0xaa,0x54}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa0,0x8a,0x0a,0x0a},{0xaa,0xaa,0xaa,0x02},{0x08,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x09},{0x2a,0xaa,0xa0,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x82,0x82,0xa0,0xa1},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0x59,0x8a,0xaa,0x54}},{{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0xaa,0x01},{0xa2,0x8a,0x2a,0x09},{0xaa,0xaa,0xaa,0x09},{0x28,0x2a,0x8a,0x01},{0x2a,0xaa,0xaa,0x89},{0x2a,0xaa,0xa8,0xa1},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0xa0,0xa9},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x54}},{{0xaa,0xaa,0xaa,0x58},{0x2a,0xaa,0xa5,0x05},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x01},{0x2a,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x01},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0xa9},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x59,0xaa,0xaa,0x54}},{{0xaa,0xaa,0x96,0xa8},{0xaa,0xaa,0x55,0x09},{0xaa,0x8a,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0x21},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x98,0xa9},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa4,0x55},{0xaa,0xa8,0x8a,0x55},{0xaa,0xaa,0xa5,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x54,0xaa,0xaa,0x54}},{{0xaa,0xa5,0x96,0xa8},{0xaa,0xa5,0x55,0xa9},{0xaa,0xaa,0xaa,0x09},{0xaa,0xaa,0xaa,0x09},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xa8,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x90,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0xaa,0x55},{0xa6,0x99,0x55,0x55},{0x94,0xaa,0xa6,0x50}},{{0xaa,0xa5,0x56,0xa8},{0xaa,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xa9,0x15,0x55},{0x92,0x95,0x65,0x55},{0xaa,0xaa,0xa5,0x55},{0x95,0x95,0x55,0x55},{0x94,0xaa,0x96,0x00}},{{0xa9,0x55,0x56,0xa8},{0xa9,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0x05},{0xaa,0xaa,0xaa,0xa5},{0x2a,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x98,0x51},{0xaa,0xa9,0x59,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x9a,0x85,0x55,0x55},{0x94,0x95,0x55,0x55},{0x99,0xa9,0x95,0x55},{0x95,0x55,0x55,0x55},{0x94,0xaa,0x96,0x00}},{{0x95,0x55,0x56,0xa8},{0xa5,0x55,0x5a,0xa5},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0xa5},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0x96,0x65},{0xaa,0xaa,0x1a,0x59},{0xaa,0x59,0x51,0x55},{0xaa,0xa9,0x5a,0x55},{0xaa,0xaa,0xaa,0x55},{0xa8,0x55,0x55,0x55},{0x98,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x94,0x6a,0x96,0x00}},{{0x95,0x55,0x55,0x94},{0x95,0x55,0xaa,0x95},{0xaa,0xa6,0xaa,0x05},{0xaa,0xaa,0x6a,0x95},{0x2a,0xaa,0xa5,0x55},{0x9a,0x6a,0x55,0x55},{0xaa,0x85,0x5a,0x55},{0xaa,0x59,0x55,0x55},{0xaa,0xa9,0x5a,0x55},{0xa8,0xaa,0x00,0x55},{0xa8,0x55,0x55,0x55},{0x91,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x90,0x69,0x95,0x00}},{{0x55,0x55,0x55,0x54},{0x96,0x5a,0xaa,0x15},{0xaa,0xa6,0xa9,0x05},{0xaa,0x9a,0x65,0x55},{0x2a,0x96,0x65,0x55},{0x96,0x65,0x55,0x55},{0xa1,0x95,0x56,0x55},{0x28,0x55,0x55,0x55},{0xaa,0xa9,0x52,0x55},{0xa9,0x01,0x05,0x55},{0x25,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x00}},{{0x55,0x55,0x69,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa6,0xa5,0x85},{0x9a,0x56,0x55,0x55},{0xaa,0x95,0x65,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0xa1,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x00}},{{0x55,0x5a,0xa9,0x55},{0x9a,0xaa,0xaa,0x55},{0xaa,0xa5,0xa5,0x85},{0x92,0x55,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x15,0x56,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa0,0x65,0x55,0x00}},{{0x56,0xaa,0xa9,0x55},{0x99,0xaa,0xa1,0x55},{0xaa,0x65,0x95,0x45},{0x95,0x55,0x55,0x55},{0xa6,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x54,0x55},{0x55,0x55,0x55,0x55},{0x05,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x00}},{{0x6a,0xaa,0xaa,0x55},{0x95,0xaa,0x15,0x55},{0x9a,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa0,0x55,0x55,0x00}},{{0xaa,0xaa,0xaa,0x55},{0x95,0xa5,0x55,0x55},{0x99,0x65,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa8,0x55,0x55,0x00}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x15,0x65,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x55,0x00}},{{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0x55,0x41,0x00}},{{0xaa,0xaa,0x56,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x56},{0x55,0x55,0x55,0x55},{0x69,0x55,0x55,0x55},{0xaa,0x55,0x41,0x00}},{{0xa9,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x55,0x55,0x96},{0x65,0x55,0x55,0x56},{0x6a,0x65,0x55,0xa6},{0xaa,0x94,0x49,0x00}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x6a,0x2a,0x8a,0xaa},{0x6a,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x51,0x56},{0x65,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x40,0xaa},{0x55,0x54,0x45,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x56,0xa6,0x50},{0x55,0x56,0x95,0x56},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x95,0x55,0x55},{0x55,0x55,0x95,0x04},{0x45,0x05,0x55,0xaa},{0x55,0x55,0x55,0xaa},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x45,0x48,0x58,0x50},{0x55,0x55,0x41,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x54,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x54},{0x41,0x04,0x44,0x12},{0x6a,0x2a,0x21,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x69},{0x55,0x55,0x55,0x54},{0x45,0x05,0x15,0x16},{0x41,0x41,0x15,0x02},{0x6a,0x00,0xa0,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x66},{0x55,0x59,0x59,0xa6},{0x60,0x00,0x00,0x0a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x6a,0x59,0x51,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x50,0x55,0x55,0x52},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x6a,0x55,0x55,0x02},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xa5,0x96,0xa6,0x5a},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_5 = { .phases = 46, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_5_data[0] }; +const uint8_t epd_wp_ED047TC2_5_6_data[43][16][4] = {{{0x02,0xaa,0x00,0x00},{0x20,0x22,0xa8,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x00,0x22,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xa8,0x20},{0x00,0x00,0x00,0x00},{0x20,0x02,0x08,0x80},{0x00,0x80,0x00,0x00},{0x20,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x2a,0xaa,0x00,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x28},{0x00,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x20,0x22,0xaa,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x20},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa0,0x20,0x2a},{0x28,0x22,0xa8,0xa8},{0x28,0x00,0x00,0x00}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0x22,0x02,0x08,0x80},{0x00,0xa8,0x22,0x2a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x80}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0x80},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x22,0x2a,0xaa,0xa0},{0x00,0x00,0x00,0x00},{0xa2,0x82,0x08,0x80},{0x08,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x40}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x20},{0x20,0x00,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x2a,0x2a,0xaa,0xa8},{0x00,0x00,0x00,0x00},{0xaa,0x82,0x88,0xa0},{0x8a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0x94},{0x24,0x00,0x28,0x40}},{{0xaa,0xaa,0x20,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x20,0x88,0x00,0x2a},{0x20,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0x20,0x80,0x00,0x02},{0xaa,0x2a,0xaa,0x80},{0x80,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0x8a,0x8a,0xa0},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x24,0x00,0x28,0x40}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x80},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x22,0x80,0x00,0x00},{0x00,0x00,0x00,0x28},{0xa0,0xa0,0xa8,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0x2a,0xaa,0xa8},{0x08,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa5},{0xa6,0xaa,0xaa,0x95},{0x24,0x00,0x26,0x40}},{{0xaa,0xaa,0xa0,0x00},{0x20,0xaa,0xaa,0x42},{0x80,0x00,0x00,0x22},{0x20,0x88,0x00,0x2a},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xa2,0xa8,0xaa,0x02},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xa8},{0x08,0x00,0x00,0x20},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa6,0x55},{0x56,0x02,0x95,0x54}},{{0xaa,0xaa,0xa0,0x04},{0x20,0xaa,0xa5,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x26},{0x2a,0x80,0x00,0x02},{0x20,0x80,0x20,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x82},{0x80,0x00,0x00,0x01},{0x20,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0x98},{0x88,0x80,0x00,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xa5,0xa9,0x65,0x55},{0x56,0x0a,0x95,0x54}},{{0xaa,0xa9,0xa0,0x24},{0x20,0xa9,0x55,0x4a},{0x80,0x00,0x00,0x29},{0xa0,0x88,0x00,0x25},{0x2a,0x80,0x00,0x02},{0x20,0xa0,0x28,0x28},{0xaa,0xaa,0xaa,0x01},{0xaa,0x2a,0xaa,0x80},{0xa0,0x00,0x00,0x01},{0x20,0xa2,0xa8,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xa2,0xa8,0xaa},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xa5,0x95,0x55,0x55},{0x56,0x0a,0x95,0x54}},{{0xaa,0x95,0xa8,0xa4},{0x20,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x29},{0xa2,0x88,0x00,0x15},{0x2a,0x80,0x00,0x01},{0x20,0xa8,0x28,0x14},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x81},{0xa0,0x00,0x00,0x01},{0xa2,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x94},{0x88,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x56,0x89,0x55,0x54}},{{0xaa,0x95,0x98,0x94},{0xa0,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x25},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0x20,0xaa,0xa8,0x94},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0xa1},{0xa0,0x22,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x94},{0xa8,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0xa9,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x14}},{{0xa9,0x55,0x9a,0x98},{0xa8,0xa9,0x55,0x45},{0xa0,0x00,0x00,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x00,0x21},{0xa2,0xaa,0xaa,0x94},{0xaa,0xaa,0xaa,0x89},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x2a,0xa0,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x56},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0xa6,0x55},{0xaa,0xaa,0x95,0x55},{0x95,0x55,0x55,0x55},{0x55,0xa5,0x55,0x14}},{{0xa5,0x55,0x5a,0xa8},{0xa8,0x95,0x55,0x45},{0xa0,0x82,0x20,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x85,0x69},{0xaa,0x2a,0xa8,0x29},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xa9,0xa9,0xa5,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0xa5,0x41,0x14}},{{0x95,0x55,0x6a,0x68},{0xa8,0x55,0x55,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0x88,0x00,0x15},{0xaa,0x80,0x20,0x21},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xa9,0x55,0x69},{0xaa,0x2a,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0x99,0xa9,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x65,0x40,0x14}},{{0x95,0x55,0x66,0x58},{0xa8,0x55,0x5a,0x85},{0xa8,0xaa,0xa0,0x15},{0xaa,0xa8,0xa0,0x15},{0xaa,0x62,0xa8,0x19},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x95},{0xaa,0x95,0x55,0x55},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa9,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x65,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x91,0x55,0x40,0x14}},{{0x95,0x56,0xa5,0x94},{0xa8,0x56,0xaa,0x85},{0xa8,0xaa,0xa0,0x95},{0xaa,0xa8,0xa0,0x15},{0xaa,0x6a,0xaa,0x15},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x55,0x55},{0x89,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0x99,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x50,0x00,0x14}},{{0x55,0x6a,0x89,0x94},{0x98,0x6a,0xaa,0x85},{0xaa,0xaa,0xa0,0x95},{0xaa,0xa6,0xa0,0x15},{0x8a,0x6a,0xaa,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa9,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xaa,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x89,0x50,0x00,0x14}},{{0x56,0xaa,0x9a,0x14},{0x98,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xa2,0x15},{0x99,0x6a,0xaa,0x95},{0xaa,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xa6,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xa9,0x10,0x00,0x04}},{{0x5a,0xaa,0x12,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0xaa,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0xa9,0x10,0x00,0x04}},{{0x6a,0xaa,0x55,0x54},{0xaa,0xaa,0xaa,0x81},{0xaa,0xaa,0xaa,0x95},{0x9a,0x66,0xaa,0x15},{0x95,0x6a,0xaa,0x95},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x8a,0x55,0x55,0x55},{0xaa,0x00,0x00,0x00}},{{0x6a,0xaa,0x55,0x55},{0x9a,0x96,0xaa,0x41},{0x6a,0xaa,0xaa,0x55},{0x99,0x66,0xaa,0x95},{0x95,0x6a,0x95,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x59,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0x99,0x65},{0xaa,0x00,0x00,0x00}},{{0xaa,0xaa,0x55,0x55},{0x96,0x56,0xa5,0x51},{0x6a,0x69,0x8a,0x55},{0x95,0x66,0xaa,0x95},{0x95,0x69,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xaa,0xa8,0x55,0x55},{0x96,0x55,0x55,0x55},{0x6a,0x65,0x58,0x55},{0x95,0x66,0x59,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xa9,0x45,0x55,0x45},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x00,0x00,0x00}},{{0xa5,0x55,0x55,0x41},{0x96,0x55,0x55,0x55},{0x56,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x5a,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x95,0x55,0x55,0x41},{0x56,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x45,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x56,0x59,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x2a},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x51},{0x59,0x55,0x55,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x51},{0x55,0x55,0x55,0x56},{0x55,0x15,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x00,0x15},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0x6a,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x10,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x42},{0x6a,0x95,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x59},{0x15,0x55,0x55,0x82},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x55},{0x99,0x50,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x51,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0xaa,0x99,0x55,0x6a},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_6 = { .phases = 43, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_6_data[0] }; +const uint8_t epd_wp_ED047TC2_5_7_data[40][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x04,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x0a,0x08,0x80},{0x00,0x00,0x00,0x08},{0x00,0x80,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa0,0x80,0x00,0x00},{0x08,0x80,0x20,0x00},{0x00,0x12,0x22,0x00},{0x00,0x00,0x00,0x00},{0x1a,0x20,0x00,0x00},{0x01,0x80,0x00,0x00},{0x88,0x00,0x00,0x00},{0x00,0x10,0x80,0x00},{0x20,0x0a,0x88,0x82},{0x80,0x00,0x05,0x08},{0x0a,0xa0,0x00,0x20},{0x20,0x00,0x00,0x20},{0x00,0x80,0x00,0x08},{0x80,0x28,0x08,0x80},{0x2a,0x80,0xa0,0x28},{0x20,0x00,0x80,0x04}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x11,0x22,0xa2,0x00},{0x04,0x04,0x00,0x00},{0x2a,0xa0,0x20,0x00},{0x22,0xa0,0x00,0x00},{0x98,0x12,0x00,0x0a},{0x18,0xa0,0x80,0x00},{0x28,0x0a,0x8a,0x82},{0x88,0x88,0x09,0x28},{0x0a,0xa2,0x20,0x20},{0x20,0x00,0x02,0xa0},{0x00,0xa4,0x00,0x08},{0xa8,0xa8,0xa8,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x20,0x02,0x88,0x84}},{{0xa8,0xa0,0x00,0x00},{0x08,0x80,0x20,0x00},{0x22,0x22,0xa2,0x28},{0x04,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x20,0x0a},{0x98,0x56,0x02,0x8a},{0xa8,0xa4,0x80,0x00},{0x28,0x0a,0xaa,0x82},{0x88,0xaa,0x0a,0x28},{0x2a,0xaa,0xa8,0x22},{0x20,0x40,0xa2,0xa2},{0x12,0xa8,0xa0,0x28},{0xa8,0xaa,0xaa,0xa0},{0xaa,0xaa,0xaa,0xa8},{0x28,0x82,0xa8,0x84}},{{0xa8,0xa0,0x00,0x00},{0x08,0xa0,0x20,0x00},{0x26,0x22,0xa2,0x28},{0x05,0x08,0x00,0x00},{0x2a,0xa0,0x28,0x00},{0x2a,0xa0,0x28,0x0a},{0x99,0xaa,0x82,0x8a},{0xaa,0xa8,0xa2,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0x28},{0x2a,0xaa,0xa8,0xa2},{0x20,0xa6,0xa2,0xa2},{0x92,0xaa,0xa8,0x28},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x98},{0x58,0x8a,0xa8,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xa0,0x20,0x00},{0x2a,0x66,0xa2,0x28},{0x09,0x0a,0x00,0x00},{0x2a,0xa2,0x28,0x00},{0x2a,0xa0,0xa8,0x0a},{0xa9,0xaa,0x82,0x8a},{0xaa,0xaa,0xaa,0x00},{0x28,0x8a,0xaa,0x82},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa2},{0x25,0xa6,0xaa,0xa2},{0xaa,0xaa,0xa8,0x2a},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0x58,0x8a,0xaa,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0x20,0x80},{0x2a,0xa6,0xa2,0x28},{0x19,0x0a,0x00,0x00},{0x2a,0xa2,0xa8,0x00},{0x2a,0xaa,0xa8,0x89},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x02},{0x2a,0x8a,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x81},{0x2a,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa0,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0x2a,0xaa,0xa8,0x04},{0x2a,0xaa,0xa8,0xa9},{0xaa,0xaa,0x8a,0x89},{0xaa,0xaa,0xaa,0x82},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa4},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0x58,0xaa,0xa9,0x94}},{{0xa8,0xa0,0x00,0x00},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xa2,0x28},{0x9a,0x2a,0x00,0x00},{0xaa,0xaa,0xa8,0x88},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x96},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x95},{0x5a,0xaa,0xa9,0x54}},{{0xa8,0xa0,0x00,0x14},{0x0a,0xaa,0xa8,0x82},{0xaa,0xaa,0xaa,0x28},{0xaa,0x2a,0x00,0x00},{0xaa,0xaa,0xaa,0x99},{0x2a,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0x55,0x55},{0x5a,0xaa,0x69,0x54}},{{0xa8,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x16},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa5,0x55},{0xa9,0xa5,0x55,0x55},{0x9a,0xaa,0x65,0x50}},{{0x98,0x50,0x00,0x14},{0x8a,0xaa,0x9a,0x81},{0xaa,0xaa,0xaa,0x15},{0xaa,0x2a,0x08,0x00},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x85},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x64,0x50}},{{0x98,0x50,0x00,0x28},{0x8a,0x6a,0x9a,0x41},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x18,0x80},{0xaa,0xaa,0x96,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xa9,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xaa,0xa5,0x59},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x80,0x55},{0xaa,0xaa,0xa9,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0xa9,0x54,0x50}},{{0x94,0x50,0x00,0x28},{0xa6,0x55,0x55,0x61},{0xaa,0xaa,0xa9,0x15},{0xaa,0xaa,0x28,0x80},{0xa9,0x9a,0x96,0x95},{0xaa,0xaa,0x96,0x55},{0xaa,0xa9,0x69,0x65},{0xaa,0xaa,0x69,0x95},{0xaa,0xa5,0x65,0x55},{0xaa,0xa6,0x25,0x55},{0xaa,0x01,0x55,0x55},{0xaa,0xaa,0x59,0x55},{0xaa,0x55,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0xa5,0x54,0x40}},{{0x94,0xa0,0x00,0x28},{0xa5,0x55,0x55,0x51},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0xa1},{0xa5,0x59,0x55,0x55},{0xaa,0x5a,0x55,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xaa,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0xa5,0x15,0x55},{0xa9,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x65,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x55,0x59},{0xaa,0xa9,0x59,0x15},{0xaa,0xaa,0x68,0x95},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0xaa,0xa5,0x65,0x55},{0xaa,0x55,0x55,0x55},{0xaa,0xa5,0x55,0x55},{0xaa,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa8,0x65,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x55},{0x8a,0x99,0x59,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0xa5,0x65,0x55},{0xa5,0x55,0x55,0x55},{0x92,0x25,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0xa0,0x00,0x14},{0xa5,0x55,0x65,0x95},{0x89,0x99,0x55,0x15},{0xaa,0xa5,0xaa,0x95},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x25,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x54,0x40}},{{0x64,0x50,0x80,0x15},{0xa5,0x95,0x65,0x95},{0x99,0x95,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x26,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x58,0x5a,0x80,0x15},{0xa9,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0xaa,0x95,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa4,0x55,0x14,0x00}},{{0x98,0x5a,0x80,0x15},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x2a,0x95,0xa5,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0xa6,0x54,0x14,0x00}},{{0x98,0x5a,0x48,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x55,0x55,0x15},{0x25,0x95,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0x55,0x55,0x65},{0xa6,0x54,0x10,0x00}},{{0x9a,0x55,0x68,0x55},{0x6a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x25,0x55,0x95,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x25,0x55,0x55,0x66},{0x2a,0xaa,0xaa,0x6a},{0xa6,0x10,0x00,0x00}},{{0x9a,0x55,0x64,0x41},{0x5a,0xaa,0x9a,0x55},{0x15,0x55,0x55,0x15},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0xa6,0x10,0x08,0x00}},{{0x9a,0x55,0x94,0x81},{0x5a,0x6a,0x9a,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x46,0x0a,0x9a,0x81},{0xa6,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x0a,0xa9,0x41},{0xa5,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x15,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x44,0x85,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x0a,0x65,0x41},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x55,0x55,0x69},{0x55,0x55,0x55,0x69},{0x55,0x56,0x11,0x59},{0x55,0x55,0x55,0x61},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x66},{0x65,0x44,0x42,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x51},{0x55,0xaa,0xaa,0x54},{0x45,0x55,0x55,0x56},{0x59,0x59,0x11,0x56},{0x55,0x55,0x14,0x52},{0x55,0x55,0x55,0x55},{0x55,0x51,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x46,0x05,0x55,0x41},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x61},{0x40,0x55,0x55,0x80},{0x6a,0xaa,0xaa,0xaa},{0x55,0x04,0x02,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x59,0x55,0x65,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x40,0x00,0x00,0x42},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x64,0x0a,0x9a,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x45,0x05,0x55,0x55},{0x55,0x55,0x55,0x59},{0x65,0x55,0x55,0x55},{0x55,0x64,0x55,0x41},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x6a,0x2a,0x82,0x2a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x45},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x2a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x44},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x40},{0x55,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x42},{0x95,0x55,0x51,0x42},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x50,0x50,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_7 = { .phases = 40, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_7_data[0] }; +const uint8_t epd_wp_ED047TC2_5_8_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x80,0x08,0x82},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x00,0x00,0x00,0x08},{0x00,0x00,0x00,0x00},{0x02,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x00,0x8a,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0x20,0x00,0x00,0x08},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x20},{0x80,0x00,0x00,0x00},{0xaa,0x08,0xaa,0x08},{0x00,0x00,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0x20,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x82},{0xa0,0x00,0x00,0x0a},{0x20,0x00,0x00,0x00},{0x02,0x82,0x00,0x2a},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa8},{0x00,0x20,0x08,0x00}},{{0xa8,0x00,0x0a,0x00},{0x08,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0xa0,0x08,0x81},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x81},{0xa0,0x00,0x00,0x05},{0x20,0x00,0x00,0x01},{0x02,0x82,0x00,0xa9},{0x80,0x00,0x00,0x01},{0xaa,0xaa,0xaa,0xa4},{0x12,0x28,0xaa,0x00}},{{0xa8,0x00,0x0a,0x00},{0x88,0xa0,0x8a,0x02},{0x00,0x20,0x00,0x20},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x82,0xa8,0x08,0x81},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x08},{0x00,0x02,0x0a,0x80},{0x88,0x00,0x02,0x81},{0xa0,0x00,0x00,0x25},{0x28,0x00,0x00,0x21},{0x22,0x82,0x00,0xa5},{0x80,0x00,0x00,0x21},{0xaa,0xaa,0xaa,0xa4},{0x19,0x2a,0xaa,0x80}},{{0xa8,0x00,0x0a,0x00},{0x8a,0xa8,0x8a,0x0a},{0x00,0x20,0x00,0x28},{0x80,0x00,0x00,0x00},{0x20,0x00,0x00,0x0a},{0x82,0xaa,0x08,0x81},{0x08,0x20,0x02,0x02},{0x08,0x00,0x00,0x08},{0x28,0x02,0x0a,0x80},{0x88,0x08,0x0a,0x81},{0xa0,0x00,0x08,0x25},{0x2a,0x00,0x0a,0x21},{0x22,0xa2,0x00,0x95},{0x80,0x02,0x00,0xa1},{0xaa,0xaa,0xaa,0xa5},{0x19,0xaa,0xaa,0x80}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0x8a,0x0a},{0x02,0x20,0x00,0x28},{0x88,0x00,0x00,0x02},{0x20,0x00,0x00,0x09},{0xa2,0xaa,0xa8,0x85},{0x8a,0x28,0x0a,0x09},{0x88,0x00,0x00,0x08},{0x28,0x02,0x8a,0x80},{0x88,0x0a,0x0a,0x81},{0xa8,0x02,0x08,0x25},{0xaa,0xaa,0x0a,0x21},{0x2a,0xaa,0x2a,0x95},{0xa0,0x02,0x82,0x81},{0xaa,0xaa,0xaa,0x95},{0x19,0xaa,0xaa,0x80}},{{0xa8,0x00,0x05,0x00},{0x8a,0xaa,0xaa,0x09},{0x02,0x20,0x08,0x04},{0x88,0x00,0x00,0x21},{0x28,0x00,0x00,0x09},{0xaa,0xaa,0xa8,0x85},{0x8a,0xaa,0x0a,0x09},{0x88,0x08,0x00,0x04},{0xaa,0x82,0x8a,0x82},{0xaa,0xaa,0xaa,0x81},{0xa8,0x22,0xa8,0x15},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0x2a,0x95},{0xa0,0x22,0x82,0x91},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xaa,0x84}},{{0xa8,0x00,0x05,0x10},{0x8a,0xaa,0xaa,0x09},{0x22,0x20,0x28,0x14},{0x88,0x00,0x00,0x25},{0x28,0x00,0x00,0x05},{0xaa,0xaa,0xa8,0x45},{0xaa,0xaa,0xaa,0x05},{0x88,0x0a,0x00,0x85},{0xaa,0xa2,0x8a,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0x2a,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa2,0x2a,0x8a,0x95},{0xaa,0xaa,0xaa,0x95},{0x15,0x6a,0xa6,0x84}},{{0xa8,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x09},{0xaa,0x22,0xaa,0x15},{0x88,0x00,0x00,0x25},{0xa8,0x00,0x00,0x25},{0xaa,0xaa,0xa8,0x65},{0xaa,0xaa,0xaa,0x25},{0xa8,0x2a,0x80,0xa5},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xa2,0xaa,0x8a,0x95},{0xa9,0xaa,0x66,0x55},{0x15,0x6a,0x56,0x44}},{{0x94,0x00,0x05,0x90},{0x8a,0xaa,0x65,0x29},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x08,0x00,0x25},{0xaa,0xaa,0xa6,0x65},{0xaa,0xaa,0xaa,0x25},{0xaa,0x2a,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x45},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0x29,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0xa9,0xa9,0x55,0x55},{0x25,0x6a,0x55,0x54}},{{0x94,0x00,0x0a,0x64},{0x8a,0xaa,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x88,0x00,0x00,0x25},{0xa8,0x0a,0x0a,0x15},{0xaa,0x6a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0x8a,0xa5},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xa9,0x69,0xaa,0x55},{0xaa,0xaa,0xaa,0x55},{0x99,0xa5,0x55,0x55},{0x21,0x15,0x55,0x54}},{{0x94,0x00,0x0a,0x64},{0xaa,0x9a,0x65,0x19},{0xaa,0x22,0xaa,0x95},{0x8a,0x00,0x00,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x5a,0xa6,0x55},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa8,0x55},{0x9a,0xaa,0xa6,0x55},{0x9a,0xaa,0xa5,0x55},{0xa9,0x69,0xaa,0x55},{0xaa,0xa9,0x6a,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x54}},{{0x94,0x00,0x0a,0xa5},{0xaa,0x5a,0x65,0x15},{0xaa,0x22,0xaa,0x95},{0xaa,0xa0,0x08,0x15},{0xa8,0x2a,0x8a,0x15},{0xaa,0x55,0x56,0x55},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x15},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa5,0x55},{0x9a,0xa9,0x56,0x55},{0x9a,0xa1,0x55,0x55},{0xa9,0x69,0x95,0x55},{0xaa,0xa9,0x69,0x55},{0x95,0x55,0x55,0x55},{0x22,0x15,0x55,0x54}},{{0x68,0x00,0x0a,0x95},{0xa6,0x55,0x55,0x15},{0xaa,0x12,0x8a,0x15},{0xaa,0xa0,0x28,0x15},{0xa8,0x2a,0x8a,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0xaa,0xa5,0x95},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0xa5,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0x91,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x9a,0xa9,0x65,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x54}},{{0x68,0x00,0x0a,0x55},{0xa6,0x55,0x9a,0x15},{0xaa,0x12,0x06,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x15},{0xa9,0x55,0x56,0x55},{0xaa,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xa9,0x65,0x55},{0xaa,0xa5,0x55,0x55},{0x9a,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x99,0x95,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa2,0x15,0x55,0x54}},{{0x68,0x00,0x05,0x55},{0xa5,0x55,0x9a,0x25},{0xa9,0x91,0x55,0x55},{0xaa,0xaa,0x28,0x15},{0xa8,0x2a,0xaa,0x95},{0x59,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa5,0x6a,0x55},{0xaa,0xa9,0x65,0x55},{0xa4,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x54}},{{0x68,0x00,0x05,0x55},{0xa5,0x65,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xaa,0xaa,0xa8,0x95},{0x9a,0x25,0x65,0x95},{0x51,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xa6,0x85,0x65,0x55},{0x9a,0x29,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x15,0x55,0x54}},{{0x54,0x00,0x05,0x55},{0xa9,0xa5,0x9a,0x25},{0x99,0x91,0x55,0x55},{0xa6,0xaa,0xaa,0x95},{0x96,0xa5,0x65,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa6,0x85,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x96,0x55,0x55,0x55},{0xaa,0x95,0x11,0x54}},{{0x94,0x00,0x05,0x55},{0x69,0xaa,0xaa,0x25},{0x95,0x99,0x55,0x55},{0xa6,0xaa,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x56},{0xa6,0x55,0x55,0x59},{0xaa,0x95,0x21,0x54}},{{0x94,0x00,0x85,0x51},{0x6a,0xaa,0xaa,0xa5},{0x95,0x99,0x55,0x55},{0x65,0x59,0x96,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x66},{0xaa,0x56,0x99,0x6a},{0xaa,0xaa,0xaa,0xa8}},{{0x94,0x22,0x85,0x51},{0x6a,0xaa,0x20,0x95},{0x55,0x59,0x55,0x55},{0x55,0x55,0x56,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x66,0x56,0x95,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x96,0x2a,0x65,0x01},{0xa2,0x8a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x96,0x95,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x15,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x96,0xa9,0x50,0x01},{0xa6,0x0a,0x65,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x45,0x55,0x55,0x4a},{0x55,0x55,0x55,0x55},{0x66,0x96,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0x95,0x90,0x01},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x55,0x95,0x55,0x95},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x52},{0x65,0x54,0x01,0x2a},{0x65,0x55,0x55,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x56,0xa0,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x64},{0x66,0x6a,0xa9,0x50},{0x55,0x55,0x55,0x64},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x55},{0x45,0x50,0x00,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x6a,0x60,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x56},{0x55,0x5a,0x95,0x5a},{0x55,0x15,0x55,0x20},{0x55,0x55,0x55,0x5a},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x56},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0xa9,0x50,0x05},{0x55,0x55,0x55,0x55},{0x65,0x55,0x55,0x65},{0x55,0x55,0x55,0x55},{0x59,0x65,0x6a,0xa6},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x41,0x50,0x15,0x6a},{0x45,0x54,0x55,0x91},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x42,0x95,0x50,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x51},{0x65,0x55,0x55,0x54},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x54,0x10,0x6a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x55,0x50,0x15},{0x55,0x55,0x55,0x55},{0x6a,0xa2,0xaa,0xa2},{0x52,0xa6,0x65,0x92},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x41,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xa2},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x40,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x84,0x50,0x05,0x0a},{0x40,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0xa5,0x50,0x15,0x48},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x45},{0x00,0x00,0x00,0x00},{0x81,0x51,0x11,0x68},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x45,0x55,0x55,0x44},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_8 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_8_data[0] }; +const uint8_t epd_wp_ED047TC2_5_9_data[38][16][4] = {{{0x00,0x00,0x00,0x00},{0x0a,0x82,0x02,0x00},{0x40,0x00,0x00,0x00},{0x00,0x80,0x02,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x28,0x00,0x00,0x02},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x0a,0x8a,0x82,0x00},{0x40,0x08,0x00,0x40},{0x00,0x80,0x22,0x08},{0x00,0x08,0x08,0x08},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x10,0x04,0x00,0x00},{0x11,0x40,0x20,0x00},{0x81,0x00,0x00,0x20},{0x28,0x08,0x00,0x82},{0x00,0x20,0x80,0x80},{0x00,0x00,0x02,0x80}},{{0x80,0x00,0x00,0x00},{0x6a,0x8a,0x8a,0x00},{0x90,0x08,0x01,0x40},{0x00,0x80,0x22,0x08},{0x00,0x28,0x88,0x0a},{0x80,0x08,0x00,0x00},{0x00,0x08,0x02,0x00},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x80,0x00},{0x14,0x14,0x00,0x00},{0x21,0x50,0x20,0x80},{0x81,0x18,0x00,0xa0},{0x29,0x0a,0x02,0x81},{0x2a,0xa2,0xaa,0xa0},{0x00,0x2a,0x02,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xa0,0x08,0x02,0x80},{0x80,0x88,0x22,0x08},{0x20,0xa8,0x89,0x0a},{0x80,0xa8,0x00,0x02},{0xaa,0x8a,0x0a,0x08},{0x00,0x08,0x02,0x00},{0x00,0x00,0x00,0x02},{0x08,0x08,0x80,0x00},{0x24,0x54,0x22,0x80},{0x25,0x52,0x2a,0xa0},{0x86,0xa8,0x20,0xa8},{0xaa,0x2a,0x82,0x81},{0x2a,0xaa,0xaa,0xa0},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x00},{0xaa,0x8a,0x2a,0x80},{0x80,0x88,0x22,0x08},{0x22,0xaa,0x8a,0x0a},{0x82,0xa8,0x00,0x02},{0xaa,0xaa,0x0a,0x0a},{0x00,0x08,0x02,0x28},{0x00,0x00,0x00,0x02},{0x2a,0x8a,0x80,0x00},{0xa5,0xaa,0xa2,0xa0},{0x26,0x96,0xaa,0xa0},{0x8a,0xa8,0xa0,0xa8},{0xaa,0x2a,0x8a,0x81},{0x2a,0xaa,0xaa,0xa8},{0x00,0xaa,0x22,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x0a},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0x2a,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x00,0x02},{0x2a,0xaa,0x80,0x00},{0xa9,0xaa,0xa2,0xa0},{0x26,0xa6,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0x2a,0x8a,0x41},{0xaa,0xaa,0xaa,0xa8},{0x08,0xaa,0x12,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0x8a,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x29},{0xa2,0xa8,0x02,0x02},{0xaa,0xaa,0xaa,0x0a},{0x00,0x08,0x02,0x2a},{0x00,0x00,0x08,0x80},{0x2a,0xaa,0x8a,0x22},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa0},{0x8a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x69},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x12,0x40}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x80,0x88,0x22,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x02},{0xaa,0xaa,0xaa,0x09},{0x20,0x08,0x02,0x28},{0x00,0x02,0x0a,0xa0},{0x2a,0xaa,0x8a,0x2a},{0xaa,0xaa,0xaa,0xa0},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xaa,0xa8},{0x28,0xaa,0x11,0x44}},{{0x80,0x00,0x00,0x00},{0xaa,0xaa,0x8a,0x80},{0xaa,0xaa,0xaa,0x80},{0x81,0x88,0xa2,0x24},{0xaa,0xaa,0x8a,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0x8a,0x02,0x28},{0x00,0x82,0xaa,0xa1},{0x2a,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x95},{0xa6,0xaa,0xa9,0x55},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0x91,0x44}},{{0x80,0x00,0x00,0x20},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0x80},{0x82,0x88,0xaa,0x24},{0xaa,0xaa,0xaa,0x25},{0xaa,0xaa,0x0a,0x21},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x82,0x04},{0x20,0xa2,0xaa,0xa1},{0x2a,0xaa,0xaa,0x29},{0xaa,0xaa,0xaa,0xa8},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x55},{0x96,0xa5,0x65,0x55},{0xaa,0xaa,0xaa,0x54},{0x2a,0xaa,0x91,0x44}},{{0x80,0x00,0x00,0x10},{0xaa,0xaa,0x89,0x80},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x9a,0x14},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0x8a,0x21},{0xaa,0xaa,0xaa,0x85},{0x2a,0xaa,0x8a,0x15},{0x20,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0x25},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0xaa,0x55},{0x96,0x95,0x55,0x55},{0xaa,0xaa,0xaa,0x56},{0x2a,0x99,0x91,0x44}},{{0x80,0x00,0x00,0x94},{0xaa,0xa9,0x45,0x44},{0xaa,0xaa,0xaa,0xa0},{0xa2,0xa8,0x99,0x16},{0xaa,0xa6,0xa6,0x95},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xa9,0xa5},{0xaa,0xaa,0xa9,0x95},{0x2a,0xaa,0xaa,0x69},{0x2a,0xaa,0xaa,0x95},{0xaa,0xaa,0xaa,0x5a},{0xaa,0xaa,0x9a,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0xaa,0x55,0x56},{0x1a,0x95,0x99,0x04}},{{0x80,0x00,0x00,0x64},{0xa9,0x65,0x45,0x48},{0xaa,0xaa,0xa9,0xa2},{0xa2,0x6a,0x99,0x15},{0xaa,0xa5,0x65,0x95},{0xaa,0xaa,0xaa,0x99},{0xaa,0xaa,0xa5,0xa5},{0xaa,0xaa,0xa9,0x95},{0xaa,0xaa,0xaa,0x59},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x99,0x55},{0xaa,0xaa,0x95,0x55},{0xaa,0xaa,0x9a,0x55},{0x95,0x95,0x55,0x55},{0xaa,0x99,0x55,0x55},{0x19,0x55,0x89,0x04}},{{0x40,0x00,0x00,0xa4},{0xa5,0x65,0x45,0x4a},{0xaa,0xaa,0xa9,0xa1},{0xa2,0x6a,0x99,0x15},{0xa9,0x95,0x65,0x95},{0xaa,0xaa,0xaa,0x95},{0xaa,0xa5,0x95,0xa5},{0xaa,0xa6,0xa9,0x95},{0xaa,0xaa,0xa6,0x55},{0x2a,0xaa,0x6a,0x95},{0xaa,0xaa,0x59,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0xa6,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x99,0x55,0x55},{0x15,0x55,0x49,0x14}},{{0x40,0x00,0x00,0x54},{0xa5,0x65,0x45,0x88},{0xaa,0xaa,0xa9,0xa1},{0xaa,0x66,0x11,0x15},{0xa9,0x55,0x65,0x55},{0xaa,0x96,0xa9,0x95},{0xa5,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x15},{0xaa,0xaa,0x95,0x55},{0x26,0xa5,0x65,0x95},{0xaa,0xa9,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x15,0x55,0x45,0x14}},{{0x40,0x00,0x00,0x55},{0xa5,0x55,0x46,0x89},{0xaa,0xa6,0xa5,0x61},{0xaa,0x66,0x51,0x15},{0x95,0x55,0x55,0x55},{0x28,0x56,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa6,0xa9,0x55},{0xaa,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0xaa,0xa9,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x14}},{{0xa0,0x00,0x00,0x55},{0x95,0x56,0x8a,0x99},{0xaa,0xaa,0x9a,0x51},{0xaa,0x66,0x55,0x95},{0x95,0x55,0x55,0x55},{0x29,0x55,0xa5,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xa5,0x45,0x55},{0xaa,0xa9,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x9a,0xa9,0x55,0x55},{0xa5,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x45,0x14}},{{0xa0,0x00,0x00,0x55},{0x9a,0x9a,0x8a,0x65},{0xaa,0xa5,0x56,0x51},{0x6a,0x56,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x85,0x55,0x55,0x55},{0xaa,0x59,0x55,0x55},{0x95,0x55,0x55,0x55},{0x9a,0x55,0x55,0x55},{0x99,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x96},{0x95,0x55,0x55,0x55},{0x05,0x55,0x45,0x14}},{{0xa0,0x00,0x20,0x51},{0x5a,0xaa,0x8a,0x65},{0xa5,0x65,0x56,0x59},{0x69,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x85,0x55,0x45,0x10}},{{0x60,0x28,0xa0,0x51},{0x6a,0xaa,0x8a,0x65},{0x95,0x55,0x56,0x55},{0x59,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x84,0x55,0x44,0x10}},{{0x6a,0xaa,0xa8,0x11},{0x6a,0xaa,0x8a,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x45,0x44,0x10}},{{0x5a,0xaa,0x64,0x01},{0xa6,0x99,0x45,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xa6,0x44,0x46,0x10}},{{0x5a,0x95,0x56,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x99,0x01},{0x95,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x56,0x5a,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x95},{0x95,0x55,0x55,0x51},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x65,0x55},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x25,0x6a,0x99,0x01},{0x15,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x65,0x65},{0x56,0x5a,0x56,0x56},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x65},{0x95,0x55,0x41,0x56},{0x95,0x55,0x55,0x41},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x5a,0x66,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0xaa,0x56,0x05},{0x55,0x55,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x95,0x61},{0x55,0x55,0x55,0x59},{0x55,0x55,0x55,0x45},{0x55,0x55,0x55,0x59},{0x55,0x55,0x54,0x55},{0x55,0x54,0x00,0x15},{0x91,0x55,0x15,0x42},{0x55,0x55,0x24,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x2a,0x95,0x56,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x65,0x49,0x91},{0x55,0x55,0x54,0x44},{0x55,0x55,0x55,0x49},{0x15,0x55,0x55,0x54},{0x55,0x51,0x54,0x0a},{0x55,0x04,0x00,0x2a},{0xaa,0xaa,0xaa,0xaa},{0x55,0x54,0x10,0x55},{0x65,0x56,0x9a,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x05},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xa2,0x1a,0x06,0x50},{0x68,0xa0,0xa8,0xaa},{0x55,0x45,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x45,0x04,0x00,0xaa},{0x55,0x55,0x65,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x51,0x05,0x01,0x02},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x6a},{0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x2a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x06},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x58},{0x55,0x55,0x55,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x6a,0xaa,0xa9,0xa4},{0x55,0x55,0x55,0x00},{0x15,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x54},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_9 = { .phases = 38, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_9_data[0] }; +const uint8_t epd_wp_ED047TC2_5_10_data[44][16][4] = {{{0x00,0x00,0x00,0x00},{0x80,0x80,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x00,0x00},{0x00,0x80,0x00,0x00},{0x80,0x00,0x08,0x02},{0x00,0x80,0x00,0x08},{0x10,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x02,0x00,0x00,0x00},{0xa2,0x88,0x20,0x05},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x02},{0x08,0x00,0x02,0x00},{0x00,0x00,0x00,0x00},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x80,0x20,0x00},{0x00,0x80,0x00,0x00},{0x00,0x82,0x00,0x00},{0xa8,0x00,0x08,0x82},{0x00,0x80,0x20,0x0a},{0x92,0x00,0x00,0x8a},{0x2a,0x20,0xa2,0xa8},{0x00,0x00,0x00,0x08}},{{0x02,0x00,0x00,0x00},{0xa2,0x8a,0x20,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x08,0x05,0x02,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x00,0x80,0x20,0x00},{0x02,0xa0,0xa0,0x00},{0x00,0x82,0x00,0x02},{0xaa,0x20,0x08,0x82},{0x84,0x80,0xa0,0x0a},{0xa2,0x84,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x08}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa0,0x05},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x15,0x42,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xa0,0x20,0x80},{0x02,0xaa,0xa8,0x00},{0x00,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x82},{0x9a,0x90,0xa8,0x0a},{0xa6,0xa8,0x00,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x00,0x80,0x28}},{{0x82,0x00,0x00,0x00},{0xa2,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x40},{0x00,0x00,0x00,0x02},{0x29,0x1a,0x46,0x00},{0x00,0x00,0x00,0x02},{0x00,0x02,0x02,0x00},{0x00,0x00,0x00,0x0a},{0x02,0xaa,0x28,0x80},{0x2a,0xaa,0xa8,0x00},{0x02,0x82,0x00,0x02},{0xaa,0xa8,0x2a,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0x08,0x8a},{0x2a,0xaa,0xaa,0xaa},{0x22,0x8a,0x88,0x24}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x09},{0x00,0x00,0x00,0x90},{0x02,0xa0,0x08,0x02},{0x2a,0x2a,0x86,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x80},{0x2a,0xaa,0xa8,0x20},{0x02,0x82,0x00,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xa8,0xaa,0x0a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0x8a,0x8a,0xa4}},{{0x82,0x00,0x00,0x00},{0xaa,0xaa,0xa8,0x0a},{0x80,0x00,0x00,0x90},{0x02,0xaa,0x2a,0x02},{0x2a,0xaa,0x8a,0x20},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xa2,0xa2,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0xaa},{0x1a,0xaa,0x4a,0x54}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0x90},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa0},{0x08,0x00,0x00,0x02},{0x00,0x02,0x02,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xa8,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x16,0xaa,0x46,0x54}},{{0x82,0x00,0x00,0x08},{0xaa,0xaa,0xaa,0x0a},{0x80,0x02,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0x8a},{0xaa,0xaa,0xaa,0x2a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa4},{0x15,0x9a,0x65,0x54}},{{0x82,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0x80,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x02},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x00,0x02,0x82,0x20},{0x00,0x00,0x00,0x0a},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0x20},{0x2a,0xaa,0xaa,0x02},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0x55},{0x15,0x95,0x65,0x54}},{{0x81,0x00,0x00,0x28},{0xaa,0xaa,0xaa,0x0a},{0xa2,0x22,0x00,0xaa},{0x02,0xaa,0xaa,0x8a},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x02,0x82,0x20},{0x00,0x0a,0x00,0x09},{0x2a,0xaa,0xaa,0x82},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0xa9},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x55},{0x15,0x55,0x55,0x54}},{{0x81,0x00,0x80,0xa8},{0xaa,0xaa,0x9a,0x2a},{0xa2,0xa2,0x02,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xaa,0xa8},{0x28,0x00,0x00,0x02},{0x0a,0x82,0x82,0xa0},{0x00,0x8a,0x80,0x09},{0x2a,0xaa,0xaa,0x22},{0x2a,0xaa,0xaa,0xa2},{0xaa,0xaa,0xaa,0x01},{0xaa,0xaa,0xa2,0x21},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0xa9,0x55},{0x15,0x55,0x55,0x54}},{{0x81,0x00,0x80,0xa8},{0xaa,0x66,0x9a,0x2a},{0xa2,0xa2,0x22,0xaa},{0x02,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0x2a,0xa2,0xa0,0x80},{0x02,0x8a,0x80,0x05},{0x2a,0xaa,0x8a,0x20},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa1},{0xaa,0xaa,0xa0,0x61},{0xaa,0xaa,0xaa,0xa5},{0xaa,0xaa,0xaa,0x65},{0xaa,0xaa,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x81,0x00,0x80,0x94},{0xaa,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa9},{0x2a,0xaa,0xa9,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x82},{0x02,0x8a,0x82,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xa8,0xaa,0xa1},{0xaa,0xaa,0xa0,0x65},{0xaa,0xaa,0x20,0x85},{0xaa,0xaa,0xaa,0x65},{0xaa,0x95,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x41,0x00,0x40,0x94},{0x69,0x65,0x56,0x26},{0xa2,0xaa,0x22,0xaa},{0x82,0xaa,0xaa,0xa1},{0x2a,0xaa,0xaa,0xaa},{0xa8,0x00,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xa2,0x05},{0x2a,0xaa,0x8a,0x21},{0x2a,0xaa,0xaa,0x9a},{0xaa,0x28,0xaa,0xa9},{0xaa,0xaa,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x42,0x00,0x48,0xa4},{0x59,0x55,0x55,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xaa,0x25},{0x2a,0xaa,0xaa,0x9a},{0xa8,0x80,0x00,0x01},{0xaa,0xaa,0xa8,0x8a},{0xaa,0xaa,0xaa,0x05},{0x2a,0xaa,0x8a,0x29},{0x2a,0xaa,0x56,0x99},{0xaa,0x28,0xa8,0xa9},{0xaa,0x82,0x80,0x65},{0xaa,0x2a,0x00,0x85},{0xaa,0xaa,0xa6,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x42,0x00,0x48,0x64},{0x59,0x59,0x65,0xa9},{0xa6,0xaa,0x22,0x69},{0x82,0xaa,0xa0,0x65},{0x2a,0xaa,0xa9,0x56},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0xa9,0x8a},{0xaa,0xaa,0xaa,0x05},{0xaa,0x2a,0x86,0x69},{0x2a,0x55,0x55,0x99},{0xaa,0x69,0x89,0xa9},{0x96,0x82,0x00,0x45},{0xaa,0x22,0x10,0x05},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0x62,0x00,0x4a,0x54},{0x59,0x9a,0xa9,0x95},{0xaa,0xaa,0x22,0x65},{0x82,0xaa,0xa5,0x45},{0x26,0xaa,0xa9,0x55},{0xaa,0x80,0x00,0x09},{0xaa,0xa9,0x29,0x89},{0xaa,0xaa,0xaa,0x85},{0xaa,0x55,0x54,0x69},{0x21,0x55,0x55,0x55},{0xaa,0x69,0x45,0xa9},{0x95,0x55,0x55,0x55},{0xaa,0x22,0x10,0x05},{0x89,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x54}},{{0xa2,0x00,0x8a,0x54},{0x66,0xaa,0xaa,0x95},{0xaa,0xaa,0x22,0x55},{0x82,0x95,0x55,0x55},{0x16,0xa5,0x55,0x55},{0xa2,0xa0,0x20,0x09},{0xaa,0xa9,0x29,0x09},{0xaa,0xaa,0xaa,0x85},{0xa9,0x55,0x55,0x59},{0x11,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xa1,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x25,0x55,0x55,0x54}},{{0xa2,0x00,0x86,0x54},{0xa6,0xaa,0xaa,0xa5},{0xaa,0xaa,0x22,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x5a,0xa9,0x55},{0xa2,0xaa,0x28,0x01},{0xaa,0xa9,0x29,0x55},{0xaa,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x55,0x55,0x54}},{{0xa1,0x00,0x85,0x54},{0xaa,0xa2,0xaa,0x65},{0xaa,0xaa,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x15,0xa5,0x55,0x55},{0xa2,0xaa,0xa8,0x01},{0xaa,0xa9,0x69,0x55},{0xaa,0xa5,0x69,0xa5},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x29,0x45,0x55,0x54}},{{0xa1,0x00,0x85,0x54},{0x9a,0x95,0x55,0x55},{0xaa,0x99,0x21,0x55},{0xa9,0x55,0x55,0x55},{0x16,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa2,0xa9,0x55,0x55},{0xaa,0xa5,0x69,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x85,0x54}},{{0x61,0x00,0x45,0x54},{0x95,0x55,0x55,0x55},{0xaa,0x99,0x61,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0xa5,0x55,0x55,0x55},{0xaa,0x65,0x55,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x2a,0x65,0x89,0x94}},{{0x61,0x00,0x45,0x50},{0x95,0x55,0x55,0x55},{0x9a,0x99,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x85},{0x95,0x55,0x55,0x55},{0xa9,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x2a,0xaa,0x8a,0xa8}},{{0x61,0x00,0x45,0x10},{0x15,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x96,0xaa,0xaa,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xa8}},{{0x51,0x20,0x41,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0xa9,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x16,0x6a,0x94,0x65},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x50,0x2a,0x40,0x00},{0x55,0x55,0x55,0x55},{0x59,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x2a,0x00,0x01},{0x55,0x55,0x55,0x55},{0x51,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0xa9},{0xaa,0xaa,0xaa,0xa8}},{{0x28,0xa9,0x00,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x28,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x99,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x24,0x95,0x20,0x01},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x99},{0x95,0x55,0x55,0x55},{0x15,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x99},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x9a},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x14,0x6a,0x20,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x56},{0x95,0x55,0x55,0x65},{0x55,0x14,0x54,0x56},{0x41,0x55,0x55,0x56},{0x55,0x55,0x55,0x5a},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x14,0x6a,0x10,0x01},{0x55,0x55,0x55,0x56},{0x55,0x55,0x55,0x95},{0x55,0x55,0x55,0x11},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x59,0x55,0x95,0x55},{0x55,0x55,0x55,0x54},{0x55,0x55,0x55,0x15},{0x6a,0xaa,0xaa,0x99},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x96,0x10,0x05},{0x55,0x55,0x55,0x19},{0x55,0x55,0x55,0x65},{0x55,0x55,0x55,0x21},{0xa9,0x55,0x56,0xa5},{0x55,0x55,0x55,0x55},{0x66,0xa9,0x69,0x54},{0x55,0x50,0x14,0x1a},{0x6a,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x46},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x95,0x10,0x45},{0x55,0x55,0x55,0x15},{0x55,0x55,0x55,0x65},{0x6a,0x6a,0x9a,0x11},{0x95,0x55,0x55,0x55},{0x69,0x55,0x55,0x59},{0x51,0x56,0x16,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x18,0x55,0x10,0x55},{0x00,0x00,0x00,0x00},{0x55,0x65,0x56,0x54},{0x55,0x15,0x45,0x02},{0x80,0x00,0x00,0x0a},{0x55,0x55,0x55,0x16},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x15,0x55,0x15,0x55},{0x00,0x00,0x00,0x00},{0x59,0x55,0x55,0x14},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x65,0x45,0x54,0x0a},{0x2a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x40,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0x15,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x80,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0x95,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x95,0x55,0x55,0x55},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x6a,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_10 = { .phases = 44, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_10_data[0] }; +const uint8_t epd_wp_ED047TC2_5_11_data[57][16][4] = {{{0x20,0x8a,0x80,0x00},{0x15,0x55,0x5a,0xa4},{0x44,0x10,0x0a,0x41},{0x40,0x00,0x09,0x54},{0x10,0x50,0x00,0x00},{0x00,0x00,0x04,0x28},{0x40,0x00,0x00,0x00},{0x00,0x00,0x20,0x00},{0x00,0x00,0x40,0x00},{0x00,0x00,0x00,0x00},{0x00,0x40,0x00,0x68},{0x00,0x00,0x40,0x00},{0x00,0x00,0x0a,0x54},{0x00,0x0a,0x80,0x00},{0x10,0x09,0x60,0x00},{0x00,0x00,0x00,0x50}},{{0xaa,0xaa,0x8a,0x00},{0x0a,0x60,0x0a,0xa8},{0x54,0x54,0x8a,0x41},{0x41,0x02,0x09,0x54},{0x15,0x50,0x06,0x24},{0x00,0x08,0xa4,0x28},{0x44,0x00,0x09,0xa8},{0x05,0x00,0x2a,0xa8},{0x01,0x10,0x46,0xa8},{0x04,0x00,0x00,0xa8},{0x00,0x40,0x00,0x54},{0x04,0x00,0x44,0xa8},{0x00,0x00,0x8a,0x54},{0x00,0x0a,0x8a,0x58},{0x50,0x19,0x65,0x54},{0x00,0x00,0x00,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x6a,0xaa,0xa8},{0x55,0x94,0x89,0x55},{0x41,0x02,0x09,0x54},{0x15,0x50,0x66,0x24},{0x40,0x04,0xa4,0x68},{0x44,0x0a,0x09,0x54},{0x05,0x08,0x55,0x54},{0x11,0x14,0x56,0x54},{0x04,0x40,0x00,0x58},{0x01,0x40,0x0a,0x54},{0x04,0x0a,0x44,0xa8},{0x01,0x00,0x8a,0x54},{0x00,0x0a,0x6a,0x54},{0x50,0x19,0x65,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x2a,0x2a,0xaa,0xa8},{0x96,0x95,0x55,0x55},{0x51,0x0a,0x05,0x54},{0x15,0x50,0x66,0xa4},{0x40,0x04,0x54,0x54},{0x44,0x05,0x09,0x54},{0x05,0x18,0x55,0x54},{0x51,0x14,0x56,0x54},{0x04,0x40,0x02,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x58},{0x01,0x0a,0x85,0x54},{0x01,0x05,0x65,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x01,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x96,0xa5,0x55,0x55},{0x51,0x09,0x05,0x55},{0x15,0x50,0x65,0x94},{0x44,0x14,0x54,0x54},{0x54,0x15,0x95,0x54},{0x05,0x56,0x55,0x54},{0x51,0x14,0x55,0x54},{0x14,0x40,0x82,0x54},{0x01,0x40,0x8a,0x54},{0x04,0x05,0x44,0x54},{0x01,0x0a,0x45,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x54},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x49,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x14,0x55,0x55},{0x14,0x40,0x8a,0x54},{0x01,0x40,0x85,0x54},{0x04,0x15,0x44,0x54},{0x01,0x0a,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x6a,0xaa,0xaa,0xa8},{0x9a,0xa6,0x55,0x55},{0x51,0x55,0x25,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x95,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0xa9,0x54},{0x01,0x40,0x45,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x65,0x54},{0x01,0x05,0x55,0x54},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x50,0x55,0x54},{0x54,0x14,0x54,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x14,0x40,0x69,0x55},{0x01,0x40,0x65,0x55},{0x04,0x15,0x44,0x54},{0x01,0x05,0x55,0x54},{0x01,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x52,0x55,0x54},{0x54,0x14,0x56,0x54},{0x54,0x15,0x55,0x55},{0x05,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x65,0x55},{0x01,0x50,0x65,0x55},{0x04,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x54,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x51,0x55,0x15,0x55},{0x15,0x92,0x55,0x55},{0x55,0x14,0x56,0x54},{0x54,0x55,0x55,0x55},{0x45,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x40,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xa6,0x65,0x55},{0x91,0x55,0x15,0x55},{0x16,0x92,0x55,0x55},{0x55,0x14,0x56,0x55},{0x54,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x50,0x55,0x55},{0x05,0x15,0x64,0x54},{0x01,0x05,0x55,0x55},{0x11,0x05,0x55,0x55},{0x55,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0x92,0x55,0x95,0x55},{0x6a,0x91,0x55,0x55},{0x55,0x54,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x15,0x55,0x55},{0x15,0x48,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x05,0x15,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x8a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0x91,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x4a,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa5,0x15,0x55,0x55},{0x00,0x00,0x05,0x54}},{{0xaa,0xaa,0x4a,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x55,0x55,0x55},{0x6a,0xa1,0x55,0x55},{0x95,0x54,0x55,0x55},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x5a,0x55,0x55},{0x15,0x55,0x54,0x55},{0x11,0x05,0x55,0x55},{0x55,0x05,0x55,0x55},{0xa9,0x15,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0xa5,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0x65,0x55},{0xa6,0x95,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0x99,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0x56,0x55,0x55,0x55},{0x15,0x46,0x55,0x55},{0x01,0x55,0x55,0x55},{0x15,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x05,0x55,0x55},{0xa9,0x66,0x55,0x55},{0x00,0x10,0x45,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x55},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x55,0x55},{0xa9,0x54,0x55,0x55},{0x99,0x55,0x55,0x55},{0x5a,0x55,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x15,0x45,0x55,0x55},{0x11,0x55,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x56,0x15,0x55,0x55},{0xa9,0x66,0x95,0x55},{0x00,0x10,0x55,0x54}},{{0xaa,0x95,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xa6,0x96},{0xa6,0xa5,0x56,0x55},{0x6a,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x55,0x55,0x55},{0x5a,0x95,0x55,0x55},{0xa6,0x55,0x55,0x55},{0x19,0x45,0x55,0x55},{0x11,0x95,0x55,0x55},{0x19,0x55,0x54,0x55},{0x56,0x15,0x55,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x66,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x9a,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xa8},{0xaa,0xaa,0xaa,0x96},{0xaa,0xa6,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0x68,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x5a,0xa5,0x55,0x55},{0xaa,0x65,0x55,0x55},{0x29,0x85,0x55,0x55},{0x12,0x95,0x55,0x55},{0x59,0x55,0x56,0x55},{0x56,0x15,0x55,0x55},{0xa6,0x15,0x55,0x55},{0xaa,0x6a,0x9a,0x55},{0x00,0x14,0x55,0x54}},{{0x95,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0x55},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0x59,0x55},{0xa9,0x65,0x55,0x55},{0x9a,0xa5,0x55,0x55},{0xaa,0x69,0x95,0x55},{0x2a,0x85,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x55,0x95,0x55},{0x56,0x15,0x55,0x55},{0xaa,0x1a,0x95,0x55},{0xaa,0x6a,0xaa,0xa9},{0x00,0x15,0x55,0x54}},{{0x55,0x55,0x45,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x56,0xa9},{0xaa,0xa5,0x99,0x55},{0xaa,0xa8,0xa9,0x55},{0xa9,0xaa,0x56,0x55},{0xaa,0xa5,0x95,0x55},{0xaa,0x69,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x52,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0x66,0x15,0x55,0x55},{0xaa,0x1a,0xaa,0xa5},{0xaa,0xaa,0xaa,0xa9},{0x20,0x95,0x55,0x54}},{{0x55,0x55,0x8a,0x00},{0xaa,0xaa,0xa5,0x5a},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0x99,0x59},{0xaa,0xa8,0xa9,0x55},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0x6a,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x5a,0x6a,0x99,0x55},{0xa6,0x15,0x55,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x5a,0x8a,0x00},{0xaa,0xaa,0x55,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xa5,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0x95,0x55,0x55},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0x9a,0xa9},{0xaa,0x1a,0xaa,0xa9},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0x6a,0x8a,0x00},{0xaa,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xa9,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x66,0x55},{0xaa,0xaa,0xaa,0x55},{0xaa,0xaa,0xa9,0x55},{0x6a,0x95,0x55,0x55},{0x56,0xa5,0x55,0x95},{0x6a,0xaa,0x99,0x55},{0xaa,0x1a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x26,0x95,0x55,0x54}},{{0x55,0xaa,0x8a,0x00},{0xa9,0x55,0x5a,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0x6a,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0x95},{0xaa,0xaa,0x6a,0xa9},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xaa,0xaa,0xa9},{0x6a,0x95,0x55,0x55},{0x66,0xa5,0x55,0xa9},{0xaa,0xaa,0x99,0x55},{0xaa,0x2a,0xaa,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x12,0x45,0x55,0x54}},{{0x6a,0xaa,0x8a,0x00},{0xa5,0x55,0xa5,0x56},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0x59},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x6a,0x95,0x55,0xa5},{0xa6,0xa5,0x9a,0xa9},{0xaa,0xaa,0x99,0xa5},{0xaa,0x2a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x41,0x55,0x54}},{{0xaa,0xaa,0x8a,0x00},{0x95,0x6a,0xa5,0x56},{0xaa,0x69,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa9},{0xaa,0xa9,0xa9,0xa9},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0x96,0xa9},{0xa6,0xa5,0xaa,0xaa},{0xaa,0xaa,0x99,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x85,0x00},{0x55,0x6a,0xa5,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xa9,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x95,0xaa,0xaa},{0xaa,0xa5,0xaa,0xaa},{0xaa,0xaa,0xa9,0xa9},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x11,0x40,0x00,0x54}},{{0xaa,0xaa,0x45,0x00},{0x5a,0x6a,0x55,0x56},{0xa9,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x99,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x40,0x02,0xa0}},{{0xaa,0xa5,0x45,0x00},{0x6a,0x55,0x55,0x56},{0x69,0x59,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xa9,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x40,0x02,0xa8}},{{0xaa,0x55,0x45,0x00},{0x6a,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0xa5,0x55,0x45,0x00},{0x66,0x95,0x55,0x55},{0x65,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x55,0x95,0x55,0x55},{0x55,0x55,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x5a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x99,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x59,0x55,0x69},{0x69,0x6a,0xaa,0xaa},{0xaa,0x5a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x95,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x6a,0xaa,0xaa},{0xa9,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x0a,0xa8}},{{0x55,0x55,0x45,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x6a,0x5a,0xa9,0xaa},{0xa5,0x6a,0xaa,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x0a,0xa8}},{{0x55,0x55,0x40,0x00},{0x95,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0xa9,0xaa},{0x95,0x6a,0x66,0xaa},{0xaa,0x6a,0xaa,0xaa},{0xaa,0x9a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa8}},{{0x55,0x50,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x99,0xaa},{0x55,0x46,0x66,0xaa},{0xa8,0x6a,0x9a,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x01,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x20,0x8a,0xa8}},{{0x50,0x00,0x00,0x80},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x94,0x95,0x95,0x56},{0x55,0x45,0x55,0xa6},{0x65,0x96,0x96,0xaa},{0x26,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x08,0x28,0xaa,0xa8}},{{0x00,0x00,0x00,0x60},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x55,0xa6},{0x55,0x96,0x66,0xaa},{0x2a,0x4a,0xaa,0xaa},{0xaa,0x8a,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x88,0x2a,0xaa,0xa8}},{{0x00,0x00,0x20,0x50},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x95,0x66,0x6a},{0x12,0x86,0xaa,0xaa},{0x85,0x4a,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xa9,0xaa,0xaa,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0xa8,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x61,0x09,0x55,0x55},{0x45,0x55,0x55,0xaa},{0xa8,0xaa,0xaa,0xaa},{0x98,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x10,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x45,0x99,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x56,0xaa},{0x94,0x6a,0xaa,0xaa},{0x56,0x65,0x55,0x55},{0xa6,0x55,0x66,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x00,0x25,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x68,0x95,0x55,0x55},{0xa9,0x8a,0xaa,0xaa},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x00,0x05,0x65,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xa4,0x6a,0xaa,0xaa},{0x02,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xa8}},{{0x05,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x01,0x50,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xa8}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x55,0x55,0x55,0x55},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0xaa,0xaa,0xaa,0xaa},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_ED047TC2_5_11 = { .phases = 57, .phase_times = NULL, .luts = (const uint8_t*)&epd_wp_ED047TC2_5_11_data[0] }; +const EpdWaveformPhases* epd_wm_ed047tc2_5_ranges[7] = { &epd_wp_ED047TC2_5_5,&epd_wp_ED047TC2_5_6,&epd_wp_ED047TC2_5_7,&epd_wp_ED047TC2_5_8,&epd_wp_ED047TC2_5_9,&epd_wp_ED047TC2_5_10,&epd_wp_ED047TC2_5_11 }; const EpdWaveformMode epd_wm_ed047tc2_5 = { .type = 5, .temp_ranges = 7, .range_data = &epd_wm_ed047tc2_5_ranges[0] }; const EpdWaveformTempInterval ed047tc2_intervals[14] = { { .min = 0, .max = 3 },{ .min = 3, .max = 6 },{ .min = 6, .max = 9 },{ .min = 9, .max = 12 },{ .min = 12, .max = 15 },{ .min = 15, .max = 18 },{ .min = 18, .max = 21 },{ .min = 21, .max = 24 },{ .min = 24, .max = 27 },{ .min = 27, .max = 30 },{ .min = 30, .max = 33 },{ .min = 33, .max = 38 },{ .min = 38, .max = 43 },{ .min = 43, .max = 48 } }; const EpdWaveformMode* ed047tc2_modes[3] = { &epd_wm_ed047tc2_1,&epd_wm_ed047tc2_2,&epd_wm_ed047tc2_5 }; -const EpdWaveform ed047tc2 = { .num_modes = 3, .num_temp_ranges = 7, .mode_data = &ed047tc2_modes[0], .temp_intervals = &ed047tc2_intervals[0] }; +const EpdWaveform epdiy_ED047TC2 = { .num_modes = 3, .num_temp_ranges = 7, .mode_data = &ed047tc2_modes[0], .temp_intervals = &ed047tc2_intervals[0] }; \ No newline at end of file diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED060SC4.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED060SC4.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED060SC4.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED060SC4.h diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED060SCT.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED060SCT.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED060SCT.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED060SCT.h diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED060XC3.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED060XC3.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED060XC3.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED060XC3.h diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED097OC4.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED097OC4.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED097OC4.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED097OC4.h diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED097TC2.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED097TC2.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED097TC2.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED097TC2.h diff --git a/lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED133UT2.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED133UT2.h old mode 100755 new mode 100644 similarity index 100% rename from lib/libesp32_eink/epdiy/src/epd_driver/waveforms/epdiy_ED133UT2.h rename to lib/libesp32_eink/epdiy/src/waveforms/epdiy_ED133UT2.h diff --git a/lib/libesp32_eink/epdiy/src/waveforms/epdiy_NULL.h b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_NULL.h new file mode 100644 index 000000000..ffa1612ee --- /dev/null +++ b/lib/libesp32_eink/epdiy/src/waveforms/epdiy_NULL.h @@ -0,0 +1,28 @@ +const int epd_wp_epdiy_NULL_1_0_times[5] = { 1000,1000,1000,1000,1000 }; +const uint8_t epd_wp_epdiy_NULL_1_0_data[5][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_epdiy_NULL_1_0 = { .phases = 5, .phase_times = &epd_wp_epdiy_NULL_1_0_times[0], .luts = (const uint8_t*)&epd_wp_epdiy_NULL_1_0_data[0] }; +const EpdWaveformPhases* epd_wm_epdiy_NULL_1_ranges[1] = { &epd_wp_epdiy_NULL_1_0 }; +const EpdWaveformMode epd_wm_epdiy_NULL_1 = { .type = 1, .temp_ranges = 1, .range_data = &epd_wm_epdiy_NULL_1_ranges[0] }; +const int epd_wp_epdiy_NULL_2_0_times[30] = { 15,8,8,8,8,8,10,10,10,10,20,20,50,100,200,15,8,4,3,3,3,3,6,6,6,6,15,20,50,150 }; +const uint8_t epd_wp_epdiy_NULL_2_0_data[30][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_epdiy_NULL_2_0 = { .phases = 30, .phase_times = &epd_wp_epdiy_NULL_2_0_times[0], .luts = (const uint8_t*)&epd_wp_epdiy_NULL_2_0_data[0] }; +const EpdWaveformPhases* epd_wm_epdiy_NULL_2_ranges[1] = { &epd_wp_epdiy_NULL_2_0 }; +const EpdWaveformMode epd_wm_epdiy_NULL_2 = { .type = 2, .temp_ranges = 1, .range_data = &epd_wm_epdiy_NULL_2_ranges[0] }; +const int epd_wp_epdiy_NULL_5_0_times[30] = { 15,8,8,8,8,8,10,10,10,10,20,20,50,100,200,15,8,4,3,3,3,3,6,6,6,6,15,20,50,150 }; +const uint8_t epd_wp_epdiy_NULL_5_0_data[30][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_epdiy_NULL_5_0 = { .phases = 30, .phase_times = &epd_wp_epdiy_NULL_5_0_times[0], .luts = (const uint8_t*)&epd_wp_epdiy_NULL_5_0_data[0] }; +const EpdWaveformPhases* epd_wm_epdiy_NULL_5_ranges[1] = { &epd_wp_epdiy_NULL_5_0 }; +const EpdWaveformMode epd_wm_epdiy_NULL_5 = { .type = 5, .temp_ranges = 1, .range_data = &epd_wm_epdiy_NULL_5_ranges[0] }; +const int epd_wp_epdiy_NULL_16_0_times[15] = { 15,8,8,8,8,8,10,10,10,10,20,20,50,100,200 }; +const uint8_t epd_wp_epdiy_NULL_16_0_data[15][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_epdiy_NULL_16_0 = { .phases = 15, .phase_times = &epd_wp_epdiy_NULL_16_0_times[0], .luts = (const uint8_t*)&epd_wp_epdiy_NULL_16_0_data[0] }; +const EpdWaveformPhases* epd_wm_epdiy_NULL_16_ranges[1] = { &epd_wp_epdiy_NULL_16_0 }; +const EpdWaveformMode epd_wm_epdiy_NULL_16 = { .type = 16, .temp_ranges = 1, .range_data = &epd_wm_epdiy_NULL_16_ranges[0] }; +const int epd_wp_epdiy_NULL_17_0_times[15] = { 15,8,4,3,3,3,3,6,6,6,6,15,20,50,150 }; +const uint8_t epd_wp_epdiy_NULL_17_0_data[15][16][4] = {{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}},{{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}}}; +const EpdWaveformPhases epd_wp_epdiy_NULL_17_0 = { .phases = 15, .phase_times = &epd_wp_epdiy_NULL_17_0_times[0], .luts = (const uint8_t*)&epd_wp_epdiy_NULL_17_0_data[0] }; +const EpdWaveformPhases* epd_wm_epdiy_NULL_17_ranges[1] = { &epd_wp_epdiy_NULL_17_0 }; +const EpdWaveformMode epd_wm_epdiy_NULL_17 = { .type = 17, .temp_ranges = 1, .range_data = &epd_wm_epdiy_NULL_17_ranges[0] }; +const EpdWaveformTempInterval epdiy_NULL_intervals[1] = { { .min = 20, .max = 30 } }; +const EpdWaveformMode* epdiy_NULL_modes[5] = { &epd_wm_epdiy_NULL_1,&epd_wm_epdiy_NULL_2,&epd_wm_epdiy_NULL_5,&epd_wm_epdiy_NULL_16,&epd_wm_epdiy_NULL_17 }; +const EpdWaveform epdiy_NULL = { .num_modes = 5, .num_temp_ranges = 1, .mode_data = &epdiy_NULL_modes[0], .temp_intervals = &epdiy_NULL_intervals[0] }; diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 71fdb9890..81fbf377e 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -2553,14 +2553,6 @@ void SyslogAsync(bool refresh) { } else { strcpy(msgid, "-"); // - } -/* - char msgid[2] = { 0 }; - char* line_msgid = strchr(msg_start, ':'); - if ((line_msgid == nullptr) || (line_msgid - msg_start != 3)) { // Only 3 character message id supported - strcpy(msgid, "-"); // - - } -*/ -/* snprintf_P(header, sizeof(header), PSTR("<%d>1 %s%s000%s %s tasmota - %s -"), 128 + min(loglevel * 3, 7), // Error (1) = 131, Info (2) = 134, Debug (3) = 135, DebugMore = (4) 135 GetDate().c_str(), timestamp, GetTimeZone().c_str(), // 1970-01-01T00:00:02.096000+01:00