Compare commits

...

No commits in common. "gh-pages" and "master" have entirely different histories.

162 changed files with 14381 additions and 2980 deletions

13
.clang-format Normal file
View file

@ -0,0 +1,13 @@
Language: Cpp
BasedOnStyle: Google
IndentWidth: 2
ColumnLimit: 80
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBraces: Attach
DerivePointerAlignment: false
PointerAlignment: Left
SpacesBeforeTrailingComments: 1

46
.github/ISSUE_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,46 @@
Thank you for opening an issue on an Adafruit Arduino library repository. To
improve the speed of resolution please review the following guidelines and
common troubleshooting steps below before creating the issue:
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
something isn't working as expected. In many cases the problem is a common issue
that you will more quickly receive help from the forum community. GitHub issues
are meant for known defects in the code. If you don't know if there is a defect
in the code then start with troubleshooting on the forum first.
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
check all of the steps and commands to run have been followed. Consult the
forum if you're unsure or have questions about steps in a guide/tutorial.
- **For Arduino projects check these very common issues to ensure they don't apply**:
- For uploading sketches or communicating with the board make sure you're using
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
very hard to tell the difference between a data and charge cable! Try using the
cable with other devices or swapping to another cable to confirm it is not
the problem.
- **Be sure you are supplying adequate power to the board.** Check the specs of
your board and plug in an external power supply. In many cases just
plugging a board into your computer is not enough to power it and other
peripherals.
- **Double check all soldering joints and connections.** Flakey connections
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
- **Ensure you are using an official Arduino or Adafruit board.** We can't
guarantee a clone board will have the same functionality and work as expected
with this code and don't support them.
If you're sure this issue is a defect in the code and checked the steps above
please fill in the following fields to provide enough troubleshooting information.
You may delete the guideline and text above to just leave the following details:
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
VERSION HERE**
- List the steps to reproduce the problem below (if possible attach a sketch or
copy the sketch code in too): **LIST REPRO STEPS BELOW**

26
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,26 @@
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
Before you open the request please review the following guidelines and tips to
help it be more easily integrated:
- **Describe the scope of your change--i.e. what the change does and what parts
of the code were modified.** This will help us understand any risks of integrating
the code.
- **Describe any known limitations with your change.** For example if the change
doesn't apply to a supported platform of the library please mention it.
- **Please run any tests or examples that can exercise your modified code.** We
strive to not break users of the code and running tests/examples helps with this
process.
Thank you again for contributing! We will try to test and integrate the change
as soon as we can, but be aware we have many GitHub repositories to manage and
can't immediately respond to every request. There is no need to bump or check in
on a pull request (it will clutter the discussion of the request).
Also don't be worried if the request is closed or not integrated--sometimes the
priorities of Adafruit's GitHub code (education, ease of use) might not match the
priorities of the pull request. Don't fret, the open source community thrives on
forks and GitHub makes it easy to keep your changes in a forked repo.
After reviewing the guidelines above you can delete this text from the pull request.

72
.github/workflows/githubci.yml vendored Normal file
View file

@ -0,0 +1,72 @@
name: Arduino Library CI
on: [pull_request, push, repository_dispatch]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arduino-platform:
- 'uno'
- 'leonardo'
- 'mega2560'
- 'esp8266'
- 'esp32'
- 'trinket_m0'
- 'cpb'
- 'cpx'
- 'metro_m0'
- 'metro_m4_tinyusb'
steps:
- uses: actions/setup-python@v4
with:
python-version: '3.8'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
# manually install SDFat
- name: extra libraries
run: |
git clone --quiet https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat
git clone --quiet https://github.com/adafruit/Adafruit_SPIFlash.git /home/runner/Arduino/libraries/Adafruit_SPIFlash
- name: test platforms
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
clang_and_doxy:
runs-on: ubuntu-latest
steps:
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Checkout code
uses: actions/checkout@v2
- name: Checkout adafruit/ci-arduino
uses: actions/checkout@v2
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
- name: doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
PRETTYNAME : "Adafruit E-Paper Display Library"
run: bash ci/doxy_gen_and_deploy.sh

8
.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
default.vim
fontconvert/fontconvert
# Our handy .gitignore for automation ease
Doxyfile*
doxygen_sqlite3.db
html
.DS_STORE
*~

View file

@ -1 +0,0 @@

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# Adafruit EPD Library [![Build CI](https://github.com/adafruit/Adafruit_EPD/actions/workflows/githubci.yml/badge.svg)](https://github.com/adafruit/Adafruit_EPD/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_EPD/html/index.html)
<img src="https://cdn-shop.adafruit.com/970x728/3625-03.jpg" height="300"/>
This is a library for the Adafruit E-paper displays:
* https://www.adafruit.com/products/3625
Check out the links above for our tutorials and wiring diagrams. These devices use SPI to communicate
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
Written by Dean Miller for Adafruit Industries.
MIT license, all text above must be included in any redistribution

View file

@ -0,0 +1,137 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_EPD.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// Uncomment the following line if you are using 1.54" EPD with IL0373
// Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 1.54" EPD with SSD1680
// Adafruit_SSD1680 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 1.54" EPD with SSD1608
// Adafruit_SSD1608 display(200, 200, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 1.54" EPD with SSD1681
// Adafruit_SSD1681 display(200, 200, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 1.54" EPD with UC8151D
// Adafruit_UC8151D display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.13" EPD with SSD1680
// Adafruit_SSD1680 display(250, 122, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.13" EPD with SSD1675
// Adafruit_SSD1675 display(250, 122, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.13" EPD with SSD1675B
// Adafruit_SSD1675B display(250, 122, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.13" EPD with UC8151D
// Adafruit_UC8151D display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.13" EPD with IL0373
Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
//#define FLEXIBLE_213
// Uncomment the following line if you are using 2.7" EPD with IL91874
// Adafruit_IL91874 display(264, 176, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.7" EPD with EK79686
// Adafruit_EK79686 display(264, 176, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.9" EPD with IL0373
// Adafruit_IL0373 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI); #define FLEXIBLE_290
// Uncomment the following line if you are using 2.9" EPD with SSD1680
// Adafruit_SSD1680 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// Uncomment the following line if you are using 2.9" EPD with UC8151D
// Adafruit_UC8151D display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
#define COLOR1 EPD_BLACK
#define COLOR2 EPD_RED
void setup() {
Serial.begin(115200);
// while (!Serial) { delay(10); }
Serial.println("Adafruit EPD test");
display.begin();
#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
// The flexible displays have different buffers and invert settings!
display.setBlackBuffer(1, false);
display.setColorBuffer(1, false);
#endif
// large block of text
display.clearBuffer();
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
COLOR1);
display.display();
delay(5000);
display.clearBuffer();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, COLOR1);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i,
COLOR2); // on grayscale this will be mid-gray
}
display.display();
}
void loop() {
// don't do anything!
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

@ -0,0 +1,129 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ESP8266
#define SRAM_CS 16
#define EPD_CS 0
#define EPD_DC 15
#endif
#ifdef ESP32
#define SRAM_CS 32
#define EPD_CS 15
#define EPD_DC 33
#endif
#if defined (__AVR_ATmega32U4__) || defined(ARDUINO_SAMD_FEATHER_M0) || defined(ARDUINO_FEATHER_M4) || defined (__AVR_ATmega328P__) || defined(ARDUINO_NRF52840_FEATHER)
#define SRAM_CS 6
#define EPD_CS 9
#define EPD_DC 10
#endif
#ifdef TEENSYDUINO
#define SRAM_CS 3
#define EPD_CS 4
#define EPD_DC 10
#endif
#ifdef ARDUINO_STM32_FEATHER
#define TFT_DC PB4
#define TFT_CS PA15
#define STMPE_CS PC7
#endif
#ifdef ARDUINO_NRF52832_FEATHER
#define SRAM_CS 30
#define EPD_CS 31
#define EPD_DC 11
#endif
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040
#define SRAM_CS 8
#define EPD_CS 9
#define EPD_DC 10
#endif
#define EPD_RESET -1 // can set to -1 and share with microcontroller Reset!
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
// Uncomment the following line if you are using 2.13" Monochrome EPD with SSD1680
ThinkInk_213_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_B74 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Uncomment the following line if you are using 2.13" Tri-Color EPD with SSD1680
//ThinkInk_213_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Uncomment the following line if you are using 2.13" EPD with SSD1675
// ThinkInk_213_Mono_B72 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Uncomment the following line if you are using 2.13" EPD with SSD1675B
//ThinkInk_213_Mono_B73 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Uncomment the following line if you are using 2.13" EPD with UC8151D
//ThinkInk_213_Mono_M21 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//Uncomment the following line if you are using 2.13" EPD with IL0373
//ThinkInk_213_Tricolor_Z16 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//#define FLEXIBLE_213
// Uncomment the following line if you are using 2.9" Tri-Color EPD with IL0373
//ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Uncomment the following line if you are using 2.9" Grayscale EPD with IL0373
//ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//#define FLEXIBLE_290
// Uncomment the following line if you are using 2.9" Monochrome EPD with UC8151D
//ThinkInk_290_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Uncomment the following line if you are using 2.9" Tri-Color EPD with UC8151D
//ThinkInk_290_Tricolor_Z13 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
#define COLOR1 EPD_BLACK
#define COLOR2 EPD_RED
void setup() {
Serial.begin(115200);
//while (!Serial) { delay(10); }
Serial.println("2.13 inch EInk Featherwing test");
display.begin();
#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
// The flexible displays have different buffers and invert settings!
display.setBlackBuffer(1, false);
display.setColorBuffer(1, false);
#endif
// large block of text
display.clearBuffer();
testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", COLOR1);
display.display();
delay(5000);
display.clearBuffer();
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, COLOR1);
}
for (int16_t i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, COLOR2); // on grayscale this will be mid-gray
}
display.display();
}
void loop() {
//don't do anything!
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

View file

View file

@ -0,0 +1,92 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#define EPD_CS 0
#define EPD_DC 1
#define SRAM_CS -1
#define EPD_RESET PIN_A3 // can set to -1 and share with microcontroller Reset!
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
// You will need to use Adafruit's CircuitPlayground Express Board Definition
// for Gizmos rather than the Arduino version since there are additional SPI
// ports exposed.
#if (SPI_INTERFACES_COUNT == 1)
SPIClass* spi = &SPI;
#else
SPIClass* spi = &SPI1;
#endif
// 1.54" 152x152 Tricolor EPD with ILI0373 chipset
//ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 1.54" 200x200 Tricolor EPD with SSD1681 chipset
ThinkInk_154_Tricolor_Z90 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
float p = 3.1415926;
void setup(void) {
Serial.begin(115200);
Serial.print("Hello! EPD Gizmo Test");
display.begin(THINKINK_TRICOLOR);
Serial.println("Initialized");
}
void loop() {
Serial.println("Banner demo");
display.clearBuffer();
display.setTextSize(3);
display.setCursor((display.width() - 144)/2, (display.height() - 24)/2);
display.setTextColor(EPD_BLACK);
display.print("Tri");
display.setTextColor(EPD_RED);
display.print("Color");
display.display();
delay(15000);
Serial.println("Color rectangle demo");
display.clearBuffer();
display.fillRect(display.width()/3, 0, display.width()/3, display.height(), EPD_BLACK);
display.fillRect((display.width()*2)/3, 0, display.width()/3, display.height(), EPD_RED);
display.display();
delay(15000);
Serial.println("Text demo");
// large block of text
display.clearBuffer();
display.setTextSize(1);
testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", EPD_BLACK);
display.display();
delay(15000);
display.clearBuffer();
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, EPD_BLACK);
}
for (int16_t i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, EPD_RED);
}
display.display();
delay(15000);
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

@ -0,0 +1,147 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// ThinkInk_154_Grayscale4_T8 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 1.54" Grayscale Breakout (SSD1681)
//ThinkInk_154_Grayscale4_M05 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.13" 212x104 Grayscale display with IL0373 chipset
// ThinkInk_213_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.13" Grayscale Featherwing or Breakout (SSD1680Z)
ThinkInk_213_Grayscale4_MFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
// 2.66" Monochrome display with 296x152 pixels and SSD1680 chipset
// ThinkInk_266_Grayscale4_MFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
// EPD_SPI);
// 2.9" Grayscale Featherwing or Breakout with IL0373
// ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
// EPD_SPI);
// 2.9" 4-Grayscale display with 296x128 pixels and SSD1680 chipset
// ThinkInk_290_Grayscale4_EAAMFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 4.2" 4-Grayscale display with SSD1683 chipset
// ThinkInk_420_Grayscale4_MFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
#define COLOR1 EPD_BLACK
#define COLOR2 EPD_LIGHT
#define COLOR3 EPD_DARK
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit EPD full update test in mono & grayscale");
}
bool gray = false;
void loop() {
// alternate modes!
if (gray) {
display.begin(THINKINK_GRAYSCALE4);
Serial.println("Grayscale!");
} else {
display.begin(THINKINK_MONO);
Serial.println("Monochrome!");
}
display.clearBuffer();
display.setTextSize(3);
display.setTextColor(EPD_BLACK);
display.setCursor((display.width() - 180) / 2, (display.height() - 24) / 2);
if (gray) {
String text = "Grayscale";
uint16_t colors[] = {EPD_BLACK, EPD_DARK, EPD_LIGHT};
for (int i = 0; i < text.length(); i++) {
// Change color for every character (0: BLACK, 1: DARK, 2: LIGHT, 3: BLACK, etc.)
display.setTextColor(colors[i % 3]);
display.print(text.charAt(i));
}
} else {
display.print("Monochrome");
}
gray = !gray;
display.display();
delay(2000);
display.clearBuffer();
display.fillRect(display.width() / 4, 0, display.width() / 4,
display.height(), EPD_LIGHT);
display.fillRect((display.width() * 2) / 4, 0, display.width() / 4,
display.height(), EPD_DARK);
display.fillRect((display.width() * 3) / 4, 0, display.width() / 4,
display.height(), EPD_BLACK);
display.display();
delay(2000);
Serial.println("Text demo");
// large block of text
display.clearBuffer();
display.setTextSize(1);
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
COLOR1);
display.display();
delay(2000);
display.clearBuffer();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, COLOR1);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i,
COLOR2); // on grayscale this will be mid-gray
}
display.display();
delay(2000);
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

@ -0,0 +1,149 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// 1.54" Monochrome displays with 200x200 pixels and SSD1681 chipset
// ThinkInk_154_Mono_D67 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 1.54" Monochrome displays with 200x200 pixels and SSD1608 chipset
// ThinkInk_154_Mono_D27 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 1.54" Monochrome displays with 152x152 pixels and UC8151D chipset
// ThinkInk_154_Mono_M10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.13" Monochrome displays with 250x122 pixels and SSD1675 chipset
ThinkInk_213_Mono_B72 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.13" Monochrome displays with 250x122 pixels and SSD1675B chipset
// ThinkInk_213_Mono_B73 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.13" Monochrome displays with 250x122 pixels and SSD1680 chipset
// ThinkInk_213_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// ThinkInk_213_Mono_B74 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// The GDEY0213B74 is like the B74 above but is not 'shifted down' by 8 pixels
// ThinkInk_213_Mono_GDEY0213B74 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.13" Monochrome displays with 212x104 pixels and UC8151D chipset
// ThinkInk_213_Mono_M21 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.66" Monochrome display with 296x152 pixels and SSD1680 chipset
// ThinkInk_266_Grayscale4_MFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
// EPD_SPI);
// 2.9" 4-level Grayscale (use mono) displays with 296x128 pixels and SSD1680 chip
// ThinkInk_290_Grayscale4_EAAMFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 2.9" 4-level Grayscale (use mono) displays with 296x128 pixels and IL0373 chipset
// ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.9" Monochrome displays with 296x128 pixels and UC8151D chipset
// ThinkInk_290_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 3.7" Monochrome Display with 420x240 pixels and UC8253 chipset
// ThinkInk_370_Mono_BAAMFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 4.2" Monochrome displays with 400x300 pixels and SSD1619 chipset
// ThinkInk_420_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 4.2" Monochrome displays with 400x300 pixels and UC8276 chipset
// ThinkInk_420_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 4.2" Grayscale/Monochrome displays with 400x300 pixels and SSD1683 chipset
// ThinkInk_420_Grayscale4_MFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 5.83" Monochrome displays with 648 x 480 pixels and UC8179 chipset
// ThinkInk_583_Mono_AAAMFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 7.5" Monochrome displays with 800 x 480 pixels and UC8179 chipset
// ThinkInk_750_Mono_AAAMFGN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit EPD full update test in mono");
display.begin(THINKINK_MONO);
}
void loop() {
Serial.println("Banner demo");
display.clearBuffer();
display.setTextSize(3);
display.setCursor((display.width() - 180) / 2, (display.height() - 24) / 2);
display.setTextColor(EPD_BLACK);
display.print("Monochrome");
display.display();
delay(2000);
Serial.println("B/W rectangle demo");
display.clearBuffer();
display.fillRect(display.width() / 2, 0, display.width() / 2,
display.height(), EPD_BLACK);
display.display();
delay(2000);
Serial.println("Text demo");
// large block of text
display.clearBuffer();
display.setTextSize(1);
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
EPD_BLACK);
display.display();
delay(2000);
display.clearBuffer();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, EPD_BLACK);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i, EPD_BLACK);
}
display.display();
delay(2000);
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

@ -0,0 +1,71 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
ThinkInk_154_Mono_D67 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit counter");
display.begin(THINKINK_MONO);
display.setRotation(0);
}
uint16_t counter = 0;
void loop() {
display.clearBuffer();
display.setTextSize(4);
display.setTextColor(EPD_BLACK);
display.setCursor(32, 32);
display.print((counter / 1000) % 10);
display.print((counter / 100) % 10);
display.print((counter / 10) % 10);
display.print(counter % 10);
if ((counter % 10) == 0) {
display.display(false);
} else {
// redraw only 4th digit
display.displayPartial(32 + (24 * 3), 32, 32 + (24 * 4), 32 + (4 * 8));
}
counter++;
/*
display.fillRect(0, 0, 16, 32, EPD_BLACK);
display.fillRect(4, 4, 8, 24, EPD_WHITE);
// display.display();
display.displayPartial(0, 0, 16, 32);
delay(3000);
*/
}

View file

@ -0,0 +1,114 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// 2.13" Quadcolor EPD with JD79661 chipset
ThinkInk_213_Quadcolor_AJHE5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 3.52" Quadcolor EPD with JD79667 chipset
//ThinkInk_352_Quadcolor_AJHE5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit EPD full update test in red/yellow/black/white");
display.begin(THINKINK_QUADCOLOR);
}
void loop() {
Serial.println("Banner demo");
display.clearBuffer();
display.setTextSize(3);
display.setCursor((display.width() - 144) / 2, (display.height() - 24) / 2);
String text = "QuadColor";
uint16_t colors[] = {EPD_BLACK, EPD_RED, EPD_YELLOW};
for (int i = 0; i < text.length(); i++) {
// Change color for every character (0: BLACK, 1: RED, 2: YELLOW, 3: BLACK, etc.)
display.setTextColor(colors[i % 3]);
display.print(text.charAt(i));
}
display.display();
delay(15000);
Serial.println("Color quadrant demo");
display.clearBuffer();
// Top-left quadrant - EPD_BLACK
display.fillRect(0, 0, display.width() / 2, display.height() / 2, EPD_BLACK);
// Top-right quadrant - EPD_RED
display.fillRect(display.width() / 2, 0, display.width() / 2, display.height() / 2, EPD_RED);
// Bottom-left quadrant - EPD_YELLOW
display.fillRect(0, display.height() / 2, display.width() / 2, display.height() / 2, EPD_YELLOW);
// Bottom-right quadrant - assume you have a 4th color like EPD_WHITE or another color
display.fillRect(display.width() / 2, display.height() / 2, display.width() / 2, display.height() / 2, EPD_WHITE);
display.display();
delay(15000);
Serial.println("Text demo");
// large block of text
display.clearBuffer();
display.setTextSize(1);
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
EPD_BLACK);
display.display();
delay(15000);
display.clearBuffer();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, EPD_BLACK);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i, EPD_RED);
}
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(display.width()/2, display.height()-1, i, 0,
EPD_YELLOW);
}
display.display();
delay(15000);
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

@ -0,0 +1,168 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_ThinkInk.h"
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
// 1.54" 152x152 Tricolor EPD with ILI0373 chipset
// ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 1.54" 152x152 Tricolor EPD with SSD1680 chipset
// ThinkInk_154_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 1.54" 200x200 Tricolor EPD with SSD1681 chipset
// ThinkInk_154_Tricolor_Z90 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.13" Tricolor EPD with SSD1680 chipset
ThinkInk_213_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
// 2.13" Tricolor EPD with SSD1680Z chipset
// ThinkInk_213_Tricolor_MFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.13" Tricolor EPD with IL0373 chipset
// ThinkInk_213_Tricolor_Z16 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.66" Tricolor EPD with SSD1680Z chipset
// ThinkInk_266_Tricolor_MFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.7" Tricolor Featherwing or Breakout with IL91874 chipset
// ThinkInk_270_Tricolor_C44 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.7" Tricolor Featherwing or Breakout with EK79686 chipset
// ThinkInk_270_Tricolor_Z70 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.9" Tricolor Featherwing or Breakout with IL0373 chipset
// ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.9" Tricolor Featherwing or Breakout with UC8151D chipset
// ThinkInk_290_Tricolor_Z13 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 2.9" Tricolor Featherwing or Breakout with SSD1680 chipset and negative
// offset
// ThinkInk_290_Tricolor_Z94 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 3.7" Tricolor Display with 420x240 pixels and UC8253 chipset
// ThinkInk_370_Tricolor_BABMFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// ThinkInk_420_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// ThinkInk_420_Tricolor_Z21 display(EPD_DC, EPD_RESET,
// EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 4.2" Tricolor EPD with SSD1683 chipset
// ThinkInk_420_Tricolor_MFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
// 5.83 Tricolor displays with 648x480 pixels and UC8179 chipset
// ThinkInk_583_Tricolor_AABMFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
// 7.5" Tricolor displays with 800x480 pixels and UC8179 chipset
// ThinkInk_750_Tricolor_AABMFGNR display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY, EPD_SPI);
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit EPD full update test in red/black/white");
display.begin(THINKINK_TRICOLOR);
}
void loop() {
Serial.println("Banner demo");
display.clearBuffer();
display.setTextSize(3);
display.setCursor((display.width() - 144) / 2, (display.height() - 24) / 2);
display.setTextColor(EPD_BLACK);
display.print("Tri");
display.setTextColor(EPD_RED);
display.print("Color");
display.display();
delay(15000);
Serial.println("Color rectangle demo");
display.clearBuffer();
display.fillRect(display.width() / 3, 0, display.width() / 3,
display.height(), EPD_BLACK);
display.fillRect((display.width() * 2) / 3, 0, display.width() / 3,
display.height(), EPD_RED);
display.display();
delay(15000);
Serial.println("Text demo");
// large block of text
display.clearBuffer();
display.setTextSize(1);
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
EPD_BLACK);
display.display();
delay(15000);
display.clearBuffer();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, EPD_BLACK);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i, EPD_RED);
}
display.display();
delay(15000);
}
void testdrawtext(const char *text, uint16_t color) {
display.setCursor(0, 0);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
}

