Compare commits
No commits in common. "master" and "gh-pages" have entirely different histories.
|
|
@ -1,13 +0,0 @@
|
|||
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
|
|
@ -1,46 +0,0 @@
|
|||
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
|
|
@ -1,26 +0,0 @@
|
|||
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
|
|
@ -1,72 +0,0 @@
|
|||
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
|
|
@ -1,8 +0,0 @@
|
|||
default.vim
|
||||
fontconvert/fontconvert
|
||||
# Our handy .gitignore for automation ease
|
||||
Doxyfile*
|
||||
doxygen_sqlite3.db
|
||||
html
|
||||
.DS_STORE
|
||||
*~
|
||||
1
.nojekyll
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
13
README.md
|
|
@ -1,13 +0,0 @@
|
|||
# Adafruit EPD Library [](https://github.com/adafruit/Adafruit_EPD/actions)[](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
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
*/
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,291 +0,0 @@
|
|||
/***************************************************
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 788 KiB |
|
Before Width: | Height: | Size: 788 KiB |
|
|
@ -1,329 +0,0 @@
|
|||
/***************************************************
|
||||
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();
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/***************************************************
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/***************************************************
|
||||
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); }
|
||||
BIN
html/bc_s.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
html/bdwn.png
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
html/closed.png
Normal file
|
After Width: | Height: | Size: 132 B |
BIN
html/doc.png
Normal file
|
After Width: | Height: | Size: 746 B |
1596
html/doxygen.css
Normal file
BIN
html/doxygen.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
97
html/dynsections.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
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('▼');
|
||||
$(this).show();
|
||||
} else if (l==level+1) {
|
||||
i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
|
||||
a.html('►');
|
||||
$(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('►');
|
||||
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('▼');
|
||||
// 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('►');
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
BIN
html/folderclosed.png
Normal file
|
After Width: | Height: | Size: 616 B |
BIN
html/folderopen.png
Normal file
|
After Width: | Height: | Size: 597 B |
73
html/index.html
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<!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  <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
Normal file
26
html/menu.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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();
|
||||
}
|
||||
2
html/menudata.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
var menudata={children:[
|
||||
{text:"Main Page",url:"index.html"}]}
|
||||
BIN
html/nav_f.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
html/nav_g.png
Normal file
|
After Width: | Height: | Size: 95 B |
BIN
html/nav_h.png
Normal file
|
After Width: | Height: | Size: 98 B |
BIN
html/open.png
Normal file
|
After Width: | Height: | Size: 123 B |
BIN
html/search/close.png
Normal file
|
After Width: | Height: | Size: 273 B |
BIN
html/search/mag_sel.png
Normal file
|
After Width: | Height: | Size: 563 B |
12
html/search/nomatches.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!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>
|
||||
271
html/search/search.css
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
/*---------------- 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;
|
||||
}
|
||||
|
||||
791
html/search/search.js
Normal file
|
|
@ -0,0 +1,791 @@
|
|||
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='•';
|
||||
}
|
||||
else
|
||||
{
|
||||
node.innerHTML=' ';
|
||||
}
|
||||
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"> </span>'+indexSectionLabels[key];
|
||||
results.appendChild(link);
|
||||
}
|
||||
searchBox.OnSelectItem(0);
|
||||
}
|
||||
|
||||
BIN
html/search/search_l.png
Normal file
|
After Width: | Height: | Size: 604 B |
BIN
html/search/search_m.png
Normal file
|
After Width: | Height: | Size: 158 B |
BIN
html/search/search_r.png
Normal file
|
After Width: | Height: | Size: 612 B |
12
html/search/searchdata.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
var indexSectionsWithContent =
|
||||
{
|
||||
};
|
||||
|
||||
var indexSectionNames =
|
||||
{
|
||||
};
|
||||
|
||||
var indexSectionLabels =
|
||||
{
|
||||
};
|
||||
|
||||
BIN
html/splitbar.png
Normal file
|
After Width: | Height: | Size: 314 B |
BIN
html/sync_off.png
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
html/sync_on.png
Normal file
|
After Width: | Height: | Size: 845 B |
BIN
html/tab_a.png
Normal file
|
After Width: | Height: | Size: 142 B |
BIN
html/tab_b.png
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
html/tab_h.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
html/tab_s.png
Normal file
|
After Width: | Height: | Size: 184 B |
1
html/tabs.css
Normal file
11
index.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
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
|
|
@ -1,21 +0,0 @@
|
|||
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.
|
||||
|
|
@ -1,728 +0,0 @@
|
|||
/*!
|
||||
* @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
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
/*!
|
||||
* @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_ */
|
||||
|
|
@ -1,401 +0,0 @@
|
|||
#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
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#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;
|
||||
};
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#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_
|
||||
|
|
@ -1,386 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,338 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,316 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,314 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,299 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
#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
|
||||