View file

@ -0,0 +1,291 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_EPD.h"
#include <Adafruit_SPIFlash.h>
#include <SPI.h>
#include <SdFat.h>
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_CS 9
#define EPD_DC 10
#define SRAM_CS -1 // Use the build in memory, we need 133KB!
#define EPD_RESET 6 // can set to -1 and share with microcontroller Reset!
#define EPD_BUSY 5 // can set to -1 to not use a pin (will wait a fixed delay)
#define EPD_SPI &SPI // primary SPI
#endif
// Uncomment the following line if you are using ACeP 7 color 5.65"
Adafruit_ACEP display(600, 448, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
Adafruit_FlashTransport_QSPI flashTransport;
Adafruit_SPIFlash flash(&flashTransport);
FatFileSystem fatfs;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Adafruit ACeP EPD test");
if (!flash.begin()) {
Serial.println("Error, failed to initialize flash chip!");
while (1)
delay(1);
}
Serial.print("Flash chip JEDEC ID: 0x");
Serial.println(flash.getJEDECID(), HEX);
// First call begin to mount the filesystem. Check that it returns true
// to make sure the filesystem was mounted.
if (!fatfs.begin(&flash)) {
Serial.println("Error, failed to mount newly formatted filesystem!");
Serial.println(
"Was the flash chip formatted with the fatfs_format example?");
while (1)
delay(1);
}
Serial.println("Mounted filesystem!");
File root = fatfs.open("/");
printDirectory(root, 0);
display.begin();
display.setRotation(0);
display.clearBuffer();
// draw 7 color bars
for (uint8_t color = ACEP_COLOR_BLACK; color <= ACEP_COLOR_ORANGE; color++) {
display.fillRect(display.width() * color / 7, 0, display.width() / 7,
display.height(), color);
}
display.display();
}
void loop() {
bmpDraw("adafruit_characters.bmp", 0, 0);
bmpDraw("adabot.bmp", 0, 0);
}
// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates. It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel). Increasing the buffer
// size takes more of the Arduino's precious RAM but
// makes loading a little faster. 20 pixels seems a
// good balance.
#define BUFFPIXEL 20
bool bmpDraw(const char *filename, int16_t x, int16_t y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3 * BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col, x2, y2, bx1, by1;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
if ((x >= display.width()) || (y >= display.height()))
return false;
Serial.println();
Serial.print(F("Loading image '"));
Serial.print(filename);
Serial.println('\'');
// Open requested file on SD card
if ((bmpFile = fatfs.open(filename, FILE_READ)) == false) {
Serial.print(F("File not found"));
return false;
}
// Parse BMP header
if (read16(bmpFile) == 0x4D42) { // BMP signature
Serial.print(F("File size: "));
Serial.println(read32(bmpFile));
(void)read32(bmpFile); // Read & ignore creator bytes
bmpImageoffset = read32(bmpFile); // Start of image data
Serial.print(F("Image Offset: "));
Serial.println(bmpImageoffset, DEC);
// Read DIB header
Serial.print(F("Header size: "));
Serial.println(read32(bmpFile));
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if (read16(bmpFile) == 1) { // # planes -- must be '1'
bmpDepth = read16(bmpFile); // bits per pixel
Serial.print(F("Bit Depth: "));
Serial.println(bmpDepth);
if ((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
goodBmp = true; // Supported BMP format -- proceed!
Serial.print(F("Image size: "));
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if (bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
x2 = x + bmpWidth - 1; // Lower-right corner
y2 = y + bmpHeight - 1;
if ((x2 >= 0) && (y2 >= 0)) { // On screen?
w = bmpWidth; // Width/height of section to load/display
h = bmpHeight;
bx1 = by1 = 0; // UL coordinate in BMP file
for (row = 0; row < h; row++) { // For each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on every line, but this
// method covers a lot of gritty details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position actually needs to change
// (avoids a lot of cluster math in SD library).
if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - (row + by1)) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + (row + by1) * rowSize;
pos += bx1 * 3; // Factor in starting column (bx1)
if (bmpFile.position() != pos) { // Need seek?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // Force buffer reload
}
for (col = 0; col < w; col++) { // For each pixel...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer)) { // Indeed
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
}
// Convert pixel from BMP to EPD format, push to display
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
uint32_t color = r;
color <<= 8;
color |= g;
color <<= 8;
color |= b;
uint8_t c;
switch (color) {
case 0x000000:
c = ACEP_COLOR_BLACK;
break;
case 0xFFFFFF:
c = ACEP_COLOR_WHITE;
break;
case 0x00FF00:
c = ACEP_COLOR_GREEN;
break;
case 0x0000FF:
c = ACEP_COLOR_BLUE;
break;
case 0xFF0000:
c = ACEP_COLOR_RED;
break;
case 0xFFFF00:
c = ACEP_COLOR_YELLOW;
break;
case 0xFF8000:
c = ACEP_COLOR_ORANGE;
break;
default: {
Serial.print("Unknown color 0x");
Serial.println(color, HEX);
c = ACEP_COLOR_WHITE;
}
}
display.writePixel(col, row, c);
} // end pixel
} // end scanline
} // end onscreen
display.display();
Serial.print(F("Loaded in "));
Serial.print(millis() - startTime);
Serial.println(" ms");
} // end goodBmp
}
}
bmpFile.close();
if (!goodBmp) {
Serial.println(F("BMP format not recognized."));
return false;
}
return true;
}
// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.
uint16_t read16(File &f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File &f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
void printDirectory(File dir, int numTabs) {
char filename[80];
while (true) {
File entry = dir.openNextFile();
if (!entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
entry.getName(filename, 80);
Serial.print(filename);
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

View file

@ -0,0 +1,329 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_EPD.h"
#include <Adafruit_GFX.h> // Core graphics library
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
/* Uncomment the following line if you are using 1.54" tricolor EPD */
// Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 1.54" monochrome EPD */
// Adafruit_SSD1608 display(200, 200, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.13" tricolor EPD */
Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
//#define FLEXIBLE_213
/* Uncomment the following line if you are using 2.13" monochrome 250*122 EPD */
// Adafruit_SSD1675 display(250, 122, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.7" tricolor or grayscale EPD
*/
// Adafruit_IL91874 display(264, 176, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.9" EPD */
// Adafruit_IL0373 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI); #define FLEXIBLE_290
/* Uncomment the following line if you are using 4.2" tricolor EPD */
// Adafruit_IL0398 display(300, 400, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
float p = 3.1415926;
void setup(void) {
Serial.begin(9600);
Serial.print("Hello! EPD Test");
display.begin();
#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
// The flexible displays have different buffers and invert settings!
display.setBlackBuffer(1, false);
display.setColorBuffer(1, false);
#endif
Serial.println("Initialized");
display.clearBuffer();
display.fillRect(display.width() / 3, 0, display.width() / 3,
display.height(), EPD_RED);
display.fillRect((display.width() * 2) / 3, 0, display.width() / 3,
display.height(), EPD_BLACK);
display.display();
delay(15 * 1000);
// large block of text
display.clearBuffer();
display.fillScreen(EPD_WHITE);
testdrawtext(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
"tortor imperdiet posuere. ",
EPD_BLACK);
delay(15 * 1000);
// epd print function!
epdPrintTest();
delay(15 * 1000);
// a single pixel
display.clearBuffer();
display.drawPixel(display.width() / 2, display.height() / 2, EPD_BLACK);
delay(15 * 1000);
testtriangles();
delay(15 * 1000);
// line draw test
testlines(EPD_BLACK);
delay(15 * 1000);
// optimized lines
testfastlines(EPD_BLACK, EPD_RED);
delay(15 * 1000);
testdrawrects(EPD_RED);
delay(15 * 1000);
testfillrects(EPD_BLACK, EPD_RED);
delay(15 * 1000);
display.fillScreen(EPD_WHITE);
testfillcircles(10, EPD_RED);
testdrawcircles(10, EPD_BLACK);
delay(15 * 1000);
testroundrects();
delay(15 * 1000);
mediabuttons();
Serial.println("done");
}
void loop() { delay(500); }
void testlines(uint16_t color) {
display.clearBuffer();
display.fillScreen(EPD_WHITE);
for (int16_t x = 0; x < display.width(); x += 6) {
display.drawLine(0, 0, x, display.height() - 1, color);
}
for (int16_t y = 0; y < display.height(); y += 6) {
display.drawLine(0, 0, display.width() - 1, y, color);
}
display.fillScreen(EPD_WHITE);
for (int16_t x = 0; x < display.width(); x += 6) {
display.drawLine(display.width() - 1, 0, x, display.height() - 1, color);
}
for (int16_t y = 0; y < display.height(); y += 6) {
display.drawLine(display.width() - 1, 0, 0, y, color);
}
display.fillScreen(EPD_WHITE);
for (int16_t x = 0; x < display.width(); x += 6) {
display.drawLine(0, display.height() - 1, x, 0, color);
}
for (int16_t y = 0; y < display.height(); y += 6) {
display.drawLine(0, display.height() - 1, display.width() - 1, y, color);
}
display.fillScreen(EPD_WHITE);
for (int16_t x = 0; x < display.width(); x += 6) {
display.drawLine(display.width() - 1, display.height() - 1, x, 0, color);
}
for (int16_t y = 0; y < display.height(); y += 6) {
display.drawLine(display.width() - 1, display.height() - 1, 0, y, color);
}
display.display();
}
void testdrawtext(const char *text, uint16_t color) {
display.clearBuffer();
display.setCursor(5, 5);
display.setTextColor(color);
display.setTextWrap(true);
display.print(text);
display.display();
}
void testfastlines(uint16_t color1, uint16_t color2) {
display.clearBuffer();
display.fillScreen(EPD_WHITE);
for (int16_t y = 0; y < display.height(); y += 5) {
display.drawFastHLine(0, y, display.width(), color1);
}
for (int16_t x = 0; x < display.width(); x += 5) {
display.drawFastVLine(x, 0, display.height(), color2);
}
display.display();
}
void testdrawrects(uint16_t color) {
display.clearBuffer();
display.fillScreen(EPD_WHITE);
for (int16_t x = 0; x < display.width(); x += 6) {
display.drawRect(display.width() / 2 - x / 2, display.height() / 2 - x / 2,
x, x, color);
}
display.display();
}
void testfillrects(uint16_t color1, uint16_t color2) {
display.clearBuffer();
display.fillScreen(EPD_WHITE);
for (int16_t x = display.width() - 1; x > 6; x -= 6) {
display.fillRect(display.width() / 2 - x / 2, display.height() / 2 - x / 2,
x, x, color1);
display.drawRect(display.width() / 2 - x / 2, display.height() / 2 - x / 2,
x, x, color2);
}
display.display();
}
void testfillcircles(uint8_t radius, uint16_t color) {
display.clearBuffer();
for (int16_t x = radius; x < display.width(); x += radius * 2) {
for (int16_t y = radius; y < display.height(); y += radius * 2) {
display.fillCircle(x, y, radius, color);
}
}
display.display();
}
void testdrawcircles(uint8_t radius, uint16_t color) {
display.clearBuffer();
for (int16_t x = 0; x < display.width() + radius; x += radius * 2) {
for (int16_t y = 0; y < display.height() + radius; y += radius * 2) {
display.drawCircle(x, y, radius, color);
}
}
display.display();
}
void testtriangles() {
display.clearBuffer();
display.fillScreen(EPD_WHITE);
int color = EPD_BLACK;
int t;
int w = display.width() / 2;
int x = display.height() - 1;
int y = 0;
int z = display.width();
for (t = 0; t <= 15; t++) {
display.drawTriangle(w, y, y, x, z, x, color);
x -= 4;
y += 4;
z -= 4;
if (t == 8)
color = EPD_RED;
}
display.display();
}
void testroundrects() {
display.clearBuffer();
display.fillScreen(EPD_WHITE);
int color = EPD_BLACK;
int i;
int t;
for (t = 0; t <= 4; t += 1) {
int x = 0;
int y = 0;
int w = display.width() - 2;
int h = display.height() - 2;
for (i = 0; i <= 16; i += 1) {
display.drawRoundRect(x, y, w, h, 5, color);
x += 2;
y += 3;
w -= 4;
h -= 6;
if (i == 7)
color = EPD_RED;
}
color = EPD_BLACK;
}
display.display();
}
void epdPrintTest() {
display.clearBuffer();
display.setCursor(5, 5);
display.fillScreen(EPD_WHITE);
display.setTextColor(EPD_BLACK);
display.setTextSize(2);
display.println("Hello World!");
display.setTextSize(1);
display.setTextColor(EPD_RED);
display.print(p, 6);
display.println(" Want pi?");
display.println(" ");
display.print(8675309, HEX); // print 8,675,309 out in HEX!
display.println(" Print HEX!");
display.println(" ");
display.setTextColor(EPD_BLACK);
display.println("Sketch has been");
display.println("running for: ");
display.setTextColor(EPD_RED);
display.print(millis() / 1000);
display.setTextColor(EPD_BLACK);
display.print(" seconds.");
display.display();
}
void mediabuttons() {
display.clearBuffer();
// play
display.fillScreen(EPD_WHITE);
display.fillRoundRect(25, 10, 78, 60, 8, EPD_BLACK);
display.fillTriangle(42, 20, 42, 60, 90, 40, EPD_RED);
// pause
display.fillRoundRect(25, 90, 78, 60, 8, EPD_BLACK);
display.fillRoundRect(39, 98, 20, 45, 5, EPD_RED);
display.fillRoundRect(69, 98, 20, 45, 5, EPD_RED);
display.display();
}

View file

@ -0,0 +1,87 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_EPD.h"
#include <Adafruit_GFX.h> // Core graphics library
// Default is FeatherWing pinouts
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
/* Uncomment the following line if you are using 1.54" tricolor EPD */
// Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 1.54" monochrome EPD */
// Adafruit_SSD1608 display(200, 200, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.13" tricolor EPD */
Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
//#define FLEXIBLE_213
/* Uncomment the following line if you are using 2.13" monochrome 250*122 EPD */
// Adafruit_SSD1675 display(250, 122, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.7" tricolor or grayscale EPD
*/
// Adafruit_IL91874 display(264, 176, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.9" EPD */
// Adafruit_IL0373 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI); #define FLEXIBLE_290
/* Uncomment the following line if you are using 4.2" tricolor EPD */
// Adafruit_IL0398 display(300, 400, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
void setup(void) {
Serial.begin(115200);
Serial.print("Hello! EPD Test");
display.begin();
Serial.println("Initialized");
#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
// The flexible displays have different buffers and invert settings!
display.setBlackBuffer(1, false);
display.setColorBuffer(1, false);
#endif
}
void loop() {
for (int rot = 0; rot < 4; rot++) {
display.setRotation(rot);
display.clearBuffer();
display.fillScreen(EPD_WHITE);
display.drawRect(10, 20, 10, 20, EPD_BLACK);
display.display();
delay(1000);
}
}

View file

@ -0,0 +1,92 @@
/***************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_EPD.h"
#include <Adafruit_GFX.h> // Core graphics library
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
// Feather RP2040 ThinkInk
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
#define SRAM_CS -1 // use onboard RAM
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
#else
#define EPD_DC 10
#define EPD_CS 9
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
#define SRAM_CS 6
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
#define EPD_SPI &SPI // primary SPI
#endif
/* Uncomment the following line if you are using 1.54" tricolor EPD */
// Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 1.54" monochrome EPD */
// Adafruit_SSD1608 display(200, 200, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.13" tricolor EPD */
Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
EPD_SPI);
//#define FLEXIBLE_213
/* Uncomment the following line if you are using 2.13" monochrome 250*122 EPD */
// Adafruit_SSD1675 display(250, 122, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.7" tricolor or grayscale EPD
*/
// Adafruit_IL91874 display(264, 176, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
/* Uncomment the following line if you are using 2.9" EPD */
// Adafruit_IL0373 display(296, 128, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI); #define FLEXIBLE_290
/* Uncomment the following line if you are using 4.2" tricolor EPD */
// Adafruit_IL0398 display(300, 400, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS,
// EPD_BUSY, EPD_SPI);
void setup(void) {
Serial.begin(115200);
Serial.print("Hello! EPD Test");
display.begin();
#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
// The flexible displays have different buffers and invert settings!
display.setBlackBuffer(1, false);
display.setColorBuffer(1, false);
#endif
Serial.println("Initialized");
display.setRotation(2);
// large block of text
display.clearBuffer();
display.setTextWrap(true);
display.setCursor(10, 10);
display.setTextSize(1);
display.setTextColor(EPD_BLACK);
display.print(
"Get as much education as you can. Nobody can take that away from you");
display.setCursor(50, 70);
display.setTextColor(EPD_RED);
display.print("--Eben Upton");
display.display();
}
void loop() { delay(500); }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -1,97 +0,0 @@
function toggleVisibility(linkObj)
{
var base = $(linkObj).attr('id');
var summary = $('#'+base+'-summary');
var content = $('#'+base+'-content');
var trigger = $('#'+base+'-trigger');
var src=$(trigger).attr('src');
if (content.is(':visible')===true) {
content.hide();
summary.show();
$(linkObj).addClass('closed').removeClass('opened');
$(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
content.show();
summary.hide();
$(linkObj).removeClass('closed').addClass('opened');
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
}
return false;
}
function updateStripes()
{
$('table.directory tr').
removeClass('even').filter(':visible:even').addClass('even');
}
function toggleLevel(level)
{
$('table.directory tr').each(function() {
var l = this.id.split('_').length-1;
var i = $('#img'+this.id.substring(3));
var a = $('#arr'+this.id.substring(3));
if (l<level+1) {
i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
a.html('&#9660;');
$(this).show();
} else if (l==level+1) {
i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
a.html('&#9658;');
$(this).show();
} else {
$(this).hide();
}
});
updateStripes();
}
function toggleFolder(id)
{
// the clicked row
var currentRow = $('#row_'+id);
// all rows after the clicked row
var rows = currentRow.nextAll("tr");
var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
// only match elements AFTER this one (can't hide elements before)
var childRows = rows.filter(function() { return this.id.match(re); });
// first row is visible we are HIDING
if (childRows.filter(':first').is(':visible')===true) {
// replace down arrow by right arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
currentRowSpans.filter(".arrow").html('&#9658;');
rows.filter("[id^=row_"+id+"]").hide(); // hide all children
} else { // we are SHOWING
// replace right arrow by down arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
currentRowSpans.filter(".arrow").html('&#9660;');
// replace down arrows by right arrows for child rows
var childRowsSpans = childRows.find("span");
childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
childRowsSpans.filter(".arrow").html('&#9658;');
childRows.show(); //show all children
}
updateStripes();
}
function toggleInherit(id)
{
var rows = $('tr.inherit.'+id);
var img = $('tr.inherit_header.'+id+' img');
var src = $(img).attr('src');
if (rows.filter(':first').is(':visible')===true) {
rows.css('display','none');
$(img).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
rows.css('display','table-row'); // using show() causes jump in firefox
$(img).attr('src',src.substring(0,src.length-10)+'open.png');
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

View file

@ -1,73 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Adafruit E-Paper Display Library: Main Page</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Adafruit E-Paper Display Library
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">Adafruit E-Paper Display Library Documentation</div> </div>
</div><!--header-->
<div class="contents">
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>

87
html/jquery.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,26 +0,0 @@
function initMenu(relPath,searchEnabled,serverSide,searchPage,search) {
function makeTree(data,relPath) {
var result='';
if ('children' in data) {
result+='<ul>';
for (var i in data.children) {
result+='<li><a href="'+relPath+data.children[i].url+'">'+
data.children[i].text+'</a>'+
makeTree(data.children[i],relPath)+'</li>';
}
result+='</ul>';
}
return result;
}
$('#main-nav').append(makeTree(menudata,relPath));
$('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu');
if (searchEnabled) {
if (serverSide) {
$('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><div class="left"><form id="FSearchBox" action="'+searchPage+'" method="get"><img id="MSearchSelect" src="'+relPath+'search/mag.png" alt=""/><input type="text" id="MSearchField" name="query" value="'+search+'" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)"></form></div><div class="right"></div></div></li>');
} else {
$('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><span class="left"><img id="MSearchSelect" src="'+relPath+'search/mag_sel.png" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/><input type="text" id="MSearchField" value="'+search+'" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/></span><span class="right"><a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="'+relPath+'search/close.png" alt=""/></a></span></div></li>');
}
}
$('#main-menu').smartmenus();
}

View file

@ -1,2 +0,0 @@
var menudata={children:[
{text:"Main Page",url:"index.html"}]}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 B

View file

@ -1,12 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</body>
</html>

View file

@ -1,271 +0,0 @@
/*---------------- Search Box */
#FSearchBox {
float: left;
}
#MSearchBox {
white-space : nowrap;
float: none;
margin-top: 8px;
right: 0px;
width: 170px;
height: 24px;
z-index: 102;
}
#MSearchBox .left
{
display:block;
position:absolute;
left:10px;
width:20px;
height:19px;
background:url('search_l.png') no-repeat;
background-position:right;
}
#MSearchSelect {
display:block;
position:absolute;
width:20px;
height:19px;
}
.left #MSearchSelect {
left:4px;
}
.right #MSearchSelect {
right:5px;
}
#MSearchField {
display:block;
position:absolute;
height:19px;
background:url('search_m.png') repeat-x;
border:none;
width:115px;
margin-left:20px;
padding-left:4px;
color: #909090;
outline: none;
font: 9pt Arial, Verdana, sans-serif;
-webkit-border-radius: 0px;
}
#FSearchBox #MSearchField {
margin-left:15px;
}
#MSearchBox .right {
display:block;
position:absolute;
right:10px;
top:8px;
width:20px;
height:19px;
background:url('search_r.png') no-repeat;
background-position:left;
}
#MSearchClose {
display: none;
position: absolute;
top: 4px;
background : none;
border: none;
margin: 0px 4px 0px 0px;
padding: 0px 0px;
outline: none;
}
.left #MSearchClose {
left: 6px;
}
.right #MSearchClose {
right: 2px;
}
.MSearchBoxActive #MSearchField {
color: #000000;
}
/*---------------- Search filter selection */
#MSearchSelectWindow {
display: none;
position: absolute;
left: 0; top: 0;
border: 1px solid #90A5CE;
background-color: #F9FAFC;
z-index: 10001;
padding-top: 4px;
padding-bottom: 4px;
-moz-border-radius: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
}
.SelectItem {
font: 8pt Arial, Verdana, sans-serif;
padding-left: 2px;
padding-right: 12px;
border: 0px;
}
span.SelectionMark {
margin-right: 4px;
font-family: monospace;
outline-style: none;
text-decoration: none;
}
a.SelectItem {
display: block;
outline-style: none;
color: #000000;
text-decoration: none;
padding-left: 6px;
padding-right: 12px;
}
a.SelectItem:focus,
a.SelectItem:active {
color: #000000;
outline-style: none;
text-decoration: none;
}
a.SelectItem:hover {
color: #FFFFFF;
background-color: #3D578C;
outline-style: none;
text-decoration: none;
cursor: pointer;
display: block;
}
/*---------------- Search results window */
iframe#MSearchResults {
width: 60ex;
height: 15em;
}
#MSearchResultsWindow {
display: none;
position: absolute;
left: 0; top: 0;
border: 1px solid #000;
background-color: #EEF1F7;
z-index:10000;
}
/* ----------------------------------- */
#SRIndex {
clear:both;
padding-bottom: 15px;
}
.SREntry {
font-size: 10pt;
padding-left: 1ex;
}
.SRPage .SREntry {
font-size: 8pt;
padding: 1px 5px;
}
body.SRPage {
margin: 5px 2px;
}
.SRChildren {
padding-left: 3ex; padding-bottom: .5em
}
.SRPage .SRChildren {
display: none;
}
.SRSymbol {
font-weight: bold;
color: #425E97;
font-family: Arial, Verdana, sans-serif;
text-decoration: none;
outline: none;
}
a.SRScope {
display: block;
color: #425E97;
font-family: Arial, Verdana, sans-serif;
text-decoration: none;
outline: none;
}
a.SRSymbol:focus, a.SRSymbol:active,
a.SRScope:focus, a.SRScope:active {
text-decoration: underline;
}
span.SRScope {
padding-left: 4px;
}
.SRPage .SRStatus {
padding: 2px 5px;
font-size: 8pt;
font-style: italic;
}
.SRResult {
display: none;
}
DIV.searchresults {
margin-left: 10px;
margin-right: 10px;
}
/*---------------- External search page results */
.searchresult {
background-color: #F0F3F8;
}
.pages b {
color: white;
padding: 5px 5px 3px 5px;
background-image: url("../tab_a.png");
background-repeat: repeat-x;
text-shadow: 0 1px 1px #000000;
}
.pages {
line-height: 17px;
margin-left: 4px;
text-decoration: none;
}
.hl {
font-weight: bold;
}
#searchresults {
margin-bottom: 20px;
}
.searchpages {
margin-top: 10px;
}

View file

@ -1,791 +0,0 @@
function convertToId(search)
{
var result = '';
for (i=0;i<search.length;i++)
{
var c = search.charAt(i);
var cn = c.charCodeAt(0);
if (c.match(/[a-z0-9\u0080-\uFFFF]/))
{
result+=c;
}
else if (cn<16)
{
result+="_0"+cn.toString(16);
}
else
{
result+="_"+cn.toString(16);
}
}
return result;
}
function getXPos(item)
{
var x = 0;
if (item.offsetWidth)
{
while (item && item!=document.body)
{
x += item.offsetLeft;
item = item.offsetParent;
}
}
return x;
}
function getYPos(item)
{
var y = 0;
if (item.offsetWidth)
{
while (item && item!=document.body)
{
y += item.offsetTop;
item = item.offsetParent;
}
}
return y;
}
/* A class handling everything associated with the search panel.
Parameters:
name - The name of the global variable that will be
storing this instance. Is needed to be able to set timeouts.
resultPath - path to use for external files
*/
function SearchBox(name, resultsPath, inFrame, label)
{
if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }
// ---------- Instance variables
this.name = name;
this.resultsPath = resultsPath;
this.keyTimeout = 0;
this.keyTimeoutLength = 500;
this.closeSelectionTimeout = 300;
this.lastSearchValue = "";
this.lastResultsPage = "";
this.hideTimeout = 0;
this.searchIndex = 0;
this.searchActive = false;
this.insideFrame = inFrame;
this.searchLabel = label;
// ----------- DOM Elements
this.DOMSearchField = function()
{ return document.getElementById("MSearchField"); }
this.DOMSearchSelect = function()
{ return document.getElementById("MSearchSelect"); }
this.DOMSearchSelectWindow = function()
{ return document.getElementById("MSearchSelectWindow"); }
this.DOMPopupSearchResults = function()
{ return document.getElementById("MSearchResults"); }
this.DOMPopupSearchResultsWindow = function()
{ return document.getElementById("MSearchResultsWindow"); }
this.DOMSearchClose = function()
{ return document.getElementById("MSearchClose"); }
this.DOMSearchBox = function()
{ return document.getElementById("MSearchBox"); }
// ------------ Event Handlers
// Called when focus is added or removed from the search field.
this.OnSearchFieldFocus = function(isActive)
{
this.Activate(isActive);
}
this.OnSearchSelectShow = function()
{
var searchSelectWindow = this.DOMSearchSelectWindow();
var searchField = this.DOMSearchSelect();
if (this.insideFrame)
{
var left = getXPos(searchField);
var top = getYPos(searchField);
left += searchField.offsetWidth + 6;
top += searchField.offsetHeight;
// show search selection popup
searchSelectWindow.style.display='block';
left -= searchSelectWindow.offsetWidth;
searchSelectWindow.style.left = left + 'px';
searchSelectWindow.style.top = top + 'px';
}
else
{
var left = getXPos(searchField);
var top = getYPos(searchField);
top += searchField.offsetHeight;
// show search selection popup
searchSelectWindow.style.display='block';
searchSelectWindow.style.left = left + 'px';
searchSelectWindow.style.top = top + 'px';
}
// stop selection hide timer
if (this.hideTimeout)
{
clearTimeout(this.hideTimeout);
this.hideTimeout=0;
}
return false; // to avoid "image drag" default event
}
this.OnSearchSelectHide = function()
{
this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
this.closeSelectionTimeout);
}
// Called when the content of the search field is changed.
this.OnSearchFieldChange = function(evt)
{
if (this.keyTimeout) // kill running timer
{
clearTimeout(this.keyTimeout);
this.keyTimeout = 0;
}
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==40 || e.keyCode==13)
{
if (e.shiftKey==1)
{
this.OnSearchSelectShow();
var win=this.DOMSearchSelectWindow();
for (i=0;i<win.childNodes.length;i++)
{
var child = win.childNodes[i]; // get span within a
if (child.className=='SelectItem')
{
child.focus();
return;
}
}
return;
}
else if (window.frames.MSearchResults.searchResults)
{
var elem = window.frames.MSearchResults.searchResults.NavNext(0);
if (elem) elem.focus();
}
}
else if (e.keyCode==27) // Escape out of the search field
{
this.DOMSearchField().blur();
this.DOMPopupSearchResultsWindow().style.display = 'none';
this.DOMSearchClose().style.display = 'none';
this.lastSearchValue = '';
this.Activate(false);
return;
}
// strip whitespaces
var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
if (searchValue != this.lastSearchValue) // search value has changed
{
if (searchValue != "") // non-empty search
{
// set timer for search update
this.keyTimeout = setTimeout(this.name + '.Search()',
this.keyTimeoutLength);
}
else // empty search field
{
this.DOMPopupSearchResultsWindow().style.display = 'none';
this.DOMSearchClose().style.display = 'none';
this.lastSearchValue = '';
}
}
}
this.SelectItemCount = function(id)
{
var count=0;
var win=this.DOMSearchSelectWindow();
for (i=0;i<win.childNodes.length;i++)
{
var child = win.childNodes[i]; // get span within a
if (child.className=='SelectItem')
{
count++;
}
}
return count;
}
this.SelectItemSet = function(id)
{
var i,j=0;
var win=this.DOMSearchSelectWindow();
for (i=0;i<win.childNodes.length;i++)
{
var child = win.childNodes[i]; // get span within a
if (child.className=='SelectItem')
{
var node = child.firstChild;
if (j==id)
{
node.innerHTML='&#8226;';
}
else
{
node.innerHTML='&#160;';
}
j++;
}
}
}
// Called when an search filter selection is made.
// set item with index id as the active item
this.OnSelectItem = function(id)
{
this.searchIndex = id;
this.SelectItemSet(id);
var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
if (searchValue!="" && this.searchActive) // something was found -> do a search
{
this.Search();
}
}
this.OnSearchSelectKey = function(evt)
{
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
{
this.searchIndex++;
this.OnSelectItem(this.searchIndex);
}
else if (e.keyCode==38 && this.searchIndex>0) // Up
{
this.searchIndex--;
this.OnSelectItem(this.searchIndex);
}
else if (e.keyCode==13 || e.keyCode==27)
{
this.OnSelectItem(this.searchIndex);
this.CloseSelectionWindow();
this.DOMSearchField().focus();
}
return false;
}
// --------- Actions
// Closes the results window.
this.CloseResultsWindow = function()
{
this.DOMPopupSearchResultsWindow().style.display = 'none';
this.DOMSearchClose().style.display = 'none';
this.Activate(false);
}
this.CloseSelectionWindow = function()
{
this.DOMSearchSelectWindow().style.display = 'none';
}
// Performs a search.
this.Search = function()
{
this.keyTimeout = 0;
// strip leading whitespace
var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
var code = searchValue.toLowerCase().charCodeAt(0);
var idxChar = searchValue.substr(0, 1).toLowerCase();
if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
{
idxChar = searchValue.substr(0, 2);
}
var resultsPage;
var resultsPageWithSearch;
var hasResultsPage;
var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
if (idx!=-1)
{
var hexCode=idx.toString(16);
resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
hasResultsPage = true;
}
else // nothing available for this search term
{
resultsPage = this.resultsPath + '/nomatches.html';
resultsPageWithSearch = resultsPage;
hasResultsPage = false;
}
window.frames.MSearchResults.location = resultsPageWithSearch;
var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
if (domPopupSearchResultsWindow.style.display!='block')
{
var domSearchBox = this.DOMSearchBox();
this.DOMSearchClose().style.display = 'inline';
if (this.insideFrame)
{
var domPopupSearchResults = this.DOMPopupSearchResults();
domPopupSearchResultsWindow.style.position = 'relative';
domPopupSearchResultsWindow.style.display = 'block';
var width = document.body.clientWidth - 8; // the -8 is for IE :-(
domPopupSearchResultsWindow.style.width = width + 'px';
domPopupSearchResults.style.width = width + 'px';
}
else
{
var domPopupSearchResults = this.DOMPopupSearchResults();
var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
domPopupSearchResultsWindow.style.display = 'block';
left -= domPopupSearchResults.offsetWidth;
domPopupSearchResultsWindow.style.top = top + 'px';
domPopupSearchResultsWindow.style.left = left + 'px';
}
}
this.lastSearchValue = searchValue;
this.lastResultsPage = resultsPage;
}
// -------- Activation Functions
// Activates or deactivates the search panel, resetting things to
// their default values if necessary.
this.Activate = function(isActive)
{
if (isActive || // open it
this.DOMPopupSearchResultsWindow().style.display == 'block'
)
{
this.DOMSearchBox().className = 'MSearchBoxActive';
var searchField = this.DOMSearchField();
if (searchField.value == this.searchLabel) // clear "Search" term upon entry
{
searchField.value = '';
this.searchActive = true;
}
}
else if (!isActive) // directly remove the panel
{
this.DOMSearchBox().className = 'MSearchBoxInactive';
this.DOMSearchField().value = this.searchLabel;
this.searchActive = false;
this.lastSearchValue = ''
this.lastResultsPage = '';
}
}
}
// -----------------------------------------------------------------------
// The class that handles everything on the search results page.
function SearchResults(name)
{
// The number of matches from the last run of <Search()>.
this.lastMatchCount = 0;
this.lastKey = 0;
this.repeatOn = false;
// Toggles the visibility of the passed element ID.
this.FindChildElement = function(id)
{
var parentElement = document.getElementById(id);
var element = parentElement.firstChild;
while (element && element!=parentElement)
{
if (element.nodeName == 'DIV' && element.className == 'SRChildren')
{
return element;
}
if (element.nodeName == 'DIV' && element.hasChildNodes())
{
element = element.firstChild;
}
else if (element.nextSibling)
{
element = element.nextSibling;
}
else
{
do
{
element = element.parentNode;
}
while (element && element!=parentElement && !element.nextSibling);
if (element && element!=parentElement)
{
element = element.nextSibling;
}
}
}
}
this.Toggle = function(id)
{
var element = this.FindChildElement(id);
if (element)
{
if (element.style.display == 'block')
{
element.style.display = 'none';
}
else
{
element.style.display = 'block';
}
}
}
// Searches for the passed string. If there is no parameter,
// it takes it from the URL query.
//
// Always returns true, since other documents may try to call it
// and that may or may not be possible.
this.Search = function(search)
{
if (!search) // get search word from URL
{
search = window.location.search;
search = search.substring(1); // Remove the leading '?'
search = unescape(search);
}
search = search.replace(/^ +/, ""); // strip leading spaces
search = search.replace(/ +$/, ""); // strip trailing spaces
search = search.toLowerCase();
search = convertToId(search);
var resultRows = document.getElementsByTagName("div");
var matches = 0;
var i = 0;
while (i < resultRows.length)
{
var row = resultRows.item(i);
if (row.className == "SRResult")
{
var rowMatchName = row.id.toLowerCase();
rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
if (search.length<=rowMatchName.length &&
rowMatchName.substr(0, search.length)==search)
{
row.style.display = 'block';
matches++;
}
else
{
row.style.display = 'none';
}
}
i++;
}
document.getElementById("Searching").style.display='none';
if (matches == 0) // no results
{
document.getElementById("NoMatches").style.display='block';
}
else // at least one result
{
document.getElementById("NoMatches").style.display='none';
}
this.lastMatchCount = matches;
return true;
}
// return the first item with index index or higher that is visible
this.NavNext = function(index)
{
var focusItem;
while (1)
{
var focusName = 'Item'+index;
focusItem = document.getElementById(focusName);
if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
{
break;
}
else if (!focusItem) // last element
{
break;
}
focusItem=null;
index++;
}
return focusItem;
}
this.NavPrev = function(index)
{
var focusItem;
while (1)
{
var focusName = 'Item'+index;
focusItem = document.getElementById(focusName);
if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
{
break;
}
else if (!focusItem) // last element
{
break;
}
focusItem=null;
index--;
}
return focusItem;
}
this.ProcessKeys = function(e)
{
if (e.type == "keydown")
{
this.repeatOn = false;
this.lastKey = e.keyCode;
}
else if (e.type == "keypress")
{
if (!this.repeatOn)
{
if (this.lastKey) this.repeatOn = true;
return false; // ignore first keypress after keydown
}
}
else if (e.type == "keyup")
{
this.lastKey = 0;
this.repeatOn = false;
}
return this.lastKey!=0;
}
this.Nav = function(evt,itemIndex)
{
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==13) return true;
if (!this.ProcessKeys(e)) return false;
if (this.lastKey==38) // Up
{
var newIndex = itemIndex-1;
var focusItem = this.NavPrev(newIndex);
if (focusItem)
{
var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
if (child && child.style.display == 'block') // children visible
{
var n=0;
var tmpElem;
while (1) // search for last child
{
tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
if (tmpElem)
{
focusItem = tmpElem;
}
else // found it!
{
break;
}
n++;
}
}
}
if (focusItem)
{
focusItem.focus();
}
else // return focus to search field
{
parent.document.getElementById("MSearchField").focus();
}
}
else if (this.lastKey==40) // Down
{
var newIndex = itemIndex+1;
var focusItem;
var item = document.getElementById('Item'+itemIndex);
var elem = this.FindChildElement(item.parentNode.parentNode.id);
if (elem && elem.style.display == 'block') // children visible
{
focusItem = document.getElementById('Item'+itemIndex+'_c0');
}
if (!focusItem) focusItem = this.NavNext(newIndex);
if (focusItem) focusItem.focus();
}
else if (this.lastKey==39) // Right
{
var item = document.getElementById('Item'+itemIndex);
var elem = this.FindChildElement(item.parentNode.parentNode.id);
if (elem) elem.style.display = 'block';
}
else if (this.lastKey==37) // Left
{
var item = document.getElementById('Item'+itemIndex);
var elem = this.FindChildElement(item.parentNode.parentNode.id);
if (elem) elem.style.display = 'none';
}
else if (this.lastKey==27) // Escape
{
parent.searchBox.CloseResultsWindow();
parent.document.getElementById("MSearchField").focus();
}
else if (this.lastKey==13) // Enter
{
return true;
}
return false;
}
this.NavChild = function(evt,itemIndex,childIndex)
{
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==13) return true;
if (!this.ProcessKeys(e)) return false;
if (this.lastKey==38) // Up
{
if (childIndex>0)
{
var newIndex = childIndex-1;
document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
}
else // already at first child, jump to parent
{
document.getElementById('Item'+itemIndex).focus();
}
}
else if (this.lastKey==40) // Down
{
var newIndex = childIndex+1;
var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
if (!elem) // last child, jump to parent next parent
{
elem = this.NavNext(itemIndex+1);
}
if (elem)
{
elem.focus();
}
}
else if (this.lastKey==27) // Escape
{
parent.searchBox.CloseResultsWindow();
parent.document.getElementById("MSearchField").focus();
}
else if (this.lastKey==13) // Enter
{
return true;
}
return false;
}
}
function setKeyActions(elem,action)
{
elem.setAttribute('onkeydown',action);
elem.setAttribute('onkeypress',action);
elem.setAttribute('onkeyup',action);
}
function setClassAttr(elem,attr)
{
elem.setAttribute('class',attr);
elem.setAttribute('className',attr);
}
function createResults()
{
var results = document.getElementById("SRResults");
for (var e=0; e<searchData.length; e++)
{
var id = searchData[e][0];
var srResult = document.createElement('div');
srResult.setAttribute('id','SR_'+id);
setClassAttr(srResult,'SRResult');
var srEntry = document.createElement('div');
setClassAttr(srEntry,'SREntry');
var srLink = document.createElement('a');
srLink.setAttribute('id','Item'+e);
setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
setClassAttr(srLink,'SRSymbol');
srLink.innerHTML = searchData[e][1][0];
srEntry.appendChild(srLink);
if (searchData[e][1].length==2) // single result
{
srLink.setAttribute('href',searchData[e][1][1][0]);
if (searchData[e][1][1][1])
{
srLink.setAttribute('target','_parent');
}
var srScope = document.createElement('span');
setClassAttr(srScope,'SRScope');
srScope.innerHTML = searchData[e][1][1][2];
srEntry.appendChild(srScope);
}
else // multiple results
{
srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
var srChildren = document.createElement('div');
setClassAttr(srChildren,'SRChildren');
for (var c=0; c<searchData[e][1].length-1; c++)
{
var srChild = document.createElement('a');
srChild.setAttribute('id','Item'+e+'_c'+c);
setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
setClassAttr(srChild,'SRScope');
srChild.setAttribute('href',searchData[e][1][c+1][0]);
if (searchData[e][1][c+1][1])
{
srChild.setAttribute('target','_parent');
}
srChild.innerHTML = searchData[e][1][c+1][2];
srChildren.appendChild(srChild);
}
srEntry.appendChild(srChildren);
}
srResult.appendChild(srEntry);
results.appendChild(srResult);
}
}
function init_search()
{
var results = document.getElementById("MSearchSelectWindow");
for (var key in indexSectionLabels)
{
var link = document.createElement('a');
link.setAttribute('class','SelectItem');
link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
link.href='javascript:void(0)';
link.innerHTML='<span class="SelectionMark">&#160;</span>'+indexSectionLabels[key];
results.appendChild(link);
}
searchBox.OnSelectItem(0);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 612 B

View file

@ -1,12 +0,0 @@
var indexSectionsWithContent =
{
};
var indexSectionNames =
{
};
var indexSectionLabels =
{
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

File diff suppressed because one or more lines are too long

View file

@ -1,11 +0,0 @@
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="1;url=html/index.html">
<title>Page Redirection</title>
</head>
<body>
If you are not redirected automatically, follow the <a href="html/index.html">link to the documentation</a>
</body>
</html>

10
library.properties Normal file
View file

@ -0,0 +1,10 @@
name=Adafruit EPD
version=4.6.4
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=ePaper display driver
paragraph=ePaper display driver
category=Display
url=https://github.com/adafruit/Adafruit_EPD
architectures=*
depends=Adafruit GFX Library

21
license.txt Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 limor fried
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

728
src/Adafruit_EPD.cpp Normal file
View file

@ -0,0 +1,728 @@
/*!
* @file Adafruit_EPD.cpp
*
* @mainpage Adafruit EPD driver
*
* @section intro_sec Introduction
*
* This is the documentation for Adafruit's EPD driver for the
* Arduino platform. It is designed specifically to work with the
* Adafruit EPD breakouts.
*
* These displays use SPI to communicate, 6 pins are required to
* interface
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section dependencies Dependencies
*
* This library depends on <a
* href="https://github.com/adafruit/Adafruit-GFX-Library"> Adafruit_GFX</a>
* being present on your system. Please make sure you have installed the latest
* version before using this library.
*
* @section author Author
*
* Written by Dean Miller for Adafruit Industries.
*
* @section license License
*
* BSD license, all text here must be included in any redistribution.
*
*/
#include "Adafruit_EPD.h"
#include <stdlib.h>
bool Adafruit_EPD::_isInTransaction = false;
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param spi_mosi the SID pin to use
@param spi_clock the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param spi_miso the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_EPD::Adafruit_EPD(int width, int height, int16_t spi_mosi,
int16_t spi_clock, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t spi_miso,
int16_t BUSY)
: Adafruit_GFX(width, height), sram(spi_mosi, spi_miso, spi_clock, SRCS) {
_cs_pin = CS;
_reset_pin = RST;
_dc_pin = DC;
_busy_pin = BUSY;
if (SRCS >= 0) {
use_sram = true;
} else {
use_sram = false;
}
spi_dev = new Adafruit_SPIDevice(CS, spi_clock, spi_miso, spi_mosi,
4000000, // frequency
SPI_BITORDER_MSBFIRST, // bit order
SPI_MODE0 // data mode
);
singleByteTxns = false;
buffer1_size = buffer2_size = 0;
buffer1_addr = buffer2_addr = 0;
colorbuffer_addr = blackbuffer_addr = 0;
buffer1 = buffer2 = color_buffer = black_buffer = NULL;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
@param spi the SPI bus to use
*/
/**************************************************************************/
Adafruit_EPD::Adafruit_EPD(int width, int height, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t BUSY,
SPIClass* spi)
: Adafruit_GFX(width, height), sram(SRCS) {
_cs_pin = CS;
_reset_pin = RST;
_dc_pin = DC;
_busy_pin = BUSY;
if (SRCS >= 0) {
use_sram = true;
} else {
use_sram = false;
}
spi_dev = new Adafruit_SPIDevice(CS,
4000000, // frequency
SPI_BITORDER_MSBFIRST, // bit order
SPI_MODE0, // data mode
spi);
singleByteTxns = false;
buffer1_size = buffer2_size = 0;
buffer1_addr = buffer2_addr = 0;
colorbuffer_addr = blackbuffer_addr = 0;
buffer1 = buffer2 = color_buffer = black_buffer = NULL;
}
/**************************************************************************/
/*!
@brief default destructor
*/
/**************************************************************************/
Adafruit_EPD::~Adafruit_EPD() {
if (buffer1 != NULL) {
free(buffer1);
buffer1 = NULL;
}
if (buffer2 != NULL) {
free(buffer2);
buffer2 = NULL;
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_EPD::begin(bool reset) {
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, false); // red defaults to not inverted
layer_colors[EPD_WHITE] = 0b00;
layer_colors[EPD_BLACK] = 0b01;
layer_colors[EPD_RED] = 0b10;
layer_colors[EPD_GRAY] = 0b10;
layer_colors[EPD_DARK] = 0b01;
layer_colors[EPD_LIGHT] = 0b10;
if (use_sram) {
sram.begin();
sram.write8(0, K640_SEQUENTIAL_MODE, MCPSRAM_WRSR);
}
// Serial.println("set pins");
// set pin directions
pinMode(_dc_pin, OUTPUT);
pinMode(_cs_pin, OUTPUT);
#if defined(BUSIO_USE_FAST_PINIO)
csPort = (BusIO_PortReg*)portOutputRegister(digitalPinToPort(_cs_pin));
csPinMask = digitalPinToBitMask(_cs_pin);
dcPort = (BusIO_PortReg*)portOutputRegister(digitalPinToPort(_dc_pin));
dcPinMask = digitalPinToBitMask(_dc_pin);
#endif
csHigh();
if (!spi_dev->begin()) {
return;
}
// Serial.println("hard reset");
if (reset) {
hardwareReset();
}
// Serial.println("busy");
if (_busy_pin >= 0) {
pinMode(_busy_pin, INPUT);
}
// Serial.println("done!");
}
/**************************************************************************/
/*!
@brief reset Perform a hardware reset
*/
/**************************************************************************/
void Adafruit_EPD::hardwareReset(void) {
if (_reset_pin >= 0) {
// Setup reset pin direction
pinMode(_reset_pin, OUTPUT);
// VDD (3.3V) goes high at start, lets just chill for a ms
digitalWrite(_reset_pin, HIGH);
delay(10);
// bring reset low
digitalWrite(_reset_pin, LOW);
// wait 10ms
delay(10);
// bring out of reset
digitalWrite(_reset_pin, HIGH);
delay(10);
}
}
/**************************************************************************/
/*!
@brief draw a single pixel on the screen
@param x the x axis position
@param y the y axis position
@param color the color of the pixel
*/
/**************************************************************************/
void Adafruit_EPD::drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
uint8_t *black_pBuf, *color_pBuf;
// Serial.printf("(%d, %d) -> ", x, y);
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
EPD_swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
break;
case 3:
EPD_swap(x, y);
y = HEIGHT - y - 1;
break;
}
// deal with non-8-bit heights
uint16_t _HEIGHT = HEIGHT;
if (_HEIGHT % 8 != 0) {
_HEIGHT += 8 - (_HEIGHT % 8);
}
// Serial.printf("(%d, %d) : ", x, y);
uint16_t addr;
if (_data_entry_mode == THINKINK_UC8179) {
addr = ((uint32_t)(HEIGHT - 1 - y) * (uint32_t)WIDTH + x) / 8;
} else { // THINKINK_STANDARD default!
addr = ((uint32_t)(WIDTH - 1 - x) * (uint32_t)_HEIGHT + y) / 8;
}
uint8_t black_c, color_c;
// Serial.printf("0x%0x\n\r",addr);
if (use_sram) {
black_c = sram.read8(blackbuffer_addr + addr);
black_pBuf = &black_c;
color_c = sram.read8(colorbuffer_addr + addr);
color_pBuf = &color_c;
} else {
color_pBuf = color_buffer + addr;
black_pBuf = black_buffer + addr;
}
bool color_bit, black_bit;
black_bit = layer_colors[color] & 0x1;
color_bit = layer_colors[color] & 0x2;
uint8_t bit_idx;
if (_data_entry_mode == THINKINK_UC8179) {
bit_idx = x;
} else { // THINKINK_STANDARD default!
bit_idx = y;
}
if ((color_bit && colorInverted) || (!color_bit && !colorInverted)) {
*color_pBuf &= ~(1 << (7 - bit_idx % 8));
} else {
*color_pBuf |= (1 << (7 - bit_idx % 8));
}
if ((black_bit && blackInverted) || (!black_bit && !blackInverted)) {
*black_pBuf &= ~(1 << (7 - bit_idx % 8));
} else {
*black_pBuf |= (1 << (7 - bit_idx % 8));
}
if (use_sram) {
sram.write8(colorbuffer_addr + addr, *color_pBuf);
sram.write8(blackbuffer_addr + addr, *black_pBuf);
}
}
void Adafruit_EPD::writeRAMFramebufferToEPD(uint8_t* framebuffer,
uint32_t framebuffer_size,
uint8_t EPDlocation,
bool invertdata) {
// write image
writeRAMCommand(EPDlocation);
dcHigh();
// Serial.printf("Writing from RAM location %04x: \n", &framebuffer);
for (uint32_t i = 0; i < framebuffer_size; i++) {
uint8_t d = framebuffer[i];
if (invertdata)
d = ~d;
/*
Serial.printf("%02x", d);
if ((i+1) % (WIDTH/8) == 0)
Serial.println();
*/
SPItransfer(d);
}
// Serial.println();
csHigh();
return;
}
void Adafruit_EPD::writeSRAMFramebufferToEPD(uint16_t SRAM_buffer_addr,
uint32_t buffer_size,
uint8_t EPDlocation,
bool invertdata) {
(void)invertdata;
uint8_t c;
// use SRAM
sram.csLow();
_isInTransaction = true;
// send read command
SPItransfer(MCPSRAM_READ);
// send address
SPItransfer(SRAM_buffer_addr >> 8);
SPItransfer(SRAM_buffer_addr & 0xFF);
// first data byte from SRAM will be transfered in at the same time
// as the EPD command is transferred out
c = writeRAMCommand(EPDlocation);
dcHigh();
for (uint32_t i = 0; i < buffer_size; i++) {
c = SPItransfer(c);
/*
Serial.print("0x"); Serial.print((byte)c, HEX); Serial.print(", ");
if (i % 32 == 31) {
Serial.println();
Serial.print("$");
Serial.print(i, HEX);
Serial.print(": ");
}
*/
}
csHigh();
sram.csHigh();
_isInTransaction = false;
}
/**************************************************************************/
/*!
@brief Transfer the data stored in the buffer(s) to the display
*/
/**************************************************************************/
void Adafruit_EPD::display(bool sleep) {
#ifdef EPD_DEBUG
Serial.println(" Powering Up");
#endif
powerUp();
#ifdef EPD_DEBUG
Serial.println(" Set RAM address");
#endif
// Set X & Y ram counters
setRAMAddress(0, 0);
if (use_sram) {
#ifdef EPD_DEBUG
Serial.println(" Write SRAM buff to EPD");
#endif
writeSRAMFramebufferToEPD(buffer1_addr, buffer1_size, 0);
} else {
#ifdef EPD_DEBUG
Serial.println(" Write RAM buff to EPD");
#endif
writeRAMFramebufferToEPD(buffer1, buffer1_size, 0);
}
if (buffer2_size != 0) {
// oh there's another buffer eh?
delay(2);
// Set X & Y ram counters
setRAMAddress(0, 0);
if (use_sram) {
writeSRAMFramebufferToEPD(buffer2_addr, buffer2_size, 1);
} else {
writeRAMFramebufferToEPD(buffer2, buffer2_size, 1);
}
}
#ifdef EPD_DEBUG
Serial.println(" Update");
#endif
update();
partialsSinceLastFullUpdate = 0;
if (sleep) {
#ifdef EPD_DEBUG
Serial.println(" Powering Down");
#endif
powerDown();
}
}
/**************************************************************************/
/*!
@brief Determine whether the black pixel data is the first or second buffer
@param index 0 or 1, for primary or secondary value
@param inverted Whether to invert the logical value
*/
/**************************************************************************/
void Adafruit_EPD::setBlackBuffer(int8_t index, bool inverted) {
if (index == 0) {
if (use_sram) {
blackbuffer_addr = buffer1_addr;
} else {
black_buffer = buffer1;
}
}
if (index == 1) {
if (use_sram) {
blackbuffer_addr = buffer2_addr;
} else {
black_buffer = buffer2;
}
}
blackInverted = inverted;
}
/**************************************************************************/
/*!
@brief Determine whether the color pixel data is the first or second buffer
@param index 0 or 1, for primary or secondary value
@param inverted Whether to invert the logical value
*/
/**************************************************************************/
void Adafruit_EPD::setColorBuffer(int8_t index, bool inverted) {
if (index == 0) {
if (use_sram) {
colorbuffer_addr = buffer1_addr;
} else {
color_buffer = buffer1;
}
}
if (index == 1) {
if (use_sram) {
colorbuffer_addr = buffer2_addr;
} else {
color_buffer = buffer2;
}
}
colorInverted = inverted;
}
/**************************************************************************/
/*!
@brief clear all data buffers
*/
/**************************************************************************/
void Adafruit_EPD::clearBuffer() {
if (use_sram) {
if (blackInverted) {
sram.erase(blackbuffer_addr, buffer1_size, 0xFF);
} else {
sram.erase(blackbuffer_addr, buffer1_size, 0x00);
}
if (colorInverted) {
sram.erase(colorbuffer_addr, buffer2_size, 0xFF);
} else {
sram.erase(colorbuffer_addr, buffer2_size, 0x00);
}
} else {
if (black_buffer) {
if (blackInverted) {
memset(black_buffer, 0xFF, buffer1_size);
} else {
memset(black_buffer, 0x00, buffer1_size);
}
}
if (color_buffer) {
if (colorInverted) {
memset(color_buffer, 0xFF, buffer2_size);
} else {
memset(color_buffer, 0x00, buffer2_size);
}
}
}
}
/**************************************************************************/
/*!
@brief clear the display twice to remove any spooky ghost images
*/
/**************************************************************************/
void Adafruit_EPD::clearDisplay() {
clearBuffer();
display();
delay(100);
display();
}
/**************************************************************************/
/*!
*/
/**************************************************************************/
void Adafruit_EPD::EPD_commandList(const uint8_t* init_code) {
uint8_t buf[250];
while (init_code[0] != 0xFE) {
uint8_t cmd = init_code[0];
init_code++;
uint8_t num_args = init_code[0];
init_code++;
if (cmd == 0xFF) {
busy_wait();
delay(num_args);
continue;
}
if (num_args > sizeof(buf)) {
Serial.println(F("ERROR - buf not large enough!"));
while (1)
delay(10);
}
for (int i = 0; i < num_args; i++) {
buf[i] = init_code[0];
init_code++;
}
EPD_command(cmd, buf, num_args);
}
}
/**************************************************************************/
/*!
@brief send an EPD command followed by data
@param c the command to send
@param buf the buffer of data to send
@param len the length of the data buffer
*/
/**************************************************************************/
void Adafruit_EPD::EPD_command(uint8_t c, const uint8_t* buf, uint16_t len) {
EPD_command(c, false);
EPD_data(buf, len);
}
/**************************************************************************/
/*!
@brief send an EPD command with no data
@param c the command to send
@param end if true the cs pin will be pulled high following the transaction.
If false the cs pin will remain low.
@returns the data byte read over the SPI bus
*/
/**************************************************************************/
uint8_t Adafruit_EPD::EPD_command(uint8_t c, bool end) {
// SPI
csHigh();
dcLow();
csLow();
uint8_t data = SPItransfer(c);
#ifdef EPD_DEBUG
Serial.print(F("\tCommand: 0x"));
Serial.println(c, HEX);
#endif
if (end) {
csHigh();
}
return data;
}
/**************************************************************************/
/*!
@brief send data to the display
@param buf the data buffer to send
@param len the length of the data buffer
*/
/**************************************************************************/
void Adafruit_EPD::EPD_data(const uint8_t* buf, uint16_t len) {
// SPI
dcHigh();
#ifdef EPD_DEBUG
Serial.print("\tData: ");
#endif
for (uint16_t i = 0; i < len; i++) {
SPItransfer(buf[i]);
#ifdef EPD_DEBUG
Serial.print("0x");
Serial.print(buf[i], HEX);
Serial.print(", ");
#endif
}
#ifdef EPD_DEBUG
Serial.println();
#endif
csHigh();
}
/**************************************************************************/
/*!
@brief send data to the display
@param data the data byte to send
*/
/**************************************************************************/
void Adafruit_EPD::EPD_data(uint8_t data) {
// SPI
csHigh();
dcHigh();
csLow();
#ifdef DEBUG
Serial.print("Data: ");
Serial.print("0x");
Serial.println(data, HEX);
#endif
SPItransfer(data);
csHigh();
}
/**************************************************************************/
/*!
@brief transfer a single byte over SPI.
@param d the data to send
@returns the data byte read
*/
/**************************************************************************/
uint8_t Adafruit_EPD::SPItransfer(uint8_t d) {
// Serial.print("-> 0x"); Serial.println((byte)d, HEX);
if (singleByteTxns) {
uint8_t b;
csLow();
b = spi_dev->transfer(d);
csHigh();
return b;
} else {
return spi_dev->transfer(d);
}
}
/**************************************************************************/
/*!
@brief set chip select pin high
*/
/**************************************************************************/
void Adafruit_EPD::csHigh() {
#ifdef BUSIO_USE_FAST_PINIO
*csPort = *csPort | csPinMask;
#else
digitalWrite(_cs_pin, HIGH);
#endif
if (_isInTransaction) {
spi_dev->endTransaction();
_isInTransaction = false;
}
}
/**************************************************************************/
/*!
@brief set chip select pin low
*/
/**************************************************************************/
void Adafruit_EPD::csLow() {
if (!_isInTransaction) {
spi_dev->beginTransaction();
_isInTransaction = true;
}
#ifdef BUSIO_USE_FAST_PINIO
*csPort = *csPort & ~csPinMask;
#else
digitalWrite(_cs_pin, LOW);
#endif
}
/**************************************************************************/
/*!
@brief set data/command pin high
*/
/**************************************************************************/
void Adafruit_EPD::dcHigh() {
#ifdef BUSIO_USE_FAST_PINIO
*dcPort = *dcPort | dcPinMask;
#else
digitalWrite(_dc_pin, HIGH);
#endif
}
/**************************************************************************/
/*!
@brief set data/command pin low
*/
/**************************************************************************/
void Adafruit_EPD::dcLow() {
#ifdef BUSIO_USE_FAST_PINIO
*dcPort = *dcPort & ~dcPinMask;
#else
digitalWrite(_dc_pin, LOW);
#endif
}

228
src/Adafruit_EPD.h Normal file
View file

@ -0,0 +1,228 @@
/*!
* @file Adafruit_EPD.h
*
* This is a library for our EPD displays based on EPD drivers.
* Designed specifically to work with Adafruit EPD displays.
*
* These displays use SPI to communicate, 4 or 5 pins are required to
* interface
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Dean Miller for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
*/
#ifndef _ADAFRUIT_EPD_H_
#define _ADAFRUIT_EPD_H_
// #define EPD_DEBUG
#define RAMBUFSIZE 64 ///< size of the ram buffer
#include <Adafruit_GFX.h>
#include <Adafruit_SPIDevice.h>
#include "Adafruit_MCPSRAM.h"
/**************************************************************************/
/*!
@brief available EPD colors
*/
/**************************************************************************/
enum {
EPD_WHITE, ///< white color
EPD_BLACK, ///< black color
EPD_RED, ///< red color
EPD_GRAY, ///< gray color ('red' on grayscale)
EPD_DARK, ///< darker color
EPD_LIGHT, ///< lighter color
EPD_YELLOW, ///< fourth color on some displays
EPD_NUM_COLORS
};
typedef enum {
THINKINK_STANDARD = 0, // 99% of panels use this setup!
THINKINK_UC8179 = 1, // .... except for UC8179?
} thinkink_sramentrymode_t;
typedef enum {
THINKINK_MONO,
THINKINK_TRICOLOR,
THINKINK_GRAYSCALE4,
THINKINK_MONO_PARTIAL,
THINKINK_QUADCOLOR,
} thinkinkmode_t;
#define EPD_swap(a, b) \
{ \
int16_t t = a; \
a = b; \
b = t; \
} ///< simple swap function
/**************************************************************************/
/*!
@brief Class for interfacing with Adafruit EPD display breakouts.
*/
/**************************************************************************/
class Adafruit_EPD : public Adafruit_GFX {
public:
Adafruit_EPD(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_EPD(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
~Adafruit_EPD();
void begin(bool reset = true);
void drawPixel(int16_t x, int16_t y, uint16_t color);
void clearBuffer();
void clearDisplay();
void setBlackBuffer(int8_t index, bool inverted);
void setColorBuffer(int8_t index, bool inverted);
void display(bool sleep = false);
thinkinkmode_t getMode(void) {
return inkmode;
}
protected:
thinkink_sramentrymode_t _data_entry_mode = THINKINK_STANDARD;
void writeRAMFramebufferToEPD(uint8_t* buffer, uint32_t buffer_size,
uint8_t EPDlocation, bool invertdata = false);
void writeSRAMFramebufferToEPD(uint16_t SRAM_buffer_addr,
uint32_t buffer_size, uint8_t EPDlocation,
bool invertdata = false);
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
virtual uint8_t writeRAMCommand(uint8_t index) = 0;
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
virtual void setRAMAddress(uint16_t x, uint16_t y) = 0;
virtual void busy_wait(void) = 0;
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
virtual void powerUp() = 0;
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
virtual void update(void) = 0;
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
virtual void powerDown(void) = 0;
void hardwareReset(void);
int16_t _dc_pin, ///< data/command pin
_reset_pin, ///< reset pin
_cs_pin, ///< chip select pin
_busy_pin; ///< busy pin
Adafruit_SPIDevice* spi_dev = NULL; ///< SPI object
static bool _isInTransaction; ///< true if SPI bus is in trasnfer state
bool singleByteTxns; ///< if true CS will go high after every data byte
///< transferred
const uint8_t* _epd_init_code = NULL;
const uint8_t* _epd_lut_code = NULL;
const uint8_t* _epd_partial_init_code = NULL;
const uint8_t* _epd_partial_lut_code = NULL;
uint16_t default_refresh_delay = 15000;
Adafruit_MCPSRAM sram; ///< the ram chip object if using off-chip ram
bool blackInverted; ///< is black channel inverted
bool colorInverted; ///< is red channel inverted
uint8_t layer_colors[EPD_NUM_COLORS];
uint32_t buffer1_size; ///< size of the primary buffer
uint32_t buffer2_size; ///< size of the secondary buffer
uint8_t* buffer1; ///< the pointer to the primary buffer if using on-chip ram
uint8_t*
buffer2; ///< the pointer to the secondary buffer if using on-chip ram
uint8_t*
color_buffer; ///< the pointer to the color buffer if using on-chip ram
uint8_t*
black_buffer; ///< the pointer to the black buffer if using on-chip ram
uint16_t buffer1_addr; ///< The SRAM address offsets for the primary buffer
uint16_t buffer2_addr; ///< The SRAM address offsets for the secondary buffer
uint16_t colorbuffer_addr; ///< The SRAM address offsets for the color buffer
uint16_t blackbuffer_addr; ///< The SRAM address offsets for the black buffer
void EPD_commandList(const uint8_t* init_code);
void EPD_command(uint8_t c, const uint8_t* buf, uint16_t len);
uint8_t EPD_command(uint8_t c, bool end = true);
void EPD_data(const uint8_t* buf, uint16_t len);
void EPD_data(uint8_t data);
uint8_t SPItransfer(uint8_t c);
bool use_sram; ///< true if we are using an SRAM chip as a framebuffer
thinkinkmode_t inkmode; // Ink mode passed to begin()
uint8_t partialsSinceLastFullUpdate = 0;
#if defined(BUSIO_USE_FAST_PINIO)
BusIO_PortReg *csPort, *dcPort;
BusIO_PortMask csPinMask, dcPinMask;
#endif
void csLow();
void csHigh();
void dcHigh();
void dcLow();
};
#include "drivers/Adafruit_ACeP.h"
#include "drivers/Adafruit_EK79686.h"
#include "drivers/Adafruit_IL0373.h"
#include "drivers/Adafruit_IL0398.h"
#include "drivers/Adafruit_IL91874.h"
#include "drivers/Adafruit_JD79661.h"
#include "drivers/Adafruit_JD79667.h"
#include "drivers/Adafruit_SSD1608.h"
#include "drivers/Adafruit_SSD1619.h"
#include "drivers/Adafruit_SSD1675.h"
#include "drivers/Adafruit_SSD1675B.h"
#include "drivers/Adafruit_SSD1680.h"
#include "drivers/Adafruit_SSD1681.h"
#include "drivers/Adafruit_SSD1683.h"
#include "drivers/Adafruit_UC8151D.h"
#include "drivers/Adafruit_UC8179.h"
#include "drivers/Adafruit_UC8253.h"
#include "drivers/Adafruit_UC8276.h"
#endif /* _ADAFRUIT_EPD_H_ */

401
src/Adafruit_MCPSRAM.cpp Normal file
View file

@ -0,0 +1,401 @@
#include "Adafruit_MCPSRAM.h"
#include <Arduino.h>
#include <SPI.h>
/**************************************************************************/
/*!
@brief Class constructor when using software SPI
@param mosi master out slave in pin
@param miso master in slave out pin
@param sck serial clock pin
@param cs chip select pin
*/
/**************************************************************************/
Adafruit_MCPSRAM::Adafruit_MCPSRAM(int16_t mosi, int16_t miso, int16_t sck,
int16_t cs) {
_mosi = mosi;
_miso = miso;
_sck = sck;
_cs = cs;
hwSPI = false;
}
/**************************************************************************/
/*!
@brief Class constructor when using hardware SPI
@param cs chip select pin
@param spi the SPI bus to use
*/
/**************************************************************************/
Adafruit_MCPSRAM::Adafruit_MCPSRAM(int16_t cs, SPIClass* spi) {
_cs = cs;
_spi = spi;
hwSPI = true;
}
/**************************************************************************/
/*!
@brief begin communication with the SRAM chip
*/
/**************************************************************************/
void Adafruit_MCPSRAM::begin() {
pinMode(_cs, OUTPUT);
#ifdef HAVE_PORTREG
csport = portOutputRegister(digitalPinToPort(_cs));
cspinmask = digitalPinToBitMask(_cs);
#endif
csHigh();
if (!hwSPI) {
// set pins for software-SPI
pinMode(_mosi, OUTPUT);
pinMode(_sck, OUTPUT);
#ifdef HAVE_PORTREG
clkport = portOutputRegister(digitalPinToPort(_sck));
clkpinmask = digitalPinToBitMask(_sck);
mosiport = portOutputRegister(digitalPinToPort(_mosi));
mosipinmask = digitalPinToBitMask(_mosi);
misoport = portOutputRegister(digitalPinToPort(_miso));
misopinmask = digitalPinToBitMask(_miso);
#endif
}
if (hwSPI) {
_spi->begin();
#ifndef SPI_HAS_TRANSACTION
_spi->setClockDivider(4);
#endif
}
csLow();
for (int i = 0; i < 3; i++) {
if (hwSPI) {
(void)_spi->transfer(0xFF);
} else {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
if (0xFF & bit)
*mosiport |= mosipinmask;
else
*mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sck, LOW);
if (0xFF & bit)
digitalWrite(_mosi, HIGH);
else
digitalWrite(_mosi, LOW);
digitalWrite(_sck, HIGH);
#endif
}
}
}
csHigh();
}
/**************************************************************************/
/*!
@brief write data to the specific address
@param addr the address to write to
@param buf the data buffer to write
@param num the number of bytes to write
@param reg pass MCPSRAM_WRSR if you are writing the status
register, MCPSRAM_WRITE if you are writing data. Defaults to MCPSRAM_WRITE.
*/
/**************************************************************************/
void Adafruit_MCPSRAM::write(uint16_t addr, uint8_t* buf, uint16_t num,
uint8_t reg) {
csLow();
// write command and address
uint8_t cmdbuf[3];
cmdbuf[0] = reg;
cmdbuf[1] = (addr >> 8);
cmdbuf[2] = addr & 0xFF;
for (int i = 0; i < 3; i++) {
uint8_t d = cmdbuf[i];
if (hwSPI) {
(void)_spi->transfer(d);
} else {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
if (d & bit)
*mosiport |= mosipinmask;
else
*mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sck, LOW);
if (d & bit)
digitalWrite(_mosi, HIGH);
else
digitalWrite(_mosi, LOW);
digitalWrite(_sck, HIGH);
#endif
}
}
if (reg != MCPSRAM_WRITE)
break;
}
// write buffer of data
for (uint16_t i = 0; i < num; i++) {
uint8_t d = buf[i];
if (hwSPI) {
(void)_spi->transfer(d);
} else {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
readt |= mosipinmask;
readt &= ~mosipinmask;
readask;
#elseread
digitalWrite(_sck, LOW);
if (d & bit)
digitalWrite(_mosi, HIGH);
else
digitalWrite(_mosi, LOW);
digitalWrite(_sck, HIGH);
#endif
}
}
}
csHigh();
}
/**************************************************************************/
/*!
@brief read data at the specific address
@param addr the address to read from
@param buf the data buffer to read into
@param num the number of bytes to read
@param reg pass MCPSRAM_RDSR if you are reading the status
register, MCPSRAM_READ if you are reading data. Defaults to MCPSRAM_READ.
*/
/**************************************************************************/
void Adafruit_MCPSRAM::read(uint16_t addr, uint8_t* buf, uint16_t num,
uint8_t reg) {
csLow();
// write command and address
uint8_t cmdbuf[3];
cmdbuf[0] = reg;
cmdbuf[1] = (addr >> 8);
cmdbuf[2] = addr & 0xFF;
for (int i = 0; i < 3; i++) {
uint8_t d = cmdbuf[i];
if (hwSPI) {
(void)_spi->transfer(d);
} else {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
if (d & bit)
*mosiport |= mosipinmask;
else
*mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sck, LOW);
if (d & bit)
digitalWrite(_mosi, HIGH);
else
digitalWrite(_mosi, LOW);
digitalWrite(_sck, HIGH);
#endif
}
}
if (reg != MCPSRAM_READ)
break;
}
// read data into buffer
for (uint16_t i = 0; i < num; i++) {
if (hwSPI) {
buf[i] = _spi->transfer(0x00);
} else {
buf[i] = 0;
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
*clkport |= clkpinmask;
buf[i] = (buf[i] << 1) | = *misoport & misoport;
#else
digitalWrite(_sck, LOW);
digitalWrite(_sck, HIGH);
buf[i] = (buf[i] << 1) | digitalRead(_miso);
#endif
}
}
}
csHigh();
}
/**************************************************************************/
/*!
@brief 1 byte of data at the specified address
@param addr the address to read data at
@param reg MCPSRAM_READ if reading data, MCPSRAM_RDSR if reading
a status register.
@returns the read data byte.
*/
/**************************************************************************/
uint8_t Adafruit_MCPSRAM::read8(uint16_t addr, uint8_t reg) {
uint8_t c;
this->read(addr, &c, 1, reg);
return c;
}
/**************************************************************************/
/*!
@brief read 2 bytes of data at the specified address
@param addr the address to read
@returns the read data bytes as a 16 bit unsigned integer.
*/
/**************************************************************************/
uint16_t Adafruit_MCPSRAM::read16(uint16_t addr) {
uint8_t b[2];
this->read(addr, b, 2);
return ((uint16_t)b[0] << 8) | b[1];
}
/**************************************************************************/
/*!
@brief write 1 byte of data at the specified address.
@param addr the address to write to
@param val the value to write
@param reg MCPSRAM_WRITE if writing data, MCPSRAM_WRSR if
writing a status register.
*/
/**************************************************************************/
void Adafruit_MCPSRAM::write8(uint16_t addr, uint8_t val, uint8_t reg) {
this->write(addr, &val, 1, reg);
}
/**************************************************************************/
/*!
@brief write 2 bytes of data at the specified address.
@param addr the address to write to
@param val the value to write
*/
/**************************************************************************/
void Adafruit_MCPSRAM::write16(uint16_t addr, uint16_t val) {
uint8_t b[2];
b[0] = (val >> 8);
b[1] = (val);
this->write(addr, b, 2);
}
/**************************************************************************/
/*!
@brief erase a block of data.
@param addr the address to start the erase at
@param length the number of bytes to fill
@param val the value to set the data to.
*/
/**************************************************************************/
void Adafruit_MCPSRAM::erase(uint16_t addr, uint16_t length, uint8_t val) {
csLow();
// write command and address
uint8_t cmdbuf[3];
cmdbuf[0] = MCPSRAM_WRITE;
cmdbuf[1] = (addr >> 8);
cmdbuf[2] = addr & 0xFF;
for (int i = 0; i < 3; i++) {
uint8_t d = cmdbuf[i];
if (hwSPI) {
(void)_spi->transfer(d);
} else {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
if (d & bit)
*mosiport |= mosipinmask;
else
*mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sck, LOW);
if (d & bit)
digitalWrite(_mosi, HIGH);
else
digitalWrite(_mosi, LOW);
digitalWrite(_sck, HIGH);
#endif
}
}
}
// write buffer of data
for (uint16_t i = 0; i < length; i++) {
uint8_t d = val;
if (hwSPI) {
(void)_spi->transfer(d);
} else {
for (uint8_t bit = 0x80; bit; bit >>= 1) {
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
if (d & bit)
*mosiport |= mosipinmask;
else
*mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
#else
digitalWrite(_sck, LOW);
if (d & bit)
digitalWrite(_mosi, HIGH);
else
digitalWrite(_mosi, LOW);
digitalWrite(_sck, HIGH);
#endif
}
}
}
csHigh();
}
/**************************************************************************/
/*!
@brief set chip select pin high
*/
/**************************************************************************/
void Adafruit_MCPSRAM::csHigh() {
#ifdef SPI_HAS_TRANSACTION
_spi->endTransaction();
#endif
#ifdef HAVE_PORTREG
*csport |= cspinmask;
#else
digitalWrite(_cs, HIGH);
#endif
}
/**************************************************************************/
/*!
@brief set chip select pin low
*/
/**************************************************************************/
void Adafruit_MCPSRAM::csLow() {
#ifdef SPI_HAS_TRANSACTION
_spi->beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
#endif
#ifdef HAVE_PORTREG
*csport &= ~cspinmask;
#else
digitalWrite(_cs, LOW);
#endif
}

47
src/Adafruit_MCPSRAM.h Normal file
View file

@ -0,0 +1,47 @@
#include <Arduino.h>
#include <SPI.h>
#define MCPSRAM_READ 0x03 ///< read command
#define MCPSRAM_WRITE 0x02 ///< write command
#define MCPSRAM_RDSR 0x05 ///< read status register command
#define MCPSRAM_WRSR 0x01 ///< write status register command
#define K640_SEQUENTIAL_MODE (1 << 6) ///< put ram chip in sequential mode
/**************************************************************************/
/*!
@brief Class for interfacing with Microchip SPI SRAM chips
*/
/**************************************************************************/
class Adafruit_MCPSRAM {
public:
Adafruit_MCPSRAM(int16_t mosi, int16_t miso, int16_t sck, int16_t cs);
Adafruit_MCPSRAM(int16_t cs, SPIClass* spi = &SPI);
~Adafruit_MCPSRAM() {}
void begin();
void write(uint16_t addr, uint8_t* buf, uint16_t num,
uint8_t reg = MCPSRAM_WRITE);
void read(uint16_t addr, uint8_t* buf, uint16_t num,
uint8_t reg = MCPSRAM_READ);
void erase(uint16_t addr, uint16_t length, uint8_t val = 0x00);
uint8_t read8(uint16_t addr, uint8_t reg = MCPSRAM_READ);
uint16_t read16(uint16_t addr);
void write8(uint16_t addr, uint8_t val, uint8_t reg = MCPSRAM_WRITE);
void write16(uint16_t addr, uint16_t val);
void csHigh();
void csLow();
private:
boolean hwSPI; ///< true if using hardware SPI
#ifdef HAVE_PORTREG
PortReg *mosiport, *clkport, *csport, *misoport;
PortMask mosipinmask, clkpinmask, cspinmask, misopinmask;
#endif
int16_t _cs, _mosi, _miso, _sck;
SPIClass* _spi = NULL;
};

52
src/Adafruit_ThinkInk.h Normal file
View file

@ -0,0 +1,52 @@
#ifndef _ADAFRUIT_THINKINK_H_
#define _ADAFRUIT_THINKINK_H_
#include "Adafruit_EPD.h"
#include "panels/ThinkInk_154_Grayscale4_M05.h"
#include "panels/ThinkInk_154_Grayscale4_T8.h"
#include "panels/ThinkInk_154_Mono_D27.h"
#include "panels/ThinkInk_154_Mono_D67.h"
#include "panels/ThinkInk_154_Mono_M10.h"
#include "panels/ThinkInk_154_Tricolor_RW.h"
#include "panels/ThinkInk_154_Tricolor_Z17.h"
#include "panels/ThinkInk_154_Tricolor_Z90.h"
#include "panels/ThinkInk_213_Grayscale4_MFGN.h"
#include "panels/ThinkInk_213_Grayscale4_T5.h"
#include "panels/ThinkInk_213_Mono_B72.h"
#include "panels/ThinkInk_213_Mono_B73.h"
#include "panels/ThinkInk_213_Mono_BN.h"
#include "panels/ThinkInk_213_Mono_GDEY0213B74.h"
#include "panels/ThinkInk_213_Mono_M21.h"
#include "panels/ThinkInk_213_Quadcolor_AJHE5.h"
#include "panels/ThinkInk_213_Tricolor_MFGNR.h"
#include "panels/ThinkInk_213_Tricolor_RW.h"
#include "panels/ThinkInk_213_Tricolor_Z16.h"
#include "panels/ThinkInk_266_Grayscale4_MFGN.h"
#include "panels/ThinkInk_266_Tricolor_MFGNR.h"
#include "panels/ThinkInk_270_Grayscale4_W3.h"
#include "panels/ThinkInk_270_Tricolor_C44.h"
#include "panels/ThinkInk_270_Tricolor_Z70.h"
#include "panels/ThinkInk_290_Grayscale4_EAAMFGN.h"
#include "panels/ThinkInk_290_Grayscale4_T5.h"
#include "panels/ThinkInk_290_Mono_BN.h"
#include "panels/ThinkInk_290_Mono_M06.h"
#include "panels/ThinkInk_290_Tricolor_RH.h"
#include "panels/ThinkInk_290_Tricolor_Z10.h"
#include "panels/ThinkInk_290_Tricolor_Z13.h"
#include "panels/ThinkInk_290_Tricolor_Z94.h"
#include "panels/ThinkInk_352_Quadcolor_AJHE5.h"
#include "panels/ThinkInk_370_Mono_BAAMFGN.h"
#include "panels/ThinkInk_370_Tricolor_BABMFGNR.h"
#include "panels/ThinkInk_420_Grayscale4_MFGN.h"
#include "panels/ThinkInk_420_Grayscale4_T2.h"
#include "panels/ThinkInk_420_Mono_BN.h"
#include "panels/ThinkInk_420_Mono_M06.h"
#include "panels/ThinkInk_420_Tricolor_MFGNR.h"
#include "panels/ThinkInk_420_Tricolor_RW.h"
#include "panels/ThinkInk_420_Tricolor_Z21.h"
#include "panels/ThinkInk_583_Mono_AAAMFGN.h"
#include "panels/ThinkInk_583_Tricolor_AABMFGNR.h"
#include "panels/ThinkInk_750_Mono_AAAMFGN.h"
#include "panels/ThinkInk_750_Tricolor_AABMFGNR.h"
#endif // _ADAFRUIT_THINKINK_H_

View file

@ -0,0 +1,386 @@
#include "Adafruit_ACeP.h"
#include "Adafruit_EPD.h"
#define BUSY_WAIT 500
// clang-format off
const uint8_t acep_default_init_code[] {
0xFF, 10, // wait a lil bit
ACEP_PANEL_SETTING, 2, 0xEF, 0x08, // LUT from OTP
ACEP_POWER_SETTING, 4, 0x37, 0x00, 0x23, 0x23, // 0x05&0x05?
ACEP_POWER_OFF_SEQUENCE, 1, 0x00,
ACEP_BOOSTER_SOFT_START, 3, 0xC7, 0xC7, 0x1D,
ACEP_PLL, 1, 0x3C,
ACEP_TSE, 1, 0x00,
ACEP_CDI, 1, 0x37,
ACEP_TCON, 1, 0x22,
ACEP_RESOLUTION, 4, 0x02, 0x58, 0x01, 0xC0,
ACEP_PWS, 1, 0xAA,
0xFF, 100, // 100 ms delay
ACEP_CDI, 1, 0x37,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_ACEP::Adafruit_ACEP(int width, int height, int16_t SID, int16_t SCLK,
int16_t DC, int16_t RST, int16_t CS, int16_t SRCS,
int16_t MISO, int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = (uint16_t)width * (uint16_t)height / 2;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = NULL;
}
singleByteTxns = true;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_ACEP::Adafruit_ACEP(int width, int height, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t BUSY,
SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 2;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = buffer1;
}
singleByteTxns = true;
}
/**************************************************************************/
/*!
@brief clear all data buffers
*/
/**************************************************************************/
void Adafruit_ACEP::clearBuffer() {
if (use_sram) {
sram.erase(colorbuffer_addr, buffer1_size, 0x11);
} else {
memset(color_buffer, 0x11, buffer1_size);
}
}
/**************************************************************************/
/*!
@brief clear all data buffers
*/
/**************************************************************************/
void Adafruit_ACEP::deGhost() {
uint8_t buf[4];
buf[0] = 0x02;
buf[1] = 0x58;
buf[2] = 0x01;
buf[3] = 0xC0;
EPD_command(ACEP_RESOLUTION, buf, 4);
EPD_command(ACEP_DTM);
uint32_t remaining = (600UL * 448UL / 2);
while (remaining) {
uint8_t block[256];
uint32_t numbytes = min(remaining, (uint32_t)sizeof(block));
memset(block, 0x77, numbytes);
EPD_data(block, numbytes);
remaining -= numbytes;
}
EPD_command(ACEP_POWER_ON);
busy_wait();
EPD_command(ACEP_DISPLAY_REFRESH);
busy_wait();
EPD_command(ACEP_POWER_OFF);
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy LOW
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief clear the display twice to remove any spooky ghost images
*/
/**************************************************************************/
void Adafruit_ACEP::clearDisplay() {
clearBuffer();
display();
}
/**************************************************************************/
/*!
@brief draw a single pixel on the screen
@param x the x axis position
@param y the y axis position
@param color the color of the pixel
*/
/**************************************************************************/
void Adafruit_ACEP::drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
uint8_t* pBuf;
// deal with non-8-bit heights
uint16_t _HEIGHT = HEIGHT;
if (_HEIGHT % 8 != 0) {
_HEIGHT += 8 - (_HEIGHT % 8);
}
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
EPD_swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = _HEIGHT - y - 1;
break;
case 3:
EPD_swap(x, y);
y = _HEIGHT - y - 1;
break;
}
uint32_t addr = ((uint32_t)x + (uint32_t)y * WIDTH) / 2;
bool lower_nibble = x % 2;
uint8_t color_c;
if (use_sram) {
color_c = sram.read8(colorbuffer_addr + addr);
pBuf = &color_c;
} else {
pBuf = color_buffer + addr;
}
if (lower_nibble) {
*pBuf &= 0xF0; // save higher nib
*pBuf |= (color & 0xF);
} else {
*pBuf &= 0x0F; // save lower nib
*pBuf |= (color & 0xF) << 4;
}
if (use_sram) {
sram.write8(colorbuffer_addr + addr, *pBuf);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_ACEP::busy_wait(void) {
if (_busy_pin >= 0) {
while (!digitalRead(_busy_pin)) { // wait for busy high
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_ACEP::begin(bool reset) {
Adafruit_EPD::begin(reset);
delay(100);
}
/**************************************************************************/
/*!
@brief Transfer the data stored in the buffer(s) to the display
*/
/**************************************************************************/
void Adafruit_ACEP::display(bool sleep) {
#ifdef EPD_DEBUG
Serial.println(" Powering Up");
#endif
powerUp();
#ifdef EPD_DEBUG
Serial.println(" De Ghosting");
#endif
deGhost();
delay(500);
#ifdef EPD_DEBUG
Serial.println(" Powering Up");
#endif
powerUp();
#ifdef EPD_DEBUG
Serial.println(" Write frame buffer");
#endif
if (use_sram) {
writeSRAMFramebufferToEPD(buffer1_addr, buffer1_size, 0);
} else {
writeRAMFramebufferToEPD(buffer1, buffer1_size, 0);
}
#ifdef EPD_DEBUG
Serial.println(" Update");
#endif
update();
partialsSinceLastFullUpdate = 0;
if (sleep) {
#ifdef EPD_DEBUG
Serial.println(" Powering Down");
#endif
powerDown();
}
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_ACEP::update(void) {
EPD_command(ACEP_POWER_ON);
busy_wait();
EPD_command(ACEP_DISPLAY_REFRESH);
busy_wait();
EPD_command(ACEP_POWER_OFF);
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy LOW
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_ACEP::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(200);
busy_wait();
const uint8_t* init_code = acep_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
// set resolution
buf[0] = 0x02;
buf[1] = 0x58;
buf[2] = 0x01;
buf[3] = 0xC0;
EPD_command(ACEP_RESOLUTION, buf, 4);
delay(100);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_ACEP::powerDown(void) {
uint8_t buf[1];
delay(1000);
// deep sleep
buf[0] = 0xA5;
EPD_command(ACEP_DEEP_SLEEP, buf, 1);
delay(100);
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_ACEP::writeRAMCommand(uint8_t index) {
(void)index;
return EPD_command(ACEP_DTM, false);
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_ACEP::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
}

View file

@ -0,0 +1,62 @@
#ifndef LIB_ADAFRUIT_ACEP
#define LIB_ADAFRUIT_ACEP
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define ACEP_PANEL_SETTING 0x00
#define ACEP_POWER_SETTING 0x01
#define ACEP_POWER_OFF 0x02
#define ACEP_POWER_OFF_SEQUENCE 0x03
#define ACEP_POWER_ON 0x04
#define ACEP_BOOSTER_SOFT_START 0x06
#define ACEP_DEEP_SLEEP 0x07
#define ACEP_DTM 0x10
#define ACEP_DISPLAY_REFRESH 0x12
#define ACEP_PLL 0x30
#define ACEP_TSE 0x40
#define ACEP_CDI 0x50
#define ACEP_TCON 0x60
#define ACEP_RESOLUTION 0x61
#define ACEP_PWS 0xE3
#define ACEP_COLOR_BLACK 0x0 /// 000
#define ACEP_COLOR_WHITE 0x1 /// 001
#define ACEP_COLOR_GREEN 0x2 /// 010
#define ACEP_COLOR_BLUE 0x3 /// 011
#define ACEP_COLOR_RED 0x4 /// 100
#define ACEP_COLOR_YELLOW 0x5 /// 101
#define ACEP_COLOR_ORANGE 0x6 /// 110
/**************************************************************************/
/*!
@brief Class for interfacing with ACEP EPD drivers
*/
/**************************************************************************/
class Adafruit_ACEP : public Adafruit_EPD {
public:
Adafruit_ACEP(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_ACEP(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void powerDown();
void update();
void display(bool sleep = true);
void clearBuffer();
void clearDisplay();
void deGhost();
void drawPixel(int16_t x, int16_t y, uint16_t color);
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,211 @@
#include "Adafruit_EK79686.h"
#include "Adafruit_EPD.h"
#define BUSY_WAIT 500
// clang-format off
const uint8_t ek79686_default_init_code[] {
EK79686_PSR, 1, 0x0F, // LUT from OTP 128x296
0x4D, 1, 0xAA, // FITI cmd (???)
0x87, 1, 0x28,
0x84, 1, 0x00,
0x83, 1, 0x05,
0xA8, 1, 0xDF,
0xA9, 1, 0x05,
0xB1, 1, 0xE8,
0xAB, 1, 0xA1,
0xB9, 1, 0x10,
0x88, 1, 0x80,
0x90, 1, 0x02,
0x86, 1, 0x15,
0x91, 1, 0x8D,
0xAA, 1, 0x0F,
EK79686_PON, 0,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_EK79686::Adafruit_EK79686(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_EK79686::Adafruit_EK79686(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = (uint16_t)width * (uint16_t)height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_EK79686::busy_wait(void) {
if (_busy_pin >= 0) {
do {
EPD_command(EK79686_FLG);
delay(10);
} while (!digitalRead(_busy_pin));
} else {
delay(BUSY_WAIT);
}
delay(200); // additional delay
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_EK79686::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, false); // red defaults to not-inverted
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_EK79686::update() {
EPD_command(EK79686_DRF);
delay(10);
busy_wait();
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_EK79686::powerUp() {
hardwareReset();
delay(10);
const uint8_t* init_code = ek79686_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
if (_epd_lut_code) {
EPD_commandList(_epd_lut_code);
}
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_EK79686::powerDown(void) {
uint8_t buf[1];
EPD_command(EK79686_POF); // power off
busy_wait();
buf[0] = 0xA5;
EPD_command(EK79686_DSLP, buf, 1);
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_EK79686::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(EK79686_DTM1, false);
}
if (index == 1) {
return EPD_command(EK79686_DTM2, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_EK79686::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
}

View file

@ -0,0 +1,79 @@
#ifndef LIB_ADAFRUIT_EK79686
#define LIB_ADAFRUIT_EK79686
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define EK79686_PSR 0x00
#define EK79686_PWR 0x01
#define EK79686_POF 0x02
#define EK79686_PFS 0x03
#define EK79686_PON 0x04
#define EK79686_PMEAS 0x05
#define EK79686_BTST 0x06
#define EK79686_DSLP 0x07
#define EK79686_DTM1 0x10
#define EK79686_DSP 0x11
#define EK79686_DRF 0x12
#define EK79686_DTM2 0x13
#define EK79686_PDTM1 0x14
#define EK79686_PDTM2 0x15
#define EK79686_PDRF 0x16
#define EK79686_LUT1 0x20
#define EK79686_LUTWW 0x21
#define EK79686_LUTBW 0x22
#define EK79686_LUTWB 0x23
#define EK79686_LUTBB 0x24
#define EK79686_LUTC 0x25
#define EK79686_SETVCOM 0x26
#define EK79686_OSC 0x30
#define EK79686_TSC 0x40
#define EK79686_TSE 0x41
#define EK79686_TSW 0x42
#define EK79686_TSR 0x43
#define EK79686_CDI 0x50
#define EK79686_LPD 0x51
#define EK79686_TCON 0x60
#define EK79686_TRES 0x61
#define EK79686_GSST 0x62
#define EK79686_REV 0x70
#define EK79686_FLG 0x71
#define EK79686_AMV 0x80
#define EK79686_VV 0x81
#define EK79686_VDCS 0x82
#define EK79686_PGM 0xA0
#define EK79686_APG 0xA1
#define EK79686_ROTP 0xA2
#define EK79686_CCSET 0xE0
#define EK79686_TSSET 0xE5
#define EK79686_LVD 0xE6
#define EK79686_PNLBRK 0xE7
#define EK79686_PWRSAV 0xE8
#define EK79686_AUTOSEQ 0xE9
/**************************************************************************/
/*!
@brief Class for interfacing with EK79686 EPD drivers
*/
/**************************************************************************/
class Adafruit_EK79686 : public Adafruit_EPD {
public:
Adafruit_EK79686(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_EK79686(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void powerDown();
void update();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,338 @@
#include "Adafruit_IL0373.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW IL0373_DTM1
#define EPD_RAM_RED IL0373_DTM2
#define BUSY_WAIT 100
// clang-format off
const uint8_t il0373_default_init_code[] {
IL0373_POWER_SETTING, 5, 0x03, 0x00, 0x2b, 0x2b, 0x09,
IL0373_BOOSTER_SOFT_START, 3, 0x17, 0x17, 0x17,
IL0373_POWER_ON, 0,
0xFF, 200,
IL0373_PANEL_SETTING, 1, 0xCF,
IL0373_CDI, 1, 0x37,
IL0373_PLL, 1, 0x29,
IL0373_VCM_DC_SETTING, 1, 0x0A,
0xFF, 20,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_IL0373::Adafruit_IL0373(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
@param spi the SPI bus to use
*/
/**************************************************************************/
Adafruit_IL0373::Adafruit_IL0373(int width, int height, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t BUSY,
SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_IL0373::busy_wait(void) {
// Serial.print("Waiting...");
if (_busy_pin >= 0) {
while (!digitalRead(_busy_pin)) {
delay(10); // wait for busy high
}
} else {
delay(BUSY_WAIT);
}
// Serial.println("OK!");
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_IL0373::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, true); // red defaults to inverted
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_IL0373::update() {
EPD_command(IL0373_DISPLAY_REFRESH);
delay(100);
busy_wait();
if (_busy_pin <= -1) {
delay(default_refresh_delay);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_IL0373::powerUp(void) {
uint8_t buf[5];
hardwareReset();
const uint8_t* init_code = il0373_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
if (_epd_lut_code) {
EPD_commandList(_epd_lut_code);
}
buf[0] = HEIGHT & 0xFF;
buf[1] = (WIDTH >> 8) & 0xFF;
buf[2] = WIDTH & 0xFF;
EPD_command(IL0373_RESOLUTION, buf, 3);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_IL0373::powerDown() {
// power off
uint8_t buf[4];
buf[0] = 0x17;
EPD_command(IL0373_CDI, buf, 1);
buf[0] = 0x00;
EPD_command(IL0373_VCM_DC_SETTING, buf, 0);
EPD_command(IL0373_POWER_OFF);
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_IL0373::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(EPD_RAM_BW, false);
}
if (index == 1) {
return EPD_command(EPD_RAM_RED, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_IL0373::setRAMAddress(uint16_t x, uint16_t y) {
// on this chip we do nothing
(void)x;
(void)y;
}
void Adafruit_IL0373::displayPartial(uint16_t x1, uint16_t y1, uint16_t x2,
uint16_t y2) {
uint8_t buf[7];
// check rotation, move window around if necessary
switch (getRotation()) {
case 0:
EPD_swap(x1, y1);
EPD_swap(x2, y2);
y1 = WIDTH - y1;
y2 = WIDTH - y2;
break;
case 1:
break;
case 2:
EPD_swap(x1, y1);
EPD_swap(x2, y2);
x1 = HEIGHT - x1;
x2 = HEIGHT - x2;
break;
case 3:
y1 = WIDTH - y1;
y2 = WIDTH - y2;
x1 = HEIGHT - x1;
x2 = HEIGHT - x2;
}
if (x1 > x2)
EPD_swap(x1, x2);
if (y1 > y2)
EPD_swap(y1, y2);
/*
Serial.print("x: ");
Serial.print(x1);
Serial.print(" -> ");
Serial.println(x2);
Serial.print("y: ");
Serial.print(y1);
Serial.print(" -> ");
Serial.println(y2);
*/
// x1 and x2 must be on byte boundaries
x1 -= x1 % 8; // round down;
x2 = (x2 + 7) & ~0b111; // round up
// Serial.println("Partial update!");
// backup & change init to the partial code
const uint8_t* init_code_backup = _epd_init_code;
const uint8_t* lut_code_backup = _epd_lut_code;
_epd_init_code = _epd_partial_init_code;
_epd_lut_code = _epd_partial_lut_code;
// perform standard power up
powerUp();
EPD_command(IL0373_PARTIAL_ENTER);
buf[0] = x1;
buf[1] = x2 - 1;
buf[2] = y1 >> 8;
buf[3] = y1 & 0xFF;
buf[4] = (y2 - 1) >> 8;
buf[5] = (y2 - 1) & 0xFF;
buf[6] = 0x28;
EPD_command(IL0373_PARTIAL_WINDOW, buf, 7);
// display....
// write image
writeRAMCommand(0);
dcHigh();
for (uint16_t y = y1; y < y2; y++) {
for (uint16_t x = x1; x < x2; x += 8) {
uint16_t i = (x / 8) + y * 16;
SPItransfer(black_buffer[i]);
// SPItransfer(0);
}
}
csHigh();
delay(2);
writeRAMCommand(1);
dcHigh();
// Serial.print("Transfering: ");
for (uint16_t y = y1; y < y2; y++) {
for (uint16_t x = x1; x < x2; x += 8) {
uint16_t i = (x / 8) + y * 16;
/*
Serial.print(i);
Serial.print(" (0x");
Serial.print(buffer2[i]);
Serial.print("), ");
if (i % 16 == 15) Serial.println();
*/
SPItransfer(~black_buffer[i]);
// SPItransfer(0xFF);
}
}
Serial.println();
csHigh();
#ifdef EPD_DEBUG
Serial.println(" Update");
#endif
update();
EPD_command(IL0373_PARTIAL_EXIT);
#ifdef EPD_DEBUG
Serial.println(" Powering Down");
#endif
powerDown();
// change init back
_epd_lut_code = lut_code_backup;
_epd_init_code = init_code_backup;
}

View file

@ -0,0 +1,62 @@
#ifndef LIB_ADAFRUIT_IL0373
#define LIB_ADAFRUIT_IL0373
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define IL0373_PANEL_SETTING 0x00
#define IL0373_POWER_SETTING 0x01
#define IL0373_POWER_OFF 0x02
#define IL0373_POWER_OFF_SEQUENCE 0x03
#define IL0373_POWER_ON 0x04
#define IL0373_POWER_ON_MEASURE 0x05
#define IL0373_BOOSTER_SOFT_START 0x06
#define IL0373_DEEP_SLEEP 0x07
#define IL0373_DTM1 0x10
#define IL0373_DATA_STOP 0x11
#define IL0373_DISPLAY_REFRESH 0x12
#define IL0373_DTM2 0x13
#define IL0373_PDTM1 0x14
#define IL0373_PDTM2 0x15
#define IL0373_PDRF 0x16
#define IL0373_LUT1 0x20
#define IL0373_LUTWW 0x21
#define IL0373_LUTBW 0x22
#define IL0373_LUTWB 0x23
#define IL0373_LUTBB 0x24
#define IL0373_PLL 0x30
#define IL0373_CDI 0x50
#define IL0373_RESOLUTION 0x61
#define IL0373_VCM_DC_SETTING 0x82
#define IL0373_PARTIAL_WINDOW 0x90
#define IL0373_PARTIAL_ENTER 0x91
#define IL0373_PARTIAL_EXIT 0x92
/**************************************************************************/
/*!
@brief Class for interfacing with IL0373 EPD drivers
*/
/**************************************************************************/
class Adafruit_IL0373 : public Adafruit_EPD {
private:
public:
Adafruit_IL0373(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_IL0373(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void powerDown();
void update();
void displayPartial(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,215 @@
#include "Adafruit_IL0398.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t il0398_default_init_code[] {
0xFF, 20, // busy wait
IL0398_BOOSTER_SOFT_START, 3, 0x17, 0x17, 0x17,
IL0398_POWER_ON, 0,
0xFF, 20, // busy wait
IL0398_PANEL_SETTING, 2, 0x1F, 0x0D, // lut from OTP & vcom = 0v
IL0398_VCOM, 1, 0x97,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_IL0398::Adafruit_IL0398(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_IL0398::Adafruit_IL0398(int width, int height, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t BUSY,
SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_IL0398::busy_wait(void) {
if (_busy_pin > -1) {
do {
EPD_command(IL0398_GETSTATUS);
delay(10);
} while (!digitalRead(_busy_pin)); // wait for busy HIGH
delay(200);
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_IL0398::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, true); // red defaults to inverted
setRotation(1);
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_IL0398::update() {
EPD_command(IL0398_DISPLAY_REFRESH);
delay(100);
busy_wait();
if (_busy_pin <= -1) {
delay(15000);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_IL0398::powerUp() {
uint8_t buf[4];
hardwareReset();
const uint8_t* init_code = il0398_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
if (_epd_lut_code) {
EPD_commandList(_epd_lut_code);
}
buf[0] = (HEIGHT >> 8) & 0xFF;
buf[1] = HEIGHT & 0xFF;
buf[2] = (WIDTH >> 8) & 0xFF;
buf[3] = WIDTH & 0xFF;
EPD_command(IL0398_RESOLUTION, buf, 4);
delay(20);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_IL0398::powerDown() {
uint8_t buf[4];
// power off
buf[0] = 0xF7; // border floating
EPD_command(IL0398_VCOM, buf, 1);
EPD_command(IL0398_POWER_OFF);
busy_wait();
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
buf[0] = 0xA5; // deep sleep
EPD_command(UC8276_DEEPSLEEP, buf, 1);
}
delay(100);
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_IL0398::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(EPD_RAM_BW, false);
}
if (index == 1) {
return EPD_command(EPD_RAM_RED, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_IL0398::setRAMAddress(uint16_t x, uint16_t y) {
// on this chip we do nothing
(void)x;
(void)y;
}

View file

@ -0,0 +1,77 @@
#ifndef LIB_ADAFRUIT_IL0398
#define LIB_ADAFRUIT_IL0398
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define IL0398_PANEL_SETTING 0x00
#define IL0398_POWER_SETTING 0x01
#define IL0398_POWER_OFF 0x02
#define IL0398_POWER_OFF_SEQUENCE 0x03
#define IL0398_POWER_ON 0x04
#define IL0398_POWER_ON_MEASURE 0x05
#define IL0398_BOOSTER_SOFT_START 0x06
#define IL0398_DEEP_SLEEP 0x07
#define IL0398_DTM1 0x10
#define IL0398_DATA_STOP 0x11
#define IL0398_DISPLAY_REFRESH 0x12
#define IL0398_DTM2 0x13
#define IL0398_PDTM1 0x14
#define IL0398_PDTM2 0x15
#define IL0398_PDRF 0x16
#define IL0398_LUT1 0x20
#define IL0398_LUTWW 0x21
#define IL0398_LUTBW 0x22
#define IL0398_LUTWB 0x23
#define IL0398_LUTBB 0x24
#define IL0398_PLL 0x30
#define IL0398_TEMPCALIBRATE 0x40
#define IL0398_TEMPSELECT 0x41
#define IL0398_TEMPWRITE 0x42
#define IL0398_TEMPREAD 0x43
#define IL0398_VCOM 0x50
#define IL0398_LOWPOWERDETECT 0x51
#define IL0398_TCON 0x60
#define IL0398_RESOLUTION 0x61
#define IL0398_GSSTSETTING 0x65
#define IL0398_REVISION 0x70
#define IL0398_GETSTATUS 0x71
#define IL0398_AUTOVCOM 0x80
#define IL0398_READVCOM 0x81
#define IL0398_VCM_DC_SETTING 0x82
#define IL0398_PARTWINDOW 0x90
#define IL0398_PARTIALIN 0x91
#define IL0398_PARTIALOUT 0x92
#define IL0398_PROGRAMMODE 0xA0
#define IL0398_ACTIVEPROGRAM 0xA1
#define IL0398_READOTP 0xA2
#define IL0398_CASCADESET 0xE0
#define IL0398_POWERSAVING 0xE3
#define IL0398_FORCETEMP 0xE5
/**************************************************************************/
/*!
@brief Class for interfacing with IL0398 EPD drivers
*/
/**************************************************************************/
class Adafruit_IL0398 : public Adafruit_EPD {
public:
Adafruit_IL0398(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_IL0398(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update();
void powerDown();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,253 @@
#include "Adafruit_IL91874.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t il91874_default_init_code[] {
IL91874_BOOSTER_SOFT_START, 3, 0x07, 0x07, 0x17,
IL91874_POWER_ON, 0,
0xFF, 20, // busy wait
IL91874_PANEL_SETTING, 1, 0x1f, // LUT from OTP
IL91874_PDRF, 1, 0x00,
0xF8, 2, 0x60, 0xA5, // boost
0xF8, 2, 0x73, 0x23, // boost
0xF8, 2, 0x7C, 0x00, // boost
IL91874_CDI, 1, 0x97,
0xFE};
// clang-format on
const unsigned char lut_vcomDC[] = {
0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A,
0x00, 0x00, 0x08, 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x00, 0x0A,
0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00,
0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
// R21H
const unsigned char lut_ww[] = {
0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00,
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00,
0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
// R22H r
const unsigned char lut_bw[] = {
0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A, 0x00, 0x00,
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x90, 0x0A, 0x0A, 0x00,
0x00, 0x08, 0xB0, 0x04, 0x10, 0x00, 0x00, 0x05, 0xB0, 0x03, 0x0E,
0x00, 0x00, 0x0A, 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01};
// R23H w
const unsigned char lut_bb[] = {
0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00,
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00,
0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
// R24H b
const unsigned char lut_wb[] = {
0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x20, 0x0A, 0x0A, 0x00, 0x00,
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x10, 0x0A, 0x0A, 0x00,
0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_IL91874::Adafruit_IL91874(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_IL91874::Adafruit_IL91874(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_IL91874::busy_wait(void) {
if (_busy_pin >= 0) {
while (!digitalRead(_busy_pin)) {
delay(1); // wait for busy low
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_IL91874::begin(bool reset) {
singleByteTxns = true;
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, true); // red defaults to not inverted
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_IL91874::update() {
EPD_command(IL91874_DISPLAY_REFRESH);
delay(100);
busy_wait();
if (_busy_pin <= -1) {
delay(default_refresh_delay);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_IL91874::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(200);
const uint8_t* init_code = il91874_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
if (_epd_lut_code) {
EPD_commandList(_epd_lut_code);
}
buf[0] = (HEIGHT >> 8) & 0xFF;
buf[1] = HEIGHT & 0xFF;
buf[2] = (WIDTH >> 8) & 0xFF;
buf[3] = WIDTH & 0xFF;
EPD_command(IL91874_RESOLUTION, buf, 4);
buf[0] = 0x00;
EPD_command(IL91874_PDRF, buf, 1);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_IL91874::powerDown() {
uint8_t buf[1];
buf[0] = 0xF7;
EPD_command(IL91874_CDI, buf, 1);
// power off
EPD_command(IL91874_POWER_OFF);
busy_wait();
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
buf[0] = 0xA5;
EPD_command(IL91874_DEEP_SLEEP, buf, 1);
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_IL91874::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(EPD_RAM_BW, false);
}
if (index == 1) {
return EPD_command(EPD_RAM_RED, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_IL91874::setRAMAddress(uint16_t x, uint16_t y) {
// on this chip we do nothing
(void)x;
(void)y;
}

View file

@ -0,0 +1,56 @@
#ifndef LIB_ADAFRUIT_IL91874
#define LIB_ADAFRUIT_IL91874
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define IL91874_PANEL_SETTING 0x00
#define IL91874_POWER_SETTING 0x01
#define IL91874_POWER_OFF 0x02
#define IL91874_POWER_OFF_SEQUENCE 0x03
#define IL91874_POWER_ON 0x04
#define IL91874_POWER_ON_MEASURE 0x05
#define IL91874_BOOSTER_SOFT_START 0x06
#define IL91874_DEEP_SLEEP 0x07
#define IL91874_DTM1 0x10
#define IL91874_DATA_STOP 0x11
#define IL91874_DISPLAY_REFRESH 0x12
#define IL91874_PDTM1 0x14
#define IL91874_PDTM2 0x15
#define IL91874_PDRF 0x16
#define IL91874_LUT1 0x20
#define IL91874_LUTWW 0x21
#define IL91874_LUTBW 0x22
#define IL91874_LUTWB 0x23
#define IL91874_LUTBB 0x24
#define IL91874_PLL 0x30
#define IL91874_CDI 0x50
#define IL91874_RESOLUTION 0x61
#define IL91874_VCM_DC_SETTING 0x82
/**************************************************************************/
/*!
@brief Class for interfacing with IL0373 EPD drivers
*/
/**************************************************************************/
class Adafruit_IL91874 : public Adafruit_EPD {
public:
Adafruit_IL91874(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_IL91874(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update();
void powerDown();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,316 @@
#include "Adafruit_JD79661.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t jd79661_default_init_code[] {
0xFF, 10, // wait a lil bit
0x4D, 1, 0x78,
JD79661_PANEL_SETTING, 2, 0x8F, 0x29, // PSR, Display resolution is 128x250
JD79661_POWER_SETTING, 2, 0x07, 0x00, // PWR
0x03, 3, 0x10, 0x54, 0x44, // POFS
JD79661_BOOSTER_SOFTSTART, 7, 0x05, 0x00, 0x3F, 0x0A, 0x25, 0x12, 0x1A,
JD79661_CDI, 1, 0x37, // CDI
0x60, 2, 0x02, 0x02, // TCON
JD79661_RESOLUTION, 4, 0, 128, 0, 250, // TRES
0xE7, 1, 0x1C,
0xE3, 1, 0x22,
0xB4, 1, 0xD0,
0xB5, 1, 0x03,
0xE9, 1, 0x01,
JD79661_PLL_CONTROL, 1, 0x08,
JD79661_POWER_ON, 0,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_JD79661::Adafruit_JD79661(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = width * height / 4;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = buffer1;
}
singleByteTxns = true;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_JD79661::Adafruit_JD79661(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = width * height / 4;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = buffer1;
}
singleByteTxns = true;
}
/**************************************************************************/
/*!
@brief clear all data buffers
*/
/**************************************************************************/
void Adafruit_JD79661::clearBuffer() {
if (use_sram) {
sram.erase(colorbuffer_addr, buffer1_size, 0x55);
} else {
memset(buffer1, 0x55, buffer1_size);
}
}
/**************************************************************************/
/*!
@brief draw a single pixel on the screen
@param x the x axis position
@param y the y axis position
@param color the color of the pixel
*/
/**************************************************************************/
void Adafruit_JD79661::drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
uint8_t* pBuf;
// deal with non-4-bit heights
uint16_t _WIDTH = WIDTH;
if (_WIDTH % 4 != 0) {
_WIDTH += 4 - (_WIDTH % 4);
}
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
EPD_swap(x, y);
x = _WIDTH - x - 1;
// remove the offset
x -= _WIDTH - WIDTH;
break;
case 2:
x = _WIDTH - x - 1;
y = HEIGHT - y - 1;
// re-add the offset
x += _WIDTH - WIDTH;
break;
case 3:
EPD_swap(x, y);
y = HEIGHT - y - 1;
break;
}
uint32_t addr = ((uint32_t)x + (uint32_t)y * _WIDTH) / 4;
uint8_t color_c;
if (use_sram) {
color_c = sram.read8(colorbuffer_addr + addr);
pBuf = &color_c;
} else {
pBuf = color_buffer + addr;
}
if (color == EPD_BLACK) {
color = JD79661_BLACK;
} else if (color == EPD_RED) {
color = JD79661_RED;
} else if (color == EPD_YELLOW) {
color = JD79661_YELLOW;
} else if (color == EPD_WHITE) {
color = JD79661_WHITE;
}
uint8_t byte_offset_mask = 0x3 << (3 - (x % 4)) * 2;
uint8_t byte_offset_value = (color & 0x3) << (3 - (x % 4)) * 2;
*pBuf &= ~byte_offset_mask; // save reverse mask
*pBuf |= byte_offset_value; // now add in the new color
if (use_sram) {
sram.write8(colorbuffer_addr + addr, *pBuf);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_JD79661::busy_wait(void) {
if (_busy_pin >= 0) {
while (!digitalRead(_busy_pin)) { // wait for busy HIGH!
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_JD79661::begin(bool reset) {
Adafruit_EPD::begin(reset);
delay(100);
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_JD79661::update() {
uint8_t buf[1];
// display update sequence
buf[0] = 0x00;
EPD_command(JD79661_DISPLAY_REFRESH, buf, 1);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
void Adafruit_JD79661::hardwareReset(void) {
if (_reset_pin >= 0) {
// Setup reset pin direction
pinMode(_reset_pin, OUTPUT);
// VDD (3.3V) goes high at start, lets just chill for a ms
digitalWrite(_reset_pin, HIGH);
delay(20);
// bring reset low
digitalWrite(_reset_pin, LOW);
// wait 40ms
delay(40);
// bring out of reset
digitalWrite(_reset_pin, HIGH);
delay(50);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_JD79661::powerUp() {
hardwareReset();
busy_wait();
const uint8_t* init_code = jd79661_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_JD79661::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x00;
EPD_command(JD79661_POWER_OFF, buf, 1);
busy_wait();
buf[0] = 0xA5;
EPD_command(JD79661_DEEP_SLEEP, buf, 1);
delay(100);
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_JD79661::writeRAMCommand(uint8_t index) {
(void)index;
EPD_command(JD79661_DATA_START_XMIT);
return true;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_JD79661::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
}

View file

@ -0,0 +1,53 @@
#ifndef LIB_ADAFRUIT_JD79661
#define LIB_ADAFRUIT_JD79661
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define JD79661_PANEL_SETTING 0x00
#define JD79661_POWER_SETTING 0x01
#define JD79661_POWER_OFF 0x02
#define JD79661_POWER_ON 0x04
#define JD79661_BOOSTER_SOFTSTART 0x06
#define JD79661_DATA_START_XMIT 0x10
#define JD79661_DISPLAY_REFRESH 0x12
#define JD79661_DEEP_SLEEP 0x07
#define JD79661_PLL_CONTROL 0x30
#define JD79661_CDI 0x50
#define JD79661_RESOLUTION 0x61
#define JD79661_BLACK 0b00
#define JD79661_WHITE 0b01
#define JD79661_YELLOW 0b10
#define JD79661_RED 0b11
/**************************************************************************/
/*!
@brief Class for interfacing with JD79661 EPD drivers
*/
/**************************************************************************/
class Adafruit_JD79661 : public Adafruit_EPD {
public:
Adafruit_JD79661(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_JD79661(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update(void);
void powerDown();
void clearBuffer();
void drawPixel(int16_t x, int16_t y, uint16_t color);
void hardwareReset(void);
protected:
void busy_wait();
void setRAMAddress(uint16_t x, uint16_t y);
uint8_t writeRAMCommand(uint8_t index);
};
#endif

View file

@ -0,0 +1,314 @@
#include "Adafruit_JD79667.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t jd79667_default_init_code[] {
0xFF, 10, // wait a lil bit
0x4D, 1, 0x78,
JD79667_PANEL_SETTING, 2, 0x0F, 0x29, // PSR, Display resolution is 180x384
JD79667_POWER_SETTING, 2, 0x07, 0x00, // PWR
0x03, 3, 0x10, 0x54, 0x44, // POFS
JD79667_BOOSTER_SOFTSTART, 7, 0x05, 0x00, 0x3F, 0x0A, 0x25, 0x12, 0x1A,
JD79667_CDI, 1, 0x37, // CDI
0x60, 2, 0x02, 0x02, // TCON
JD79667_RESOLUTION, 4, 0, 180, 1, 128, // TRES 180x384
0xE7, 1, 0x1C,
0xE3, 1, 0x22,
0xB4, 1, 0xD0,
0xB5, 1, 0x03,
0xE9, 1, 0x01,
JD79667_PLL_CONTROL, 1, 0x08,
JD79667_POWER_ON, 0,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_JD79667::Adafruit_JD79667(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = width * height / 4;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = buffer1;
}
singleByteTxns = true;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_JD79667::Adafruit_JD79667(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = width * height / 4;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = buffer1;
}
singleByteTxns = true;
}
/**************************************************************************/
/*!
@brief clear all data buffers
*/
/**************************************************************************/
void Adafruit_JD79667::clearBuffer() {
if (use_sram) {
sram.erase(colorbuffer_addr, buffer1_size, 0x55);
} else {
memset(buffer1, 0x55, buffer1_size);
}
}
/**************************************************************************/
/*!
@brief draw a single pixel on the screen
@param x the x axis position
@param y the y axis position
@param color the color of the pixel
*/
/**************************************************************************/
void Adafruit_JD79667::drawPixel(int16_t x, int16_t y, uint16_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
uint8_t* pBuf;
// deal with non-4-bit heights
uint16_t _WIDTH = WIDTH;
if (_WIDTH % 4 != 0) {
_WIDTH += 4 - (_WIDTH % 4);
}
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
EPD_swap(x, y);
x = _WIDTH - x - 1;
// remove the offset
x -= _WIDTH - WIDTH;
break;
case 2:
x = _WIDTH - x - 1;
y = HEIGHT - y - 1;
// re-add the offset
x += _WIDTH - WIDTH;
break;
case 3:
EPD_swap(x, y);
y = HEIGHT - y - 1;
break;
}
uint32_t addr = ((uint32_t)x + (uint32_t)y * _WIDTH) / 4;
uint8_t color_c;
if (use_sram) {
color_c = sram.read8(colorbuffer_addr + addr);
pBuf = &color_c;
} else {
pBuf = color_buffer + addr;
}
if (color == EPD_BLACK) {
color = JD79667_BLACK;
} else if (color == EPD_RED) {
color = JD79667_RED;
} else if (color == EPD_YELLOW) {
color = JD79667_YELLOW;
} else if (color == EPD_WHITE) {
color = JD79667_WHITE;
}
uint8_t byte_offset_mask = 0x3 << (3 - (x % 4)) * 2;
uint8_t byte_offset_value = (color & 0x3) << (3 - (x % 4)) * 2;
*pBuf &= ~byte_offset_mask; // save reverse mask
*pBuf |= byte_offset_value; // now add in the new color
if (use_sram) {
sram.write8(colorbuffer_addr + addr, *pBuf);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_JD79667::busy_wait(void) {
if (_busy_pin >= 0) {
while (!digitalRead(_busy_pin)) { // wait for busy HIGH!
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_JD79667::begin(bool reset) {
Adafruit_EPD::begin(reset);
delay(100);
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_JD79667::update() {
uint8_t buf[1];
// display update sequence
buf[0] = 0x00;
EPD_command(JD79667_DISPLAY_REFRESH, buf, 1);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
void Adafruit_JD79667::hardwareReset(void) {
if (_reset_pin >= 0) {
// Setup reset pin direction
pinMode(_reset_pin, OUTPUT);
// VDD (3.3V) goes high at start, lets just chill for a ms
digitalWrite(_reset_pin, HIGH);
delay(20);
// bring reset low
digitalWrite(_reset_pin, LOW);
// wait 40ms
delay(40);
// bring out of reset
digitalWrite(_reset_pin, HIGH);
delay(50);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_JD79667::powerUp() {
hardwareReset();
busy_wait();
const uint8_t* init_code = jd79667_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_JD79667::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x00;
EPD_command(JD79667_POWER_OFF, buf, 1);
busy_wait();
delay(100);
buf[0] = 0xA5;
EPD_command(JD79667_DEEP_SLEEP, buf, 1);
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_JD79667::writeRAMCommand(uint8_t index) {
(void)index;
EPD_command(JD79667_DATA_START_XMIT);
return true;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_JD79667::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
}

View file

@ -0,0 +1,53 @@
#ifndef LIB_ADAFRUIT_JD79667
#define LIB_ADAFRUIT_JD79667
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define JD79667_PANEL_SETTING 0x00
#define JD79667_POWER_SETTING 0x01
#define JD79667_POWER_OFF 0x02
#define JD79667_POWER_ON 0x04
#define JD79667_BOOSTER_SOFTSTART 0x06
#define JD79667_DATA_START_XMIT 0x10
#define JD79667_DISPLAY_REFRESH 0x12
#define JD79667_DEEP_SLEEP 0x07
#define JD79667_PLL_CONTROL 0x30
#define JD79667_CDI 0x50
#define JD79667_RESOLUTION 0x61
#define JD79667_BLACK 0b00
#define JD79667_WHITE 0b01
#define JD79667_YELLOW 0b10
#define JD79667_RED 0b11
/**************************************************************************/
/*!
@brief Class for interfacing with JD79667 EPD drivers
*/
/**************************************************************************/
class Adafruit_JD79667 : public Adafruit_EPD {
public:
Adafruit_JD79667(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_JD79667(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update(void);
void powerDown();
void clearBuffer();
void drawPixel(int16_t x, int16_t y, uint16_t color);
void hardwareReset(void);
protected:
void busy_wait();
void setRAMAddress(uint16_t x, uint16_t y);
uint8_t writeRAMCommand(uint8_t index);
};
#endif

View file

@ -0,0 +1,258 @@
#include "Adafruit_SSD1608.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define BUSY_WAIT 500
const unsigned char LUT_DATA[30] = {
0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 0x66, 0x69,
0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 0x00, 0x00, 0x00, 0x00,
0xF8, 0xB4, 0x13, 0x51, 0x35, 0x51, 0x51, 0x19, 0x01, 0x00};
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1608::Adafruit_SSD1608(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = (uint16_t)width * (uint16_t)height / 8;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = NULL;
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1608::Adafruit_SSD1608(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = (uint16_t)width * (uint16_t)height / 8;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = buffer1;
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1608::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_SSD1608::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(0, true); // no secondary buffer, so we'll just reuse index 0
delay(100);
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1608::update() {
uint8_t buf[1];
// display update sequence
buf[0] = 0xC7;
EPD_command(SSD1608_DISP_CTRL2, buf, 1);
EPD_command(SSD1608_MASTER_ACTIVATE);
busy_wait();
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1608::powerUp() {
uint8_t buf[5];
hardwareReset();
busy_wait();
// soft reset
EPD_command(SSD1608_SW_RESET);
busy_wait();
// driver output control
buf[0] = HEIGHT - 1;
buf[1] = (HEIGHT - 1) >> 8;
buf[2] = 0x00;
EPD_command(SSD1608_DRIVER_CONTROL, buf, 3);
// Set dummy line period
buf[0] = 0x1B;
EPD_command(SSD1608_WRITE_DUMMY, buf, 1);
// Set gate line width
buf[0] = 0x0B;
EPD_command(SSD1608_WRITE_GATELINE, buf, 1);
// Data entry sequence
buf[0] = 0x03;
EPD_command(SSD1608_DATA_MODE, buf, 1);
// Set ram X start/end postion
buf[0] = 0x00;
buf[1] = WIDTH / 8 - 1;
EPD_command(SSD1608_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = HEIGHT - 1;
buf[3] = (HEIGHT - 1) >> 8;
EPD_command(SSD1608_SET_RAMYPOS, buf, 4);
// Vcom Voltage
buf[0] = 0x70;
EPD_command(SSD1608_WRITE_VCOM, buf, 1);
EPD_command(SSD1608_WRITE_LUT, LUT_DATA, 30);
/*
// border color
buf[0] = 0x03;
EPD_command(SSD1608_WRITE_BORDER, buf, 1);
// Set gate voltage
buf[0] = LUT_DATA[70];
EPD_command(SSD1608_GATE_VOLTAGE, buf, 1);
// Set source voltage
buf[0] = LUT_DATA[71];
buf[1] = LUT_DATA[72];
buf[2] = LUT_DATA[73];
EPD_command(SSD1608_SOURCE_VOLTAGE, buf, 3);
*/
/*
// set RAM x address count ;
buf[0] = 0;
EPD_command(SSD1608_SET_RAMXCOUNT, buf, 1);
// set RAM y address count;
buf[0] = HEIGHT - 1;
buf[1] = (HEIGHT - 1) >> 8;
EPD_command(SSD1608_SET_RAMYCOUNT, buf, 2);
*/
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1608::powerDown(void) {
uint8_t buf[2];
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1608_DEEP_SLEEP, buf, 1);
delay(100);
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_SSD1608::writeRAMCommand(uint8_t index) {
(void)index;
return EPD_command(SSD1608_WRITE_RAM, false);
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1608::setRAMAddress(uint16_t x, uint16_t y) {
uint8_t buf[2];
// Set RAM X address counter
buf[0] = x;
EPD_command(SSD1608_SET_RAMXCOUNT, buf, 1);
// Set RAM Y address counter
buf[0] = y >> 8;
buf[1] = y;
EPD_command(SSD1608_SET_RAMYCOUNT, buf, 2);
}

View file

@ -0,0 +1,65 @@
#ifndef LIB_ADAFRUIT_SSD1608
#define LIB_ADAFRUIT_SSD1608
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define SSD1608_DRIVER_CONTROL 0x01
#define SSD1608_GATE_VOLTAGE 0x03
#define SSD1608_SOURCE_VOLTAGE 0x04
#define SSD1608_DISPLAY_CONTROL 0x07
#define SSD1608_NON_OVERLAP 0x0B
#define SSD1608_BOOSTER_SOFT_START 0x0C
#define SSD1608_GATE_SCAN_START 0x0F
#define SSD1608_DEEP_SLEEP 0x10
#define SSD1608_DATA_MODE 0x11
#define SSD1608_SW_RESET 0x12
#define SSD1608_TEMP_WRITE 0x1A
#define SSD1608_TEMP_READ 0x1B
#define SSD1608_TEMP_CONTROL 0x1C
#define SSD1608_TEMP_LOAD 0x1D
#define SSD1608_MASTER_ACTIVATE 0x20
#define SSD1608_DISP_CTRL1 0x21
#define SSD1608_DISP_CTRL2 0x22
#define SSD1608_WRITE_RAM 0x24
#define SSD1608_READ_RAM 0x25
#define SSD1608_VCOM_SENSE 0x28
#define SSD1608_VCOM_DURATION 0x29
#define SSD1608_WRITE_VCOM 0x2C
#define SSD1608_READ_OTP 0x2D
#define SSD1608_WRITE_LUT 0x32
#define SSD1608_WRITE_DUMMY 0x3A
#define SSD1608_WRITE_GATELINE 0x3B
#define SSD1608_WRITE_BORDER 0x3C
#define SSD1608_SET_RAMXPOS 0x44
#define SSD1608_SET_RAMYPOS 0x45
#define SSD1608_SET_RAMXCOUNT 0x4E
#define SSD1608_SET_RAMYCOUNT 0x4F
#define SSD1608_NOP 0xFF
/**************************************************************************/
/*!
@brief Class for interfacing with SSD1608 EPD drivers
*/
/**************************************************************************/
class Adafruit_SSD1608 : public Adafruit_EPD {
public:
Adafruit_SSD1608(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_SSD1608(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void powerDown();
void update();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,271 @@
#include "Adafruit_SSD1619.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t ssd1619_default_init_code[] {
SSD1619_SW_RESET, 0, // soft reset
0xFF, 20, // busy wait
SSD1619_SET_ANALOGBLOCK, 1, 0x54, // set analog block control
SSD1619_SET_DIGITALBLOCK, 1, 0x3B, // set digital block control
SSD1619_DATA_MODE, 1, 0x03, // Ram data entry mode
SSD1619_WRITE_BORDER, 1, 0x01, // border color
SSD1619_TEMP_CONTROL, 1, 0x80, // Temp control
SSD1619_DISP_CTRL2, 1, 0xB1,
SSD1619_MASTER_ACTIVATE, 0,
0xFF, 20, // busy wait
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1619::Adafruit_SSD1619(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
singleByteTxns = true;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1619::Adafruit_SSD1619(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
singleByteTxns = true;
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1619::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_SSD1619::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, false); // red defaults to un inverted
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1619::update() {
uint8_t buf[1];
// display update sequence
// buf[0] = 0x40;
// EPD_command(SSD1619_DISP_CTRL1, buf, 1);
buf[0] = 0xC7;
EPD_command(SSD1619_DISP_CTRL2, buf, 1);
EPD_command(SSD1619_MASTER_ACTIVATE);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1619::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(100);
busy_wait();
const uint8_t* init_code = ssd1619_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
// Set display size and driver output control
buf[0] = (WIDTH - 1);
buf[1] = (WIDTH - 1) >> 8;
buf[2] = 0x00;
EPD_command(SSD1619_DRIVER_CONTROL, buf, 3);
setRAMWindow(0, 0, HEIGHT - 1, WIDTH - 1);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1619::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1619_DEEP_SLEEP, buf, 1);
delay(100);
} else {
EPD_command(SSD1619_SW_RESET);
busy_wait();
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_SSD1619::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(SSD1619_WRITE_RAM1, false);
}
if (index == 1) {
return EPD_command(SSD1619_WRITE_RAM2, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1619::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
uint8_t buf[2];
// set RAM x address count
buf[0] = 0x00;
EPD_command(SSD1619_SET_RAMXCOUNT, buf, 1);
// set RAM y address count
buf[0] = 0x0;
buf[1] = 0x0;
EPD_command(SSD1619_SET_RAMYCOUNT, buf, 2);
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1619::setRAMWindow(uint16_t x1, uint16_t y1, uint16_t x2,
uint16_t y2) {
uint8_t buf[5];
// Set ram X start/end postion
buf[0] = x1 / 8;
buf[1] = x2 / 8;
EPD_command(SSD1619_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = y1;
buf[1] = y1 >> 8;
buf[2] = y2;
buf[3] = y2 >> 8;
EPD_command(SSD1619_SET_RAMYPOS, buf, 4);
}

View file

@ -0,0 +1,62 @@
#ifndef LIB_ADAFRUIT_SSD1619
#define LIB_ADAFRUIT_SSD1619
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define SSD1619_DRIVER_CONTROL 0x01
#define SSD1619_GATE_VOLTAGE 0x03
#define SSD1619_SOURCE_VOLTAGE 0x04
#define SSD1619_PROGOTP_INITIAL 0x08
#define SSD1619_PROGREG_INITIAL 0x09
#define SSD1619_READREG_INITIAL 0x0A
#define SSD1619_BOOST_SOFTSTART 0x0C
#define SSD1619_DEEP_SLEEP 0x10
#define SSD1619_DATA_MODE 0x11
#define SSD1619_SW_RESET 0x12
#define SSD1619_TEMP_CONTROL 0x18
#define SSD1619_TEMP_WRITE 0x1A
#define SSD1619_MASTER_ACTIVATE 0x20
#define SSD1619_DISP_CTRL1 0x21
#define SSD1619_DISP_CTRL2 0x22
#define SSD1619_WRITE_RAM1 0x24
#define SSD1619_WRITE_RAM2 0x26
#define SSD1619_WRITE_VCOM 0x2C
#define SSD1619_READ_OTP 0x2D
#define SSD1619_READ_STATUS 0x2F
#define SSD1619_WRITE_LUT 0x32
#define SSD1619_WRITE_BORDER 0x3C
#define SSD1619_SET_RAMXPOS 0x44
#define SSD1619_SET_RAMYPOS 0x45
#define SSD1619_SET_RAMXCOUNT 0x4E
#define SSD1619_SET_RAMYCOUNT 0x4F
#define SSD1619_SET_ANALOGBLOCK 0x74
#define SSD1619_SET_DIGITALBLOCK 0x7E
/**************************************************************************/
/*!
@brief Class for interfacing with SSD1619 EPD drivers
*/
/**************************************************************************/
class Adafruit_SSD1619 : public Adafruit_EPD {
public:
Adafruit_SSD1619(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_SSD1619(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update(void);
void powerDown();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void setRAMWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void busy_wait();
};
#endif

View file

@ -0,0 +1,296 @@
#include "Adafruit_SSD1675.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
const unsigned char LUT_DATA[] = {
0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, // LUT0: BB: VS 0 ~7
0x10, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, // LUT1: BW: VS 0 ~7
0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, // LUT2: WB: VS 0 ~7
0x10, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, // LUT3: WW: VS 0 ~7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUT4: VCOM: VS 0 ~7
0x03, 0x03, 0x00, 0x00, 0x02, // TP0 A~D RP0
0x09, 0x09, 0x00, 0x00, 0x02, // TP1 A~D RP1
0x03, 0x03, 0x00, 0x00, 0x02, // TP2 A~D RP2
0x00, 0x00, 0x00, 0x00, 0x00, // TP3 A~D RP3
0x00, 0x00, 0x00, 0x00, 0x00, // TP4 A~D RP4
0x00, 0x00, 0x00, 0x00, 0x00, // TP5 A~D RP5
0x00, 0x00, 0x00, 0x00, 0x00, // TP6 A~D RP6
0x15, 0x41, 0xA8, 0x32, 0x30, 0x0A,
};
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1675::Adafruit_SSD1675(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1675::Adafruit_SSD1675(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1675::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_SSD1675::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(0, true); // no secondary buffer, so we'll just reuse index 0
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1675::update() {
uint8_t buf[1];
// display update sequence
buf[0] = 0xC7;
EPD_command(SSD1675_DISP_CTRL2, buf, 1);
EPD_command(SSD1675_MASTER_ACTIVATE);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1675::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(100);
busy_wait();
// soft reset
EPD_command(SSD1675_SW_RESET);
busy_wait();
// set analog block control
buf[0] = 0x54;
EPD_command(SSD1675_SET_ANALOGBLOCK, buf, 1);
// set digital block control
buf[0] = 0x3B;
EPD_command(SSD1675_SET_DIGITALBLOCK, buf, 1);
// driver output control
buf[0] = 0xFA; // 250-1
buf[1] = 0x01;
buf[2] = 0x00;
EPD_command(SSD1675_DRIVER_CONTROL, buf, 3);
// Data entry sequence
buf[0] = 0x03;
EPD_command(SSD1675_DATA_MODE, buf, 1);
// Set ram X start/end postion
buf[0] = 0x00;
buf[1] = 0x0F; // (15+1) * 8 = 128
EPD_command(SSD1675_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = 0x00; // 0xF9-->(249+1)=250
buf[1] = 0x00;
buf[2] = 0xF9;
buf[3] = 0x00;
EPD_command(SSD1675_SET_RAMYPOS, buf, 4);
// border color
buf[0] = 0x03;
EPD_command(SSD1675_WRITE_BORDER, buf, 1);
// Vcom Voltage
buf[0] = 0x70;
EPD_command(SSD1675_WRITE_VCOM, buf, 1);
// Set gate voltage
buf[0] = LUT_DATA[70];
EPD_command(SSD1675_GATE_VOLTAGE, buf, 1);
// Set source voltage
buf[0] = LUT_DATA[71];
buf[1] = LUT_DATA[72];
buf[2] = LUT_DATA[73];
EPD_command(SSD1675_SOURCE_VOLTAGE, buf, 3);
// Set dummy line period
buf[0] = LUT_DATA[74];
EPD_command(SSD1675_WRITE_DUMMY, buf, 1);
// Set gate line width
buf[0] = LUT_DATA[75];
EPD_command(SSD1675_WRITE_GATELINE, buf, 1);
EPD_command(SSD1675_WRITE_LUT, LUT_DATA, 70);
// set RAM x address count to 0;
buf[0] = 0;
EPD_command(SSD1675_SET_RAMXCOUNT, buf, 1);
// set RAM y address count to 0X127;
buf[0] = 0xF9;
buf[1] = 0;
EPD_command(SSD1675_SET_RAMYCOUNT, buf, 2);
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1675::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1675_DEEP_SLEEP, buf, 1);
delay(100);
} else {
EPD_command(SSD1675_SW_RESET);
busy_wait();
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_SSD1675::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(SSD1675_WRITE_RAM1, false);
}
if (index == 1) {
return EPD_command(SSD1675_WRITE_RAM2, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1675::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
uint8_t buf[2];
// Set RAM X address counter
buf[0] = 0;
EPD_command(SSD1675_SET_RAMXCOUNT, buf, 1);
// Set RAM Y address counter
buf[0] = 0xF9;
buf[1] = 0x00;
EPD_command(SSD1675_SET_RAMYCOUNT, buf, 2);
}

View file

@ -0,0 +1,60 @@
#ifndef LIB_ADAFRUIT_SSD1675
#define LIB_ADAFRUIT_SSD1675
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define SSD1675_DRIVER_CONTROL 0x01
#define SSD1675_GATE_VOLTAGE 0x03
#define SSD1675_SOURCE_VOLTAGE 0x04
#define SSD1675_DEEP_SLEEP 0x10
#define SSD1675_DATA_MODE 0x11
#define SSD1675_SW_RESET 0x12
#define SSD1675_HV_READY 0x14
#define SSD1675_VCI_READY 0x15
#define SSD1675_TEMP_WRITE 0x1A
#define SSD1675_MASTER_ACTIVATE 0x20
#define SSD1675_DISP_CTRL1 0x21
#define SSD1675_DISP_CTRL2 0x22
#define SSD1675_WRITE_RAM1 0x24
#define SSD1675_WRITE_RAM2 0x26
#define SSD1675_WRITE_VCOM 0x2C
#define SSD1675_READ_OTP 0x2D
#define SSD1675_READ_STATUS 0x2F
#define SSD1675_WRITE_LUT 0x32
#define SSD1675_WRITE_DUMMY 0x3A
#define SSD1675_WRITE_GATELINE 0x3B
#define SSD1675_WRITE_BORDER 0x3C
#define SSD1675_SET_RAMXPOS 0x44
#define SSD1675_SET_RAMYPOS 0x45
#define SSD1675_SET_RAMXCOUNT 0x4E
#define SSD1675_SET_RAMYCOUNT 0x4F
#define SSD1675_SET_ANALOGBLOCK 0x74
#define SSD1675_SET_DIGITALBLOCK 0x7E
/**************************************************************************/
/*!
@brief Class for interfacing with SSD1675 EPD drivers
*/
/**************************************************************************/
class Adafruit_SSD1675 : public Adafruit_EPD {
public:
Adafruit_SSD1675(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_SSD1675(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update();
void powerDown();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,299 @@
#include "Adafruit_SSD1675B.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
#define SSD1675B_USELUT
const unsigned char LUT_DATA[] = {
0xA0, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xA0, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03,
0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x41, 0xA8, 0x32, 0x50, 0x2C, 0x0B,
};
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1675B::Adafruit_SSD1675B(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1675B::Adafruit_SSD1675B(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = width * height / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1675B::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_SSD1675B::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(0, true); // no secondary buffer, so we'll just reuse index 0
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1675B::update() {
uint8_t buf[1];
// display update sequence
buf[0] = 0xC7;
EPD_command(SSD1675B_DISP_CTRL2, buf, 1);
EPD_command(SSD1675B_MASTER_ACTIVATE);
busy_wait();
if (_busy_pin <= -1) {
delay(3000);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1675B::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(100);
busy_wait();
// soft reset
EPD_command(SSD1675B_SW_RESET);
busy_wait();
#ifdef SSD1675B_USELUT
// set analog block control
buf[0] = 0x54;
EPD_command(SSD1675B_SET_ANALOGBLOCK, buf, 1);
// set digital block control
buf[0] = 0x3B;
EPD_command(SSD1675B_SET_DIGITALBLOCK, buf, 1);
#endif
// driver output control
buf[0] = WIDTH - 1;
buf[1] = (WIDTH - 1) >> 8;
buf[2] = 0x00;
EPD_command(SSD1675B_DRIVER_CONTROL, buf, 3);
// Data entry sequence
buf[0] = 0x03;
EPD_command(SSD1675B_DATA_MODE, buf, 1);
// Set ram X start/end postion
buf[0] = 0x00;
buf[1] = HEIGHT / 8;
EPD_command(SSD1675B_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = WIDTH - 1;
buf[3] = (WIDTH - 1) >> 8;
EPD_command(SSD1675B_SET_RAMYPOS, buf, 4);
// border color
buf[0] = 0x03;
EPD_command(SSD1675B_WRITE_BORDER, buf, 1);
#ifdef SSD1675B_USELUT
// Vcom Voltage
buf[0] = 0x50;
EPD_command(SSD1675B_WRITE_VCOM, buf, 1);
// Set gate voltage
buf[0] = LUT_DATA[100];
EPD_command(SSD1675B_GATE_VOLTAGE, buf, 1);
// Set source voltage
buf[0] = LUT_DATA[101];
buf[1] = LUT_DATA[102];
buf[2] = LUT_DATA[103];
EPD_command(SSD1675B_SOURCE_VOLTAGE, buf, 3);
// Set dummy line period
buf[0] = LUT_DATA[105];
EPD_command(SSD1675B_WRITE_DUMMY, buf, 1);
// Set gate line width
buf[0] = LUT_DATA[106];
EPD_command(SSD1675B_WRITE_GATELINE, buf, 1);
EPD_command(SSD1675B_WRITE_LUT, LUT_DATA, 99);
#endif
// set RAM x address count to 0
buf[0] = 0;
EPD_command(SSD1675_SET_RAMXCOUNT, buf, 1);
// set RAM y address count to max
buf[0] = WIDTH - 1;
buf[1] = (WIDTH - 1) >> 8;
EPD_command(SSD1675_SET_RAMYCOUNT, buf, 2);
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1675B::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1675B_DEEP_SLEEP, buf, 1);
delay(100);
} else {
EPD_command(SSD1675B_SW_RESET);
busy_wait();
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_SSD1675B::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(SSD1675_WRITE_RAM1, false);
}
if (index == 1) {
return EPD_command(SSD1675_WRITE_RAM2, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1675B::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
uint8_t buf[2];
// Set RAM X address counter
buf[0] = 0;
EPD_command(SSD1675_SET_RAMXCOUNT, buf, 1);
// Set RAM Y address counter
buf[0] = WIDTH - 1;
buf[1] = (WIDTH - 1) >> 8;
EPD_command(SSD1675_SET_RAMYCOUNT, buf, 2);
}

View file

@ -0,0 +1,60 @@
#ifndef LIB_ADAFRUIT_SSD1675B
#define LIB_ADAFRUIT_SSD1675B
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define SSD1675B_DRIVER_CONTROL 0x01
#define SSD1675B_GATE_VOLTAGE 0x03
#define SSD1675B_SOURCE_VOLTAGE 0x04
#define SSD1675B_DEEP_SLEEP 0x10
#define SSD1675B_DATA_MODE 0x11
#define SSD1675B_SW_RESET 0x12
#define SSD1675B_HV_READY 0x14
#define SSD1675B_VCI_READY 0x15
#define SSD1675B_TEMP_WRITE 0x1A
#define SSD1675B_MASTER_ACTIVATE 0x20
#define SSD1675B_DISP_CTRL1 0x21
#define SSD1675B_DISP_CTRL2 0x22
#define SSD1675B_WRITE_RAM1 0x24
#define SSD1675B_WRITE_RAM2 0x26
#define SSD1675B_WRITE_VCOM 0x2C
#define SSD1675B_READ_OTP 0x2D
#define SSD1675B_READ_STATUS 0x2F
#define SSD1675B_WRITE_LUT 0x32
#define SSD1675B_WRITE_DUMMY 0x3A
#define SSD1675B_WRITE_GATELINE 0x3B
#define SSD1675B_WRITE_BORDER 0x3C
#define SSD1675B_SET_RAMXPOS 0x44
#define SSD1675B_SET_RAMYPOS 0x45
#define SSD1675B_SET_RAMXCOUNT 0x4E
#define SSD1675B_SET_RAMYCOUNT 0x4F
#define SSD1675B_SET_ANALOGBLOCK 0x74
#define SSD1675B_SET_DIGITALBLOCK 0x7E
/**************************************************************************/
/*!
@brief Class for interfacing with SSD1675 EPD drivers
*/
/**************************************************************************/
class Adafruit_SSD1675B : public Adafruit_EPD {
public:
Adafruit_SSD1675B(int width, int height, int16_t SID, int16_t SCLK,
int16_t DC, int16_t RST, int16_t CS, int16_t SRCS,
int16_t MISO, int16_t BUSY = -1);
Adafruit_SSD1675B(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update();
void powerDown();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
};
#endif

View file

@ -0,0 +1,259 @@
#include "Adafruit_SSD1680.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t ssd1680_default_init_code[] {
SSD1680_SW_RESET, 0, // soft reset
0xFF, 20, // busy wait
SSD1680_DATA_MODE, 1, 0x03, // Ram data entry mode
SSD1680_WRITE_BORDER, 1, 0x05, // border color
SSD1680_WRITE_VCOM, 1, 0x36, // Vcom Voltage
SSD1680_GATE_VOLTAGE, 1, 0x17, // Set gate voltage
SSD1680_SOURCE_VOLTAGE, 3, 0x41, 0x00, 0x32, // Set source voltage
SSD1680_SET_RAMXCOUNT, 1, 1,
SSD1680_SET_RAMYCOUNT, 2, 0, 0,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1680::Adafruit_SSD1680(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
singleByteTxns = true;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1680::Adafruit_SSD1680(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
singleByteTxns = true;
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1680::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_SSD1680::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, false); // red defaults to un inverted
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1680::update() {
uint8_t buf[1];
buf[0] = _display_update_val; // varies for mono vs gray4 mode
EPD_command(SSD1680_DISP_CTRL2, buf, 1);
EPD_command(SSD1680_MASTER_ACTIVATE);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1680::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(100);
busy_wait();
const uint8_t* init_code = ssd1680_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
uint8_t height = HEIGHT;
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
// Set ram X start/end postion
buf[0] = _xram_offset;
buf[1] = height / 8 - 1 + _xram_offset;
EPD_command(SSD1680_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = (WIDTH - 1);
buf[3] = (WIDTH - 1) >> 8;
EPD_command(SSD1680_SET_RAMYPOS, buf, 4);
// Set LUT (if we have one)
if (_epd_lut_code) {
EPD_commandList(_epd_lut_code);
}
// Set display size and driver output control
buf[0] = (WIDTH - 1);
buf[1] = (WIDTH - 1) >> 8;
buf[2] = 0x00;
EPD_command(SSD1680_DRIVER_CONTROL, buf, 3);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1680::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1680_DEEP_SLEEP, buf, 1);
delay(100);
} else {
EPD_command(SSD1680_SW_RESET);
busy_wait();
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_SSD1680::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(SSD1680_WRITE_RAM1, false);
}
if (index == 1) {
return EPD_command(SSD1680_WRITE_RAM2, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1680::setRAMAddress(uint16_t x, uint16_t y) {
(void)x;
(void)y;
uint8_t buf[2];
// set RAM x address count
buf[0] = _xram_offset;
EPD_command(SSD1680_SET_RAMXCOUNT, buf, 1);
// set RAM y address count
buf[0] = 0;
buf[1] = 0;
EPD_command(SSD1680_SET_RAMYCOUNT, buf, 2);
}

View file

@ -0,0 +1,63 @@
#ifndef LIB_ADAFRUIT_SSD1680
#define LIB_ADAFRUIT_SSD1680
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define SSD1680_DRIVER_CONTROL 0x01
#define SSD1680_GATE_VOLTAGE 0x03
#define SSD1680_SOURCE_VOLTAGE 0x04
#define SSD1680_PROGOTP_INITIAL 0x08
#define SSD1680_PROGREG_INITIAL 0x09
#define SSD1680_READREG_INITIAL 0x0A
#define SSD1680_BOOST_SOFTSTART 0x0C
#define SSD1680_DEEP_SLEEP 0x10
#define SSD1680_DATA_MODE 0x11
#define SSD1680_SW_RESET 0x12
#define SSD1680_TEMP_CONTROL 0x18
#define SSD1680_TEMP_WRITE 0x1A
#define SSD1680_MASTER_ACTIVATE 0x20
#define SSD1680_DISP_CTRL1 0x21
#define SSD1680_DISP_CTRL2 0x22
#define SSD1680_WRITE_RAM1 0x24
#define SSD1680_WRITE_RAM2 0x26
#define SSD1680_WRITE_VCOM 0x2C
#define SSD1680_READ_OTP 0x2D
#define SSD1680_READ_STATUS 0x2F
#define SSD1680_WRITE_LUT 0x32
#define SSD1680_WRITE_BORDER 0x3C
#define SSD1680_END_OPTION 0x3F
#define SSD1680_SET_RAMXPOS 0x44
#define SSD1680_SET_RAMYPOS 0x45
#define SSD1680_SET_RAMXCOUNT 0x4E
#define SSD1680_SET_RAMYCOUNT 0x4F
/**************************************************************************/
/*!
@brief Class for interfacing with SSD1680 EPD drivers
*/
/**************************************************************************/
class Adafruit_SSD1680 : public Adafruit_EPD {
public:
Adafruit_SSD1680(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_SSD1680(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update();
void powerDown();
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void busy_wait();
int8_t _xram_offset = 1;
uint8_t _display_update_val = 0xF4;
};
#endif

View file

@ -0,0 +1,364 @@
#include "Adafruit_SSD1681.h"
#include "Adafruit_EPD.h"
#define EPD_RAM_BW 0x10
#define EPD_RAM_RED 0x13
#define BUSY_WAIT 500
// clang-format off
const uint8_t ssd1681_default_init_code[] {
SSD1681_SW_RESET, 0, // soft reset
0xFF, 20, // busy wait
SSD1681_DATA_MODE, 1, 0x03, // Ram data entry mode
SSD1681_WRITE_BORDER, 1, 0x05, // border color
SSD1681_TEMP_CONTROL, 1, 0x80, // Temp control
SSD1681_SET_RAMXCOUNT, 1, 0,
SSD1681_SET_RAMYCOUNT, 2, 0, 0,
0xFE};
// clang-format on
/**************************************************************************/
/*!
@brief constructor if using external SRAM chip and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param MISO the MISO pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1681::Adafruit_SSD1681(int width, int height, int16_t SID,
int16_t SCLK, int16_t DC, int16_t RST,
int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
singleByteTxns = true;
}
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
/**************************************************************************/
/*!
@brief constructor if using on-chip RAM and hardware SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param SRCS the SRAM chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
Adafruit_SSD1681::Adafruit_SSD1681(int width, int height, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS,
int16_t BUSY, SPIClass* spi)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = ((uint32_t)width * (uint32_t)height) / 8;
buffer2_size = buffer1_size;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = buffer1_size;
buffer1 = buffer2 = NULL;
} else {
buffer1 = (uint8_t*)malloc(buffer1_size);
buffer2 = (uint8_t*)malloc(buffer2_size);
}
singleByteTxns = true;
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1681::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
delay(10);
}
} else {
delay(BUSY_WAIT);
}
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void Adafruit_SSD1681::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(1, false); // red defaults to un inverted
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1681::update() {
uint8_t buf[1];
// display update sequence
buf[0] = _display_update_val; // varies for mono vs gray4 mode
EPD_command(SSD1681_DISP_CTRL2, buf, 1);
EPD_command(SSD1681_MASTER_ACTIVATE);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1681::updatePartial(void) {
uint8_t buf[1];
// display update sequence
buf[0] = 0xFF;
EPD_command(SSD1681_DISP_CTRL2, buf, 1);
EPD_command(SSD1681_MASTER_ACTIVATE);
busy_wait();
if (_busy_pin <= -1) {
delay(1000);
}
}
void Adafruit_SSD1681::displayPartial(uint16_t x1, uint16_t y1, uint16_t x2,
uint16_t y2) {
// check rotation, move window around if necessary
switch (getRotation()) {
case 0:
EPD_swap(x1, y1);
EPD_swap(x2, y2);
y1 = WIDTH - y1;
y2 = WIDTH - y2;
break;
case 1:
break;
case 2:
EPD_swap(x1, y1);
EPD_swap(x2, y2);
x1 = HEIGHT - x1;
x2 = HEIGHT - x2;
break;
case 3:
y1 = WIDTH - y1;
y2 = WIDTH - y2;
x1 = HEIGHT - x1;
x2 = HEIGHT - x2;
}
if (x1 > x2)
EPD_swap(x1, x2);
if (y1 > y2)
EPD_swap(y1, y2);
/*
Serial.print("x: ");
Serial.print(x1);
Serial.print(" -> ");
Serial.println(x2);
Serial.print("y: ");
Serial.print(y1);
Serial.print(" -> ");
Serial.println(y2);
*/
// x1 and x2 must be on byte boundaries
x1 -= x1 % 8; // round down;
x2 = (x2 + 7) & ~0b111; // round up
Serial.println("---------------partial=============");
// perform standard power up
powerUp();
// display....
// setRAMWindow(0, 0, 16/8, 16);
setRAMWindow(x1 / 8, y1, x2 / 8, y2);
setRAMAddress(x1 / 8, y1);
// write image
writeRAMCommand(0);
Serial.print("Transfering: ");
dcHigh();
for (uint16_t y = y1; y < y2; y++) {
for (uint16_t x = x1; x < x2; x += 8) {
uint16_t i = (x / 8) + y * 25;
SPItransfer(black_buffer[i]);
// SPItransfer(0xAA);
}
}
csHigh();
#ifdef EPD_DEBUG
Serial.println(" UpdatePartial");
#endif
updatePartial();
#ifdef EPD_DEBUG
Serial.println(" partial Powering Down");
#endif
powerDown();
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1681::powerUp() {
uint8_t buf[5];
hardwareReset();
delay(100);
busy_wait();
const uint8_t* init_code = ssd1681_default_init_code;
if (_epd_init_code != NULL) {
init_code = _epd_init_code;
}
EPD_commandList(init_code);
setRAMWindow(0, 0, (HEIGHT / 8) - 1, WIDTH - 1);
// Set LUT (if we have one)
if (_epd_lut_code) {
EPD_commandList(_epd_lut_code);
}
// Set display size and driver output control
buf[0] = (WIDTH - 1);
buf[1] = (WIDTH - 1) >> 8;
buf[2] = 0x00;
EPD_command(SSD1681_DRIVER_CONTROL, buf, 3);
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1681::powerDown() {
uint8_t buf[1];
// Only deep sleep if we can get out of it
if (_reset_pin >= 0) {
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1681_DEEP_SLEEP, buf, 1);
delay(100);
} else {
EPD_command(SSD1681_SW_RESET);
busy_wait();
}
}
/**************************************************************************/
/*!
@brief Send the specific command to start writing to EPD display RAM
@param index The index for which buffer to write (0 or 1 or tri-color
displays) Ignored for monochrome displays.
@returns The byte that is read from SPI at the same time as sending the
command
*/
/**************************************************************************/
uint8_t Adafruit_SSD1681::writeRAMCommand(uint8_t index) {
if (index == 0) {
return EPD_command(SSD1681_WRITE_RAM1, false);
}
if (index == 1) {
return EPD_command(SSD1681_WRITE_RAM2, false);
}
return 0;
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1681::setRAMAddress(uint16_t x, uint16_t y) {
uint8_t buf[2];
// set RAM x address count
buf[0] = x;
EPD_command(SSD1681_SET_RAMXCOUNT, buf, 1);
// set RAM y address count
buf[0] = y;
buf[1] = y >> 8;
EPD_command(SSD1681_SET_RAMYCOUNT, buf, 2);
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1681::setRAMWindow(uint16_t x1, uint16_t y1, uint16_t x2,
uint16_t y2) {
uint8_t buf[5];
// Set ram X start/end postion
buf[0] = x1;
buf[1] = x2;
EPD_command(SSD1681_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = y1;
buf[1] = y1 >> 8;
buf[2] = y2;
buf[3] = y2 >> 8;
EPD_command(SSD1681_SET_RAMYPOS, buf, 4);
}

View file

@ -0,0 +1,63 @@
#ifndef LIB_ADAFRUIT_SSD1681
#define LIB_ADAFRUIT_SSD1681
#include <Arduino.h>
#include "Adafruit_EPD.h"
#define SSD1681_DRIVER_CONTROL 0x01
#define SSD1681_GATE_VOLTAGE 0x03
#define SSD1681_SOURCE_VOLTAGE 0x04
#define SSD1681_PROGOTP_INITIAL 0x08
#define SSD1681_PROGREG_INITIAL 0x09
#define SSD1681_READREG_INITIAL 0x0A
#define SSD1681_BOOST_SOFTSTART 0x0C
#define SSD1681_DEEP_SLEEP 0x10
#define SSD1681_DATA_MODE 0x11
#define SSD1681_SW_RESET 0x12
#define SSD1681_TEMP_CONTROL 0x18
#define SSD1681_TEMP_WRITE 0x1A
#define SSD1681_MASTER_ACTIVATE 0x20
#define SSD1681_DISP_CTRL1 0x21
#define SSD1681_DISP_CTRL2 0x22
#define SSD1681_WRITE_RAM1 0x24
#define SSD1681_WRITE_RAM2 0x26
#define SSD1681_WRITE_VCOM 0x2C
#define SSD1681_READ_OTP 0x2D
#define SSD1681_READ_STATUS 0x2F
#define SSD1681_WRITE_LUT 0x32
#define SSD1681_WRITE_BORDER 0x3C
#define SSD1681_SET_RAMXPOS 0x44
#define SSD1681_SET_RAMYPOS 0x45
#define SSD1681_SET_RAMXCOUNT 0x4E
#define SSD1681_SET_RAMYCOUNT 0x4F
/**************************************************************************/
/*!
@brief Class for interfacing with SSD1681 EPD drivers
*/
/**************************************************************************/
class Adafruit_SSD1681 : public Adafruit_EPD {
public:
Adafruit_SSD1681(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
int16_t BUSY = -1);
Adafruit_SSD1681(int width, int height, int16_t DC, int16_t RST, int16_t CS,
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
void begin(bool reset = true);
void powerUp();
void update(void);
void updatePartial(void);
void powerDown();
void displayPartial(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
protected:
uint8_t writeRAMCommand(uint8_t index);
void setRAMAddress(uint16_t x, uint16_t y);
void setRAMWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void busy_wait();
uint8_t _display_update_val = 0xF7;
};
#endif

Some files were not shown because too many files have changed in this diff Show more