From 3c62507f38de992763104ef325689c831f3fc987 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 23 Jul 2019 11:09:07 +0200
Subject: [PATCH] Update Adafruit libraries SSD1306 and GFX
Update Adafruit libraries SSD1306 and GFX
---
.../Adafruit_SPITFT.cpp | 555 -----
.../Adafruit_SPITFT.h | 125 -
.../Adafruit_SPITFT_Macros.h | 118 -
.../.gitignore | 0
.../.travis.yml | 3 +-
.../Adafruit_GFX.cpp | 496 ++--
.../Adafruit_GFX.h | 174 +-
.../Adafruit_SPITFT.cpp | 2217 +++++++++++++++++
.../Adafruit_SPITFT.h | 519 ++++
.../Adafruit_SPITFT_Macros.h | 6 +
.../Fonts/FreeMono12pt7b.h | 0
.../Fonts/FreeMono18pt7b.h | 0
.../Fonts/FreeMono24pt7b.h | 0
.../Fonts/FreeMono9pt7b.h | 0
.../Fonts/FreeMonoBold12pt7b.h | 0
.../Fonts/FreeMonoBold18pt7b.h | 0
.../Fonts/FreeMonoBold24pt7b.h | 0
.../Fonts/FreeMonoBold9pt7b.h | 0
.../Fonts/FreeMonoBoldOblique12pt7b.h | 0
.../Fonts/FreeMonoBoldOblique18pt7b.h | 0
.../Fonts/FreeMonoBoldOblique24pt7b.h | 0
.../Fonts/FreeMonoBoldOblique9pt7b.h | 0
.../Fonts/FreeMonoOblique12pt7b.h | 0
.../Fonts/FreeMonoOblique18pt7b.h | 0
.../Fonts/FreeMonoOblique24pt7b.h | 0
.../Fonts/FreeMonoOblique9pt7b.h | 0
.../Fonts/FreeSans12pt7b.h | 0
.../Fonts/FreeSans18pt7b.h | 0
.../Fonts/FreeSans24pt7b.h | 0
.../Fonts/FreeSans9pt7b.h | 0
.../Fonts/FreeSansBold12pt7b.h | 0
.../Fonts/FreeSansBold18pt7b.h | 0
.../Fonts/FreeSansBold24pt7b.h | 0
.../Fonts/FreeSansBold9pt7b.h | 0
.../Fonts/FreeSansBoldOblique12pt7b.h | 0
.../Fonts/FreeSansBoldOblique18pt7b.h | 0
.../Fonts/FreeSansBoldOblique24pt7b.h | 0
.../Fonts/FreeSansBoldOblique9pt7b.h | 0
.../Fonts/FreeSansOblique12pt7b.h | 0
.../Fonts/FreeSansOblique18pt7b.h | 0
.../Fonts/FreeSansOblique24pt7b.h | 0
.../Fonts/FreeSansOblique9pt7b.h | 0
.../Fonts/FreeSerif12pt7b.h | 0
.../Fonts/FreeSerif18pt7b.h | 0
.../Fonts/FreeSerif24pt7b.h | 0
.../Fonts/FreeSerif9pt7b.h | 0
.../Fonts/FreeSerifBold12pt7b.h | 0
.../Fonts/FreeSerifBold18pt7b.h | 0
.../Fonts/FreeSerifBold24pt7b.h | 0
.../Fonts/FreeSerifBold9pt7b.h | 0
.../Fonts/FreeSerifBoldItalic12pt7b.h | 0
.../Fonts/FreeSerifBoldItalic18pt7b.h | 0
.../Fonts/FreeSerifBoldItalic24pt7b.h | 0
.../Fonts/FreeSerifBoldItalic9pt7b.h | 0
.../Fonts/FreeSerifItalic12pt7b.h | 0
.../Fonts/FreeSerifItalic18pt7b.h | 0
.../Fonts/FreeSerifItalic24pt7b.h | 0
.../Fonts/FreeSerifItalic9pt7b.h | 0
.../Fonts/Org_01.h | 0
.../Fonts/Picopixel.h | 0
.../Fonts/Tiny3x3a2pt7b.h} | 0
.../Fonts/TomThumb.h | 0
.../README.md | 2 +-
.../examples/mock_ili9341/mock_ili9341.ino | 2 +-
.../fontconvert/Makefile | 0
.../fontconvert/fontconvert.c | 14 +
.../fontconvert/fontconvert_win.md | 0
.../fontconvert/makefonts.sh | 0
.../gfxfont.h | 0
.../glcdfont.c | 4 +
.../library.properties | 2 +-
.../license.txt | 0
.../Adafruit_SSD1306.cpp | 729 ------
lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.h | 186 --
lib/Adafruit_SSD1306-1.1.2/README.md | 32 -
lib/Adafruit_SSD1306-1.1.2/README.txt | 24 -
.../ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino | 375 ---
.../ssd1306_128x32_spi/ssd1306_128x32_spi.ino | 368 ---
.../ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino | 375 ---
.../ssd1306_128x64_spi/ssd1306_128x64_spi.ino | 368 ---
lib/Adafruit_SSD1306-1.1.2/library.properties | 9 -
.../.github/ISSUE_TEMPLATE.md | 0
.../.github/PULL_REQUEST_TEMPLATE.md | 0
lib/Adafruit_SSD1306-1.3.0/.gitignore | 4 +
lib/Adafruit_SSD1306-1.3.0/.travis.yml | 29 +
.../Adafruit_SSD1306.cpp | 1101 ++++++++
lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.h | 179 ++
lib/Adafruit_SSD1306-1.3.0/README.md | 54 +
.../OLED_featherwing/OLED_featherwing.ino | 79 +
.../ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino | 410 +++
.../ssd1306_128x32_spi/ssd1306_128x32_spi.ino | 423 ++++
.../ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino | 410 +++
.../ssd1306_128x64_spi/ssd1306_128x64_spi.ino | 424 ++++
lib/Adafruit_SSD1306-1.3.0/library.properties | 9 +
.../license.txt | 0
lib/Adafruit_SSD1306-1.3.0/splash.h | 108 +
96 files changed, 6381 insertions(+), 3552 deletions(-)
delete mode 100644 lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.cpp
delete mode 100644 lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.h
delete mode 100644 lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT_Macros.h
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/.gitignore (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/.travis.yml (87%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Adafruit_GFX.cpp (85%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Adafruit_GFX.h (54%)
create mode 100644 lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.cpp
create mode 100644 lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.h
create mode 100644 lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT_Macros.h
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMono12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMono18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMono24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMono9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBold12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBold18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBold24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBold9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBoldOblique12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBoldOblique18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBoldOblique24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoBoldOblique9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoOblique12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoOblique18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoOblique24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeMonoOblique9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSans12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSans18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSans24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSans9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBold12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBold18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBold24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBold9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBoldOblique12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBoldOblique18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBoldOblique24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansBoldOblique9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansOblique12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansOblique18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansOblique24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSansOblique9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerif12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerif18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerif24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerif9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBold12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBold18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBold24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBold9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBoldItalic12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBoldItalic18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBoldItalic24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifBoldItalic9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifItalic12pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifItalic18pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifItalic24pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/FreeSerifItalic9pt7b.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/Org_01.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/Picopixel.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9/Fonts/Tiny3x3a2pt7b => Adafruit-GFX-Library-1.5.6/Fonts/Tiny3x3a2pt7b.h} (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/Fonts/TomThumb.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/README.md (94%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/examples/mock_ili9341/mock_ili9341.ino (99%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/fontconvert/Makefile (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/fontconvert/fontconvert.c (94%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/fontconvert/fontconvert_win.md (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/fontconvert/makefonts.sh (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/gfxfont.h (100%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/glcdfont.c (98%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/library.properties (96%)
rename lib/{Adafruit-GFX-Library-1.2.9 => Adafruit-GFX-Library-1.5.6}/license.txt (100%)
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.cpp
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.h
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/README.md
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/README.txt
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x32_spi/ssd1306_128x32_spi.ino
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x64_spi/ssd1306_128x64_spi.ino
delete mode 100644 lib/Adafruit_SSD1306-1.1.2/library.properties
rename lib/{Adafruit_SSD1306-1.1.2 => Adafruit_SSD1306-1.3.0}/.github/ISSUE_TEMPLATE.md (100%)
rename lib/{Adafruit_SSD1306-1.1.2 => Adafruit_SSD1306-1.3.0}/.github/PULL_REQUEST_TEMPLATE.md (100%)
create mode 100644 lib/Adafruit_SSD1306-1.3.0/.gitignore
create mode 100644 lib/Adafruit_SSD1306-1.3.0/.travis.yml
create mode 100644 lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.cpp
create mode 100644 lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.h
create mode 100644 lib/Adafruit_SSD1306-1.3.0/README.md
create mode 100644 lib/Adafruit_SSD1306-1.3.0/examples/OLED_featherwing/OLED_featherwing.ino
create mode 100644 lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino
create mode 100644 lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_spi/ssd1306_128x32_spi.ino
create mode 100644 lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino
create mode 100644 lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_spi/ssd1306_128x64_spi.ino
create mode 100644 lib/Adafruit_SSD1306-1.3.0/library.properties
rename lib/{Adafruit_SSD1306-1.1.2 => Adafruit_SSD1306-1.3.0}/license.txt (100%)
create mode 100644 lib/Adafruit_SSD1306-1.3.0/splash.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.cpp b/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.cpp
deleted file mode 100644
index 51b53cc3b..000000000
--- a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.cpp
+++ /dev/null
@@ -1,555 +0,0 @@
-/*!
-* @file Adafruit_SPITFT.cpp
-*
-* @mainpage Adafruit SPI TFT Displays
-*
-* @section intro_sec Introduction
- This is our library for generic SPI TFT Displays with
- address windows and 16 bit color (e.g. ILI9341, HX8357D, ST7735...)
-
- Check out the links above for our tutorials and wiring diagrams
- These displays use SPI to communicate, 4 or 5 pins are required to
- interface (RST is optional)
- 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
-* @section dependencies Dependencies
-*
-* This library depends on
-* Adafruit_GFX being present on your system. Please make sure you have
-* installed the latest version before using this library.
-*
-* @section author Author
-*
-* Written by Limor "ladyada" Fried for Adafruit Industries.
-*
-* @section license License
-*
-* BSD license, all text here must be included in any redistribution.
-*
-*/
-
-#ifndef __AVR_ATtiny85__ // NOT A CHANCE of this stuff working on ATtiny!
-
-#include "Adafruit_SPITFT.h"
-#ifndef ARDUINO_STM32_FEATHER
- #include "pins_arduino.h"
-#ifndef RASPI
- #include "wiring_private.h"
-#endif
-#endif
-#include
-
-#include "Adafruit_SPITFT_Macros.h"
-
-
-
-/**************************************************************************/
-/*!
- @brief Pass 8-bit (each) R,G,B, get back 16-bit packed color
- This function converts 8-8-8 RGB data to 16-bit 5-6-5
- @param red Red 8 bit color
- @param green Green 8 bit color
- @param blue Blue 8 bit color
- @return Unsigned 16-bit down-sampled color in 5-6-5 format
-*/
-/**************************************************************************/
-uint16_t Adafruit_SPITFT::color565(uint8_t red, uint8_t green, uint8_t blue) {
- return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
-}
-
-
-/**************************************************************************/
-/*!
- @brief Instantiate Adafruit SPI display driver with software SPI
- @param w Display width in pixels
- @param h Display height in pixels
- @param cs Chip select pin #
- @param dc Data/Command pin #
- @param mosi SPI MOSI pin #
- @param sclk SPI Clock pin #
- @param rst Reset pin # (optional, pass -1 if unused)
- @param miso SPI MISO pin # (optional, pass -1 if unused)
-*/
-/**************************************************************************/
-Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h,
- int8_t cs, int8_t dc, int8_t mosi,
- int8_t sclk, int8_t rst, int8_t miso)
- : Adafruit_GFX(w, h) {
- _cs = cs;
- _dc = dc;
- _rst = rst;
- _sclk = sclk;
- _mosi = mosi;
- _miso = miso;
- _freq = 0;
-#ifdef USE_FAST_PINIO
- dcport = (RwReg *)portOutputRegister(digitalPinToPort(dc));
- dcpinmask = digitalPinToBitMask(dc);
- clkport = (RwReg *)portOutputRegister(digitalPinToPort(sclk));
- clkpinmask = digitalPinToBitMask(sclk);
- mosiport = (RwReg *)portOutputRegister(digitalPinToPort(mosi));
- mosipinmask = digitalPinToBitMask(mosi);
- if(miso >= 0){
- misoport = (RwReg *)portInputRegister(digitalPinToPort(miso));
- misopinmask = digitalPinToBitMask(miso);
- } else {
- misoport = 0;
- misopinmask = 0;
- }
- if(cs >= 0) {
- csport = (RwReg *)portOutputRegister(digitalPinToPort(cs));
- cspinmask = digitalPinToBitMask(cs);
- } else {
- // No chip-select line defined; might be permanently tied to GND.
- // Assign a valid GPIO register (though not used for CS), and an
- // empty pin bitmask...the nonsense bit-twiddling might be faster
- // than checking _cs and possibly branching.
- csport = dcport;
- cspinmask = 0;
- }
-#endif
-}
-
-/**************************************************************************/
-/*!
- @brief Instantiate Adafruit SPI display driver with hardware SPI
- @param w Display width in pixels
- @param h Display height in pixels
- @param cs Chip select pin #
- @param dc Data/Command pin #
- @param rst Reset pin # (optional, pass -1 if unused)
-*/
-/**************************************************************************/
-Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h,
- int8_t cs, int8_t dc, int8_t rst)
- : Adafruit_GFX(w, h) {
- _cs = cs;
- _dc = dc;
- _rst = rst;
- _sclk = -1;
- _mosi = -1;
- _miso = -1;
- _freq = 0;
-#ifdef USE_FAST_PINIO
- clkport = 0;
- clkpinmask = 0;
- mosiport = 0;
- mosipinmask = 0;
- misoport = 0;
- misopinmask = 0;
- dcport = (RwReg *)portOutputRegister(digitalPinToPort(dc));
- dcpinmask = digitalPinToBitMask(dc);
- if(cs >= 0) {
- csport = (RwReg *)portOutputRegister(digitalPinToPort(cs));
- cspinmask = digitalPinToBitMask(cs);
- } else {
- // See notes in prior constructor.
- csport = dcport;
- cspinmask = 0;
- }
-#endif
-}
-
-/**************************************************************************/
-/*!
- @brief Initialiaze the SPI interface (hardware or software)
- @param freq The desired maximum SPI hardware clock frequency
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::initSPI(uint32_t freq) {
- _freq = freq;
-
- // Control Pins
- if(_cs >= 0) {
- pinMode(_cs, OUTPUT);
- digitalWrite(_cs, HIGH); // Deselect
- }
- pinMode(_dc, OUTPUT);
- digitalWrite(_dc, LOW);
-
- // Software SPI
- if(_sclk >= 0){
- pinMode(_mosi, OUTPUT);
- digitalWrite(_mosi, LOW);
- pinMode(_sclk, OUTPUT);
- digitalWrite(_sclk, HIGH);
- if(_miso >= 0){
- pinMode(_miso, INPUT);
- }
- }
-
- // Hardware SPI
- SPI_BEGIN();
-
- // toggle RST low to reset
- if (_rst >= 0) {
- pinMode(_rst, OUTPUT);
- digitalWrite(_rst, HIGH);
- delay(100);
- digitalWrite(_rst, LOW);
- delay(100);
- digitalWrite(_rst, HIGH);
- delay(200);
- }
-}
-
-/**************************************************************************/
-/*!
- @brief Read one byte from SPI interface (hardware or software
- @returns One byte, MSB order
-*/
-/**************************************************************************/
-uint8_t Adafruit_SPITFT::spiRead() {
- if(_sclk < 0){
- return HSPI_READ();
- }
- if(_miso < 0){
- return 0;
- }
- uint8_t r = 0;
- for (uint8_t i=0; i<8; i++) {
- SSPI_SCK_LOW();
- SSPI_SCK_HIGH();
- r <<= 1;
- if (SSPI_MISO_READ()){
- r |= 0x1;
- }
- }
- return r;
-}
-
-/**************************************************************************/
-/*!
- @brief Write one byte to SPI interface (hardware or software
- @param b One byte to send, MSB order
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::spiWrite(uint8_t b) {
- if(_sclk < 0){
- HSPI_WRITE(b);
- return;
- }
- for(uint8_t bit = 0x80; bit; bit >>= 1){
- if((b) & bit){
- SSPI_MOSI_HIGH();
- } else {
- SSPI_MOSI_LOW();
- }
- SSPI_SCK_LOW();
- SSPI_SCK_HIGH();
- }
-}
-
-
-/*
- * Transaction API
- * */
-
-/**************************************************************************/
-/*!
- @brief Begin an SPI transaction & set CS low.
-*/
-/**************************************************************************/
-void inline Adafruit_SPITFT::startWrite(void){
- SPI_BEGIN_TRANSACTION();
- SPI_CS_LOW();
-}
-
-/**************************************************************************/
-/*!
- @brief Begin an SPI transaction & set CS high.
-*/
-/**************************************************************************/
-void inline Adafruit_SPITFT::endWrite(void){
- SPI_CS_HIGH();
- SPI_END_TRANSACTION();
-}
-
-/**************************************************************************/
-/*!
- @brief Write a command byte (must have a transaction in progress)
- @param cmd The 8-bit command to send
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::writeCommand(uint8_t cmd){
- SPI_DC_LOW();
- spiWrite(cmd);
- SPI_DC_HIGH();
-}
-
-/**************************************************************************/
-/*!
- @brief Push a 2-byte color to the framebuffer RAM, will start transaction
- @param color 16-bit 5-6-5 Color to draw
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::pushColor(uint16_t color) {
- startWrite();
- SPI_WRITE16(color);
- endWrite();
-}
-
-
-
-/**************************************************************************/
-/*!
- @brief Blit multiple 2-byte colors (must have a transaction in progress)
- @param colors Array of 16-bit 5-6-5 Colors to draw
- @param len How many pixels to draw - 2 bytes per pixel!
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::writePixels(uint16_t * colors, uint32_t len){
- SPI_WRITE_PIXELS((uint8_t*)colors , len * 2);
-}
-
-/**************************************************************************/
-/*!
- @brief Blit a 2-byte color many times (must have a transaction in progress)
- @param color The 16-bit 5-6-5 Color to draw
- @param len How many pixels to draw
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len){
-#ifdef SPI_HAS_WRITE_PIXELS
- if(_sclk >= 0){
- for (uint32_t t=0; t SPI_MAX_PIXELS_AT_ONCE)?SPI_MAX_PIXELS_AT_ONCE:len;
- uint16_t tlen = 0;
-
- for (uint32_t t=0; tblen)?blen:len;
- writePixels(temp, tlen);
- len -= tlen;
- }
-#else
- uint8_t hi = color >> 8, lo = color;
- if(_sclk < 0){ //AVR Optimization
- for (uint32_t t=len; t; t--){
- HSPI_WRITE(hi);
- HSPI_WRITE(lo);
- }
- return;
- }
- for (uint32_t t=len; t; t--){
- spiWrite(hi);
- spiWrite(lo);
- }
-#endif
-}
-
-/**************************************************************************/
-/*!
- @brief Write a pixel (must have a transaction in progress)
- @param x x coordinate
- @param y y coordinate
- @param color 16-bit 5-6-5 Color to draw with
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) {
- if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
- setAddrWindow(x,y,1,1);
- writePixel(color);
-}
-
-/**************************************************************************/
-/*!
- @brief Write a filled rectangle (must have a transaction in progress)
- @param x Top left corner x coordinate
- @param y Top left corner y coordinate
- @param w Width in pixels
- @param h Height in pixels
- @param color 16-bit 5-6-5 Color to fill with
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){
- if((x >= _width) || (y >= _height)) return;
- int16_t x2 = x + w - 1, y2 = y + h - 1;
- if((x2 < 0) || (y2 < 0)) return;
-
- // Clip left/top
- if(x < 0) {
- x = 0;
- w = x2 + 1;
- }
- if(y < 0) {
- y = 0;
- h = y2 + 1;
- }
-
- // Clip right/bottom
- if(x2 >= _width) w = _width - x;
- if(y2 >= _height) h = _height - y;
-
- int32_t len = (int32_t)w * h;
- setAddrWindow(x, y, w, h);
- writeColor(color, len);
-}
-
-/**************************************************************************/
-/*!
- @brief Write a perfectly vertical line (must have a transaction in progress)
- @param x Top-most x coordinate
- @param y Top-most y coordinate
- @param h Height in pixels
- @param color 16-bit 5-6-5 Color to fill with
-*/
-/**************************************************************************/
-void inline Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){
- writeFillRect(x, y, 1, h, color);
-}
-
-/**************************************************************************/
-/*!
- @brief Write a perfectly horizontal line (must have a transaction in progress)
- @param x Left-most x coordinate
- @param y Left-most y coordinate
- @param w Width in pixels
- @param color 16-bit 5-6-5 Color to fill with
-*/
-/**************************************************************************/
-void inline Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){
- writeFillRect(x, y, w, 1, color);
-}
-
-/**************************************************************************/
-/*!
- @brief Draw a pixel - sets up transaction
- @param x x coordinate
- @param y y coordinate
- @param color 16-bit 5-6-5 Color to draw with
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color){
- startWrite();
- writePixel(x, y, color);
- endWrite();
-}
-
-/**************************************************************************/
-/*!
- @brief Write a perfectly vertical line - sets up transaction
- @param x Top-most x coordinate
- @param y Top-most y coordinate
- @param h Height in pixels
- @param color 16-bit 5-6-5 Color to fill with
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y,
- int16_t h, uint16_t color) {
- startWrite();
- writeFastVLine(x, y, h, color);
- endWrite();
-}
-
-/**************************************************************************/
-/*!
- @brief Write a perfectly horizontal line - sets up transaction
- @param x Left-most x coordinate
- @param y Left-most y coordinate
- @param w Width in pixels
- @param color 16-bit 5-6-5 Color to fill with
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y,
- int16_t w, uint16_t color) {
- startWrite();
- writeFastHLine(x, y, w, color);
- endWrite();
-}
-
-/**************************************************************************/
-/*!
- @brief Fill a rectangle completely with one color.
- @param x Top left corner x coordinate
- @param y Top left corner y coordinate
- @param w Width in pixels
- @param h Height in pixels
- @param color 16-bit 5-6-5 Color to fill with
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
- uint16_t color) {
- startWrite();
- writeFillRect(x,y,w,h,color);
- endWrite();
-}
-
-
-/**************************************************************************/
-/*!
- @brief Invert the display using built-in hardware command
- @param i True if you want to invert, false to make 'normal'
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::invertDisplay(boolean i) {
- startWrite();
- writeCommand(i ? invertOnCommand : invertOffCommand);
- endWrite();
-}
-
-
-/**************************************************************************/
-/*!
- @brief Draw a 16-bit image (RGB 5/6/5) at the specified (x,y) position.
- For 16-bit display devices; no color reduction performed.
- Adapted from https://github.com/PaulStoffregen/ILI9341_t3
- by Marc MERLIN. See examples/pictureEmbed to use this.
- 5/6/2017: function name and arguments have changed for compatibility
- with current GFX library and to avoid naming problems in prior
- implementation. Formerly drawBitmap() with arguments in different order.
-
- @param x Top left corner x coordinate
- @param y Top left corner y coordinate
- @param pcolors 16-bit array with 16-bit color bitmap
- @param w Width of bitmap in pixels
- @param h Height of bitmap in pixels
-*/
-/**************************************************************************/
-void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y,
- uint16_t *pcolors, int16_t w, int16_t h) {
-
- int16_t x2, y2; // Lower-right coord
- if(( x >= _width ) || // Off-edge right
- ( y >= _height) || // " top
- ((x2 = (x+w-1)) < 0 ) || // " left
- ((y2 = (y+h-1)) < 0) ) return; // " bottom
-
- int16_t bx1=0, by1=0, // Clipped top-left within bitmap
- saveW=w; // Save original bitmap width value
- if(x < 0) { // Clip left
- w += x;
- bx1 = -x;
- x = 0;
- }
- if(y < 0) { // Clip top
- h += y;
- by1 = -y;
- y = 0;
- }
- if(x2 >= _width ) w = _width - x; // Clip right
- if(y2 >= _height) h = _height - y; // Clip bottom
-
- pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left
- startWrite();
- setAddrWindow(x, y, w, h); // Clipped area
- while(h--) { // For each (clipped) scanline...
- writePixels(pcolors, w); // Push one (clipped) row
- pcolors += saveW; // Advance pointer by one full (unclipped) line
- }
- endWrite();
-}
-
-#endif // !__AVR_ATtiny85__
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.h b/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.h
deleted file mode 100644
index 53cdd985d..000000000
--- a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT.h
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef _ADAFRUIT_SPITFT_
-#define _ADAFRUIT_SPITFT_
-
-#if ARDUINO >= 100
- #include "Arduino.h"
- #include "Print.h"
-#else
- #include "WProgram.h"
-#endif
-#include
-#include "Adafruit_GFX.h"
-
-#define USE_FAST_PINIO
-
-#if defined(__AVR__)
- typedef volatile uint8_t RwReg;
-#elif defined(ARDUINO_STM32_FEATHER)
- typedef volatile uint32 RwReg;
- #undef USE_FAST_PINIO
-#elif defined(__OPENCR__) || defined (__OPENCM904__)
- #undef USE_FAST_PINIO
-#elif defined(ARDUINO_FEATHER52) || defined(__arm__)
- typedef volatile uint32_t RwReg;
-#elif defined(ESP32) || defined(ESP8266)
- typedef volatile uint32_t RwReg;
- #undef USE_FAST_PINIO
-#else
- #undef USE_FAST_PINIO
-#endif
-
-#include "Adafruit_SPITFT_Macros.h"
-
-/// A heavily optimized SPI display subclass of GFX. Manages SPI bitbanging, transactions, DMA, etc! Despite being called SPITFT, the classic SPI data/command interface is also used by OLEDs.
-class Adafruit_SPITFT : public Adafruit_GFX {
- protected:
-
- public:
- Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST = -1, int8_t _MISO = -1);
- Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t _CS, int8_t _DC, int8_t _RST = -1);
-
- virtual void begin(uint32_t freq) = 0; ///< Virtual begin() function to set SPI frequency, must be overridden in subclass. @param freq Maximum SPI hardware clock speed
-
- void initSPI(uint32_t freq);
-
- // Required Non-Transaction
- void drawPixel(int16_t x, int16_t y, uint16_t color);
-
- // Transaction API
- void startWrite(void);
- void endWrite(void);
-
- void writePixel(int16_t x, int16_t y, uint16_t color);
- void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
- void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
- void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
-
- // Transaction API not used by GFX
-
- /*!
- @brief SPI displays set an address window rectangle for blitting pixels
- @param x Top left corner x coordinate
- @param y Top left corner x coordinate
- @param w Width of window
- @param h Height of window
- */
- virtual void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0;
-
- /*!
- @brief Write a 2-byte color (must have a transaction in progress)
- @param color 16-bit 5-6-5 Color to draw
- */
- void inline writePixel(uint16_t color) { SPI_WRITE16(color); }
- void writePixels(uint16_t * colors, uint32_t len);
- void writeColor(uint16_t color, uint32_t len);
- void pushColor(uint16_t color);
-
- // Recommended Non-Transaction
- void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
- void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
- void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
-
- using Adafruit_GFX::drawRGBBitmap; // Check base class first
- void drawRGBBitmap(int16_t x, int16_t y,
- uint16_t *pcolors, int16_t w, int16_t h);
- void invertDisplay(boolean i);
-
- uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
-
- protected:
- uint32_t _freq; ///< SPI clock frequency (for hardware SPI)
-#if defined (__AVR__) || defined(TEENSYDUINO) || defined (ESP8266) || defined (ESP32)
- int8_t _cs, _dc, _rst, _sclk, _mosi, _miso;
-#else
- int32_t _cs, ///< Arduino pin # for chip-select pin
- _dc, ///< Arduino pin # for data-command pin
- _rst, ///< Arduino pin # for reset pin
- _sclk, ///< Arduino pin # for SPI clock pin
- _mosi, ///< Arduino pin # for SPI MOSI pin
- _miso; ///< Arduino pin # for SPI MISO pin
-#endif
-
-#ifdef USE_FAST_PINIO
- volatile RwReg *mosiport, ///< Direct chip register for toggling MOSI with fast bitbang IO
- *misoport, ///< Direct chip register for toggling MISO with fast bitbang IO
- *clkport, ///< Direct chip register for toggling CLK with fast bitbang IO
- *dcport, ///< Direct chip register for toggling DC with fast bitbang IO
- *csport; ///< Direct chip register for toggling CS with fast bitbang IO
- RwReg mosipinmask, ///< bitmask for turning on/off MOSI with fast register bitbang IO
- misopinmask, ///< bitmask for turning on/off MISO with fast register bitbang IO
- clkpinmask, ///< bitmask for turning on/off CLK with fast register bitbang IO
- cspinmask, ///< bitmask for turning on/off CS with fast register bitbang IO
- dcpinmask; ///< bitmask for turning on/off DC with fast register bitbang IO
-#endif
-
- void writeCommand(uint8_t cmd);
- void spiWrite(uint8_t v);
- uint8_t spiRead(void);
-
- uint8_t invertOnCommand = 0, ///< SPI command byte to turn on invert
- invertOffCommand = 0; ///< SPI command byte to turn off invert
- int16_t _xstart = 0; ///< Many displays don't have pixels starting at (0,0) of the internal framebuffer, this is the x offset from 0 to align
- int16_t _ystart = 0; ///< Many displays don't have pixels starting at (0,0) of the internal framebuffer, this is the y offset from 0 to align
-};
-
-#endif
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT_Macros.h b/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT_Macros.h
deleted file mode 100644
index f0466ef5f..000000000
--- a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_SPITFT_Macros.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef _ADAFRUIT_SPITFT_MACROS
-#define _ADAFRUIT_SPITFT_MACROS
-
-/*
- * Control Pins
- * */
-
-#ifdef USE_FAST_PINIO
-#define SPI_DC_HIGH() *dcport |= dcpinmask
-#define SPI_DC_LOW() *dcport &= ~dcpinmask
-#define SPI_CS_HIGH() *csport |= cspinmask
-#define SPI_CS_LOW() *csport &= ~cspinmask
-#else
-#define SPI_DC_HIGH() digitalWrite(_dc, HIGH)
-#define SPI_DC_LOW() digitalWrite(_dc, LOW)
-#define SPI_CS_HIGH() { if(_cs >= 0) digitalWrite(_cs, HIGH); }
-#define SPI_CS_LOW() { if(_cs >= 0) digitalWrite(_cs, LOW); }
-#endif
-
-/*
- * Software SPI Macros
- * */
-
-#ifdef USE_FAST_PINIO
-#define SSPI_MOSI_HIGH() *mosiport |= mosipinmask
-#define SSPI_MOSI_LOW() *mosiport &= ~mosipinmask
-#define SSPI_SCK_HIGH() *clkport |= clkpinmask
-#define SSPI_SCK_LOW() *clkport &= ~clkpinmask
-#define SSPI_MISO_READ() ((*misoport & misopinmask) != 0)
-#else
-#define SSPI_MOSI_HIGH() digitalWrite(_mosi, HIGH)
-#define SSPI_MOSI_LOW() digitalWrite(_mosi, LOW)
-#define SSPI_SCK_HIGH() digitalWrite(_sclk, HIGH)
-#define SSPI_SCK_LOW() digitalWrite(_sclk, LOW)
-#define SSPI_MISO_READ() digitalRead(_miso)
-#endif
-
-#define SSPI_BEGIN_TRANSACTION()
-#define SSPI_END_TRANSACTION()
-#define SSPI_WRITE(v) spiWrite(v)
-#define SSPI_WRITE16(s) SSPI_WRITE((s) >> 8); SSPI_WRITE(s)
-#define SSPI_WRITE32(l) SSPI_WRITE((l) >> 24); SSPI_WRITE((l) >> 16); SSPI_WRITE((l) >> 8); SSPI_WRITE(l)
-#define SSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ SSPI_WRITE(((uint8_t*)(c))[i+1]); SSPI_WRITE(((uint8_t*)(c))[i]); }
-
-/*
- * Hardware SPI Macros
- * */
-
-#define SPI_OBJECT SPI
-
-#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1)
- #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2);
-#elif defined (__arm__)
- #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(11);
-#elif defined(ESP8266) || defined(ESP32)
- #define HSPI_SET_CLOCK() SPI_OBJECT.setFrequency(_freq);
-#elif defined(RASPI)
- #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(_freq);
-#elif defined(ARDUINO_ARCH_STM32F1)
- #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(_freq);
-#else
- #define HSPI_SET_CLOCK()
-#endif
-
-#ifdef SPI_HAS_TRANSACTION
- #define HSPI_BEGIN_TRANSACTION() SPI_OBJECT.beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE0))
- #define HSPI_END_TRANSACTION() SPI_OBJECT.endTransaction()
-#else
- #define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); SPI_OBJECT.setBitOrder(MSBFIRST); SPI_OBJECT.setDataMode(SPI_MODE0)
- #define HSPI_END_TRANSACTION()
-#endif
-
-#ifdef ESP32
- #define SPI_HAS_WRITE_PIXELS
-#endif
-#if defined(ESP8266) || defined(ESP32)
- // Optimized SPI (ESP8266 and ESP32)
- #define HSPI_READ() SPI_OBJECT.transfer(0)
- #define HSPI_WRITE(b) SPI_OBJECT.write(b)
- #define HSPI_WRITE16(s) SPI_OBJECT.write16(s)
- #define HSPI_WRITE32(l) SPI_OBJECT.write32(l)
- #ifdef SPI_HAS_WRITE_PIXELS
- #define SPI_MAX_PIXELS_AT_ONCE 32
- #define HSPI_WRITE_PIXELS(c,l) SPI_OBJECT.writePixels(c,l)
- #else
- #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<((l)/2); i++){ SPI_WRITE16(((uint16_t*)(c))[i]); }
- #endif
-#else
- // Standard Byte-by-Byte SPI
-
- #if defined (__AVR__) || defined(TEENSYDUINO)
-static inline uint8_t _avr_spi_read(void) __attribute__((always_inline));
-static inline uint8_t _avr_spi_read(void) {
- uint8_t r = 0;
- SPDR = r;
- while(!(SPSR & _BV(SPIF)));
- r = SPDR;
- return r;
-}
- #define HSPI_WRITE(b) {SPDR = (b); while(!(SPSR & _BV(SPIF)));}
- #define HSPI_READ() _avr_spi_read()
- #else
- #define HSPI_WRITE(b) SPI_OBJECT.transfer((uint8_t)(b))
- #define HSPI_READ() HSPI_WRITE(0)
- #endif
- #define HSPI_WRITE16(s) HSPI_WRITE((s) >> 8); HSPI_WRITE(s)
- #define HSPI_WRITE32(l) HSPI_WRITE((l) >> 24); HSPI_WRITE((l) >> 16); HSPI_WRITE((l) >> 8); HSPI_WRITE(l)
- #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ HSPI_WRITE(((uint8_t*)(c))[i+1]); HSPI_WRITE(((uint8_t*)(c))[i]); }
-#endif
-
-#define SPI_BEGIN() if(_sclk < 0){SPI_OBJECT.begin();}
-#define SPI_BEGIN_TRANSACTION() if(_sclk < 0){HSPI_BEGIN_TRANSACTION();}
-#define SPI_END_TRANSACTION() if(_sclk < 0){HSPI_END_TRANSACTION();}
-#define SPI_WRITE16(s) if(_sclk < 0){HSPI_WRITE16(s);}else{SSPI_WRITE16(s);}
-#define SPI_WRITE32(l) if(_sclk < 0){HSPI_WRITE32(l);}else{SSPI_WRITE32(l);}
-#define SPI_WRITE_PIXELS(c,l) if(_sclk < 0){HSPI_WRITE_PIXELS(c,l);}else{SSPI_WRITE_PIXELS(c,l);}
-
-#endif // _ADAFRUIT_SPITFT_MACROS
diff --git a/lib/Adafruit-GFX-Library-1.2.9/.gitignore b/lib/Adafruit-GFX-Library-1.5.6/.gitignore
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/.gitignore
rename to lib/Adafruit-GFX-Library-1.5.6/.gitignore
diff --git a/lib/Adafruit-GFX-Library-1.2.9/.travis.yml b/lib/Adafruit-GFX-Library-1.5.6/.travis.yml
similarity index 87%
rename from lib/Adafruit-GFX-Library-1.2.9/.travis.yml
rename to lib/Adafruit-GFX-Library-1.5.6/.travis.yml
index a856c6db6..d0836629f 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/.travis.yml
+++ b/lib/Adafruit-GFX-Library-1.5.6/.travis.yml
@@ -9,7 +9,6 @@ git:
quiet: true
env:
global:
- - ARDUINO_IDE_VERSION="1.8.5"
- PRETTYNAME="Adafruit GFX Library"
before_install:
@@ -24,4 +23,4 @@ script:
# Generate and deploy documentation
after_success:
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
- - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
\ No newline at end of file
+ - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_GFX.cpp b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_GFX.cpp
similarity index 85%
rename from lib/Adafruit-GFX-Library-1.2.9/Adafruit_GFX.cpp
rename to lib/Adafruit-GFX-Library-1.5.6/Adafruit_GFX.cpp
index c431a17c8..880678301 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/Adafruit_GFX.cpp
+++ b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_GFX.cpp
@@ -62,6 +62,30 @@ POSSIBILITY OF SUCH DAMAGE.
#define pgm_read_pointer(addr) ((void *)pgm_read_word(addr))
#endif
+inline GFXglyph * pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c)
+{
+#ifdef __AVR__
+ return &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
+#else
+ // expression in __AVR__ section may generate "dereferencing type-punned pointer will break strict-aliasing rules" warning
+ // In fact, on other platforms (such as STM32) there is no need to do this pointer magic as program memory may be read in a usual way
+ // So expression may be simplified
+ return gfxFont->glyph + c;
+#endif //__AVR__
+}
+
+inline uint8_t * pgm_read_bitmap_ptr(const GFXfont *gfxFont)
+{
+#ifdef __AVR__
+ return (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
+#else
+ // expression in __AVR__ section generates "dereferencing type-punned pointer will break strict-aliasing rules" warning
+ // In fact, on other platforms (such as STM32) there is no need to do this pointer magic as program memory may be read in a usual way
+ // So expression may be simplified
+ return gfxFont->bitmap;
+#endif //__AVR__
+}
+
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
@@ -84,7 +108,7 @@ WIDTH(w), HEIGHT(h)
_height = HEIGHT;
rotation = 0;
cursor_y = cursor_x = 0;
- textsize = 1;
+ textsize_x = textsize_y = 1;
textcolor = textbgcolor = 0xFFFF;
wrap = true;
_cp437 = false;
@@ -103,6 +127,9 @@ WIDTH(w), HEIGHT(h)
/**************************************************************************/
void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
uint16_t color) {
+#if defined(ESP8266)
+ yield();
+#endif
int16_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
_swap_int16_t(x0, y0);
@@ -317,6 +344,9 @@ void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
/**************************************************************************/
void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
uint16_t color) {
+#if defined(ESP8266)
+ yield();
+#endif
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
@@ -353,7 +383,7 @@ void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
/**************************************************************************/
/*!
- @brief Quarter-circle drawer, used to do circles and roundrects
+ @brief Quarter-circle drawer, used to do circles and roundrects
@param x0 Center-point x coordinate
@param y0 Center-point y coordinate
@param r Radius of circle
@@ -417,25 +447,29 @@ void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
/**************************************************************************/
/*!
- @brief Quarter-circle drawer with fill, used to do circles and roundrects
- @param x0 Center-point x coordinate
- @param y0 Center-point y coordinate
- @param r Radius of circle
- @param cornername Mask bit #1 or bit #2 to indicate which quarters of the circle we're doing
- @param delta Offset from center-point, used for round-rects
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Quarter-circle drawer with fill, used for circles and roundrects
+ @param x0 Center-point x coordinate
+ @param y0 Center-point y coordinate
+ @param r Radius of circle
+ @param corners Mask bits indicating which quarters we're doing
+ @param delta Offset from center-point, used for round-rects
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
- uint8_t cornername, int16_t delta, uint16_t color) {
+ uint8_t corners, int16_t delta, uint16_t color) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
+ int16_t px = x;
+ int16_t py = y;
- while (x= 0) {
y--;
ddF_y += 2;
@@ -444,15 +478,18 @@ void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
x++;
ddF_x += 2;
f += ddF_x;
-
- if (cornername & 0x1) {
- writeFastVLine(x0+x, y0-y, 2*y+1+delta, color);
- writeFastVLine(x0+y, y0-x, 2*x+1+delta, color);
+ // These checks avoid double-drawing certain lines, important
+ // for the SSD1306 library which has an INVERT drawing mode.
+ if(x < (y + 1)) {
+ if(corners & 1) writeFastVLine(x0+x, y0-y, 2*y+delta, color);
+ if(corners & 2) writeFastVLine(x0-x, y0-y, 2*y+delta, color);
}
- if (cornername & 0x2) {
- writeFastVLine(x0-x, y0-y, 2*y+1+delta, color);
- writeFastVLine(x0-y, y0-x, 2*x+1+delta, color);
+ if(y != py) {
+ if(corners & 1) writeFastVLine(x0+py, y0-px, 2*px+delta, color);
+ if(corners & 2) writeFastVLine(x0-py, y0-px, 2*px+delta, color);
+ py = y;
}
+ px = x;
}
}
@@ -488,7 +525,9 @@ void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h,
*/
/**************************************************************************/
void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
- int16_t h, int16_t r, uint16_t color) {
+ int16_t h, int16_t r, uint16_t color) {
+ int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
+ if(r > max_radius) r = max_radius;
// smarter version
startWrite();
writeFastHLine(x+r , y , w-2*r, color); // Top
@@ -515,11 +554,12 @@ void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
*/
/**************************************************************************/
void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
- int16_t h, int16_t r, uint16_t color) {
+ int16_t h, int16_t r, uint16_t color) {
+ int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
+ if(r > max_radius) r = max_radius;
// smarter version
startWrite();
writeFillRect(x+r, y, w-2*r, h, color);
-
// draw four corners
fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color);
@@ -620,8 +660,8 @@ void Adafruit_GFX::fillTriangle(int16_t x0, int16_t y0,
// For lower part of triangle, find scanline crossings for segments
// 0-2 and 1-2. This loop is skipped if y1=y2.
- sa = dx12 * (y - y1);
- sb = dx02 * (y - y0);
+ sa = (int32_t)dx12 * (y - y1);
+ sb = (int32_t)dx02 * (y - y0);
for(; y<=y2; y++) {
a = x1 + sa / dy12;
b = x0 + sb / dy02;
@@ -646,7 +686,7 @@ void Adafruit_GFX::fillTriangle(int16_t x0, int16_t y0,
@param y Top left corner y coordinate
@param bitmap byte array with monochrome bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
@param color 16-bit 5-6-5 Color to draw with
*/
/**************************************************************************/
@@ -674,7 +714,7 @@ void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
@param y Top left corner y coordinate
@param bitmap byte array with monochrome bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
@param color 16-bit 5-6-5 Color to draw pixels with
@param bg 16-bit 5-6-5 Color to draw background with
*/
@@ -704,7 +744,7 @@ void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
@param y Top left corner y coordinate
@param bitmap byte array with monochrome bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
@param color 16-bit 5-6-5 Color to draw with
*/
/**************************************************************************/
@@ -732,7 +772,7 @@ void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
@param y Top left corner y coordinate
@param bitmap byte array with monochrome bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
@param color 16-bit 5-6-5 Color to draw pixels with
@param bg 16-bit 5-6-5 Color to draw background with
*/
@@ -756,7 +796,7 @@ void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
/**************************************************************************/
/*!
- @brief Draw PROGMEM-resident XBitMap Files (*.xbm), exported from GIMP.
+ @brief Draw PROGMEM-resident XBitMap Files (*.xbm), exported from GIMP.
Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor.
C Array can be directly used with this function.
There is no RAM-resident version of this function; if generating bitmaps
@@ -765,7 +805,7 @@ void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
@param y Top left corner y coordinate
@param bitmap byte array with monochrome bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
@param color 16-bit 5-6-5 Color to draw pixels with
*/
/**************************************************************************/
@@ -791,13 +831,13 @@ void Adafruit_GFX::drawXBitmap(int16_t x, int16_t y,
/**************************************************************************/
/*!
- @brief Draw a PROGMEM-resident 8-bit image (grayscale) at the specified (x,y) pos.
+ @brief Draw a PROGMEM-resident 8-bit image (grayscale) at the specified (x,y) pos.
Specifically for 8-bit display devices such as IS31FL3731; no color reduction/expansion is performed.
@param x Top left corner x coordinate
@param y Top left corner y coordinate
@param bitmap byte array with grayscale bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
*/
/**************************************************************************/
void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y,
@@ -813,13 +853,13 @@ void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y,
/**************************************************************************/
/*!
- @brief Draw a RAM-resident 8-bit image (grayscale) at the specified (x,y) pos.
+ @brief Draw a RAM-resident 8-bit image (grayscale) at the specified (x,y) pos.
Specifically for 8-bit display devices such as IS31FL3731; no color reduction/expansion is performed.
@param x Top left corner x coordinate
@param y Top left corner y coordinate
@param bitmap byte array with grayscale bitmap
@param w Width of bitmap in pixels
- @param h Hieght of bitmap in pixels
+ @param h Height of bitmap in pixels
*/
/**************************************************************************/
void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y,
@@ -900,7 +940,7 @@ void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y,
/**************************************************************************/
/*!
- @brief Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) at the specified (x,y) position.
+ @brief Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) at the specified (x,y) position.
For 16-bit display devices; no color reduction performed.
@param x Top left corner x coordinate
@param y Top left corner y coordinate
@@ -922,7 +962,7 @@ void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y,
/**************************************************************************/
/*!
- @brief Draw a RAM-resident 16-bit image (RGB 5/6/5) at the specified (x,y) position.
+ @brief Draw a RAM-resident 16-bit image (RGB 5/6/5) at the specified (x,y) position.
For 16-bit display devices; no color reduction performed.
@param x Top left corner x coordinate
@param y Top left corner y coordinate
@@ -1016,13 +1056,31 @@ void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y,
/**************************************************************************/
void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
uint16_t color, uint16_t bg, uint8_t size) {
+ drawChar(x, y, c, color, bg, size, size);
+}
+
+// Draw a character
+/**************************************************************************/
+/*!
+ @brief Draw a single character
+ @param x Bottom left corner x coordinate
+ @param y Bottom left corner y coordinate
+ @param c The 8-bit font-indexed character (likely ascii)
+ @param color 16-bit 5-6-5 Color to draw chraracter with
+ @param bg 16-bit 5-6-5 Color to fill background with (if same as color, no background)
+ @param size_x Font magnification level in X-axis, 1 is 'original' size
+ @param size_y Font magnification level in Y-axis, 1 is 'original' size
+*/
+/**************************************************************************/
+void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
+ uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y) {
if(!gfxFont) { // 'Classic' built-in font
if((x >= _width) || // Clip right
(y >= _height) || // Clip bottom
- ((x + 6 * size - 1) < 0) || // Clip left
- ((y + 8 * size - 1) < 0)) // Clip top
+ ((x + 6 * size_x - 1) < 0) || // Clip left
+ ((y + 8 * size_y - 1) < 0)) // Clip top
return;
if(!_cp437 && (c >= 176)) c++; // Handle 'classic' charset behavior
@@ -1032,21 +1090,21 @@ void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
uint8_t line = pgm_read_byte(&font[c * 5 + i]);
for(int8_t j=0; j<8; j++, line >>= 1) {
if(line & 1) {
- if(size == 1)
+ if(size_x == 1 && size_y == 1)
writePixel(x+i, y+j, color);
else
- writeFillRect(x+i*size, y+j*size, size, size, color);
+ writeFillRect(x+i*size_x, y+j*size_y, size_x, size_y, color);
} else if(bg != color) {
- if(size == 1)
+ if(size_x == 1 && size_y == 1)
writePixel(x+i, y+j, bg);
else
- writeFillRect(x+i*size, y+j*size, size, size, bg);
+ writeFillRect(x+i*size_x, y+j*size_y, size_x, size_y, bg);
}
}
}
if(bg != color) { // If opaque, draw vertical line for last column
- if(size == 1) writeFastVLine(x+5, y, 8, bg);
- else writeFillRect(x+5*size, y, size, 8*size, bg);
+ if(size_x == 1 && size_y == 1) writeFastVLine(x+5, y, 8, bg);
+ else writeFillRect(x+5*size_x, y, size_x, 8*size_y, bg);
}
endWrite();
@@ -1057,8 +1115,8 @@ void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
// drawChar() directly with 'bad' characters of font may cause mayhem!
c -= (uint8_t)pgm_read_byte(&gfxFont->first);
- GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
- uint8_t *bitmap = (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
+ GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c);
+ uint8_t *bitmap = pgm_read_bitmap_ptr(gfxFont);
uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
uint8_t w = pgm_read_byte(&glyph->width),
@@ -1068,7 +1126,7 @@ void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
uint8_t xx, yy, bits = 0, bit = 0;
int16_t xo16 = 0, yo16 = 0;
- if(size > 1) {
+ if(size_x > 1 || size_y > 1) {
xo16 = xo;
yo16 = yo;
}
@@ -1098,11 +1156,11 @@ void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
bits = pgm_read_byte(&bitmap[bo++]);
}
if(bits & 0x80) {
- if(size == 1) {
+ if(size_x == 1 && size_y == 1) {
writePixel(x+xo+xx, y+yo+yy, color);
} else {
- writeFillRect(x+(xo16+xx)*size, y+(yo16+yy)*size,
- size, size, color);
+ writeFillRect(x+(xo16+xx)*size_x, y+(yo16+yy)*size_y,
+ size_x, size_y, color);
}
}
bits <<= 1;
@@ -1123,39 +1181,38 @@ size_t Adafruit_GFX::write(uint8_t c) {
if(c == '\n') { // Newline?
cursor_x = 0; // Reset x to zero,
- cursor_y += textsize * 8; // advance y one line
+ cursor_y += textsize_y * 8; // advance y one line
} else if(c != '\r') { // Ignore carriage returns
- if(wrap && ((cursor_x + textsize * 6) > _width)) { // Off right?
+ if(wrap && ((cursor_x + textsize_x * 6) > _width)) { // Off right?
cursor_x = 0; // Reset x to zero,
- cursor_y += textsize * 8; // advance y one line
+ cursor_y += textsize_y * 8; // advance y one line
}
- drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
- cursor_x += textsize * 6; // Advance x one char
+ drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x, textsize_y);
+ cursor_x += textsize_x * 6; // Advance x one char
}
} else { // Custom font
if(c == '\n') {
cursor_x = 0;
- cursor_y += (int16_t)textsize *
+ cursor_y += (int16_t)textsize_y *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} else if(c != '\r') {
uint8_t first = pgm_read_byte(&gfxFont->first);
if((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last))) {
- GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(
- &gfxFont->glyph))[c - first]);
+ GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
uint8_t w = pgm_read_byte(&glyph->width),
h = pgm_read_byte(&glyph->height);
if((w > 0) && (h > 0)) { // Is there an associated bitmap?
int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
- if(wrap && ((cursor_x + textsize * (xo + w)) > _width)) {
+ if(wrap && ((cursor_x + textsize_x * (xo + w)) > _width)) {
cursor_x = 0;
- cursor_y += (int16_t)textsize *
+ cursor_y += (int16_t)textsize_y *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
}
- drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
+ drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x, textsize_y);
}
- cursor_x += (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
+ cursor_x += (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize_x;
}
}
@@ -1163,38 +1220,6 @@ size_t Adafruit_GFX::write(uint8_t c) {
return 1;
}
-/**************************************************************************/
-/*!
- @brief Set text cursor location
- @param x X coordinate in pixels
- @param y Y coordinate in pixels
-*/
-/**************************************************************************/
-void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
- cursor_x = x;
- cursor_y = y;
-}
-
-/**************************************************************************/
-/*!
- @brief Get text cursor X location
- @returns X coordinate in pixels
-*/
-/**************************************************************************/
-int16_t Adafruit_GFX::getCursorX(void) const {
- return cursor_x;
-}
-
-/**************************************************************************/
-/*!
- @brief Get text cursor Y location
- @returns Y coordinate in pixels
-*/
-/**************************************************************************/
-int16_t Adafruit_GFX::getCursorY(void) const {
- return cursor_y;
-}
-
/**************************************************************************/
/*!
@brief Set text 'magnification' size. Each increase in s makes 1 pixel that much bigger.
@@ -1202,51 +1227,19 @@ int16_t Adafruit_GFX::getCursorY(void) const {
*/
/**************************************************************************/
void Adafruit_GFX::setTextSize(uint8_t s) {
- textsize = (s > 0) ? s : 1;
+ setTextSize(s, s);
}
/**************************************************************************/
/*!
- @brief Set text font color with transparant background
- @param c 16-bit 5-6-5 Color to draw text with
+ @brief Set text 'magnification' size. Each increase in s makes 1 pixel that much bigger.
+ @param s_x Desired text width magnification level in X-axis. 1 is default
+ @param s_y Desired text width magnification level in Y-axis. 1 is default
*/
/**************************************************************************/
-void Adafruit_GFX::setTextColor(uint16_t c) {
- // For 'transparent' background, we'll set the bg
- // to the same as fg instead of using a flag
- textcolor = textbgcolor = c;
-}
-
-/**************************************************************************/
-/*!
- @brief Set text font color with custom background color
- @param c 16-bit 5-6-5 Color to draw text with
- @param b 16-bit 5-6-5 Color to draw background/fill with
-*/
-/**************************************************************************/
-void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
- textcolor = c;
- textbgcolor = b;
-}
-
-/**************************************************************************/
-/*!
- @brief Whether text that is too long should 'wrap' around to the next line.
- @param w Set true for wrapping, false for clipping
-*/
-/**************************************************************************/
-void Adafruit_GFX::setTextWrap(boolean w) {
- wrap = w;
-}
-
-/**************************************************************************/
-/*!
- @brief Get rotation setting for display
- @returns 0 thru 3 corresponding to 4 cardinal rotations
-*/
-/**************************************************************************/
-uint8_t Adafruit_GFX::getRotation(void) const {
- return rotation;
+void Adafruit_GFX::setTextSize(uint8_t s_x, uint8_t s_y) {
+ textsize_x = (s_x > 0) ? s_x : 1;
+ textsize_y = (s_y > 0) ? s_y : 1;
}
/**************************************************************************/
@@ -1271,22 +1264,6 @@ void Adafruit_GFX::setRotation(uint8_t x) {
}
}
-/**************************************************************************/
-/*!
- @brief Enable (or disable) Code Page 437-compatible charset.
- There was an error in glcdfont.c for the longest time -- one character
- (#176, the 'light shade' block) was missing -- this threw off the index
- of every character that followed it. But a TON of code has been written
- with the erroneous character indices. By default, the library uses the
- original 'wrong' behavior and old sketches will still work. Pass 'true'
- to this function to use correct CP437 character values in your code.
- @param x Whether to enable (True) or not (False)
-*/
-/**************************************************************************/
-void Adafruit_GFX::cp437(boolean x) {
- _cp437 = x;
-}
-
/**************************************************************************/
/*!
@brief Set the font to display when print()ing, either custom or default
@@ -1329,32 +1306,32 @@ void Adafruit_GFX::charBounds(char c, int16_t *x, int16_t *y,
if(c == '\n') { // Newline?
*x = 0; // Reset x to zero, advance y by one line
- *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
+ *y += textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} else if(c != '\r') { // Not a carriage return; is normal char
uint8_t first = pgm_read_byte(&gfxFont->first),
last = pgm_read_byte(&gfxFont->last);
if((c >= first) && (c <= last)) { // Char present in this font?
- GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(
- &gfxFont->glyph))[c - first]);
+ GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
uint8_t gw = pgm_read_byte(&glyph->width),
gh = pgm_read_byte(&glyph->height),
xa = pgm_read_byte(&glyph->xAdvance);
int8_t xo = pgm_read_byte(&glyph->xOffset),
yo = pgm_read_byte(&glyph->yOffset);
- if(wrap && ((*x+(((int16_t)xo+gw)*textsize)) > _width)) {
+ if(wrap && ((*x+(((int16_t)xo+gw)*textsize_x)) > _width)) {
*x = 0; // Reset x to zero, advance y by one line
- *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
+ *y += textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
}
- int16_t ts = (int16_t)textsize,
- x1 = *x + xo * ts,
- y1 = *y + yo * ts,
- x2 = x1 + gw * ts - 1,
- y2 = y1 + gh * ts - 1;
+ int16_t tsx = (int16_t)textsize_x,
+ tsy = (int16_t)textsize_y,
+ x1 = *x + xo * tsx,
+ y1 = *y + yo * tsy,
+ x2 = x1 + gw * tsx - 1,
+ y2 = y1 + gh * tsy - 1;
if(x1 < *minx) *minx = x1;
if(y1 < *miny) *miny = y1;
if(x2 > *maxx) *maxx = x2;
if(y2 > *maxy) *maxy = y2;
- *x += xa * ts;
+ *x += xa * tsx;
}
}
@@ -1362,20 +1339,20 @@ void Adafruit_GFX::charBounds(char c, int16_t *x, int16_t *y,
if(c == '\n') { // Newline?
*x = 0; // Reset x to zero,
- *y += textsize * 8; // advance y one line
+ *y += textsize_y * 8; // advance y one line
// min/max x/y unchaged -- that waits for next 'normal' character
} else if(c != '\r') { // Normal char; ignore carriage returns
- if(wrap && ((*x + textsize * 6) > _width)) { // Off right?
+ if(wrap && ((*x + textsize_x * 6) > _width)) { // Off right?
*x = 0; // Reset x to zero,
- *y += textsize * 8; // advance y one line
+ *y += textsize_y * 8; // advance y one line
}
- int x2 = *x + textsize * 6 - 1, // Lower-right pixel of char
- y2 = *y + textsize * 8 - 1;
+ int x2 = *x + textsize_x * 6 - 1, // Lower-right pixel of char
+ y2 = *y + textsize_y * 8 - 1;
if(x2 > *maxx) *maxx = x2; // Track max x, y
if(y2 > *maxy) *maxy = y2;
if(*x < *minx) *minx = *x; // Track min x, y
if(*y < *miny) *miny = *y;
- *x += textsize * 6; // Advance x one char
+ *x += textsize_x * 6; // Advance x one char
}
}
}
@@ -1470,26 +1447,6 @@ void Adafruit_GFX::getTextBounds(const __FlashStringHelper *str,
}
}
-/**************************************************************************/
-/*!
- @brief Get width of the display, accounting for the current rotation
- @returns Width in pixels
-*/
-/**************************************************************************/
-int16_t Adafruit_GFX::width(void) const {
- return _width;
-}
-
-/**************************************************************************/
-/*!
- @brief Get height of the display, accounting for the current rotation
- @returns Height in pixels
-*/
-/**************************************************************************/
-int16_t Adafruit_GFX::height(void) const {
- return _height;
-}
-
/**************************************************************************/
/*!
@brief Invert the display (ideally using built-in hardware command)
@@ -1537,6 +1494,33 @@ void Adafruit_GFX_Button::initButton(
textcolor, label, textsize);
}
+/**************************************************************************/
+/*!
+ @brief Initialize button with our desired color/size/settings
+ @param gfx Pointer to our display so we can draw to it!
+ @param x The X coordinate of the center of the button
+ @param y The Y coordinate of the center of the button
+ @param w Width of the buttton
+ @param h Height of the buttton
+ @param outline Color of the outline (16-bit 5-6-5 standard)
+ @param fill Color of the button fill (16-bit 5-6-5 standard)
+ @param textcolor Color of the button label (16-bit 5-6-5 standard)
+ @param label Ascii string of the text inside the button
+ @param textsize_x The font magnification in X-axis of the label text
+ @param textsize_y The font magnification in Y-axis of the label text
+*/
+/**************************************************************************/
+// Classic initButton() function: pass center & size
+void Adafruit_GFX_Button::initButton(
+ Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t w, uint16_t h,
+ uint16_t outline, uint16_t fill, uint16_t textcolor,
+ char *label, uint8_t textsize_x, uint8_t textsize_y)
+{
+ // Tweak arguments and pass to the newer initButtonUL() function...
+ initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill,
+ textcolor, label, textsize_x, textsize_y);
+}
+
/**************************************************************************/
/*!
@brief Initialize button with our desired color/size/settings, with upper-left coordinates
@@ -1556,6 +1540,30 @@ void Adafruit_GFX_Button::initButtonUL(
Adafruit_GFX *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h,
uint16_t outline, uint16_t fill, uint16_t textcolor,
char *label, uint8_t textsize)
+{
+ initButtonUL(gfx, x1, y1, w, h, outline, fill, textcolor, label, textsize, textsize);
+}
+
+/**************************************************************************/
+/*!
+ @brief Initialize button with our desired color/size/settings, with upper-left coordinates
+ @param gfx Pointer to our display so we can draw to it!
+ @param x1 The X coordinate of the Upper-Left corner of the button
+ @param y1 The Y coordinate of the Upper-Left corner of the button
+ @param w Width of the buttton
+ @param h Height of the buttton
+ @param outline Color of the outline (16-bit 5-6-5 standard)
+ @param fill Color of the button fill (16-bit 5-6-5 standard)
+ @param textcolor Color of the button label (16-bit 5-6-5 standard)
+ @param label Ascii string of the text inside the button
+ @param textsize_x The font magnification in X-axis of the label text
+ @param textsize_y The font magnification in Y-axis of the label text
+*/
+/**************************************************************************/
+void Adafruit_GFX_Button::initButtonUL(
+ Adafruit_GFX *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h,
+ uint16_t outline, uint16_t fill, uint16_t textcolor,
+ char *label, uint8_t textsize_x, uint8_t textsize_y)
{
_x1 = x1;
_y1 = y1;
@@ -1564,7 +1572,8 @@ void Adafruit_GFX_Button::initButtonUL(
_outlinecolor = outline;
_fillcolor = fill;
_textcolor = textcolor;
- _textsize = textsize;
+ _textsize_x = textsize_x;
+ _textsize_y = textsize_y;
_gfx = gfx;
strncpy(_label, label, 9);
}
@@ -1592,19 +1601,19 @@ void Adafruit_GFX_Button::drawButton(boolean inverted) {
_gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
_gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
- _gfx->setCursor(_x1 + (_w/2) - (strlen(_label) * 3 * _textsize),
- _y1 + (_h/2) - (4 * _textsize));
+ _gfx->setCursor(_x1 + (_w/2) - (strlen(_label) * 3 * _textsize_x),
+ _y1 + (_h/2) - (4 * _textsize_y));
_gfx->setTextColor(text);
- _gfx->setTextSize(_textsize);
+ _gfx->setTextSize(_textsize_x, _textsize_y);
_gfx->print(_label);
}
/**************************************************************************/
/*!
- @brief Helper to let us know if a coordinate is within the bounds of the button
+ @brief Helper to let us know if a coordinate is within the bounds of the button
@param x The X coordinate to check
@param y The Y coordinate to check
- @returns True if within button graphics outline
+ @returns True if within button graphics outline
*/
/**************************************************************************/
boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
@@ -1612,25 +1621,6 @@ boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
(y >= _y1) && (y < (int16_t) (_y1 + _h)));
}
-/**************************************************************************/
-/*!
- @brief Sets the state of the button, should be done by some touch function
- @param p True for pressed, false for not.
-*/
-/**************************************************************************/
-void Adafruit_GFX_Button::press(boolean p) {
- laststate = currstate;
- currstate = p;
-}
-
-/**************************************************************************/
-/*!
- @brief Query whether the button is currently pressed
- @returns True if pressed
-*/
-/**************************************************************************/
-boolean Adafruit_GFX_Button::isPressed() { return currstate; }
-
/**************************************************************************/
/*!
@brief Query whether the button was pressed since we last checked state
@@ -1691,20 +1681,10 @@ GFXcanvas1::~GFXcanvas1(void) {
/**************************************************************************/
/*!
- @brief Get a pointer to the internal buffer memory
- @returns A pointer to the allocated buffer
-*/
-/**************************************************************************/
-uint8_t* GFXcanvas1::getBuffer(void) {
- return buffer;
-}
-
-/**************************************************************************/
-/*!
- @brief Draw a pixel to the canvas framebuffer
- @param x x coordinate
- @param y y coordinate
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Draw a pixel to the canvas framebuffer
+ @param x x coordinate
+ @param y y coordinate
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
@@ -1749,8 +1729,8 @@ void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
/**************************************************************************/
/*!
- @brief Fill the framebuffer completely with one color
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Fill the framebuffer completely with one color
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas1::fillScreen(uint16_t color) {
@@ -1783,23 +1763,12 @@ GFXcanvas8::~GFXcanvas8(void) {
if(buffer) free(buffer);
}
-
/**************************************************************************/
/*!
- @brief Get a pointer to the internal buffer memory
- @returns A pointer to the allocated buffer
-*/
-/**************************************************************************/
-uint8_t* GFXcanvas8::getBuffer(void) {
- return buffer;
-}
-
-/**************************************************************************/
-/*!
- @brief Draw a pixel to the canvas framebuffer
- @param x x coordinate
- @param y y coordinate
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Draw a pixel to the canvas framebuffer
+ @param x x coordinate
+ @param y y coordinate
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
@@ -1830,8 +1799,8 @@ void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
/**************************************************************************/
/*!
- @brief Fill the framebuffer completely with one color
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Fill the framebuffer completely with one color
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas8::fillScreen(uint16_t color) {
@@ -1900,20 +1869,10 @@ GFXcanvas16::~GFXcanvas16(void) {
/**************************************************************************/
/*!
- @brief Get a pointer to the internal buffer memory
- @returns A pointer to the allocated buffer
-*/
-/**************************************************************************/
-uint16_t* GFXcanvas16::getBuffer(void) {
- return buffer;
-}
-
-/**************************************************************************/
-/*!
- @brief Draw a pixel to the canvas framebuffer
- @param x x coordinate
- @param y y coordinate
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Draw a pixel to the canvas framebuffer
+ @param x x coordinate
+ @param y y coordinate
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
@@ -1944,8 +1903,8 @@ void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
/**************************************************************************/
/*!
- @brief Fill the framebuffer completely with one color
- @param color 16-bit 5-6-5 Color to fill with
+ @brief Fill the framebuffer completely with one color
+ @param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas16::fillScreen(uint16_t color) {
@@ -1960,3 +1919,22 @@ void GFXcanvas16::fillScreen(uint16_t color) {
}
}
+/**************************************************************************/
+/*!
+ @brief Reverses the "endian-ness" of each 16-bit pixel within the
+ canvas; little-endian to big-endian, or big-endian to little.
+ Most microcontrollers (such as SAMD) are little-endian, while
+ most displays tend toward big-endianness. All the drawing
+ functions (including RGB bitmap drawing) take care of this
+ automatically, but some specialized code (usually involving
+ DMA) can benefit from having pixel data already in the
+ display-native order. Note that this does NOT convert to a
+ SPECIFIC endian-ness, it just flips the bytes within each word.
+*/
+/**************************************************************************/
+void GFXcanvas16::byteSwap(void) {
+ if(buffer) {
+ uint32_t i, pixels = WIDTH * HEIGHT;
+ for(i=0; i= 100
virtual size_t write(uint8_t);
@@ -116,20 +169,53 @@ class Adafruit_GFX : public Print {
virtual void write(uint8_t);
#endif
- int16_t height(void) const;
- int16_t width(void) const;
+ /************************************************************************/
+ /*!
+ @brief Get width of the display, accounting for current rotation
+ @returns Width in pixels
+ */
+ /************************************************************************/
+ int16_t width(void) const { return _width; };
- uint8_t getRotation(void) const;
+ /************************************************************************/
+ /*!
+ @brief Get height of the display, accounting for current rotation
+ @returns Height in pixels
+ */
+ /************************************************************************/
+ int16_t height(void) const { return _height; }
- // get current cursor position (get rotation safe maximum values, using: width() for x, height() for y)
- int16_t getCursorX(void) const;
- int16_t getCursorY(void) const;
+ /************************************************************************/
+ /*!
+ @brief Get rotation setting for display
+ @returns 0 thru 3 corresponding to 4 cardinal rotations
+ */
+ /************************************************************************/
+ uint8_t getRotation(void) const { return rotation; }
+
+ // get current cursor position (get rotation safe maximum values,
+ // using: width() for x, height() for y)
+ /************************************************************************/
+ /*!
+ @brief Get text cursor X location
+ @returns X coordinate in pixels
+ */
+ /************************************************************************/
+ int16_t getCursorX(void) const { return cursor_x; }
+
+ /************************************************************************/
+ /*!
+ @brief Get text cursor Y location
+ @returns Y coordinate in pixels
+ */
+ /************************************************************************/
+ int16_t getCursorY(void) const { return cursor_y; };
protected:
void
charBounds(char c, int16_t *x, int16_t *y,
int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy);
- const int16_t
+ int16_t
WIDTH, ///< This is the 'raw' display width - never changes
HEIGHT; ///< This is the 'raw' display height - never changes
int16_t
@@ -141,7 +227,8 @@ class Adafruit_GFX : public Print {
textcolor, ///< 16-bit background color for print()
textbgcolor; ///< 16-bit text color for print()
uint8_t
- textsize, ///< Desired magnification of text to print()
+ textsize_x, ///< Desired magnification in X-axis of text to print()
+ textsize_y, ///< Desired magnification in Y-axis of text to print()
rotation; ///< Display rotation (0 thru 3)
boolean
wrap, ///< If set, 'wrap' text at right edge of display
@@ -160,23 +247,44 @@ class Adafruit_GFX_Button {
void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y,
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
uint16_t textcolor, char *label, uint8_t textsize);
+ void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y,
+ uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
+ uint16_t textcolor, char *label, uint8_t textsize_x, uint8_t textsize_y);
// New/alt initButton() uses upper-left corner & size
void initButtonUL(Adafruit_GFX *gfx, int16_t x1, int16_t y1,
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
uint16_t textcolor, char *label, uint8_t textsize);
+ void initButtonUL(Adafruit_GFX *gfx, int16_t x1, int16_t y1,
+ uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
+ uint16_t textcolor, char *label, uint8_t textsize_x, uint8_t textsize_y);
void drawButton(boolean inverted = false);
boolean contains(int16_t x, int16_t y);
- void press(boolean p);
- boolean isPressed();
+ /**********************************************************************/
+ /*!
+ @brief Sets button state, should be done by some touch function
+ @param p True for pressed, false for not.
+ */
+ /**********************************************************************/
+ void press(boolean p) { laststate = currstate; currstate = p; }
+
boolean justPressed();
boolean justReleased();
+ /**********************************************************************/
+ /*!
+ @brief Query whether the button is currently pressed
+ @returns True if pressed
+ */
+ /**********************************************************************/
+ boolean isPressed(void) { return currstate; };
+
private:
Adafruit_GFX *_gfx;
int16_t _x1, _y1; // Coordinates of top-left corner
uint16_t _w, _h;
- uint8_t _textsize;
+ uint8_t _textsize_x;
+ uint8_t _textsize_y;
uint16_t _outlinecolor, _fillcolor, _textcolor;
char _label[10];
@@ -191,7 +299,13 @@ class GFXcanvas1 : public Adafruit_GFX {
~GFXcanvas1(void);
void drawPixel(int16_t x, int16_t y, uint16_t color),
fillScreen(uint16_t color);
- uint8_t *getBuffer(void);
+ /**********************************************************************/
+ /*!
+ @brief Get a pointer to the internal buffer memory
+ @returns A pointer to the allocated buffer
+ */
+ /**********************************************************************/
+ uint8_t *getBuffer(void) const { return buffer; }
private:
uint8_t *buffer;
};
@@ -205,8 +319,13 @@ class GFXcanvas8 : public Adafruit_GFX {
void drawPixel(int16_t x, int16_t y, uint16_t color),
fillScreen(uint16_t color),
writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
-
- uint8_t *getBuffer(void);
+ /**********************************************************************/
+ /*!
+ @brief Get a pointer to the internal buffer memory
+ @returns A pointer to the allocated buffer
+ */
+ /**********************************************************************/
+ uint8_t *getBuffer(void) const { return buffer; }
private:
uint8_t *buffer;
};
@@ -218,8 +337,15 @@ class GFXcanvas16 : public Adafruit_GFX {
GFXcanvas16(uint16_t w, uint16_t h);
~GFXcanvas16(void);
void drawPixel(int16_t x, int16_t y, uint16_t color),
- fillScreen(uint16_t color);
- uint16_t *getBuffer(void);
+ fillScreen(uint16_t color),
+ byteSwap(void);
+ /**********************************************************************/
+ /*!
+ @brief Get a pointer to the internal buffer memory
+ @returns A pointer to the allocated buffer
+ */
+ /**********************************************************************/
+ uint16_t *getBuffer(void) const { return buffer; }
private:
uint16_t *buffer;
};
diff --git a/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.cpp b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.cpp
new file mode 100644
index 000000000..945ef41ab
--- /dev/null
+++ b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.cpp
@@ -0,0 +1,2217 @@
+/*!
+ * @file Adafruit_SPITFT.cpp
+ *
+ * @mainpage Adafruit SPI TFT Displays (and some others)
+ *
+ * @section intro_sec Introduction
+ *
+ * Part of Adafruit's GFX graphics library. Originally this class was
+ * written to handle a range of color TFT displays connected via SPI,
+ * but over time this library and some display-specific subclasses have
+ * mutated to include some color OLEDs as well as parallel-interfaced
+ * displays. The name's been kept for the sake of older code.
+ *
+ * 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
+ * Adafruit_GFX being present on your system. Please make sure you have
+ * installed the latest version before using this library.
+ *
+ * @section author Author
+ *
+ * Written by Limor "ladyada" Fried for Adafruit Industries,
+ * with contributions from the open source community.
+ *
+ * @section license License
+ *
+ * BSD license, all text here must be included in any redistribution.
+ */
+
+#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
+
+#include "Adafruit_SPITFT.h"
+
+#if defined(__AVR__)
+#if defined(__AVR_XMEGA__) //only tested with __AVR_ATmega4809__
+#define AVR_WRITESPI(x) for(SPI0_DATA = (x); (!(SPI0_INTFLAGS & _BV(SPI_IF_bp))); )
+#else
+#define AVR_WRITESPI(x) for(SPDR = (x); (!(SPSR & _BV(SPIF))); )
+#endif
+#endif
+
+#if defined(PORT_IOBUS)
+// On SAMD21, redefine digitalPinToPort() to use the slightly-faster
+// PORT_IOBUS rather than PORT (not needed on SAMD51).
+#undef digitalPinToPort
+#define digitalPinToPort(P) (&(PORT_IOBUS->Group[g_APinDescription[P].ulPort]))
+#endif // end PORT_IOBUS
+
+#if defined(USE_SPI_DMA)
+ #include
+ #include "wiring_private.h" // pinPeripheral() function
+ #include // memalign() function
+ #define tcNum 2 // Timer/Counter for parallel write strobe PWM
+ #define wrPeripheral PIO_CCL // Use CCL to invert write strobe
+
+ // DMA transfer-in-progress indicator and callback
+ static volatile bool dma_busy = false;
+ static void dma_callback(Adafruit_ZeroDMA *dma) {
+ dma_busy = false;
+ }
+
+ #if defined(__SAMD51__)
+ // Timer/counter info by index #
+ static const struct {
+ Tc *tc; // -> Timer/Counter base address
+ int gclk; // GCLK ID
+ int evu; // EVSYS user ID
+ } tcList[] = {
+ { TC0, TC0_GCLK_ID, EVSYS_ID_USER_TC0_EVU },
+ { TC1, TC1_GCLK_ID, EVSYS_ID_USER_TC1_EVU },
+ { TC2, TC2_GCLK_ID, EVSYS_ID_USER_TC2_EVU },
+ { TC3, TC3_GCLK_ID, EVSYS_ID_USER_TC3_EVU },
+ #if defined(TC4)
+ { TC4, TC4_GCLK_ID, EVSYS_ID_USER_TC4_EVU },
+ #endif
+ #if defined(TC5)
+ { TC5, TC5_GCLK_ID, EVSYS_ID_USER_TC5_EVU },
+ #endif
+ #if defined(TC6)
+ { TC6, TC6_GCLK_ID, EVSYS_ID_USER_TC6_EVU },
+ #endif
+ #if defined(TC7)
+ { TC7, TC7_GCLK_ID, EVSYS_ID_USER_TC7_EVU }
+ #endif
+ };
+ #define NUM_TIMERS (sizeof tcList / sizeof tcList[0]) ///< # timer/counters
+ #endif // end __SAMD51__
+
+#endif // end USE_SPI_DMA
+
+// Possible values for Adafruit_SPITFT.connection:
+#define TFT_HARD_SPI 0 ///< Display interface = hardware SPI
+#define TFT_SOFT_SPI 1 ///< Display interface = software SPI
+#define TFT_PARALLEL 2 ///< Display interface = 8- or 16-bit parallel
+
+
+// CONSTRUCTORS ------------------------------------------------------------
+
+/*!
+ @brief Adafruit_SPITFT constructor for software (bitbang) SPI.
+ @param w Display width in pixels at default rotation setting (0).
+ @param h Display height in pixels at default rotation setting (0).
+ @param cs Arduino pin # for chip-select (-1 if unused, tie CS low).
+ @param dc Arduino pin # for data/command select (required).
+ @param mosi Arduino pin # for bitbang SPI MOSI signal (required).
+ @param sck Arduino pin # for bitbang SPI SCK signal (required).
+ @param rst Arduino pin # for display reset (optional, display reset
+ can be tied to MCU reset, default of -1 means unused).
+ @param miso Arduino pin # for bitbang SPI MISO signal (optional,
+ -1 default, many displays don't support SPI read).
+ @return Adafruit_SPITFT object.
+ @note Output pins are not initialized; application typically will
+ need to call subclass' begin() function, which in turn calls
+ this library's initSPI() function to initialize pins.
+*/
+Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h,
+ int8_t cs, int8_t dc, int8_t mosi, int8_t sck, int8_t rst, int8_t miso) :
+ Adafruit_GFX(w, h), connection(TFT_SOFT_SPI), _rst(rst), _cs(cs), _dc(dc) {
+ swspi._sck = sck;
+ swspi._mosi = mosi;
+ swspi._miso = miso;
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(CORE_TEENSY)
+ #if !defined(KINETISK)
+ dcPinMask = digitalPinToBitMask(dc);
+ swspi.sckPinMask = digitalPinToBitMask(sck);
+ swspi.mosiPinMask = digitalPinToBitMask(mosi);
+ #endif
+ dcPortSet = portSetRegister(dc);
+ dcPortClr = portClearRegister(dc);
+ swspi.sckPortSet = portSetRegister(sck);
+ swspi.sckPortClr = portClearRegister(sck);
+ swspi.mosiPortSet = portSetRegister(mosi);
+ swspi.mosiPortClr = portClearRegister(mosi);
+ if(cs >= 0) {
+ #if !defined(KINETISK)
+ csPinMask = digitalPinToBitMask(cs);
+ #endif
+ csPortSet = portSetRegister(cs);
+ csPortClr = portClearRegister(cs);
+ } else {
+ #if !defined(KINETISK)
+ csPinMask = 0;
+ #endif
+ csPortSet = dcPortSet;
+ csPortClr = dcPortClr;
+ }
+ if(miso >= 0) {
+ swspi.misoPort = portInputRegister(miso);
+ #if !defined(KINETISK)
+ swspi.misoPinMask = digitalPinToBitMask(miso);
+ #endif
+ } else {
+ swspi.misoPort = portInputRegister(dc);
+ }
+ #else // !CORE_TEENSY
+ dcPinMask =digitalPinToBitMask(dc);
+ swspi.sckPinMask =digitalPinToBitMask(sck);
+ swspi.mosiPinMask=digitalPinToBitMask(mosi);
+ dcPortSet =&(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg);
+ dcPortClr =&(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg);
+ swspi.sckPortSet =&(PORT->Group[g_APinDescription[sck].ulPort].OUTSET.reg);
+ swspi.sckPortClr =&(PORT->Group[g_APinDescription[sck].ulPort].OUTCLR.reg);
+ swspi.mosiPortSet=&(PORT->Group[g_APinDescription[mosi].ulPort].OUTSET.reg);
+ swspi.mosiPortClr=&(PORT->Group[g_APinDescription[mosi].ulPort].OUTCLR.reg);
+ if(cs >= 0) {
+ csPinMask = digitalPinToBitMask(cs);
+ csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg);
+ csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg);
+ } else {
+ // No chip-select line defined; might be permanently tied to GND.
+ // Assign a valid GPIO register (though not used for CS), and an
+ // empty pin bitmask...the nonsense bit-twiddling might be faster
+ // than checking _cs and possibly branching.
+ csPortSet = dcPortSet;
+ csPortClr = dcPortClr;
+ csPinMask = 0;
+ }
+ if(miso >= 0) {
+ swspi.misoPinMask=digitalPinToBitMask(miso);
+ swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(miso));
+ } else {
+ swspi.misoPinMask=0;
+ swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(dc));
+ }
+ #endif // end !CORE_TEENSY
+ #else // !HAS_PORT_SET_CLR
+ dcPort =(PORTreg_t)portOutputRegister(digitalPinToPort(dc));
+ dcPinMaskSet =digitalPinToBitMask(dc);
+ swspi.sckPort =(PORTreg_t)portOutputRegister(digitalPinToPort(sck));
+ swspi.sckPinMaskSet =digitalPinToBitMask(sck);
+ swspi.mosiPort =(PORTreg_t)portOutputRegister(digitalPinToPort(mosi));
+ swspi.mosiPinMaskSet=digitalPinToBitMask(mosi);
+ if(cs >= 0) {
+ csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs));
+ csPinMaskSet = digitalPinToBitMask(cs);
+ } else {
+ // No chip-select line defined; might be permanently tied to GND.
+ // Assign a valid GPIO register (though not used for CS), and an
+ // empty pin bitmask...the nonsense bit-twiddling might be faster
+ // than checking _cs and possibly branching.
+ csPort = dcPort;
+ csPinMaskSet = 0;
+ }
+ if(miso >= 0) {
+ swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(miso));
+ swspi.misoPinMask=digitalPinToBitMask(miso);
+ } else {
+ swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(dc));
+ swspi.misoPinMask=0;
+ }
+ csPinMaskClr = ~csPinMaskSet;
+ dcPinMaskClr = ~dcPinMaskSet;
+ swspi.sckPinMaskClr = ~swspi.sckPinMaskSet;
+ swspi.mosiPinMaskClr = ~swspi.mosiPinMaskSet;
+ #endif // !end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+}
+
+/*!
+ @brief Adafruit_SPITFT constructor for hardware SPI using the board's
+ default SPI peripheral.
+ @param w Display width in pixels at default rotation setting (0).
+ @param h Display height in pixels at default rotation setting (0).
+ @param cs Arduino pin # for chip-select (-1 if unused, tie CS low).
+ @param dc Arduino pin # for data/command select (required).
+ @param rst Arduino pin # for display reset (optional, display reset
+ can be tied to MCU reset, default of -1 means unused).
+ @return Adafruit_SPITFT object.
+ @note Output pins are not initialized; application typically will
+ need to call subclass' begin() function, which in turn calls
+ this library's initSPI() function to initialize pins.
+*/
+#if defined(ESP8266) // See notes below
+Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs,
+ int8_t dc, int8_t rst) : Adafruit_GFX(w, h),
+ connection(TFT_HARD_SPI), _rst(rst), _cs(cs), _dc(dc) {
+ hwspi._spi = &SPI;
+}
+#else // !ESP8266
+Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs,
+ int8_t dc, int8_t rst) : Adafruit_SPITFT(w, h, &SPI, cs, dc, rst) {
+ // This just invokes the hardware SPI constructor below,
+ // passing the default SPI device (&SPI).
+}
+#endif // end !ESP8266
+
+#if !defined(ESP8266)
+// ESP8266 compiler freaks out at this constructor -- it can't disambiguate
+// beteween the SPIClass pointer (argument #3) and a regular integer.
+// Solution here it to just not offer this variant on the ESP8266. You can
+// use the default hardware SPI peripheral, or you can use software SPI,
+// but if there's any library out there that creates a 'virtual' SPIClass
+// peripheral and drives it with software bitbanging, that's not supported.
+/*!
+ @brief Adafruit_SPITFT constructor for hardware SPI using a specific
+ SPI peripheral.
+ @param w Display width in pixels at default rotation (0).
+ @param h Display height in pixels at default rotation (0).
+ @param spiClass Pointer to SPIClass type (e.g. &SPI or &SPI1).
+ @param cs Arduino pin # for chip-select (-1 if unused, tie CS low).
+ @param dc Arduino pin # for data/command select (required).
+ @param rst Arduino pin # for display reset (optional, display reset
+ can be tied to MCU reset, default of -1 means unused).
+ @return Adafruit_SPITFT object.
+ @note Output pins are not initialized in constructor; application
+ typically will need to call subclass' begin() function, which
+ in turn calls this library's initSPI() function to initialize
+ pins. EXCEPT...if you have built your own SERCOM SPI peripheral
+ (calling the SPIClass constructor) rather than one of the
+ built-in SPI devices (e.g. &SPI, &SPI1 and so forth), you will
+ need to call the begin() function for your object as well as
+ pinPeripheral() for the MOSI, MISO and SCK pins to configure
+ GPIO manually. Do this BEFORE calling the display-specific
+ begin or init function. Unfortunate but unavoidable.
+*/
+Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass,
+ int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(w, h),
+ connection(TFT_HARD_SPI), _rst(rst), _cs(cs), _dc(dc) {
+ hwspi._spi = spiClass;
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(CORE_TEENSY)
+ #if !defined(KINETISK)
+ dcPinMask = digitalPinToBitMask(dc);
+ #endif
+ dcPortSet = portSetRegister(dc);
+ dcPortClr = portClearRegister(dc);
+ if(cs >= 0) {
+ #if !defined(KINETISK)
+ csPinMask = digitalPinToBitMask(cs);
+ #endif
+ csPortSet = portSetRegister(cs);
+ csPortClr = portClearRegister(cs);
+ } else { // see comments below
+ #if !defined(KINETISK)
+ csPinMask = 0;
+ #endif
+ csPortSet = dcPortSet;
+ csPortClr = dcPortClr;
+ }
+ #else // !CORE_TEENSY
+ dcPinMask = digitalPinToBitMask(dc);
+ dcPortSet = &(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg);
+ dcPortClr = &(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg);
+ if(cs >= 0) {
+ csPinMask = digitalPinToBitMask(cs);
+ csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg);
+ csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg);
+ } else {
+ // No chip-select line defined; might be permanently tied to GND.
+ // Assign a valid GPIO register (though not used for CS), and an
+ // empty pin bitmask...the nonsense bit-twiddling might be faster
+ // than checking _cs and possibly branching.
+ csPortSet = dcPortSet;
+ csPortClr = dcPortClr;
+ csPinMask = 0;
+ }
+ #endif // end !CORE_TEENSY
+ #else // !HAS_PORT_SET_CLR
+ dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(dc));
+ dcPinMaskSet = digitalPinToBitMask(dc);
+ if(cs >= 0) {
+ csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs));
+ csPinMaskSet = digitalPinToBitMask(cs);
+ } else {
+ // No chip-select line defined; might be permanently tied to GND.
+ // Assign a valid GPIO register (though not used for CS), and an
+ // empty pin bitmask...the nonsense bit-twiddling might be faster
+ // than checking _cs and possibly branching.
+ csPort = dcPort;
+ csPinMaskSet = 0;
+ }
+ csPinMaskClr = ~csPinMaskSet;
+ dcPinMaskClr = ~dcPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+}
+#endif // end !ESP8266
+
+/*!
+ @brief Adafruit_SPITFT constructor for parallel display connection.
+ @param w Display width in pixels at default rotation (0).
+ @param h Display height in pixels at default rotation (0).
+ @param busWidth If tft16 (enumeration in header file), is a 16-bit
+ parallel connection, else 8-bit.
+ 16-bit isn't fully implemented or tested yet so
+ applications should pass "tft8bitbus" for now...needed to
+ stick a required enum argument in there to
+ disambiguate this constructor from the soft-SPI case.
+ Argument is ignored on 8-bit architectures (no 'wide'
+ support there since PORTs are 8 bits anyway).
+ @param d0 Arduino pin # for data bit 0 (1+ are extrapolated).
+ The 8 (or 16) data bits MUST be contiguous and byte-
+ aligned (or word-aligned for wide interface) within
+ the same PORT register (might not correspond to
+ Arduino pin sequence).
+ @param wr Arduino pin # for write strobe (required).
+ @param dc Arduino pin # for data/command select (required).
+ @param cs Arduino pin # for chip-select (optional, -1 if unused,
+ tie CS low).
+ @param rst Arduino pin # for display reset (optional, display reset
+ can be tied to MCU reset, default of -1 means unused).
+ @param rd Arduino pin # for read strobe (optional, -1 if unused).
+ @return Adafruit_SPITFT object.
+ @note Output pins are not initialized; application typically will need
+ to call subclass' begin() function, which in turn calls this
+ library's initSPI() function to initialize pins.
+ Yes, the name is a misnomer...this library originally handled
+ only SPI displays, parallel being a recent addition (but not
+ wanting to break existing code).
+*/
+Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth,
+ int8_t d0, int8_t wr, int8_t dc, int8_t cs, int8_t rst, int8_t rd) :
+ Adafruit_GFX(w, h), connection(TFT_PARALLEL), _rst(rst), _cs(cs), _dc(dc) {
+ tft8._d0 = d0;
+ tft8._wr = wr;
+ tft8._rd = rd;
+ tft8.wide = (busWidth == tft16bitbus);
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(CORE_TEENSY)
+ tft8.wrPortSet = portSetRegister(wr);
+ tft8.wrPortClr = portClearRegister(wr);
+ #if !defined(KINETISK)
+ dcPinMask = digitalPinToBitMask(dc);
+ #endif
+ dcPortSet = portSetRegister(dc);
+ dcPortClr = portClearRegister(dc);
+ if(cs >= 0) {
+ #if !defined(KINETISK)
+ csPinMask = digitalPinToBitMask(cs);
+ #endif
+ csPortSet = portSetRegister(cs);
+ csPortClr = portClearRegister(cs);
+ } else { // see comments below
+ #if !defined(KINETISK)
+ csPinMask = 0;
+ #endif
+ csPortSet = dcPortSet;
+ csPortClr = dcPortClr;
+ }
+ if(rd >= 0) { // if read-strobe pin specified...
+ #if defined(KINETISK)
+ tft8.rdPinMask = 1;
+ #else // !KINETISK
+ tft8.rdPinMask = digitalPinToBitMask(rd);
+ #endif
+ tft8.rdPortSet = portSetRegister(rd);
+ tft8.rdPortClr = portClearRegister(rd);
+ } else {
+ tft8.rdPinMask = 0;
+ tft8.rdPortSet = dcPortSet;
+ tft8.rdPortClr = dcPortClr;
+ }
+ // These are all uint8_t* pointers -- elsewhere they're recast
+ // as necessary if a 'wide' 16-bit interface is in use.
+ tft8.writePort = portOutputRegister(d0);
+ tft8.readPort = portInputRegister(d0);
+ tft8.dirSet = portModeRegister(d0);
+ tft8.dirClr = portModeRegister(d0);
+ #else // !CORE_TEENSY
+ tft8.wrPinMask = digitalPinToBitMask(wr);
+ tft8.wrPortSet = &(PORT->Group[g_APinDescription[wr].ulPort].OUTSET.reg);
+ tft8.wrPortClr = &(PORT->Group[g_APinDescription[wr].ulPort].OUTCLR.reg);
+ dcPinMask = digitalPinToBitMask(dc);
+ dcPortSet = &(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg);
+ dcPortClr = &(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg);
+ if(cs >= 0) {
+ csPinMask = digitalPinToBitMask(cs);
+ csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg);
+ csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg);
+ } else {
+ // No chip-select line defined; might be permanently tied to GND.
+ // Assign a valid GPIO register (though not used for CS), and an
+ // empty pin bitmask...the nonsense bit-twiddling might be faster
+ // than checking _cs and possibly branching.
+ csPortSet = dcPortSet;
+ csPortClr = dcPortClr;
+ csPinMask = 0;
+ }
+ if(rd >= 0) { // if read-strobe pin specified...
+ tft8.rdPinMask =digitalPinToBitMask(rd);
+ tft8.rdPortSet =&(PORT->Group[g_APinDescription[rd].ulPort].OUTSET.reg);
+ tft8.rdPortClr =&(PORT->Group[g_APinDescription[rd].ulPort].OUTCLR.reg);
+ } else {
+ tft8.rdPinMask = 0;
+ tft8.rdPortSet = dcPortSet;
+ tft8.rdPortClr = dcPortClr;
+ }
+ // Get pointers to PORT write/read/dir bytes within 32-bit PORT
+ uint8_t dBit = g_APinDescription[d0].ulPin; // d0 bit # in PORT
+ PortGroup *p = (&(PORT->Group[g_APinDescription[d0].ulPort]));
+ uint8_t offset = dBit / 8; // d[7:0] byte # within PORT
+ if(tft8.wide) offset &= ~1; // d[15:8] byte # within PORT
+ // These are all uint8_t* pointers -- elsewhere they're recast
+ // as necessary if a 'wide' 16-bit interface is in use.
+ tft8.writePort = (volatile uint8_t *)&(p->OUT.reg) + offset;
+ tft8.readPort = (volatile uint8_t *)&(p->IN.reg) + offset;
+ tft8.dirSet = (volatile uint8_t *)&(p->DIRSET.reg) + offset;
+ tft8.dirClr = (volatile uint8_t *)&(p->DIRCLR.reg) + offset;
+ #endif // end !CORE_TEENSY
+ #else // !HAS_PORT_SET_CLR
+ tft8.wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(wr));
+ tft8.wrPinMaskSet = digitalPinToBitMask(wr);
+ dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(dc));
+ dcPinMaskSet = digitalPinToBitMask(dc);
+ if(cs >= 0) {
+ csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs));
+ csPinMaskSet = digitalPinToBitMask(cs);
+ } else {
+ // No chip-select line defined; might be permanently tied to GND.
+ // Assign a valid GPIO register (though not used for CS), and an
+ // empty pin bitmask...the nonsense bit-twiddling might be faster
+ // than checking _cs and possibly branching.
+ csPort = dcPort;
+ csPinMaskSet = 0;
+ }
+ if(rd >= 0) { // if read-strobe pin specified...
+ tft8.rdPort =(PORTreg_t)portOutputRegister(digitalPinToPort(rd));
+ tft8.rdPinMaskSet =digitalPinToBitMask(rd);
+ } else {
+ tft8.rdPort = dcPort;
+ tft8.rdPinMaskSet = 0;
+ }
+ csPinMaskClr = ~csPinMaskSet;
+ dcPinMaskClr = ~dcPinMaskSet;
+ tft8.wrPinMaskClr = ~tft8.wrPinMaskSet;
+ tft8.rdPinMaskClr = ~tft8.rdPinMaskSet;
+ tft8.writePort = (PORTreg_t)portOutputRegister(digitalPinToPort(d0));
+ tft8.readPort = (PORTreg_t)portInputRegister(digitalPinToPort(d0));
+ tft8.portDir = (PORTreg_t)portModeRegister(digitalPinToPort(d0));
+ #endif // end !HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+}
+
+// end constructors -------
+
+
+// CLASS MEMBER FUNCTIONS --------------------------------------------------
+
+// begin() and setAddrWindow() MUST be declared by any subclass.
+
+/*!
+ @brief Configure microcontroller pins for TFT interfacing. Typically
+ called by a subclass' begin() function.
+ @param freq SPI frequency when using hardware SPI. If default (0)
+ is passed, will fall back on a device-specific value.
+ Value is ignored when using software SPI or parallel
+ connection.
+ @param spiMode SPI mode when using hardware SPI. MUST be one of the
+ values SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
+ defined in SPI.h. Do NOT attempt to pass '0' for
+ SPI_MODE0 and so forth...the values are NOT the same!
+ Use ONLY the defines! (Pity it's not an enum.)
+ @note Another anachronistically-named function; this is called even
+ when the display connection is parallel (not SPI). Also, this
+ could probably be made private...quite a few class functions
+ were generously put in the public section.
+*/
+void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) {
+
+ if(!freq) freq = DEFAULT_SPI_FREQ; // If no freq specified, use default
+
+ // Init basic control pins common to all connection types
+ if(_cs >= 0) {
+ pinMode(_cs, OUTPUT);
+ digitalWrite(_cs, HIGH); // Deselect
+ }
+ pinMode(_dc, OUTPUT);
+ digitalWrite(_dc, HIGH); // Data mode
+
+ if(connection == TFT_HARD_SPI) {
+
+#if defined(SPI_HAS_TRANSACTION)
+ hwspi.settings = SPISettings(freq, MSBFIRST, spiMode);
+#else
+ hwspi._freq = freq; // Save freq value for later
+#endif
+ hwspi._mode = spiMode; // Save spiMode value for later
+ // Call hwspi._spi->begin() ONLY if this is among the 'established'
+ // SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs,
+ // begin() and pinPeripheral() calls MUST be made in one's calling
+ // code, BEFORE the screen-specific begin/init function is called.
+ // Reason for this is that SPI::begin() makes its own calls to
+ // pinPeripheral() based on g_APinDescription[n].ulPinType, which
+ // on non-established SPI interface pins will always be PIO_DIGITAL
+ // or similar, while we need PIO_SERCOM or PIO_SERCOM_ALT...it's
+ // highly unique between devices and variants for each pin or
+ // SERCOM so we can't make those calls ourselves here. And the SPI
+ // device needs to be set up before calling this because it's
+ // immediately followed with initialization commands. Blargh.
+ if(
+#if !defined(SPI_INTERFACES_COUNT)
+ 1
+#endif
+#if SPI_INTERFACES_COUNT > 0
+ (hwspi._spi == &SPI)
+#endif
+#if SPI_INTERFACES_COUNT > 1
+ || (hwspi._spi == &SPI1)
+#endif
+#if SPI_INTERFACES_COUNT > 2
+ || (hwspi._spi == &SPI2)
+#endif
+#if SPI_INTERFACES_COUNT > 3
+ || (hwspi._spi == &SPI3)
+#endif
+#if SPI_INTERFACES_COUNT > 4
+ || (hwspi._spi == &SPI4)
+#endif
+#if SPI_INTERFACES_COUNT > 5
+ || (hwspi._spi == &SPI5)
+#endif
+ ) {
+ hwspi._spi->begin();
+ }
+ } else if(connection == TFT_SOFT_SPI) {
+
+ pinMode(swspi._mosi, OUTPUT);
+ digitalWrite(swspi._mosi, LOW);
+ pinMode(swspi._sck, OUTPUT);
+ digitalWrite(swspi._sck, LOW);
+ if(swspi._miso >= 0) {
+ pinMode(swspi._miso, INPUT);
+ }
+
+ } else { // TFT_PARALLEL
+
+ // Initialize data pins. We were only passed d0, so scan
+ // the pin description list looking for the other pins.
+ // They'll be on the same PORT, and within the next 7 (or 15) bits
+ // (because we need to write to a contiguous PORT byte or word).
+#if defined(__AVR__)
+ // PORT registers are 8 bits wide, so just need a register match...
+ for(uint8_t i=0; i= dBit ) &&
+ (g_APinDescription[i].ulPin <= (uint32_t)lastBit)) {
+ pinMode(i, OUTPUT);
+ digitalWrite(i, LOW);
+ }
+ }
+ #endif // end !CORE_TEENSY
+#endif
+ pinMode(tft8._wr, OUTPUT);
+ digitalWrite(tft8._wr, HIGH);
+ if(tft8._rd >= 0) {
+ pinMode(tft8._rd, OUTPUT);
+ digitalWrite(tft8._rd, HIGH);
+ }
+ }
+
+ if(_rst >= 0) {
+ // Toggle _rst low to reset
+ pinMode(_rst, OUTPUT);
+ digitalWrite(_rst, HIGH);
+ delay(100);
+ digitalWrite(_rst, LOW);
+ delay(100);
+ digitalWrite(_rst, HIGH);
+ delay(200);
+ }
+
+#if defined(USE_SPI_DMA)
+ if(((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) &&
+ (dma.allocate() == DMA_STATUS_OK)) { // Allocate channel
+ // The DMA library needs to alloc at least one valid descriptor,
+ // so we do that here. It's not used in the usual sense though,
+ // just before a transfer we copy descriptor[0] to this address.
+ if(dptr = dma.addDescriptor(NULL, NULL, 42, DMA_BEAT_SIZE_BYTE,
+ false, false)) {
+ // Alloc 2 scanlines worth of pixels on display's major axis,
+ // whichever that is, rounding each up to 2-pixel boundary.
+ int major = (WIDTH > HEIGHT) ? WIDTH : HEIGHT;
+ major += (major & 1); // -> next 2-pixel bound, if needed.
+ maxFillLen = major * 2; // 2 scanlines
+ // Note to future self: if you decide to make the pixel buffer
+ // much larger, remember that DMA transfer descriptors can't
+ // exceed 65,535 bytes (not 65,536), meaning 32,767 pixels max.
+ // Not that we have that kind of RAM to throw around right now.
+ if((pixelBuf[0] =
+ (uint16_t *)malloc(maxFillLen * sizeof(uint16_t)))) {
+ // Alloc OK. Get pointer to start of second scanline.
+ pixelBuf[1] = &pixelBuf[0][major];
+ // Determine number of DMA descriptors needed to cover
+ // entire screen when entire 2-line pixelBuf is used
+ // (round up for fractional last descriptor).
+ int numDescriptors = (WIDTH * HEIGHT + (maxFillLen - 1)) /
+ maxFillLen;
+ // DMA descriptors MUST be 128-bit (16 byte) aligned.
+ // memalign() is considered obsolete but it's replacements
+ // (aligned_alloc() or posix_memalign()) are not currently
+ // available in the version of ARM GCC in use, but this
+ // is, so here we are.
+ if((descriptor = (DmacDescriptor *)memalign(16,
+ numDescriptors * sizeof(DmacDescriptor)))) {
+ int dmac_id;
+ volatile uint32_t *data_reg;
+
+ if(connection == TFT_HARD_SPI) {
+ // THIS IS AN AFFRONT TO NATURE, but I don't know
+ // any "clean" way to get the sercom number from the
+ // the SPIClass pointer (e.g. &SPI or &SPI1), which
+ // is all we have to work with. SPIClass does contain
+ // a SERCOM pointer but it is a PRIVATE member!
+ // Doing an UNSPEAKABLY HORRIBLE THING here, directly
+ // accessing the first 32-bit value in the SPIClass
+ // structure, knowing that's (currently) where the
+ // SERCOM pointer lives, but this ENTIRELY DEPENDS on
+ // that structure not changing nor the compiler
+ // rearranging things. Oh the humanity!
+
+ if(*(SERCOM **)hwspi._spi == &sercom0) {
+ dmac_id = SERCOM0_DMAC_ID_TX;
+ data_reg = &SERCOM0->SPI.DATA.reg;
+#if defined SERCOM1
+ } else if(*(SERCOM **)hwspi._spi == &sercom1) {
+ dmac_id = SERCOM1_DMAC_ID_TX;
+ data_reg = &SERCOM1->SPI.DATA.reg;
+#endif
+#if defined SERCOM2
+ } else if(*(SERCOM **)hwspi._spi == &sercom2) {
+ dmac_id = SERCOM2_DMAC_ID_TX;
+ data_reg = &SERCOM2->SPI.DATA.reg;
+#endif
+#if defined SERCOM3
+ } else if(*(SERCOM **)hwspi._spi == &sercom3) {
+ dmac_id = SERCOM3_DMAC_ID_TX;
+ data_reg = &SERCOM3->SPI.DATA.reg;
+#endif
+#if defined SERCOM4
+ } else if(*(SERCOM **)hwspi._spi == &sercom4) {
+ dmac_id = SERCOM4_DMAC_ID_TX;
+ data_reg = &SERCOM4->SPI.DATA.reg;
+#endif
+#if defined SERCOM5
+ } else if(*(SERCOM **)hwspi._spi == &sercom5) {
+ dmac_id = SERCOM5_DMAC_ID_TX;
+ data_reg = &SERCOM5->SPI.DATA.reg;
+#endif
+#if defined SERCOM6
+ } else if(*(SERCOM **)hwspi._spi == &sercom6) {
+ dmac_id = SERCOM6_DMAC_ID_TX;
+ data_reg = &SERCOM6->SPI.DATA.reg;
+#endif
+#if defined SERCOM7
+ } else if(*(SERCOM **)hwspi._spi == &sercom7) {
+ dmac_id = SERCOM7_DMAC_ID_TX;
+ data_reg = &SERCOM7->SPI.DATA.reg;
+#endif
+ }
+ dma.setPriority(DMA_PRIORITY_3);
+ dma.setTrigger(dmac_id);
+ dma.setAction(DMA_TRIGGER_ACTON_BEAT);
+
+ // Initialize descriptor list.
+ for(int d=0; dChannel[dmaChannel].CHEVCTRL.bit.EVOE = 1;
+ DMAC->Channel[dmaChannel].CHEVCTRL.bit.EVOMODE = 0;
+
+ // CONFIGURE TIMER/COUNTER (for write strobe)
+
+ Tc *timer = tcList[tcNum].tc; // -> Timer struct
+ int id = tcList[tcNum].gclk; // Timer GCLK ID
+ GCLK_PCHCTRL_Type pchctrl;
+
+ // Set up timer clock source from GCLK
+ GCLK->PCHCTRL[id].bit.CHEN = 0; // Stop timer
+ while(GCLK->PCHCTRL[id].bit.CHEN); // Wait for it
+ pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK0_Val;
+ pchctrl.bit.CHEN = 1; // Enable
+ GCLK->PCHCTRL[id].reg = pchctrl.reg;
+ while(!GCLK->PCHCTRL[id].bit.CHEN); // Wait for it
+
+ // Disable timer/counter before configuring it
+ timer->COUNT8.CTRLA.bit.ENABLE = 0;
+ while(timer->COUNT8.SYNCBUSY.bit.STATUS);
+
+ timer->COUNT8.WAVE.bit.WAVEGEN = 2; // NPWM
+ timer->COUNT8.CTRLA.bit.MODE = 1; // 8-bit
+ timer->COUNT8.CTRLA.bit.PRESCALER = 0; // 1:1
+ while(timer->COUNT8.SYNCBUSY.bit.STATUS);
+
+ timer->COUNT8.CTRLBCLR.bit.DIR = 1; // Count UP
+ while(timer->COUNT8.SYNCBUSY.bit.CTRLB);
+ timer->COUNT8.CTRLBSET.bit.ONESHOT = 1; // One-shot
+ while(timer->COUNT8.SYNCBUSY.bit.CTRLB);
+ timer->COUNT8.PER.reg = 6; // PWM top
+ while(timer->COUNT8.SYNCBUSY.bit.PER);
+ timer->COUNT8.CC[0].reg = 2; // Compare
+ while(timer->COUNT8.SYNCBUSY.bit.CC0);
+ // Enable async input events,
+ // event action = restart.
+ timer->COUNT8.EVCTRL.bit.TCEI = 1;
+ timer->COUNT8.EVCTRL.bit.EVACT = 1;
+
+ // Enable timer
+ timer->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE;
+ while(timer->COUNT8.SYNCBUSY.bit.STATUS);
+
+#if(wrPeripheral == PIO_CCL)
+ // CONFIGURE CCL (inverts timer/counter output)
+
+ MCLK->APBCMASK.bit.CCL_ = 1; // Enable CCL clock
+ CCL->CTRL.bit.ENABLE = 0; // Disable to config
+ CCL->CTRL.bit.SWRST = 1; // Reset CCL registers
+ CCL->LUTCTRL[tcNum].bit.ENABLE = 0; // Disable LUT
+ CCL->LUTCTRL[tcNum].bit.FILTSEL = 0; // No filter
+ CCL->LUTCTRL[tcNum].bit.INSEL0 = 6; // TC input
+ CCL->LUTCTRL[tcNum].bit.INSEL1 = 0; // MASK
+ CCL->LUTCTRL[tcNum].bit.INSEL2 = 0; // MASK
+ CCL->LUTCTRL[tcNum].bit.TRUTH = 1; // Invert in 0
+ CCL->LUTCTRL[tcNum].bit.ENABLE = 1; // Enable LUT
+ CCL->CTRL.bit.ENABLE = 1; // Enable CCL
+#endif
+
+ // CONFIGURE EVENT SYSTEM
+
+ // Set up event system clock source from GCLK...
+ // Disable EVSYS, wait for disable
+ GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN = 0;
+ while(GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN);
+ pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK0_Val;
+ pchctrl.bit.CHEN = 1; // Re-enable
+ GCLK->PCHCTRL[EVSYS_GCLK_ID_0].reg = pchctrl.reg;
+ // Wait for it, then enable EVSYS clock
+ while(!GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN);
+ MCLK->APBBMASK.bit.EVSYS_ = 1;
+
+ // Connect Timer EVU to ch 0
+ EVSYS->USER[tcList[tcNum].evu].reg = 1;
+ // Datasheet recommends single write operation;
+ // reg instead of bit. Also datasheet: PATH bits
+ // must be zero when using async!
+ EVSYS_CHANNEL_Type ev;
+ ev.reg = 0;
+ ev.bit.PATH = 2; // Asynchronous
+ ev.bit.EVGEN = 0x22 + dmaChannel; // DMA channel 0+
+ EVSYS->Channel[0].CHANNEL.reg = ev.reg;
+
+ // Initialize descriptor list.
+ for(int d=0; d= 0) SPI_CS_LOW();
+}
+
+/*!
+ @brief Call after issuing command(s) or data to display. Performs
+ chip-deselect (if required) and ends an SPI transaction (if
+ using hardware SPI and transactions are supported). Required
+ for all display types; not an SPI-specific function.
+*/
+void Adafruit_SPITFT::endWrite(void) {
+ if(_cs >= 0) SPI_CS_HIGH();
+ SPI_END_TRANSACTION();
+}
+
+
+// -------------------------------------------------------------------------
+// Lower-level graphics operations. These functions require a chip-select
+// and/or SPI transaction around them (via startWrite(), endWrite() above).
+// Higher-level graphics primitives might start a single transaction and
+// then make multiple calls to these functions (e.g. circle or text
+// rendering might make repeated lines or rects) before ending the
+// transaction. It's more efficient than starting a transaction every time.
+
+/*!
+ @brief Draw a single pixel to the display at requested coordinates.
+ Not self-contained; should follow a startWrite() call.
+ @param x Horizontal position (0 = left).
+ @param y Vertical position (0 = top).
+ @param color 16-bit pixel color in '565' RGB format.
+*/
+void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) {
+ if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
+ setAddrWindow(x, y, 1, 1);
+ SPI_WRITE16(color);
+ }
+}
+
+/*!
+ @brief Issue a series of pixels from memory to the display. Not self-
+ contained; should follow startWrite() and setAddrWindow() calls.
+ @param colors Pointer to array of 16-bit pixel values in '565' RGB
+ format.
+ @param len Number of elements in 'colors' array.
+ @param block If true (default case if unspecified), function blocks
+ until DMA transfer is complete. This is simply IGNORED
+ if DMA is not enabled. If false, the function returns
+ immediately after the last DMA transfer is started,
+ and one should use the dmaWait() function before
+ doing ANY other display-related activities (or even
+ any SPI-related activities, if using an SPI display
+ that shares the bus with other devices).
+ @param bigEndian If using DMA, and if set true, bitmap in memory is in
+ big-endian order (most significant byte first). By
+ default this is false, as most microcontrollers seem
+ to be little-endian and 16-bit pixel values must be
+ byte-swapped before issuing to the display (which tend
+ to be big-endian when using SPI or 8-bit parallel).
+ If an application can optimize around this -- for
+ example, a bitmap in a uint16_t array having the byte
+ values already reordered big-endian, this can save
+ some processing time here, ESPECIALLY if using this
+ function's non-blocking DMA mode. Not all cases are
+ covered...this is really here only for SAMD DMA and
+ much forethought on the application side.
+*/
+void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
+ bool block, bool bigEndian) {
+
+ if(!len) return; // Avoid 0-byte transfers
+
+#if defined(ESP32) // ESP32 has a special SPI pixel-writing function...
+ if(connection == TFT_HARD_SPI) {
+ hwspi._spi->writePixels(colors, len * 2);
+ return;
+ }
+#elif defined(USE_SPI_DMA)
+ if((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) {
+ int maxSpan = maxFillLen / 2; // One scanline max
+ uint8_t pixelBufIdx = 0; // Active pixel buffer number
+ #if defined(__SAMD51__)
+ if(connection == TFT_PARALLEL) {
+ // Switch WR pin to PWM or CCL
+ pinPeripheral(tft8._wr, wrPeripheral);
+ }
+ #endif // end __SAMD51__
+ if(!bigEndian) { // Normal little-endian situation...
+ while(len) {
+ int count = (len < maxSpan) ? len : maxSpan;
+
+ // Because TFT and SAMD endianisms are different, must swap
+ // bytes from the 'colors' array passed into a DMA working
+ // buffer. This can take place while the prior DMA transfer
+ // is in progress, hence the need for two pixelBufs.
+ for(int i=0; isetDataMode(hwspi._mode);
+ } else {
+ pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
+ }
+ #endif // end __SAMD51__ || _SAMD21_
+ }
+ return;
+ }
+#endif // end USE_SPI_DMA
+
+ // All other cases (bitbang SPI or non-DMA hard SPI or parallel),
+ // use a loop with the normal 16-bit data write function:
+ while(len--) {
+ SPI_WRITE16(*colors++);
+ }
+}
+
+/*!
+ @brief Wait for the last DMA transfer in a prior non-blocking
+ writePixels() call to complete. This does nothing if DMA
+ is not enabled, and is not needed if blocking writePixels()
+ was used (as is the default case).
+*/
+void Adafruit_SPITFT::dmaWait(void) {
+#if defined(USE_SPI_DMA)
+ while(dma_busy);
+ #if defined(__SAMD51__) || defined(_SAMD21_)
+ if(connection == TFT_HARD_SPI) {
+ // See SAMD51/21 note in writeColor()
+ hwspi._spi->setDataMode(hwspi._mode);
+ } else {
+ pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
+ }
+ #endif // end __SAMD51__ || _SAMD21_
+#endif
+}
+
+/*!
+ @brief Issue a series of pixels, all the same color. Not self-
+ contained; should follow startWrite() and setAddrWindow() calls.
+ @param color 16-bit pixel color in '565' RGB format.
+ @param len Number of pixels to draw.
+*/
+void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) {
+
+ if(!len) return; // Avoid 0-byte transfers
+
+ uint8_t hi = color >> 8, lo = color;
+
+#if defined(ESP32) // ESP32 has a special SPI pixel-writing function...
+ if(connection == TFT_HARD_SPI) {
+ #define SPI_MAX_PIXELS_AT_ONCE 32
+ #define TMPBUF_LONGWORDS (SPI_MAX_PIXELS_AT_ONCE + 1) / 2
+ #define TMPBUF_PIXELS (TMPBUF_LONGWORDS * 2)
+ static uint32_t temp[TMPBUF_LONGWORDS];
+ uint32_t c32 = color * 0x00010001;
+ uint16_t bufLen = (len < TMPBUF_PIXELS) ? len : TMPBUF_PIXELS,
+ xferLen, fillLen;
+ // Fill temp buffer 32 bits at a time
+ fillLen = (bufLen + 1) / 2; // Round up to next 32-bit boundary
+ for(uint32_t t=0; t= 16)) { // Don't bother with DMA on short pixel runs
+ int i, d, numDescriptors;
+ if(hi == lo) { // If high & low bytes are same...
+ onePixelBuf = color;
+ // Can do this with a relatively short descriptor list,
+ // each transferring a max of 32,767 (not 32,768) pixels.
+ // This won't run off the end of the allocated descriptor list,
+ // since we're using much larger chunks per descriptor here.
+ numDescriptors = (len + 32766) / 32767;
+ for(d=0; d lastFillLen) {
+ int fillStart = lastFillLen / 2,
+ fillEnd = (((len < maxFillLen) ?
+ len : maxFillLen) + 1) / 2;
+ for(i=fillStart; isetDataMode(hwspi._mode);
+ } else {
+ pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
+ }
+ #endif // end __SAMD51__
+ return;
+ }
+ #endif // end USE_SPI_DMA
+#endif // end !ESP32
+
+ // All other cases (non-DMA hard SPI, bitbang SPI, parallel)...
+
+ if(connection == TFT_HARD_SPI) {
+#if defined(ESP8266)
+ do {
+ uint32_t pixelsThisPass = len;
+ if(pixelsThisPass > 50000) pixelsThisPass = 50000;
+ len -= pixelsThisPass;
+ yield(); // Periodic yield() on long fills
+ while(pixelsThisPass--) {
+ hwspi._spi->write(hi);
+ hwspi._spi->write(lo);
+ }
+ } while(len);
+#else // !ESP8266
+ while(len--) {
+ #if defined(__AVR__)
+ AVR_WRITESPI(hi);
+ AVR_WRITESPI(lo);
+ #elif defined(ESP32)
+ hwspi._spi->write(hi);
+ hwspi._spi->write(lo);
+ #else
+ hwspi._spi->transfer(hi);
+ hwspi._spi->transfer(lo);
+ #endif
+ }
+#endif // end !ESP8266
+ } else if(connection == TFT_SOFT_SPI) {
+#if defined(ESP8266)
+ do {
+ uint32_t pixelsThisPass = len;
+ if(pixelsThisPass > 20000) pixelsThisPass = 20000;
+ len -= pixelsThisPass;
+ yield(); // Periodic yield() on long fills
+ while(pixelsThisPass--) {
+ for(uint16_t bit=0, x=color; bit<16; bit++) {
+ if(x & 0x8000) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ SPI_SCK_LOW();
+ x <<= 1;
+ }
+ }
+ } while(len);
+#else // !ESP8266
+ while(len--) {
+ #if defined(__AVR__)
+ for(uint8_t bit=0, x=hi; bit<8; bit++) {
+ if(x & 0x80) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ SPI_SCK_LOW();
+ x <<= 1;
+ }
+ for(uint8_t bit=0, x=lo; bit<8; bit++) {
+ if(x & 0x80) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ SPI_SCK_LOW();
+ x <<= 1;
+ }
+ #else // !__AVR__
+ for(uint16_t bit=0, x=color; bit<16; bit++) {
+ if(x & 0x8000) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ x <<= 1;
+ SPI_SCK_LOW();
+ }
+ #endif // end !__AVR__
+ }
+#endif // end !ESP8266
+ } else { // PARALLEL
+ if(hi == lo) {
+#if defined(__AVR__)
+ len *= 2;
+ *tft8.writePort = hi;
+ while(len--) {
+ TFT_WR_STROBE();
+ }
+#elif defined(USE_FAST_PINIO)
+ if(!tft8.wide) {
+ len *= 2;
+ *tft8.writePort = hi;
+ } else {
+ *(volatile uint16_t *)tft8.writePort = color;
+ }
+ while(len--) {
+ TFT_WR_STROBE();
+ }
+#endif
+ } else {
+ while(len--) {
+#if defined(__AVR__)
+ *tft8.writePort = hi;
+ TFT_WR_STROBE();
+ *tft8.writePort = lo;
+#elif defined(USE_FAST_PINIO)
+ if(!tft8.wide) {
+ *tft8.writePort = hi;
+ TFT_WR_STROBE();
+ *tft8.writePort = lo;
+ } else {
+ *(volatile uint16_t *)tft8.writePort = color;
+ }
+#endif
+ TFT_WR_STROBE();
+ }
+ }
+ }
+}
+
+/*!
+ @brief Draw a filled rectangle to the display. Not self-contained;
+ should follow startWrite(). Typically used by higher-level
+ graphics primitives; user code shouldn't need to call this and
+ is likely to use the self-contained fillRect() instead.
+ writeFillRect() performs its own edge clipping and rejection;
+ see writeFillRectPreclipped() for a more 'raw' implementation.
+ @param x Horizontal position of first corner.
+ @param y Vertical position of first corner.
+ @param w Rectangle width in pixels (positive = right of first
+ corner, negative = left of first corner).
+ @param h Rectangle height in pixels (positive = below first
+ corner, negative = above first corner).
+ @param color 16-bit fill color in '565' RGB format.
+ @note Written in this deep-nested way because C by definition will
+ optimize for the 'if' case, not the 'else' -- avoids branches
+ and rejects clipped rectangles at the least-work possibility.
+*/
+void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y,
+ int16_t w, int16_t h, uint16_t color) {
+ if(w && h) { // Nonzero width and height?
+ if(w < 0) { // If negative width...
+ x += w + 1; // Move X to left edge
+ w = -w; // Use positive width
+ }
+ if(x < _width) { // Not off right
+ if(h < 0) { // If negative height...
+ y += h + 1; // Move Y to top edge
+ h = -h; // Use positive height
+ }
+ if(y < _height) { // Not off bottom
+ int16_t x2 = x + w - 1;
+ if(x2 >= 0) { // Not off left
+ int16_t y2 = y + h - 1;
+ if(y2 >= 0) { // Not off top
+ // Rectangle partly or fully overlaps screen
+ if(x < 0) { x = 0; w = x2 + 1; } // Clip left
+ if(y < 0) { y = 0; h = y2 + 1; } // Clip top
+ if(x2 >= _width) { w = _width - x; } // Clip right
+ if(y2 >= _height) { h = _height - y; } // Clip bottom
+ writeFillRectPreclipped(x, y, w, h, color);
+ }
+ }
+ }
+ }
+ }
+}
+
+/*!
+ @brief Draw a horizontal line on the display. Performs edge clipping
+ and rejection. Not self-contained; should follow startWrite().
+ Typically used by higher-level graphics primitives; user code
+ shouldn't need to call this and is likely to use the self-
+ contained drawFastHLine() instead.
+ @param x Horizontal position of first point.
+ @param y Vertical position of first point.
+ @param w Line width in pixels (positive = right of first point,
+ negative = point of first corner).
+ @param color 16-bit line color in '565' RGB format.
+*/
+void inline Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w,
+ uint16_t color) {
+ if((y >= 0) && (y < _height) && w) { // Y on screen, nonzero width
+ if(w < 0) { // If negative width...
+ x += w + 1; // Move X to left edge
+ w = -w; // Use positive width
+ }
+ if(x < _width) { // Not off right
+ int16_t x2 = x + w - 1;
+ if(x2 >= 0) { // Not off left
+ // Line partly or fully overlaps screen
+ if(x < 0) { x = 0; w = x2 + 1; } // Clip left
+ if(x2 >= _width) { w = _width - x; } // Clip right
+ writeFillRectPreclipped(x, y, w, 1, color);
+ }
+ }
+ }
+}
+
+/*!
+ @brief Draw a vertical line on the display. Performs edge clipping and
+ rejection. Not self-contained; should follow startWrite().
+ Typically used by higher-level graphics primitives; user code
+ shouldn't need to call this and is likely to use the self-
+ contained drawFastVLine() instead.
+ @param x Horizontal position of first point.
+ @param y Vertical position of first point.
+ @param h Line height in pixels (positive = below first point,
+ negative = above first point).
+ @param color 16-bit line color in '565' RGB format.
+*/
+void inline Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h,
+ uint16_t color) {
+ if((x >= 0) && (x < _width) && h) { // X on screen, nonzero height
+ if(h < 0) { // If negative height...
+ y += h + 1; // Move Y to top edge
+ h = -h; // Use positive height
+ }
+ if(y < _height) { // Not off bottom
+ int16_t y2 = y + h - 1;
+ if(y2 >= 0) { // Not off top
+ // Line partly or fully overlaps screen
+ if(y < 0) { y = 0; h = y2 + 1; } // Clip top
+ if(y2 >= _height) { h = _height - y; } // Clip bottom
+ writeFillRectPreclipped(x, y, 1, h, color);
+ }
+ }
+ }
+}
+
+/*!
+ @brief A lower-level version of writeFillRect(). This version requires
+ all inputs are in-bounds, that width and height are positive,
+ and no part extends offscreen. NO EDGE CLIPPING OR REJECTION IS
+ PERFORMED. If higher-level graphics primitives are written to
+ handle their own clipping earlier in the drawing process, this
+ can avoid unnecessary function calls and repeated clipping
+ operations in the lower-level functions.
+ @param x Horizontal position of first corner. MUST BE WITHIN
+ SCREEN BOUNDS.
+ @param y Vertical position of first corner. MUST BE WITHIN SCREEN
+ BOUNDS.
+ @param w Rectangle width in pixels. MUST BE POSITIVE AND NOT
+ EXTEND OFF SCREEN.
+ @param h Rectangle height in pixels. MUST BE POSITIVE AND NOT
+ EXTEND OFF SCREEN.
+ @param color 16-bit fill color in '565' RGB format.
+ @note This is a new function, no graphics primitives besides rects
+ and horizontal/vertical lines are written to best use this yet.
+*/
+inline void Adafruit_SPITFT::writeFillRectPreclipped(int16_t x, int16_t y,
+ int16_t w, int16_t h, uint16_t color) {
+ setAddrWindow(x, y, w, h);
+ writeColor(color, (uint32_t)w * h);
+}
+
+
+// -------------------------------------------------------------------------
+// Ever-so-slightly higher-level graphics operations. Similar to the 'write'
+// functions above, but these contain their own chip-select and SPI
+// transactions as needed (via startWrite(), endWrite()). They're typically
+// used solo -- as graphics primitives in themselves, not invoked by higher-
+// level primitives (which should use the functions above for better
+// performance).
+
+/*!
+ @brief Draw a single pixel to the display at requested coordinates.
+ Self-contained and provides its own transaction as needed
+ (see writePixel(x,y,color) for a lower-level variant).
+ Edge clipping is performed here.
+ @param x Horizontal position (0 = left).
+ @param y Vertical position (0 = top).
+ @param color 16-bit pixel color in '565' RGB format.
+*/
+void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color) {
+ // Clip first...
+ if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
+ // THEN set up transaction (if needed) and draw...
+ startWrite();
+ setAddrWindow(x, y, 1, 1);
+ SPI_WRITE16(color);
+ endWrite();
+ }
+}
+
+/*!
+ @brief Draw a filled rectangle to the display. Self-contained and
+ provides its own transaction as needed (see writeFillRect() or
+ writeFillRectPreclipped() for lower-level variants). Edge
+ clipping and rejection is performed here.
+ @param x Horizontal position of first corner.
+ @param y Vertical position of first corner.
+ @param w Rectangle width in pixels (positive = right of first
+ corner, negative = left of first corner).
+ @param h Rectangle height in pixels (positive = below first
+ corner, negative = above first corner).
+ @param color 16-bit fill color in '565' RGB format.
+ @note This repeats the writeFillRect() function almost in its entirety,
+ with the addition of a transaction start/end. It's done this way
+ (rather than starting the transaction and calling writeFillRect()
+ to handle clipping and so forth) so that the transaction isn't
+ performed at all if the rectangle is rejected. It's really not
+ that much code.
+*/
+void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
+ uint16_t color) {
+ if(w && h) { // Nonzero width and height?
+ if(w < 0) { // If negative width...
+ x += w + 1; // Move X to left edge
+ w = -w; // Use positive width
+ }
+ if(x < _width) { // Not off right
+ if(h < 0) { // If negative height...
+ y += h + 1; // Move Y to top edge
+ h = -h; // Use positive height
+ }
+ if(y < _height) { // Not off bottom
+ int16_t x2 = x + w - 1;
+ if(x2 >= 0) { // Not off left
+ int16_t y2 = y + h - 1;
+ if(y2 >= 0) { // Not off top
+ // Rectangle partly or fully overlaps screen
+ if(x < 0) { x = 0; w = x2 + 1; } // Clip left
+ if(y < 0) { y = 0; h = y2 + 1; } // Clip top
+ if(x2 >= _width) { w = _width - x; } // Clip right
+ if(y2 >= _height) { h = _height - y; } // Clip bottom
+ startWrite();
+ writeFillRectPreclipped(x, y, w, h, color);
+ endWrite();
+ }
+ }
+ }
+ }
+ }
+}
+
+/*!
+ @brief Draw a horizontal line on the display. Self-contained and
+ provides its own transaction as needed (see writeFastHLine() for
+ a lower-level variant). Edge clipping and rejection is performed
+ here.
+ @param x Horizontal position of first point.
+ @param y Vertical position of first point.
+ @param w Line width in pixels (positive = right of first point,
+ negative = point of first corner).
+ @param color 16-bit line color in '565' RGB format.
+ @note This repeats the writeFastHLine() function almost in its
+ entirety, with the addition of a transaction start/end. It's
+ done this way (rather than starting the transaction and calling
+ writeFastHLine() to handle clipping and so forth) so that the
+ transaction isn't performed at all if the line is rejected.
+*/
+void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y, int16_t w,
+ uint16_t color) {
+ if((y >= 0) && (y < _height) && w) { // Y on screen, nonzero width
+ if(w < 0) { // If negative width...
+ x += w + 1; // Move X to left edge
+ w = -w; // Use positive width
+ }
+ if(x < _width) { // Not off right
+ int16_t x2 = x + w - 1;
+ if(x2 >= 0) { // Not off left
+ // Line partly or fully overlaps screen
+ if(x < 0) { x = 0; w = x2 + 1; } // Clip left
+ if(x2 >= _width) { w = _width - x; } // Clip right
+ startWrite();
+ writeFillRectPreclipped(x, y, w, 1, color);
+ endWrite();
+ }
+ }
+ }
+}
+
+/*!
+ @brief Draw a vertical line on the display. Self-contained and provides
+ its own transaction as needed (see writeFastHLine() for a lower-
+ level variant). Edge clipping and rejection is performed here.
+ @param x Horizontal position of first point.
+ @param y Vertical position of first point.
+ @param h Line height in pixels (positive = below first point,
+ negative = above first point).
+ @param color 16-bit line color in '565' RGB format.
+ @note This repeats the writeFastVLine() function almost in its
+ entirety, with the addition of a transaction start/end. It's
+ done this way (rather than starting the transaction and calling
+ writeFastVLine() to handle clipping and so forth) so that the
+ transaction isn't performed at all if the line is rejected.
+*/
+void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y, int16_t h,
+ uint16_t color) {
+ if((x >= 0) && (x < _width) && h) { // X on screen, nonzero height
+ if(h < 0) { // If negative height...
+ y += h + 1; // Move Y to top edge
+ h = -h; // Use positive height
+ }
+ if(y < _height) { // Not off bottom
+ int16_t y2 = y + h - 1;
+ if(y2 >= 0) { // Not off top
+ // Line partly or fully overlaps screen
+ if(y < 0) { y = 0; h = y2 + 1; } // Clip top
+ if(y2 >= _height) { h = _height - y; } // Clip bottom
+ startWrite();
+ writeFillRectPreclipped(x, y, 1, h, color);
+ endWrite();
+ }
+ }
+ }
+}
+
+/*!
+ @brief Essentially writePixel() with a transaction around it. I don't
+ think this is in use by any of our code anymore (believe it was
+ for some older BMP-reading examples), but is kept here in case
+ any user code relies on it. Consider it DEPRECATED.
+ @param color 16-bit pixel color in '565' RGB format.
+*/
+void Adafruit_SPITFT::pushColor(uint16_t color) {
+ startWrite();
+ SPI_WRITE16(color);
+ endWrite();
+}
+
+/*!
+ @brief Draw a 16-bit image (565 RGB) at the specified (x,y) position.
+ For 16-bit display devices; no color reduction performed.
+ Adapted from https://github.com/PaulStoffregen/ILI9341_t3
+ by Marc MERLIN. See examples/pictureEmbed to use this.
+ 5/6/2017: function name and arguments have changed for
+ compatibility with current GFX library and to avoid naming
+ problems in prior implementation. Formerly drawBitmap() with
+ arguments in different order. Handles its own transaction and
+ edge clipping/rejection.
+ @param x Top left corner horizontal coordinate.
+ @param y Top left corner vertical coordinate.
+ @param pcolors Pointer to 16-bit array of pixel values.
+ @param w Width of bitmap in pixels.
+ @param h Height of bitmap in pixels.
+*/
+void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y,
+ uint16_t *pcolors, int16_t w, int16_t h) {
+
+ int16_t x2, y2; // Lower-right coord
+ if(( x >= _width ) || // Off-edge right
+ ( y >= _height) || // " top
+ ((x2 = (x+w-1)) < 0 ) || // " left
+ ((y2 = (y+h-1)) < 0) ) return; // " bottom
+
+ int16_t bx1=0, by1=0, // Clipped top-left within bitmap
+ saveW=w; // Save original bitmap width value
+ if(x < 0) { // Clip left
+ w += x;
+ bx1 = -x;
+ x = 0;
+ }
+ if(y < 0) { // Clip top
+ h += y;
+ by1 = -y;
+ y = 0;
+ }
+ if(x2 >= _width ) w = _width - x; // Clip right
+ if(y2 >= _height) h = _height - y; // Clip bottom
+
+ pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left
+ startWrite();
+ setAddrWindow(x, y, w, h); // Clipped area
+ while(h--) { // For each (clipped) scanline...
+ writePixels(pcolors, w); // Push one (clipped) row
+ pcolors += saveW; // Advance pointer by one full (unclipped) line
+ }
+ endWrite();
+}
+
+
+// -------------------------------------------------------------------------
+// Miscellaneous class member functions that don't draw anything.
+
+/*!
+ @brief Invert the colors of the display (if supported by hardware).
+ Self-contained, no transaction setup required.
+ @param i true = inverted display, false = normal display.
+*/
+void Adafruit_SPITFT::invertDisplay(bool i) {
+ startWrite();
+ writeCommand(i ? invertOnCommand : invertOffCommand);
+ endWrite();
+}
+
+/*!
+ @brief Given 8-bit red, green and blue values, return a 'packed'
+ 16-bit color value in '565' RGB format (5 bits red, 6 bits
+ green, 5 bits blue). This is just a mathematical operation,
+ no hardware is touched.
+ @param red 8-bit red brightnesss (0 = off, 255 = max).
+ @param green 8-bit green brightnesss (0 = off, 255 = max).
+ @param blue 8-bit blue brightnesss (0 = off, 255 = max).
+ @return 'Packed' 16-bit color value (565 format).
+*/
+uint16_t Adafruit_SPITFT::color565(uint8_t red, uint8_t green, uint8_t blue) {
+ return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
+}
+
+/*!
+ @brief Adafruit_SPITFT Send Command handles complete sending of commands and data
+ @param commandByte The Command Byte
+ @param dataBytes A pointer to the Data bytes to send
+ @param numDataBytes The number of bytes we should send
+ */
+void Adafruit_SPITFT::sendCommand(uint8_t commandByte, uint8_t *dataBytes, uint8_t numDataBytes) {
+ SPI_BEGIN_TRANSACTION();
+ if(_cs >= 0) SPI_CS_LOW();
+
+ SPI_DC_LOW(); // Command mode
+ spiWrite(commandByte); // Send the command byte
+
+ SPI_DC_HIGH();
+ for (int i=0; i= 0) SPI_CS_HIGH();
+ SPI_END_TRANSACTION();
+}
+
+/*!
+ @brief Adafruit_SPITFT Send Command handles complete sending of commands and const data
+ @param commandByte The Command Byte
+ @param dataBytes A pointer to the Data bytes to send
+ @param numDataBytes The number of bytes we should send
+ */
+void Adafruit_SPITFT::sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes) {
+ SPI_BEGIN_TRANSACTION();
+ if(_cs >= 0) SPI_CS_LOW();
+
+ SPI_DC_LOW(); // Command mode
+ spiWrite(commandByte); // Send the command byte
+
+ SPI_DC_HIGH();
+ for (int i=0; i= 0) SPI_CS_HIGH();
+ SPI_END_TRANSACTION();
+}
+
+/*!
+ @brief Read 8 bits of data from display configuration memory (not RAM).
+ This is highly undocumented/supported and should be avoided,
+ function is only included because some of the examples use it.
+ @param commandByte
+ The command register to read data from.
+ @param index
+ The byte index into the command to read from.
+ @return Unsigned 8-bit data read from display register.
+ */
+/**************************************************************************/
+uint8_t Adafruit_SPITFT::readcommand8(uint8_t commandByte, uint8_t index) {
+ uint8_t result;
+ startWrite();
+ SPI_DC_LOW(); // Command mode
+ spiWrite(commandByte);
+ SPI_DC_HIGH(); // Data mode
+ do {
+ result = spiRead();
+ } while(index--); // Discard bytes up to index'th
+ endWrite();
+ return result;
+}
+
+// -------------------------------------------------------------------------
+// Lowest-level hardware-interfacing functions. Many of these are inline and
+// compile to different things based on #defines -- typically just a few
+// instructions. Others, not so much, those are not inlined.
+
+/*!
+ @brief Start an SPI transaction if using the hardware SPI interface to
+ the display. If using an earlier version of the Arduino platform
+ (before the addition of SPI transactions), this instead attempts
+ to set up the SPI clock and mode. No action is taken if the
+ connection is not hardware SPI-based. This does NOT include a
+ chip-select operation -- see startWrite() for a function that
+ encapsulated both actions.
+*/
+inline void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION(void) {
+ if(connection == TFT_HARD_SPI) {
+#if defined(SPI_HAS_TRANSACTION)
+ hwspi._spi->beginTransaction(hwspi.settings);
+#else // No transactions, configure SPI manually...
+ #if defined(__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1)
+ hwspi._spi->setClockDivider(SPI_CLOCK_DIV2);
+ #elif defined(__arm__)
+ hwspi._spi->setClockDivider(11);
+ #elif defined(ESP8266) || defined(ESP32)
+ hwspi._spi->setFrequency(hwspi._freq);
+ #elif defined(RASPI) || defined(ARDUINO_ARCH_STM32F1)
+ hwspi._spi->setClock(hwspi._freq);
+ #endif
+ hwspi._spi->setBitOrder(MSBFIRST);
+ hwspi._spi->setDataMode(hwspi._mode);
+#endif // end !SPI_HAS_TRANSACTION
+ }
+}
+
+/*!
+ @brief End an SPI transaction if using the hardware SPI interface to
+ the display. No action is taken if the connection is not
+ hardware SPI-based or if using an earlier version of the Arduino
+ platform (before the addition of SPI transactions). This does
+ NOT include a chip-deselect operation -- see endWrite() for a
+ function that encapsulated both actions.
+*/
+inline void Adafruit_SPITFT::SPI_END_TRANSACTION(void) {
+#if defined(SPI_HAS_TRANSACTION)
+ if(connection == TFT_HARD_SPI) {
+ hwspi._spi->endTransaction();
+ }
+#endif
+}
+
+/*!
+ @brief Issue a single 8-bit value to the display. Chip-select,
+ transaction and data/command selection must have been
+ previously set -- this ONLY issues the byte. This is another of
+ those functions in the library with a now-not-accurate name
+ that's being maintained for compatibility with outside code.
+ This function is used even if display connection is parallel.
+ @param b 8-bit value to write.
+*/
+void Adafruit_SPITFT::spiWrite(uint8_t b) {
+ if(connection == TFT_HARD_SPI) {
+#if defined(__AVR__)
+ AVR_WRITESPI(b);
+#elif defined(ESP8266) || defined(ESP32)
+ hwspi._spi->write(b);
+#else
+ hwspi._spi->transfer(b);
+#endif
+ } else if(connection == TFT_SOFT_SPI) {
+ for(uint8_t bit=0; bit<8; bit++) {
+ if(b & 0x80) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ b <<= 1;
+ SPI_SCK_LOW();
+ }
+ } else { // TFT_PARALLEL
+#if defined(__AVR__)
+ *tft8.writePort = b;
+#elif defined(USE_FAST_PINIO)
+ if(!tft8.wide) *tft8.writePort = b;
+ else *(volatile uint16_t *)tft8.writePort = b;
+#endif
+ TFT_WR_STROBE();
+ }
+}
+
+/*!
+ @brief Write a single command byte to the display. Chip-select and
+ transaction must have been previously set -- this ONLY sets
+ the device to COMMAND mode, issues the byte and then restores
+ DATA mode. There is no corresponding explicit writeData()
+ function -- just use spiWrite().
+ @param cmd 8-bit command to write.
+*/
+void Adafruit_SPITFT::writeCommand(uint8_t cmd) {
+ SPI_DC_LOW();
+ spiWrite(cmd);
+ SPI_DC_HIGH();
+}
+
+/*!
+ @brief Read a single 8-bit value from the display. Chip-select and
+ transaction must have been previously set -- this ONLY reads
+ the byte. This is another of those functions in the library
+ with a now-not-accurate name that's being maintained for
+ compatibility with outside code. This function is used even if
+ display connection is parallel.
+ @return Unsigned 8-bit value read (always zero if USE_FAST_PINIO is
+ not supported by the MCU architecture).
+*/
+uint8_t Adafruit_SPITFT::spiRead(void) {
+ uint8_t b = 0;
+ uint16_t w = 0;
+ if(connection == TFT_HARD_SPI) {
+ return hwspi._spi->transfer((uint8_t)0);
+ } else if(connection == TFT_SOFT_SPI) {
+ if(swspi._miso >= 0) {
+ for(uint8_t i=0; i<8; i++) {
+ SPI_SCK_HIGH();
+ b <<= 1;
+ if(SPI_MISO_READ()) b++;
+ SPI_SCK_LOW();
+ }
+ }
+ return b;
+ } else { // TFT_PARALLEL
+ if(tft8._rd >= 0) {
+#if defined(USE_FAST_PINIO)
+ TFT_RD_LOW(); // Read line LOW
+ #if defined(__AVR__)
+ *tft8.portDir = 0x00; // Set port to input state
+ w = *tft8.readPort; // Read value from port
+ *tft8.portDir = 0xFF; // Restore port to output
+ #else // !__AVR__
+ if(!tft8.wide) { // 8-bit TFT connection
+ #if defined(HAS_PORT_SET_CLR)
+ *tft8.dirClr = 0xFF; // Set port to input state
+ w = *tft8.readPort; // Read value from port
+ *tft8.dirSet = 0xFF; // Restore port to output
+ #else // !HAS_PORT_SET_CLR
+ *tft8.portDir = 0x00; // Set port to input state
+ w = *tft8.readPort; // Read value from port
+ *tft8.portDir = 0xFF; // Restore port to output
+ #endif // end HAS_PORT_SET_CLR
+ } else { // 16-bit TFT connection
+ #if defined(HAS_PORT_SET_CLR)
+ *(volatile uint16_t *)tft8.dirClr = 0xFFFF; // Input state
+ w = *(volatile uint16_t *)tft8.readPort; // 16-bit read
+ *(volatile uint16_t *)tft8.dirSet = 0xFFFF; // Output state
+ #else // !HAS_PORT_SET_CLR
+ *(volatile uint16_t *)tft8.portDir = 0x0000; // Input state
+ w = *(volatile uint16_t *)tft8.readPort; // 16-bit read
+ *(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state
+ #endif // end !HAS_PORT_SET_CLR
+ }
+ TFT_RD_HIGH(); // Read line HIGH
+ #endif // end !__AVR__
+#else // !USE_FAST_PINIO
+ w = 0; // Parallel TFT is NOT SUPPORTED without USE_FAST_PINIO
+#endif // end !USE_FAST_PINIO
+ }
+ return w;
+ }
+}
+
+/*!
+ @brief Set the software (bitbang) SPI MOSI line HIGH.
+*/
+inline void Adafruit_SPITFT::SPI_MOSI_HIGH(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *swspi.mosiPortSet = 1;
+ #else // !KINETISK
+ *swspi.mosiPortSet = swspi.mosiPinMask;
+ #endif
+ #else // !HAS_PORT_SET_CLR
+ *swspi.mosiPort |= swspi.mosiPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(swspi._mosi, HIGH);
+ #if defined(ESP32)
+ for(volatile uint8_t i=0; i<1; i++);
+ #endif // end ESP32
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Set the software (bitbang) SPI MOSI line LOW.
+*/
+inline void Adafruit_SPITFT::SPI_MOSI_LOW(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *swspi.mosiPortClr = 1;
+ #else // !KINETISK
+ *swspi.mosiPortClr = swspi.mosiPinMask;
+ #endif
+ #else // !HAS_PORT_SET_CLR
+ *swspi.mosiPort &= swspi.mosiPinMaskClr;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(swspi._mosi, LOW);
+ #if defined(ESP32)
+ for(volatile uint8_t i=0; i<1; i++);
+ #endif // end ESP32
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Set the software (bitbang) SPI SCK line HIGH.
+*/
+inline void Adafruit_SPITFT::SPI_SCK_HIGH(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *swspi.sckPortSet = 1;
+ #else // !KINETISK
+ *swspi.sckPortSet = swspi.sckPinMask;
+ #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
+ for(volatile uint8_t i=0; i<1; i++);
+ #endif
+ #endif
+ #else // !HAS_PORT_SET_CLR
+ *swspi.sckPort |= swspi.sckPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(swspi._sck, HIGH);
+ #if defined(ESP32)
+ for(volatile uint8_t i=0; i<1; i++);
+ #endif // end ESP32
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Set the software (bitbang) SPI SCK line LOW.
+*/
+inline void Adafruit_SPITFT::SPI_SCK_LOW(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *swspi.sckPortClr = 1;
+ #else // !KINETISK
+ *swspi.sckPortClr = swspi.sckPinMask;
+ #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
+ for(volatile uint8_t i=0; i<1; i++);
+ #endif
+ #endif
+ #else // !HAS_PORT_SET_CLR
+ *swspi.sckPort &= swspi.sckPinMaskClr;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(swspi._sck, LOW);
+ #if defined(ESP32)
+ for(volatile uint8_t i=0; i<1; i++);
+ #endif // end ESP32
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Read the state of the software (bitbang) SPI MISO line.
+ @return true if HIGH, false if LOW.
+*/
+inline bool Adafruit_SPITFT::SPI_MISO_READ(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(KINETISK)
+ return *swspi.misoPort;
+ #else // !KINETISK
+ return *swspi.misoPort & swspi.misoPinMask;
+ #endif // end !KINETISK
+#else // !USE_FAST_PINIO
+ return digitalRead(swspi._miso);
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Issue a single 16-bit value to the display. Chip-select,
+ transaction and data/command selection must have been
+ previously set -- this ONLY issues the word. Despite the name,
+ this function is used even if display connection is parallel;
+ name was maintaned for backward compatibility. Naming is also
+ not consistent with the 8-bit version, spiWrite(). Sorry about
+ that. Again, staying compatible with outside code.
+ @param w 16-bit value to write.
+*/
+void Adafruit_SPITFT::SPI_WRITE16(uint16_t w) {
+ if(connection == TFT_HARD_SPI) {
+#if defined(__AVR__)
+ AVR_WRITESPI(w >> 8);
+ AVR_WRITESPI(w);
+#elif defined(ESP8266) || defined(ESP32)
+ hwspi._spi->write16(w);
+#else
+ hwspi._spi->transfer(w >> 8);
+ hwspi._spi->transfer(w);
+#endif
+ } else if(connection == TFT_SOFT_SPI) {
+ for(uint8_t bit=0; bit<16; bit++) {
+ if(w & 0x8000) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ SPI_SCK_LOW();
+ w <<= 1;
+ }
+ } else { // TFT_PARALLEL
+#if defined(__AVR__)
+ *tft8.writePort = w >> 8;
+ TFT_WR_STROBE();
+ *tft8.writePort = w;
+#elif defined(USE_FAST_PINIO)
+ if(!tft8.wide) {
+ *tft8.writePort = w >> 8;
+ TFT_WR_STROBE();
+ *tft8.writePort = w;
+ } else {
+ *(volatile uint16_t *)tft8.writePort = w;
+ }
+#endif
+ TFT_WR_STROBE();
+ }
+}
+
+/*!
+ @brief Issue a single 32-bit value to the display. Chip-select,
+ transaction and data/command selection must have been
+ previously set -- this ONLY issues the longword. Despite the
+ name, this function is used even if display connection is
+ parallel; name was maintaned for backward compatibility. Naming
+ is also not consistent with the 8-bit version, spiWrite().
+ Sorry about that. Again, staying compatible with outside code.
+ @param l 32-bit value to write.
+*/
+void Adafruit_SPITFT::SPI_WRITE32(uint32_t l) {
+ if(connection == TFT_HARD_SPI) {
+#if defined(__AVR__)
+ AVR_WRITESPI(l >> 24);
+ AVR_WRITESPI(l >> 16);
+ AVR_WRITESPI(l >> 8);
+ AVR_WRITESPI(l );
+#elif defined(ESP8266) || defined(ESP32)
+ hwspi._spi->write32(l);
+#else
+ hwspi._spi->transfer(l >> 24);
+ hwspi._spi->transfer(l >> 16);
+ hwspi._spi->transfer(l >> 8);
+ hwspi._spi->transfer(l);
+#endif
+ } else if(connection == TFT_SOFT_SPI) {
+ for(uint8_t bit=0; bit<32; bit++) {
+ if(l & 0x80000000) SPI_MOSI_HIGH();
+ else SPI_MOSI_LOW();
+ SPI_SCK_HIGH();
+ SPI_SCK_LOW();
+ l <<= 1;
+ }
+ } else { // TFT_PARALLEL
+#if defined(__AVR__)
+ *tft8.writePort = l >> 24;
+ TFT_WR_STROBE();
+ *tft8.writePort = l >> 16;
+ TFT_WR_STROBE();
+ *tft8.writePort = l >> 8;
+ TFT_WR_STROBE();
+ *tft8.writePort = l;
+#elif defined(USE_FAST_PINIO)
+ if(!tft8.wide) {
+ *tft8.writePort = l >> 24;
+ TFT_WR_STROBE();
+ *tft8.writePort = l >> 16;
+ TFT_WR_STROBE();
+ *tft8.writePort = l >> 8;
+ TFT_WR_STROBE();
+ *tft8.writePort = l;
+ } else {
+ *(volatile uint16_t *)tft8.writePort = l >> 16;
+ TFT_WR_STROBE();
+ *(volatile uint16_t *)tft8.writePort = l;
+ }
+#endif
+ TFT_WR_STROBE();
+ }
+}
+
+/*!
+ @brief Set the WR line LOW, then HIGH. Used for parallel-connected
+ interfaces when writing data.
+*/
+inline void Adafruit_SPITFT::TFT_WR_STROBE(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *tft8.wrPortClr = 1;
+ *tft8.wrPortSet = 1;
+ #else // !KINETISK
+ *tft8.wrPortClr = tft8.wrPinMask;
+ *tft8.wrPortSet = tft8.wrPinMask;
+ #endif // end !KINETISK
+ #else // !HAS_PORT_SET_CLR
+ *tft8.wrPort &= tft8.wrPinMaskClr;
+ *tft8.wrPort |= tft8.wrPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(tft8._wr, LOW);
+ digitalWrite(tft8._wr, HIGH);
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Set the RD line HIGH. Used for parallel-connected interfaces
+ when reading data.
+*/
+inline void Adafruit_SPITFT::TFT_RD_HIGH(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ *tft8.rdPortSet = tft8.rdPinMask;
+ #else // !HAS_PORT_SET_CLR
+ *tft8.rdPort |= tft8.rdPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(tft8._rd, HIGH);
+#endif // end !USE_FAST_PINIO
+}
+
+/*!
+ @brief Set the RD line LOW. Used for parallel-connected interfaces
+ when reading data.
+*/
+inline void Adafruit_SPITFT::TFT_RD_LOW(void) {
+#if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ *tft8.rdPortClr = tft8.rdPinMask;
+ #else // !HAS_PORT_SET_CLR
+ *tft8.rdPort &= tft8.rdPinMaskClr;
+ #endif // end !HAS_PORT_SET_CLR
+#else // !USE_FAST_PINIO
+ digitalWrite(tft8._rd, LOW);
+#endif // end !USE_FAST_PINIO
+}
+
+#endif // end __AVR_ATtiny85__
diff --git a/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.h b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.h
new file mode 100644
index 000000000..33a911774
--- /dev/null
+++ b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT.h
@@ -0,0 +1,519 @@
+/*!
+ * @file Adafruit_SPITFT.h
+ *
+ * Part of Adafruit's GFX graphics library. Originally this class was
+ * written to handle a range of color TFT displays connected via SPI,
+ * but over time this library and some display-specific subclasses have
+ * mutated to include some color OLEDs as well as parallel-interfaced
+ * displays. The name's been kept for the sake of older code.
+ *
+ * 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 "ladyada" Fried for Adafruit Industries,
+ * with contributions from the open source community.
+ *
+ * BSD license, all text here must be included in any redistribution.
+ */
+
+#ifndef _ADAFRUIT_SPITFT_H_
+#define _ADAFRUIT_SPITFT_H_
+
+#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
+
+#include
+#include "Adafruit_GFX.h"
+
+// HARDWARE CONFIG ---------------------------------------------------------
+
+#if defined(__AVR__)
+ typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit
+ #define USE_FAST_PINIO ///< Use direct PORT register access
+#elif defined(ARDUINO_STM32_FEATHER) // WICED
+ typedef class HardwareSPI SPIClass; ///< SPI is a bit odd on WICED
+ typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
+#elif defined(__arm__)
+ #if defined(ARDUINO_ARCH_SAMD)
+ // Adafruit M0, M4
+ typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
+ #define USE_FAST_PINIO ///< Use direct PORT register access
+ #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
+ #elif defined(CORE_TEENSY)
+ // PJRC Teensy 4.x
+ #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
+ typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
+ // PJRC Teensy 3.x
+ #else
+ typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit
+ #endif
+ #define USE_FAST_PINIO ///< Use direct PORT register access
+ #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
+ #else
+ // Arduino Due?
+ typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
+ // USE_FAST_PINIO not available here (yet)...Due has a totally different
+ // GPIO register set and will require some changes elsewhere (e.g. in
+ // constructors especially).
+ #endif
+#else // !ARM
+ // Probably ESP8266 or ESP32. USE_FAST_PINIO is not available here (yet)
+ // but don't worry about it too much...the digitalWrite() implementation
+ // on these platforms is reasonably efficient and already RAM-resident,
+ // only gotcha then is no parallel connection support for now.
+ typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
+#endif // end !ARM
+typedef volatile ADAGFX_PORT_t* PORTreg_t; ///< PORT register type
+
+#if defined(__AVR__)
+ #define DEFAULT_SPI_FREQ 8000000L ///< Hardware SPI default speed
+#else
+ #define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed
+#endif
+
+#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || defined(ADAFRUIT_PYGAMER_M4_EXPRESS)
+ #define USE_SPI_DMA ///< Auto DMA if using PyPortal
+#else
+ //#define USE_SPI_DMA ///< If set, use DMA if available
+#endif
+// Another "oops" name -- this now also handles parallel DMA.
+// If DMA is enabled, Arduino sketch MUST #include
+// Estimated RAM usage:
+// 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis,
+// e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes.
+
+#if !defined(ARDUINO_ARCH_SAMD)
+ #undef USE_SPI_DMA ///< DMA currently for SAMD chips only
+#endif
+
+#if defined(USE_SPI_DMA)
+ #pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
+ #include
+#endif
+
+// This is kind of a kludge. Needed a way to disambiguate the software SPI
+// and parallel constructors via their argument lists. Originally tried a
+// bool as the first argument to the parallel constructor (specifying 8-bit
+// vs 16-bit interface) but the compiler regards this as equivalent to an
+// integer and thus still ambiguous. SO...the parallel constructor requires
+// an enumerated type as the first argument: tft8 (for 8-bit parallel) or
+// tft16 (for 16-bit)...even though 16-bit isn't fully implemented or tested
+// and might never be, still needed that disambiguation from soft SPI.
+enum tftBusWidth { tft8bitbus, tft16bitbus }; ///< For first arg to parallel constructor
+
+// CLASS DEFINITION --------------------------------------------------------
+
+/*!
+ @brief Adafruit_SPITFT is an intermediary class between Adafruit_GFX
+ and various hardware-specific subclasses for different displays.
+ It handles certain operations that are common to a range of
+ displays (address window, area fills, etc.). Originally these were
+ all color TFT displays interfaced via SPI, but it's since expanded
+ to include color OLEDs and parallel-interfaced TFTs. THE NAME HAS
+ BEEN KEPT TO AVOID BREAKING A LOT OF SUBCLASSES AND EXAMPLE CODE.
+ Many of the class member functions similarly live on with names
+ that don't necessarily accurately describe what they're doing,
+ again to avoid breaking a lot of other code. If in doubt, read
+ the comments.
+*/
+class Adafruit_SPITFT : public Adafruit_GFX {
+
+ public:
+
+ // CONSTRUCTORS --------------------------------------------------------
+
+ // Software SPI constructor: expects width & height (at default rotation
+ // setting 0), 4 signal pins (cs, dc, mosi, sclk), 2 optional pins
+ // (reset, miso). cs argument is required but can be -1 if unused --
+ // rather than moving it to the optional arguments, it was done this way
+ // to avoid breaking existing code (-1 option was a later addition).
+ Adafruit_SPITFT(uint16_t w, uint16_t h,
+ int8_t cs, int8_t dc, int8_t mosi, int8_t sck,
+ int8_t rst = -1, int8_t miso = -1);
+
+ // Hardware SPI constructor using the default SPI port: expects width &
+ // height (at default rotation setting 0), 2 signal pins (cs, dc),
+ // optional reset pin. cs is required but can be -1 if unused -- rather
+ // than moving it to the optional arguments, it was done this way to
+ // avoid breaking existing code (-1 option was a later addition).
+ Adafruit_SPITFT(uint16_t w, uint16_t h,
+ int8_t cs, int8_t dc, int8_t rst = -1);
+
+#if !defined(ESP8266) // See notes in .cpp
+ // Hardware SPI constructor using an arbitrary SPI peripheral: expects
+ // width & height (rotation 0), SPIClass pointer, 2 signal pins (cs, dc)
+ // and optional reset pin. cs is required but can be -1 if unused.
+ Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass,
+ int8_t cs, int8_t dc, int8_t rst = -1);
+#endif // end !ESP8266
+
+ // Parallel constructor: expects width & height (rotation 0), flag
+ // indicating whether 16-bit (true) or 8-bit (false) interface, 3 signal
+ // pins (d0, wr, dc), 3 optional pins (cs, rst, rd). 16-bit parallel
+ // isn't even fully implemented but the 'wide' flag was added as a
+ // required argument to avoid ambiguity with other constructors.
+ Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth,
+ int8_t d0, int8_t wr, int8_t dc,
+ int8_t cs = -1, int8_t rst = -1, int8_t rd = -1);
+
+ // CLASS MEMBER FUNCTIONS ----------------------------------------------
+
+ // These first two functions MUST be declared by subclasses:
+
+ /*!
+ @brief Display-specific initialization function.
+ @param freq SPI frequency, in hz (or 0 for default or unused).
+ */
+ virtual void begin(uint32_t freq) = 0;
+
+ /*!
+ @brief Set up the specific display hardware's "address window"
+ for subsequent pixel-pushing operations.
+ @param x Leftmost pixel of area to be drawn (MUST be within
+ display bounds at current rotation setting).
+ @param y Topmost pixel of area to be drawn (MUST be within
+ display bounds at current rotation setting).
+ @param w Width of area to be drawn, in pixels (MUST be >0 and,
+ added to x, within display bounds at current rotation).
+ @param h Height of area to be drawn, in pixels (MUST be >0 and,
+ added to x, within display bounds at current rotation).
+ */
+ virtual void setAddrWindow(
+ uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0;
+
+ // Remaining functions do not need to be declared in subclasses
+ // unless they wish to provide hardware-specific optimizations.
+ // Brief comments here...documented more thoroughly in .cpp file.
+
+ // Subclass' begin() function invokes this to initialize hardware.
+ // freq=0 to use default SPI speed. spiMode must be one of the SPI_MODEn
+ // values defined in SPI.h, which are NOT the same as 0 for SPI_MODE0,
+ // 1 for SPI_MODE1, etc...use ONLY the SPI_MODEn defines! Only!
+ // Name is outdated (interface may be parallel) but for compatibility:
+ void initSPI(uint32_t freq = 0, uint8_t spiMode = SPI_MODE0);
+ // Chip select and/or hardware SPI transaction start as needed:
+ void startWrite(void);
+ // Chip deselect and/or hardware SPI transaction end as needed:
+ void endWrite(void);
+ void sendCommand(uint8_t commandByte, uint8_t *dataBytes = NULL, uint8_t numDataBytes = 0);
+ void sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes);
+ uint8_t readcommand8(uint8_t commandByte, uint8_t index = 0);
+
+ // These functions require a chip-select and/or SPI transaction
+ // around them. Higher-level graphics primitives might start a
+ // single transaction and then make multiple calls to these functions
+ // (e.g. circle or text rendering might make repeated lines or rects)
+ // before ending the transaction. It's more efficient than starting a
+ // transaction every time.
+ void writePixel(int16_t x, int16_t y, uint16_t color);
+ void writePixels(uint16_t *colors, uint32_t len,
+ bool block=true, bool bigEndian=false);
+ void writeColor(uint16_t color, uint32_t len);
+ void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h,
+ uint16_t color);
+ void writeFastHLine(int16_t x, int16_t y, int16_t w,
+ uint16_t color);
+ void writeFastVLine(int16_t x, int16_t y, int16_t h,
+ uint16_t color);
+ // This is a new function, similar to writeFillRect() except that
+ // all arguments MUST be onscreen, sorted and clipped. If higher-level
+ // primitives can handle their own sorting/clipping, it avoids repeating
+ // such operations in the low-level code, making it potentially faster.
+ // CALLING THIS WITH UNCLIPPED OR NEGATIVE VALUES COULD BE DISASTROUS.
+ inline void writeFillRectPreclipped(int16_t x, int16_t y,
+ int16_t w, int16_t h, uint16_t color);
+ // Another new function, companion to the new non-blocking
+ // writePixels() variant.
+ void dmaWait(void);
+
+
+ // These functions are similar to the 'write' functions above, but with
+ // a chip-select and/or SPI transaction built-in. They're typically used
+ // solo -- that is, as graphics primitives in themselves, not invoked by
+ // higher-level primitives (which should use the functions above).
+ void drawPixel(int16_t x, int16_t y, uint16_t color);
+ void fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
+ uint16_t color);
+ void drawFastHLine(int16_t x, int16_t y, int16_t w,
+ uint16_t color);
+ void drawFastVLine(int16_t x, int16_t y, int16_t h,
+ uint16_t color);
+ // A single-pixel push encapsulated in a transaction. I don't think
+ // this is used anymore (BMP demos might've used it?) but is provided
+ // for backward compatibility, consider it deprecated:
+ void pushColor(uint16_t color);
+
+ using Adafruit_GFX::drawRGBBitmap; // Check base class first
+ void drawRGBBitmap(int16_t x, int16_t y,
+ uint16_t *pcolors, int16_t w, int16_t h);
+
+ void invertDisplay(bool i);
+ uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
+
+ // Despite parallel additions, function names kept for compatibility:
+ void spiWrite(uint8_t b); // Write single byte as DATA
+ void writeCommand(uint8_t cmd); // Write single byte as COMMAND
+ uint8_t spiRead(void); // Read single byte of data
+
+ // Most of these low-level functions were formerly macros in
+ // Adafruit_SPITFT_Macros.h. Some have been made into inline functions
+ // to avoid macro mishaps. Despite the addition of code for a parallel
+ // display interface, the names have been kept for backward
+ // compatibility (some subclasses may be invoking these):
+ void SPI_WRITE16(uint16_t w); // Not inline
+ void SPI_WRITE32(uint32_t l); // Not inline
+ // Old code had both a spiWrite16() function and SPI_WRITE16 macro
+ // in addition to the SPI_WRITE32 macro. The latter two have been
+ // made into functions here, and spiWrite16() removed (use SPI_WRITE16()
+ // instead). It looks like most subclasses had gotten comfortable with
+ // SPI_WRITE16 and SPI_WRITE32 anyway so those names were kept rather
+ // than the less-obnoxious camelcase variants, oh well.
+
+ // Placing these functions entirely in the class definition inlines
+ // them implicitly them while allowing their use in other code:
+
+ /*!
+ @brief Set the chip-select line HIGH. Does NOT check whether CS pin
+ is set (>=0), that should be handled in calling function.
+ Despite function name, this is used even if the display
+ connection is parallel.
+ */
+ void SPI_CS_HIGH(void) {
+ #if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *csPortSet = 1;
+ #else // !KINETISK
+ *csPortSet = csPinMask;
+ #endif // end !KINETISK
+ #else // !HAS_PORT_SET_CLR
+ *csPort |= csPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+ #else // !USE_FAST_PINIO
+ digitalWrite(_cs, HIGH);
+ #endif // end !USE_FAST_PINIO
+ }
+
+ /*!
+ @brief Set the chip-select line LOW. Does NOT check whether CS pin
+ is set (>=0), that should be handled in calling function.
+ Despite function name, this is used even if the display
+ connection is parallel.
+ */
+ void SPI_CS_LOW(void) {
+ #if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *csPortClr = 1;
+ #else // !KINETISK
+ *csPortClr = csPinMask;
+ #endif // end !KINETISK
+ #else // !HAS_PORT_SET_CLR
+ *csPort &= csPinMaskClr;
+ #endif // end !HAS_PORT_SET_CLR
+ #else // !USE_FAST_PINIO
+ digitalWrite(_cs, LOW);
+ #endif // end !USE_FAST_PINIO
+ }
+
+ /*!
+ @brief Set the data/command line HIGH (data mode).
+ */
+ void SPI_DC_HIGH(void) {
+ #if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *dcPortSet = 1;
+ #else // !KINETISK
+ *dcPortSet = dcPinMask;
+ #endif // end !KINETISK
+ #else // !HAS_PORT_SET_CLR
+ *dcPort |= dcPinMaskSet;
+ #endif // end !HAS_PORT_SET_CLR
+ #else // !USE_FAST_PINIO
+ digitalWrite(_dc, HIGH);
+ #endif // end !USE_FAST_PINIO
+ }
+
+ /*!
+ @brief Set the data/command line LOW (command mode).
+ */
+ void SPI_DC_LOW(void) {
+ #if defined(USE_FAST_PINIO)
+ #if defined(HAS_PORT_SET_CLR)
+ #if defined(KINETISK)
+ *dcPortClr = 1;
+ #else // !KINETISK
+ *dcPortClr = dcPinMask;
+ #endif // end !KINETISK
+ #else // !HAS_PORT_SET_CLR
+ *dcPort &= dcPinMaskClr;
+ #endif // end !HAS_PORT_SET_CLR
+ #else // !USE_FAST_PINIO
+ digitalWrite(_dc, LOW);
+ #endif // end !USE_FAST_PINIO
+ }
+
+ protected:
+
+ // A few more low-level member functions -- some may have previously
+ // been macros. Shouldn't have a need to access these externally, so
+ // they've been moved to the protected section. Additionally, they're
+ // declared inline here and the code is in the .cpp file, since outside
+ // code doesn't need to see these.
+ inline void SPI_MOSI_HIGH(void);
+ inline void SPI_MOSI_LOW(void);
+ inline void SPI_SCK_HIGH(void);
+ inline void SPI_SCK_LOW(void);
+ inline bool SPI_MISO_READ(void);
+ inline void SPI_BEGIN_TRANSACTION(void);
+ inline void SPI_END_TRANSACTION(void);
+ inline void TFT_WR_STROBE(void); // Parallel interface write strobe
+ inline void TFT_RD_HIGH(void); // Parallel interface read high
+ inline void TFT_RD_LOW(void); // Parallel interface read low
+
+ // CLASS INSTANCE VARIABLES --------------------------------------------
+
+ // Here be dragons! There's a big union of three structures here --
+ // one each for hardware SPI, software (bitbang) SPI, and parallel
+ // interfaces. This is to save some memory, since a display's connection
+ // will be only one of these. The order of some things is a little weird
+ // in an attempt to get values to align and pack better in RAM.
+
+#if defined(USE_FAST_PINIO)
+#if defined(HAS_PORT_SET_CLR)
+ PORTreg_t csPortSet; ///< PORT register for chip select SET
+ PORTreg_t csPortClr; ///< PORT register for chip select CLEAR
+ PORTreg_t dcPortSet; ///< PORT register for data/command SET
+ PORTreg_t dcPortClr; ///< PORT register for data/command CLEAR
+#else // !HAS_PORT_SET_CLR
+ PORTreg_t csPort; ///< PORT register for chip select
+ PORTreg_t dcPort; ///< PORT register for data/command
+#endif // end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+#if defined(__cplusplus) && (__cplusplus >= 201100)
+ union {
+#endif
+ struct { // Values specific to HARDWARE SPI:
+ SPIClass *_spi; ///< SPI class pointer
+#if defined(SPI_HAS_TRANSACTION)
+ SPISettings settings; ///< SPI transaction settings
+#else
+ uint32_t _freq; ///< SPI bitrate (if no SPI transactions)
+#endif
+ uint32_t _mode; ///< SPI data mode (transactions or no)
+ } hwspi; ///< Hardware SPI values
+ struct { // Values specific to SOFTWARE SPI:
+#if defined(USE_FAST_PINIO)
+ PORTreg_t misoPort; ///< PORT (PIN) register for MISO
+#if defined(HAS_PORT_SET_CLR)
+ PORTreg_t mosiPortSet; ///< PORT register for MOSI SET
+ PORTreg_t mosiPortClr; ///< PORT register for MOSI CLEAR
+ PORTreg_t sckPortSet; ///< PORT register for SCK SET
+ PORTreg_t sckPortClr; ///< PORT register for SCK CLEAR
+ #if !defined(KINETISK)
+ ADAGFX_PORT_t mosiPinMask; ///< Bitmask for MOSI
+ ADAGFX_PORT_t sckPinMask; ///< Bitmask for SCK
+ #endif // end !KINETISK
+#else // !HAS_PORT_SET_CLR
+ PORTreg_t mosiPort; ///< PORT register for MOSI
+ PORTreg_t sckPort; ///< PORT register for SCK
+ ADAGFX_PORT_t mosiPinMaskSet; ///< Bitmask for MOSI SET (OR)
+ ADAGFX_PORT_t mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND)
+ ADAGFX_PORT_t sckPinMaskSet; ///< Bitmask for SCK SET (OR bitmask)
+ ADAGFX_PORT_t sckPinMaskClr; ///< Bitmask for SCK CLEAR (AND)
+#endif // end HAS_PORT_SET_CLR
+ #if !defined(KINETISK)
+ ADAGFX_PORT_t misoPinMask; ///< Bitmask for MISO
+ #endif // end !KINETISK
+#endif // end USE_FAST_PINIO
+ int8_t _mosi; ///< MOSI pin #
+ int8_t _miso; ///< MISO pin #
+ int8_t _sck; ///< SCK pin #
+ } swspi; ///< Software SPI values
+ struct { // Values specific to 8-bit parallel:
+#if defined(USE_FAST_PINIO)
+
+ #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
+ volatile uint32_t *writePort; ///< PORT register for DATA WRITE
+ volatile uint32_t *readPort; ///< PORT (PIN) register for DATA READ
+ #else
+ volatile uint8_t *writePort; ///< PORT register for DATA WRITE
+ volatile uint8_t *readPort; ///< PORT (PIN) register for DATA READ
+ #endif
+#if defined(HAS_PORT_SET_CLR)
+ // Port direction register pointers are always 8-bit regardless of
+ // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits.
+ #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
+ volatile uint32_t *dirSet; ///< PORT byte data direction SET
+ volatile uint32_t *dirClr; ///< PORT byte data direction CLEAR
+ #else
+ volatile uint8_t *dirSet; ///< PORT byte data direction SET
+ volatile uint8_t *dirClr; ///< PORT byte data direction CLEAR
+ #endif
+ PORTreg_t wrPortSet; ///< PORT register for write strobe SET
+ PORTreg_t wrPortClr; ///< PORT register for write strobe CLEAR
+ PORTreg_t rdPortSet; ///< PORT register for read strobe SET
+ PORTreg_t rdPortClr; ///< PORT register for read strobe CLEAR
+ #if !defined(KINETISK)
+ ADAGFX_PORT_t wrPinMask; ///< Bitmask for write strobe
+ #endif // end !KINETISK
+ ADAGFX_PORT_t rdPinMask; ///< Bitmask for read strobe
+#else // !HAS_PORT_SET_CLR
+ // Port direction register pointer is always 8-bit regardless of
+ // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits.
+ volatile uint8_t *portDir; ///< PORT direction register
+ PORTreg_t wrPort; ///< PORT register for write strobe
+ PORTreg_t rdPort; ///< PORT register for read strobe
+ ADAGFX_PORT_t wrPinMaskSet; ///< Bitmask for write strobe SET (OR)
+ ADAGFX_PORT_t wrPinMaskClr; ///< Bitmask for write strobe CLEAR (AND)
+ ADAGFX_PORT_t rdPinMaskSet; ///< Bitmask for read strobe SET (OR)
+ ADAGFX_PORT_t rdPinMaskClr; ///< Bitmask for read strobe CLEAR (AND)
+#endif // end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+ int8_t _d0; ///< Data pin 0 #
+ int8_t _wr; ///< Write strobe pin #
+ int8_t _rd; ///< Read strobe pin # (or -1)
+ bool wide = 0; ///< If true, is 16-bit interface
+ } tft8; ///< Parallel interface settings
+#if defined(__cplusplus) && (__cplusplus >= 201100)
+ }; ///< Only one interface is active
+#endif
+#if defined(USE_SPI_DMA) // Used by hardware SPI and tft8
+ Adafruit_ZeroDMA dma; ///< DMA instance
+ DmacDescriptor *dptr = NULL; ///< 1st descriptor
+ DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list
+ uint16_t *pixelBuf[2]; ///< Working buffers
+ uint16_t maxFillLen; ///< Max pixels per DMA xfer
+ uint16_t lastFillColor = 0; ///< Last color used w/fill
+ uint32_t lastFillLen = 0; ///< # of pixels w/last fill
+ uint8_t onePixelBuf; ///< For hi==lo fill
+#endif
+#if defined(USE_FAST_PINIO)
+#if defined(HAS_PORT_SET_CLR)
+ #if !defined(KINETISK)
+ ADAGFX_PORT_t csPinMask; ///< Bitmask for chip select
+ ADAGFX_PORT_t dcPinMask; ///< Bitmask for data/command
+ #endif // end !KINETISK
+#else // !HAS_PORT_SET_CLR
+ ADAGFX_PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR)
+ ADAGFX_PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
+ ADAGFX_PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR)
+ ADAGFX_PORT_t dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
+#endif // end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+ uint8_t connection; ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc.
+ int8_t _rst; ///< Reset pin # (or -1)
+ int8_t _cs; ///< Chip select pin # (or -1)
+ int8_t _dc; ///< Data/command pin #
+
+ int16_t _xstart = 0; ///< Internal framebuffer X offset
+ int16_t _ystart = 0; ///< Internal framebuffer Y offset
+ uint8_t invertOnCommand = 0; ///< Command to enable invert mode
+ uint8_t invertOffCommand = 0; ///< Command to disable invert mode
+
+ uint32_t _freq = 0; ///< Dummy var to keep subclasses happy
+};
+
+#endif // end __AVR_ATtiny85__
+#endif // end _ADAFRUIT_SPITFT_H_
diff --git a/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT_Macros.h b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT_Macros.h
new file mode 100644
index 000000000..fcd6253e6
--- /dev/null
+++ b/lib/Adafruit-GFX-Library-1.5.6/Adafruit_SPITFT_Macros.h
@@ -0,0 +1,6 @@
+// THIS FILE INTENTIONALLY LEFT BLANK.
+
+// Macros previously #defined here have been made into (mostly) inline
+// functions in the Adafruit_SPITFT class. Other libraries might still
+// contain code trying to #include this header file, so until everything's
+// updated this file still exists (but doing nothing) to avoid trouble.
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMono9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMono9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBold9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBold9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoBoldOblique9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoBoldOblique9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeMonoOblique9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeMonoOblique9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSans9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSans9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBold9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBold9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansBoldOblique9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansBoldOblique9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSansOblique9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSansOblique9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerif9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerif9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBold9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBold9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifBoldItalic9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifBoldItalic9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic12pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic12pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic12pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic12pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic18pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic18pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic18pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic18pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic24pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic24pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic24pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic24pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic9pt7b.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic9pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/FreeSerifItalic9pt7b.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/FreeSerifItalic9pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/Org_01.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/Org_01.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/Org_01.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/Org_01.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/Picopixel.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/Picopixel.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/Picopixel.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/Picopixel.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/Tiny3x3a2pt7b b/lib/Adafruit-GFX-Library-1.5.6/Fonts/Tiny3x3a2pt7b.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/Tiny3x3a2pt7b
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/Tiny3x3a2pt7b.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/Fonts/TomThumb.h b/lib/Adafruit-GFX-Library-1.5.6/Fonts/TomThumb.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/Fonts/TomThumb.h
rename to lib/Adafruit-GFX-Library-1.5.6/Fonts/TomThumb.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/README.md b/lib/Adafruit-GFX-Library-1.5.6/README.md
similarity index 94%
rename from lib/Adafruit-GFX-Library-1.2.9/README.md
rename to lib/Adafruit-GFX-Library-1.5.6/README.md
index cd27c33b6..37751c734 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/README.md
+++ b/lib/Adafruit-GFX-Library-1.5.6/README.md
@@ -1,4 +1,4 @@
-# Adafruit GFX Library # [](https://travis-ci.org/adafruit/Adafruit_GFX)
+# Adafruit GFX Library [](https://travis-ci.com/adafruit/Adafruit-GFX-Library)
This is the core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.). It needs to be paired with a hardware-specific library for each display device we carry (to handle the lower-level functions).
diff --git a/lib/Adafruit-GFX-Library-1.2.9/examples/mock_ili9341/mock_ili9341.ino b/lib/Adafruit-GFX-Library-1.5.6/examples/mock_ili9341/mock_ili9341.ino
similarity index 99%
rename from lib/Adafruit-GFX-Library-1.2.9/examples/mock_ili9341/mock_ili9341.ino
rename to lib/Adafruit-GFX-Library-1.5.6/examples/mock_ili9341/mock_ili9341.ino
index 3154d4095..d14183904 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/examples/mock_ili9341/mock_ili9341.ino
+++ b/lib/Adafruit-GFX-Library-1.5.6/examples/mock_ili9341/mock_ili9341.ino
@@ -362,4 +362,4 @@ unsigned long testFilledRoundRects() {
}
return micros() - start;
-}
\ No newline at end of file
+}
diff --git a/lib/Adafruit-GFX-Library-1.2.9/fontconvert/Makefile b/lib/Adafruit-GFX-Library-1.5.6/fontconvert/Makefile
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/fontconvert/Makefile
rename to lib/Adafruit-GFX-Library-1.5.6/fontconvert/Makefile
diff --git a/lib/Adafruit-GFX-Library-1.2.9/fontconvert/fontconvert.c b/lib/Adafruit-GFX-Library-1.5.6/fontconvert/fontconvert.c
similarity index 94%
rename from lib/Adafruit-GFX-Library-1.2.9/fontconvert/fontconvert.c
rename to lib/Adafruit-GFX-Library-1.5.6/fontconvert/fontconvert.c
index bfd21103c..b8a6ac944 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/fontconvert/fontconvert.c
+++ b/lib/Adafruit-GFX-Library-1.5.6/fontconvert/fontconvert.c
@@ -16,12 +16,14 @@ Keep 7-bit fonts around as an option in that case, more compact.
See notes at end for glyph nomenclature & other tidbits.
*/
+#ifndef ARDUINO
#include
#include
#include
#include
#include FT_GLYPH_H
+#include FT_TRUETYPE_DRIVER_H
#include "../gfxfont.h" // Adafruit_GFX font structures
#define DPI 141 // Approximate res. of Adafruit 2.8" TFT
@@ -116,6 +118,16 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "FreeType init error: %d", err);
return err;
}
+
+ // Use TrueType engine version 35, without subpixel rendering.
+ // This improves clarity of fonts since this library does not
+ // support rendering multiple levels of gray in a glyph.
+ // See https://github.com/adafruit/Adafruit-GFX-Library/issues/103
+ FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35;
+ FT_Property_Set( library, "truetype",
+ "interpreter-version",
+ &interpreter_version );
+
if((err = FT_New_Face(library, argv[1], 0, &face))) {
fprintf(stderr, "Font load error: %d", err);
FT_Done_FreeType(library);
@@ -282,3 +294,5 @@ the cursor on the X axis after drawing the corresponding symbol.
There's also some changes with regard to 'background' color and new GFX
fonts (classic fonts unchanged). See Adafruit_GFX.cpp for explanation.
*/
+
+#endif /* !ARDUINO */
diff --git a/lib/Adafruit-GFX-Library-1.2.9/fontconvert/fontconvert_win.md b/lib/Adafruit-GFX-Library-1.5.6/fontconvert/fontconvert_win.md
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/fontconvert/fontconvert_win.md
rename to lib/Adafruit-GFX-Library-1.5.6/fontconvert/fontconvert_win.md
diff --git a/lib/Adafruit-GFX-Library-1.2.9/fontconvert/makefonts.sh b/lib/Adafruit-GFX-Library-1.5.6/fontconvert/makefonts.sh
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/fontconvert/makefonts.sh
rename to lib/Adafruit-GFX-Library-1.5.6/fontconvert/makefonts.sh
diff --git a/lib/Adafruit-GFX-Library-1.2.9/gfxfont.h b/lib/Adafruit-GFX-Library-1.5.6/gfxfont.h
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/gfxfont.h
rename to lib/Adafruit-GFX-Library-1.5.6/gfxfont.h
diff --git a/lib/Adafruit-GFX-Library-1.2.9/glcdfont.c b/lib/Adafruit-GFX-Library-1.5.6/glcdfont.c
similarity index 98%
rename from lib/Adafruit-GFX-Library-1.2.9/glcdfont.c
rename to lib/Adafruit-GFX-Library-1.5.6/glcdfont.c
index 6f88bd23a..50245933c 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/glcdfont.c
+++ b/lib/Adafruit-GFX-Library-1.5.6/glcdfont.c
@@ -9,6 +9,10 @@
#include
#elif defined(ESP8266)
#include
+#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
+// PROGMEM is defefind for T4 to place data in specific memory section
+ #undef PROGMEM
+ #define PROGMEM
#else
#define PROGMEM
#endif
diff --git a/lib/Adafruit-GFX-Library-1.2.9/library.properties b/lib/Adafruit-GFX-Library-1.5.6/library.properties
similarity index 96%
rename from lib/Adafruit-GFX-Library-1.2.9/library.properties
rename to lib/Adafruit-GFX-Library-1.5.6/library.properties
index eea478015..78bbdbafa 100644
--- a/lib/Adafruit-GFX-Library-1.2.9/library.properties
+++ b/lib/Adafruit-GFX-Library-1.5.6/library.properties
@@ -1,5 +1,5 @@
name=Adafruit GFX Library
-version=1.2.9
+version=1.5.6
author=Adafruit
maintainer=Adafruit
sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from.
diff --git a/lib/Adafruit-GFX-Library-1.2.9/license.txt b/lib/Adafruit-GFX-Library-1.5.6/license.txt
similarity index 100%
rename from lib/Adafruit-GFX-Library-1.2.9/license.txt
rename to lib/Adafruit-GFX-Library-1.5.6/license.txt
diff --git a/lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.cpp b/lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.cpp
deleted file mode 100644
index 570a33584..000000000
--- a/lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.cpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/*********************************************************************
-This is a library for our Monochrome OLEDs based on SSD1306 drivers
-
- Pick one up today in the adafruit shop!
- ------> http://www.adafruit.com/category/63_98
-
-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 Limor Fried/Ladyada for Adafruit Industries.
-BSD license, check license.txt for more information
-All text above, and the splash screen below must be included in any redistribution
-*********************************************************************/
-
-#ifdef __AVR__
- #include
-#elif defined(ESP8266) || defined(ESP32)
- #include
-#else
- #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
-#endif
-
-#if !defined(__ARM_ARCH) && !defined(ENERGIA) && !defined(ESP8266) && !defined(ESP32) && !defined(__arc__)
- #include
-#endif
-
-#include
-
-#include
-#include
-#include "Adafruit_GFX.h"
-#include "Adafruit_SSD1306.h"
-
-// the memory buffer for the LCD
-
-static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
-#if (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH > 96*16)
-0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
-0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
-0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
-0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
-0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
-0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
-0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
-0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
-0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
-0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
-0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
-0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
-0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
-0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-#if (SSD1306_LCDHEIGHT == 64)
-0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
-0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
-0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
-0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
-0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
-0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
-0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
-0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
-0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
-0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
-0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
-0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
-0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-#endif
-#endif
-};
-
-#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
-
-// the most basic function, set a single pixel
-void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
- if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
- return;
-
- // check rotation, move pixel around if necessary
- switch (getRotation()) {
- case 1:
- ssd1306_swap(x, y);
- x = WIDTH - x - 1;
- break;
- case 2:
- x = WIDTH - x - 1;
- y = HEIGHT - y - 1;
- break;
- case 3:
- ssd1306_swap(x, y);
- y = HEIGHT - y - 1;
- break;
- }
-
- // x is which column
- switch (color)
- {
- case WHITE: buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << (y&7)); break;
- case BLACK: buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << (y&7)); break;
- case INVERSE: buffer[x+ (y/8)*SSD1306_LCDWIDTH] ^= (1 << (y&7)); break;
- }
-
-}
-
-Adafruit_SSD1306::Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) {
- cs = CS;
- rst = RST;
- dc = DC;
- sclk = SCLK;
- sid = SID;
- hwSPI = false;
-}
-
-// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
-Adafruit_SSD1306::Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) {
- dc = DC;
- rst = RST;
- cs = CS;
- hwSPI = true;
-}
-
-// initializer for I2C - we only indicate the reset pin!
-Adafruit_SSD1306::Adafruit_SSD1306(int8_t reset) :
-Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) {
- sclk = dc = cs = sid = -1;
- rst = reset;
-}
-
-
-void Adafruit_SSD1306::begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
- _vccstate = vccstate;
- _i2caddr = i2caddr;
-
- // set pin directions
- if (sid != -1){
- pinMode(dc, OUTPUT);
- pinMode(cs, OUTPUT);
-#ifdef HAVE_PORTREG
- csport = portOutputRegister(digitalPinToPort(cs));
- cspinmask = digitalPinToBitMask(cs);
- dcport = portOutputRegister(digitalPinToPort(dc));
- dcpinmask = digitalPinToBitMask(dc);
-#endif
- if (!hwSPI){
- // set pins for software-SPI
- pinMode(sid, OUTPUT);
- pinMode(sclk, OUTPUT);
-#ifdef HAVE_PORTREG
- clkport = portOutputRegister(digitalPinToPort(sclk));
- clkpinmask = digitalPinToBitMask(sclk);
- mosiport = portOutputRegister(digitalPinToPort(sid));
- mosipinmask = digitalPinToBitMask(sid);
-#endif
- }
- if (hwSPI){
- SPI.begin();
-#ifdef SPI_HAS_TRANSACTION
- SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
-#else
- SPI.setClockDivider (4);
-#endif
- }
- }
- else
- {
- // I2C Init
- Wire.begin();
-#ifdef __SAM3X8E__
- // Force 400 KHz I2C, rawr! (Uses pins 20, 21 for SDA, SCL)
- TWI1->TWI_CWGR = 0;
- TWI1->TWI_CWGR = ((VARIANT_MCK / (2 * 400000)) - 4) * 0x101;
-#endif
- }
- if ((reset) && (rst >= 0)) {
- // Setup reset pin direction (used by both SPI and I2C)
- pinMode(rst, OUTPUT);
- digitalWrite(rst, HIGH);
- // VDD (3.3V) goes high at start, lets just chill for a ms
- delay(1);
- // bring reset low
- digitalWrite(rst, LOW);
- // wait 10ms
- delay(10);
- // bring out of reset
- digitalWrite(rst, HIGH);
- // turn on VCC (9V?)
- }
-
- // Init sequence
- ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE
- ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
- ssd1306_command(0x80); // the suggested ratio 0x80
-
- ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8
- ssd1306_command(SSD1306_LCDHEIGHT - 1);
-
- ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3
- ssd1306_command(0x0); // no offset
- ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
- ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D
- if (vccstate == SSD1306_EXTERNALVCC)
- { ssd1306_command(0x10); }
- else
- { ssd1306_command(0x14); }
- ssd1306_command(SSD1306_MEMORYMODE); // 0x20
- ssd1306_command(0x00); // 0x0 act like ks0108
- ssd1306_command(SSD1306_SEGREMAP | 0x1);
- ssd1306_command(SSD1306_COMSCANDEC);
-
- #if defined SSD1306_128_32
- ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
- ssd1306_command(0x02);
- ssd1306_command(SSD1306_SETCONTRAST); // 0x81
- ssd1306_command(0x8F);
-
-#elif defined SSD1306_128_64
- ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
- ssd1306_command(0x12);
- ssd1306_command(SSD1306_SETCONTRAST); // 0x81
- if (vccstate == SSD1306_EXTERNALVCC)
- { ssd1306_command(0x9F); }
- else
- { ssd1306_command(0xCF); }
-
-#elif defined SSD1306_96_16
- ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
- ssd1306_command(0x2); //ada x12
- ssd1306_command(SSD1306_SETCONTRAST); // 0x81
- if (vccstate == SSD1306_EXTERNALVCC)
- { ssd1306_command(0x10); }
- else
- { ssd1306_command(0xAF); }
-
-#endif
-
- ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9
- if (vccstate == SSD1306_EXTERNALVCC)
- { ssd1306_command(0x22); }
- else
- { ssd1306_command(0xF1); }
- ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB
- ssd1306_command(0x40);
- ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
- ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6
-
- ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
-
- ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
-}
-
-
-void Adafruit_SSD1306::invertDisplay(uint8_t i) {
- if (i) {
- ssd1306_command(SSD1306_INVERTDISPLAY);
- } else {
- ssd1306_command(SSD1306_NORMALDISPLAY);
- }
-}
-
-void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
- if (sid != -1)
- {
- // SPI
-#ifdef HAVE_PORTREG
- *csport |= cspinmask;
- *dcport &= ~dcpinmask;
- *csport &= ~cspinmask;
-#else
- digitalWrite(cs, HIGH);
- digitalWrite(dc, LOW);
- digitalWrite(cs, LOW);
-#endif
- fastSPIwrite(c);
-#ifdef HAVE_PORTREG
- *csport |= cspinmask;
-#else
- digitalWrite(cs, HIGH);
-#endif
- }
- else
- {
- // I2C
- uint8_t control = 0x00; // Co = 0, D/C = 0
- Wire.beginTransmission(_i2caddr);
- Wire.write(control);
- Wire.write(c);
- Wire.endTransmission();
- }
-}
-
-// startscrollright
-// Activate a right handed scroll for rows start through stop
-// Hint, the display is 16 rows tall. To scroll the whole display, run:
-// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop){
- ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL);
- ssd1306_command(0X00);
- ssd1306_command(start);
- ssd1306_command(0X00);
- ssd1306_command(stop);
- ssd1306_command(0X00);
- ssd1306_command(0XFF);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
-}
-
-// startscrollleft
-// Activate a right handed scroll for rows start through stop
-// Hint, the display is 16 rows tall. To scroll the whole display, run:
-// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop){
- ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL);
- ssd1306_command(0X00);
- ssd1306_command(start);
- ssd1306_command(0X00);
- ssd1306_command(stop);
- ssd1306_command(0X00);
- ssd1306_command(0XFF);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
-}
-
-// startscrolldiagright
-// Activate a diagonal scroll for rows start through stop
-// Hint, the display is 16 rows tall. To scroll the whole display, run:
-// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop){
- ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
- ssd1306_command(0X00);
- ssd1306_command(SSD1306_LCDHEIGHT);
- ssd1306_command(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
- ssd1306_command(0X00);
- ssd1306_command(start);
- ssd1306_command(0X00);
- ssd1306_command(stop);
- ssd1306_command(0X01);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
-}
-
-// startscrolldiagleft
-// Activate a diagonal scroll for rows start through stop
-// Hint, the display is 16 rows tall. To scroll the whole display, run:
-// display.scrollright(0x00, 0x0F)
-void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop){
- ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
- ssd1306_command(0X00);
- ssd1306_command(SSD1306_LCDHEIGHT);
- ssd1306_command(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
- ssd1306_command(0X00);
- ssd1306_command(start);
- ssd1306_command(0X00);
- ssd1306_command(stop);
- ssd1306_command(0X01);
- ssd1306_command(SSD1306_ACTIVATE_SCROLL);
-}
-
-void Adafruit_SSD1306::stopscroll(void){
- ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
-}
-
-// Dim the display
-// dim = true: display is dimmed
-// dim = false: display is normal
-void Adafruit_SSD1306::dim(boolean dim) {
- uint8_t contrast;
-
- if (dim) {
- contrast = 0; // Dimmed display
- } else {
- if (_vccstate == SSD1306_EXTERNALVCC) {
- contrast = 0x9F;
- } else {
- contrast = 0xCF;
- }
- }
- // the range of contrast to too small to be really useful
- // it is useful to dim the display
- ssd1306_command(SSD1306_SETCONTRAST);
- ssd1306_command(contrast);
-}
-
-void Adafruit_SSD1306::display(void) {
- ssd1306_command(SSD1306_COLUMNADDR);
- ssd1306_command(0); // Column start address (0 = reset)
- ssd1306_command(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
-
- ssd1306_command(SSD1306_PAGEADDR);
- ssd1306_command(0); // Page start address (0 = reset)
- #if SSD1306_LCDHEIGHT == 64
- ssd1306_command(7); // Page end address
- #endif
- #if SSD1306_LCDHEIGHT == 32
- ssd1306_command(3); // Page end address
- #endif
- #if SSD1306_LCDHEIGHT == 16
- ssd1306_command(1); // Page end address
- #endif
-
- if (sid != -1)
- {
- // SPI
-#ifdef HAVE_PORTREG
- *csport |= cspinmask;
- *dcport |= dcpinmask;
- *csport &= ~cspinmask;
-#else
- digitalWrite(cs, HIGH);
- digitalWrite(dc, HIGH);
- digitalWrite(cs, LOW);
-#endif
-
- for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
- fastSPIwrite(buffer[i]);
- }
-#ifdef HAVE_PORTREG
- *csport |= cspinmask;
-#else
- digitalWrite(cs, HIGH);
-#endif
- }
- else
- {
- // save I2C bitrate
-#ifdef TWBR
- uint8_t twbrbackup = TWBR;
- TWBR = 12; // upgrade to 400KHz!
-#endif
-
- //Serial.println(TWBR, DEC);
- //Serial.println(TWSR & 0x3, DEC);
-
- // I2C
- for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
- // send a bunch of data in one xmission
- Wire.beginTransmission(_i2caddr);
- WIRE_WRITE(0x40);
- for (uint8_t x=0; x<16; x++) {
- WIRE_WRITE(buffer[i]);
- i++;
- }
- i--;
- Wire.endTransmission();
- }
-#ifdef TWBR
- TWBR = twbrbackup;
-#endif
- }
-}
-
-// clear everything
-void Adafruit_SSD1306::clearDisplay(void) {
- memset(buffer, 0, (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8));
-}
-
-
-inline void Adafruit_SSD1306::fastSPIwrite(uint8_t d) {
-
- 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(sclk, LOW);
- if(d & bit) digitalWrite(sid, HIGH);
- else digitalWrite(sid, LOW);
- digitalWrite(sclk, HIGH);
-#endif
- }
- }
-}
-
-void Adafruit_SSD1306::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
- boolean bSwap = false;
- switch(rotation) {
- case 0:
- // 0 degree rotation, do nothing
- break;
- case 1:
- // 90 degree rotation, swap x & y for rotation, then invert x
- bSwap = true;
- ssd1306_swap(x, y);
- x = WIDTH - x - 1;
- break;
- case 2:
- // 180 degree rotation, invert x and y - then shift y around for height.
- x = WIDTH - x - 1;
- y = HEIGHT - y - 1;
- x -= (w-1);
- break;
- case 3:
- // 270 degree rotation, swap x & y for rotation, then invert y and adjust y for w (not to become h)
- bSwap = true;
- ssd1306_swap(x, y);
- y = HEIGHT - y - 1;
- y -= (w-1);
- break;
- }
-
- if(bSwap) {
- drawFastVLineInternal(x, y, w, color);
- } else {
- drawFastHLineInternal(x, y, w, color);
- }
-}
-
-void Adafruit_SSD1306::drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) {
- // Do bounds/limit checks
- if(y < 0 || y >= HEIGHT) { return; }
-
- // make sure we don't try to draw below 0
- if(x < 0) {
- w += x;
- x = 0;
- }
-
- // make sure we don't go off the edge of the display
- if( (x + w) > WIDTH) {
- w = (WIDTH - x);
- }
-
- // if our width is now negative, punt
- if(w <= 0) { return; }
-
- // set up the pointer for movement through the buffer
- register uint8_t *pBuf = buffer;
- // adjust the buffer pointer for the current row
- pBuf += ((y/8) * SSD1306_LCDWIDTH);
- // and offset x columns in
- pBuf += x;
-
- register uint8_t mask = 1 << (y&7);
-
- switch (color)
- {
- case WHITE: while(w--) { *pBuf++ |= mask; }; break;
- case BLACK: mask = ~mask; while(w--) { *pBuf++ &= mask; }; break;
- case INVERSE: while(w--) { *pBuf++ ^= mask; }; break;
- }
-}
-
-void Adafruit_SSD1306::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
- bool bSwap = false;
- switch(rotation) {
- case 0:
- break;
- case 1:
- // 90 degree rotation, swap x & y for rotation, then invert x and adjust x for h (now to become w)
- bSwap = true;
- ssd1306_swap(x, y);
- x = WIDTH - x - 1;
- x -= (h-1);
- break;
- case 2:
- // 180 degree rotation, invert x and y - then shift y around for height.
- x = WIDTH - x - 1;
- y = HEIGHT - y - 1;
- y -= (h-1);
- break;
- case 3:
- // 270 degree rotation, swap x & y for rotation, then invert y
- bSwap = true;
- ssd1306_swap(x, y);
- y = HEIGHT - y - 1;
- break;
- }
-
- if(bSwap) {
- drawFastHLineInternal(x, y, h, color);
- } else {
- drawFastVLineInternal(x, y, h, color);
- }
-}
-
-
-void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color) {
-
- // do nothing if we're off the left or right side of the screen
- if(x < 0 || x >= WIDTH) { return; }
-
- // make sure we don't try to draw below 0
- if(__y < 0) {
- // __y is negative, this will subtract enough from __h to account for __y being 0
- __h += __y;
- __y = 0;
-
- }
-
- // make sure we don't go past the height of the display
- if( (__y + __h) > HEIGHT) {
- __h = (HEIGHT - __y);
- }
-
- // if our height is now negative, punt
- if(__h <= 0) {
- return;
- }
-
- // this display doesn't need ints for coordinates, use local byte registers for faster juggling
- register uint8_t y = __y;
- register uint8_t h = __h;
-
-
- // set up the pointer for fast movement through the buffer
- register uint8_t *pBuf = buffer;
- // adjust the buffer pointer for the current row
- pBuf += ((y/8) * SSD1306_LCDWIDTH);
- // and offset x columns in
- pBuf += x;
-
- // do the first partial byte, if necessary - this requires some masking
- register uint8_t mod = (y&7);
- if(mod) {
- // mask off the high n bits we want to set
- mod = 8-mod;
-
- // note - lookup table results in a nearly 10% performance improvement in fill* functions
- // register uint8_t mask = ~(0xFF >> (mod));
- static uint8_t premask[8] = {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
- register uint8_t mask = premask[mod];
-
- // adjust the mask if we're not going to reach the end of this byte
- if( h < mod) {
- mask &= (0XFF >> (mod-h));
- }
-
- switch (color)
- {
- case WHITE: *pBuf |= mask; break;
- case BLACK: *pBuf &= ~mask; break;
- case INVERSE: *pBuf ^= mask; break;
- }
-
- // fast exit if we're done here!
- if(h= 8) {
- if (color == INVERSE) { // separate copy of the code so we don't impact performance of the black/white write version with an extra comparison per loop
- do {
- *pBuf=~(*pBuf);
-
- // adjust the buffer forward 8 rows worth of data
- pBuf += SSD1306_LCDWIDTH;
-
- // adjust h & y (there's got to be a faster way for me to do this, but this should still help a fair bit for now)
- h -= 8;
- } while(h >= 8);
- }
- else {
- // store a local value to work with
- register uint8_t val = (color == WHITE) ? 255 : 0;
-
- do {
- // write our value in
- *pBuf = val;
-
- // adjust the buffer forward 8 rows worth of data
- pBuf += SSD1306_LCDWIDTH;
-
- // adjust h & y (there's got to be a faster way for me to do this, but this should still help a fair bit for now)
- h -= 8;
- } while(h >= 8);
- }
- }
-
- // now do the final partial byte, if necessary
- if(h) {
- mod = h & 7;
- // this time we want to mask the low bits of the byte, vs the high bits we did above
- // register uint8_t mask = (1 << mod) - 1;
- // note - lookup table results in a nearly 10% performance improvement in fill* functions
- static uint8_t postmask[8] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
- register uint8_t mask = postmask[mod];
- switch (color)
- {
- case WHITE: *pBuf |= mask; break;
- case BLACK: *pBuf &= ~mask; break;
- case INVERSE: *pBuf ^= mask; break;
- }
- }
-}
diff --git a/lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.h b/lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.h
deleted file mode 100644
index 1d43dfddf..000000000
--- a/lib/Adafruit_SSD1306-1.1.2/Adafruit_SSD1306.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*********************************************************************
-This is a library for our Monochrome OLEDs based on SSD1306 drivers
-
- Pick one up today in the adafruit shop!
- ------> http://www.adafruit.com/category/63_98
-
-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 Limor Fried/Ladyada for Adafruit Industries.
-BSD license, check license.txt for more information
-All text above, and the splash screen must be included in any redistribution
-*********************************************************************/
-#ifndef _Adafruit_SSD1306_H_
-#define _Adafruit_SSD1306_H_
-
-#if ARDUINO >= 100
- #include "Arduino.h"
- #define WIRE_WRITE Wire.write
-#else
- #include "WProgram.h"
- #define WIRE_WRITE Wire.send
-#endif
-
-#if defined(__SAM3X8E__)
- typedef volatile RwReg PortReg;
- typedef uint32_t PortMask;
- #define HAVE_PORTREG
-#elif defined(ARDUINO_ARCH_SAMD)
-// not supported
-#elif defined(ESP8266) || defined(ESP32) || defined(ARDUINO_STM32_FEATHER) || defined(__arc__)
- typedef volatile uint32_t PortReg;
- typedef uint32_t PortMask;
-#elif defined(__AVR__)
- typedef volatile uint8_t PortReg;
- typedef uint8_t PortMask;
- #define HAVE_PORTREG
-#else
- // chances are its 32 bit so assume that
- typedef volatile uint32_t PortReg;
- typedef uint32_t PortMask;
-#endif
-
-#include
-#include
-
-#define BLACK 0
-#define WHITE 1
-#define INVERSE 2
-
-#define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
-// Address for 128x32 is 0x3C
-// Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
-
-/*=========================================================================
- SSD1306 Displays
- -----------------------------------------------------------------------
- The driver is used in multiple displays (128x64, 128x32, etc.).
- Select the appropriate display below to create an appropriately
- sized framebuffer, etc.
-
- SSD1306_128_64 128x64 pixel display
-
- SSD1306_128_32 128x32 pixel display
-
- SSD1306_96_16
-
- -----------------------------------------------------------------------*/
- #define SSD1306_128_64
-// #define SSD1306_128_32
-// #define SSD1306_96_16
-/*=========================================================================*/
-
-#if defined SSD1306_128_64 && defined SSD1306_128_32
- #error "Only one SSD1306 display can be specified at once in SSD1306.h"
-#endif
-#if !defined SSD1306_128_64 && !defined SSD1306_128_32 && !defined SSD1306_96_16
- #error "At least one SSD1306 display must be specified in SSD1306.h"
-#endif
-
-#if defined SSD1306_128_64
- #define SSD1306_LCDWIDTH 128
- #define SSD1306_LCDHEIGHT 64
-#endif
-#if defined SSD1306_128_32
- #define SSD1306_LCDWIDTH 128
- #define SSD1306_LCDHEIGHT 32
-#endif
-#if defined SSD1306_96_16
- #define SSD1306_LCDWIDTH 96
- #define SSD1306_LCDHEIGHT 16
-#endif
-
-#define SSD1306_SETCONTRAST 0x81
-#define SSD1306_DISPLAYALLON_RESUME 0xA4
-#define SSD1306_DISPLAYALLON 0xA5
-#define SSD1306_NORMALDISPLAY 0xA6
-#define SSD1306_INVERTDISPLAY 0xA7
-#define SSD1306_DISPLAYOFF 0xAE
-#define SSD1306_DISPLAYON 0xAF
-
-#define SSD1306_SETDISPLAYOFFSET 0xD3
-#define SSD1306_SETCOMPINS 0xDA
-
-#define SSD1306_SETVCOMDETECT 0xDB
-
-#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
-#define SSD1306_SETPRECHARGE 0xD9
-
-#define SSD1306_SETMULTIPLEX 0xA8
-
-#define SSD1306_SETLOWCOLUMN 0x00
-#define SSD1306_SETHIGHCOLUMN 0x10
-
-#define SSD1306_SETSTARTLINE 0x40
-
-#define SSD1306_MEMORYMODE 0x20
-#define SSD1306_COLUMNADDR 0x21
-#define SSD1306_PAGEADDR 0x22
-
-#define SSD1306_COMSCANINC 0xC0
-#define SSD1306_COMSCANDEC 0xC8
-
-#define SSD1306_SEGREMAP 0xA0
-
-#define SSD1306_CHARGEPUMP 0x8D
-
-#define SSD1306_EXTERNALVCC 0x1
-#define SSD1306_SWITCHCAPVCC 0x2
-
-// Scrolling #defines
-#define SSD1306_ACTIVATE_SCROLL 0x2F
-#define SSD1306_DEACTIVATE_SCROLL 0x2E
-#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
-#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
-#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
-#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
-#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
-
-class Adafruit_SSD1306 : public Adafruit_GFX {
- public:
- Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);
- Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS);
- Adafruit_SSD1306(int8_t RST = -1);
-
- void begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = SSD1306_I2C_ADDRESS, bool reset=true);
- void ssd1306_command(uint8_t c);
-
- void clearDisplay(void);
- void invertDisplay(uint8_t i);
- void display();
-
- void startscrollright(uint8_t start, uint8_t stop);
- void startscrollleft(uint8_t start, uint8_t stop);
-
- void startscrolldiagright(uint8_t start, uint8_t stop);
- void startscrolldiagleft(uint8_t start, uint8_t stop);
- void stopscroll(void);
-
- void dim(boolean dim);
-
- void drawPixel(int16_t x, int16_t y, uint16_t color);
-
- virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
- virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
-
- private:
- int8_t _i2caddr, _vccstate, sid, sclk, dc, rst, cs;
- void fastSPIwrite(uint8_t c);
-
- boolean hwSPI;
-#ifdef HAVE_PORTREG
- PortReg *mosiport, *clkport, *csport, *dcport;
- PortMask mosipinmask, clkpinmask, cspinmask, dcpinmask;
-#endif
-
- inline void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline));
- inline void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) __attribute__((always_inline));
-
-};
-
-#endif /* _Adafruit_SSD1306_H_ */
diff --git a/lib/Adafruit_SSD1306-1.1.2/README.md b/lib/Adafruit_SSD1306-1.1.2/README.md
deleted file mode 100644
index d76bb285c..000000000
--- a/lib/Adafruit_SSD1306-1.1.2/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Adafruit_SSD1306
-
-
-## Compatibility
-
-MCU | Tested Works | Doesn't Work | Not Tested | Notes
------------------- | :----------: | :----------: | :---------: | -----
-Atmega328 @ 16MHz | X | | |
-Atmega328 @ 12MHz | X | | |
-Atmega32u4 @ 16MHz | X | | |
-Atmega32u4 @ 8MHz | X | | |
-ESP8266 | X | | | change OLED_RESET to different pin if using default I2C pins D4/D5.
-Atmega2560 @ 16MHz | X | | |
-ATSAM3X8E | X | | |
-ATSAM21D | X | | |
-ATtiny85 @ 16MHz | | X | |
-ATtiny85 @ 8MHz | | X | |
-Intel Curie @ 32MHz | | | X |
-STM32F2 | | | X |
-
- * ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
- * ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
- * ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
- * ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
- * ESP8266 : Adafruit Huzzah
- * ATmega2560 @ 16MHz : Arduino Mega
- * ATSAM3X8E : Arduino Due
- * ATSAM21D : Arduino Zero, M0 Pro
- * ATtiny85 @ 16MHz : Adafruit Trinket 5V
- * ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
-
-
diff --git a/lib/Adafruit_SSD1306-1.1.2/README.txt b/lib/Adafruit_SSD1306-1.1.2/README.txt
deleted file mode 100644
index 420cc153c..000000000
--- a/lib/Adafruit_SSD1306-1.1.2/README.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This is a library for our Monochrome OLEDs based on SSD1306 drivers
-
- Pick one up today in the adafruit shop!
- ------> http://www.adafruit.com/category/63_98
-
-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 Limor Fried/Ladyada for Adafruit Industries.
-Scrolling code contributed by Michael Gregg
-BSD license, check license.txt for more information
-All text above must be included in any redistribution
-
-To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_SSD1306. Check that the Adafruit_SSD1306 folder contains Adafruit_SSD1306.cpp and Adafruit_SSD1306.h
-
-Place the Adafruit_SSD1306 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.
-
-You will also have to download the Adafruit GFX Graphics core which does all the circles, text, rectangles, etc. You can get it from
-https://github.com/adafruit/Adafruit-GFX-Library
-and download/install that library as well
\ No newline at end of file
diff --git a/lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino b/lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino
deleted file mode 100644
index b3b8bfa9a..000000000
--- a/lib/Adafruit_SSD1306-1.1.2/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino
+++ /dev/null
@@ -1,375 +0,0 @@
-/*********************************************************************
-This is an example for our Monochrome OLEDs based on SSD1306 drivers
-
- Pick one up today in the adafruit shop!
- ------> http://www.adafruit.com/category/63_98
-
-This example is for a 128x32 size display using I2C to communicate
-3 pins are required to interface (2 I2C and one reset)
-
-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.
-BSD license, check license.txt for more information
-All text above, and the splash screen must be included in any redistribution
-*********************************************************************/
-
-#include
-#include
-#include
-#include
-
-#define OLED_RESET 4
-Adafruit_SSD1306 display(OLED_RESET);
-
-#define NUMFLAKES 10
-#define XPOS 0
-#define YPOS 1
-#define DELTAY 2
-
-
-#define LOGO16_GLCD_HEIGHT 16
-#define LOGO16_GLCD_WIDTH 16
-static const unsigned char PROGMEM logo16_glcd_bmp[] =
-{ B00000000, B11000000,
- B00000001, B11000000,
- B00000001, B11000000,
- B00000011, B11100000,
- B11110011, B11100000,
- B11111110, B11111000,
- B01111110, B11111111,
- B00110011, B10011111,
- B00011111, B11111100,
- B00001101, B01110000,
- B00011011, B10100000,
- B00111111, B11100000,
- B00111111, B11110000,
- B01111100, B11110000,
- B01110000, B01110000,
- B00000000, B00110000 };
-
-#if (SSD1306_LCDHEIGHT != 32)
-#error("Height incorrect, please fix Adafruit_SSD1306.h!");
-#endif
-
-void setup() {
- Serial.begin(9600);
-
- // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
- // init done
-
- // Show image buffer on the display hardware.
- // Since the buffer is intialized with an Adafruit splashscreen
- // internally, this will display the splashscreen.
- display.display();
- delay(2000);
-
- // Clear the buffer.
- display.clearDisplay();
-
- // draw a single pixel
- display.drawPixel(10, 10, WHITE);
- // Show the display buffer on the hardware.
- // NOTE: You _must_ call display after making any drawing commands
- // to make them visible on the display hardware!
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw many lines
- testdrawline();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw rectangles
- testdrawrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw multiple rectangles
- testfillrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw mulitple circles
- testdrawcircle();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw a white circle, 10 pixel radius
- display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- testdrawroundrect();
- delay(2000);
- display.clearDisplay();
-
- testfillroundrect();
- delay(2000);
- display.clearDisplay();
-
- testdrawtriangle();
- delay(2000);
- display.clearDisplay();
-
- testfilltriangle();
- delay(2000);
- display.clearDisplay();
-
- // draw the first ~12 characters in the font
- testdrawchar();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw scrolling text
- testscrolltext();
- delay(2000);
- display.clearDisplay();
-
- // text display tests
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
- display.println("Hello, world!");
- display.setTextColor(BLACK, WHITE); // 'inverted' text
- display.println(3.141592);
- display.setTextSize(2);
- display.setTextColor(WHITE);
- display.print("0x"); display.println(0xDEADBEEF, HEX);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // miniature bitmap display
- display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
- display.display();
- delay(1);
-
- // invert the display
- display.invertDisplay(true);
- delay(1000);
- display.invertDisplay(false);
- delay(1000);
- display.clearDisplay();
-
- // draw a bitmap icon and 'animate' movement
- testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
-}
-
-
-void loop() {
-
-}
-
-
-void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
- uint8_t icons[NUMFLAKES][3];
-
- // initialize
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
-
- Serial.print("x: ");
- Serial.print(icons[f][XPOS], DEC);
- Serial.print(" y: ");
- Serial.print(icons[f][YPOS], DEC);
- Serial.print(" dy: ");
- Serial.println(icons[f][DELTAY], DEC);
- }
-
- while (1) {
- // draw each icon
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
- }
- display.display();
- delay(200);
-
- // then erase it + move it
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
- // move it
- icons[f][YPOS] += icons[f][DELTAY];
- // if its gone, reinit
- if (icons[f][YPOS] > display.height()) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
- }
- }
- }
-}
-
-
-void testdrawchar(void) {
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
-
- for (uint8_t i=0; i < 168; i++) {
- if (i == '\n') continue;
- display.write(i);
- if ((i > 0) && (i % 21 == 0))
- display.println();
- }
- display.display();
- delay(1);
-}
-
-void testdrawcircle(void) {
- for (int16_t i=0; i0; i-=5) {
- display.fillTriangle(display.width()/2, display.height()/2-i,
- display.width()/2-i, display.height()/2+i,
- display.width()/2+i, display.height()/2+i, WHITE);
- if (color == WHITE) color = BLACK;
- else color = WHITE;
- display.display();
- delay(1);
- }
-}
-
-void testdrawroundrect(void) {
- for (int16_t i=0; i=0; i-=4) {
- display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
- display.display();
- delay(1);
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=display.width()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
- display.display();
- delay(1);
- }
- for (int16_t i=display.height()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
- display.display();
- delay(1);
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=0; i http://www.adafruit.com/category/63_98
-
-This example is for a 128x32 size display using 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 Limor Fried/Ladyada for Adafruit Industries.
-BSD license, check license.txt for more information
-All text above, and the splash screen must be included in any redistribution
-*********************************************************************/
-
-#include
-#include
-#include
-#include
-
-// If using software SPI (the default case):
-#define OLED_MOSI 9
-#define OLED_CLK 10
-#define OLED_DC 11
-#define OLED_CS 12
-#define OLED_RESET 13
-Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
-
-/* Uncomment this block to use hardware SPI
-#define OLED_DC 6
-#define OLED_CS 7
-#define OLED_RESET 8
-Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
-*/
-
-#define NUMFLAKES 10
-#define XPOS 0
-#define YPOS 1
-#define DELTAY 2
-
-#define LOGO16_GLCD_HEIGHT 16
-#define LOGO16_GLCD_WIDTH 16
-static const unsigned char PROGMEM logo16_glcd_bmp[] =
-{ B00000000, B11000000,
- B00000001, B11000000,
- B00000001, B11000000,
- B00000011, B11100000,
- B11110011, B11100000,
- B11111110, B11111000,
- B01111110, B11111111,
- B00110011, B10011111,
- B00011111, B11111100,
- B00001101, B01110000,
- B00011011, B10100000,
- B00111111, B11100000,
- B00111111, B11110000,
- B01111100, B11110000,
- B01110000, B01110000,
- B00000000, B00110000 };
-
-#if (SSD1306_LCDHEIGHT != 32)
-#error("Height incorrect, please fix Adafruit_SSD1306.h!");
-#endif
-
-void setup() {
- Serial.begin(9600);
-
- // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- display.begin(SSD1306_SWITCHCAPVCC);
- // init done
-
- // Show image buffer on the display hardware.
- // Since the buffer is intialized with an Adafruit splashscreen
- // internally, this will display the splashscreen.
- display.display();
- delay(2000);
-
- // Clear the buffer.
- display.clearDisplay();
-
- // draw a single pixel
- display.drawPixel(10, 10, WHITE);
- // Show the display buffer on the hardware.
- // NOTE: You _must_ call display after making any drawing commands
- // to make them visible on the display hardware!
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw many lines
- testdrawline();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw rectangles
- testdrawrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw multiple rectangles
- testfillrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw mulitple circles
- testdrawcircle();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw a white circle, 10 pixel radius
- display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- testdrawroundrect();
- delay(2000);
- display.clearDisplay();
-
- testfillroundrect();
- delay(2000);
- display.clearDisplay();
-
- testdrawtriangle();
- delay(2000);
- display.clearDisplay();
-
- testfilltriangle();
- delay(2000);
- display.clearDisplay();
-
- // draw the first ~12 characters in the font
- testdrawchar();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw scrolling text
- testscrolltext();
- delay(2000);
- display.clearDisplay();
-
- // text display tests
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
- display.println("Hello, world!");
- display.setTextColor(BLACK, WHITE); // 'inverted' text
- display.println(3.141592);
- display.setTextSize(2);
- display.setTextColor(WHITE);
- display.print("0x"); display.println(0xDEADBEEF, HEX);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // miniature bitmap display
- display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
- display.display();
-
- // invert the display
- display.invertDisplay(true);
- delay(1000);
- display.invertDisplay(false);
- delay(1000);
- display.clearDisplay();
-
- // draw a bitmap icon and 'animate' movement
- testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
-}
-
-
-void loop() {
-
-}
-
-
-void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
- uint8_t icons[NUMFLAKES][3];
-
- // initialize
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
-
- Serial.print("x: ");
- Serial.print(icons[f][XPOS], DEC);
- Serial.print(" y: ");
- Serial.print(icons[f][YPOS], DEC);
- Serial.print(" dy: ");
- Serial.println(icons[f][DELTAY], DEC);
- }
-
- while (1) {
- // draw each icon
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
- }
- display.display();
- delay(200);
-
- // then erase it + move it
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
- // move it
- icons[f][YPOS] += icons[f][DELTAY];
- // if its gone, reinit
- if (icons[f][YPOS] > display.height()) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
- }
- }
- }
-}
-
-
-void testdrawchar(void) {
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
-
- for (uint8_t i=0; i < 168; i++) {
- if (i == '\n') continue;
- display.write(i);
- if ((i > 0) && (i % 21 == 0))
- display.println();
- }
- display.display();
-}
-
-void testdrawcircle(void) {
- for (int16_t i=0; i0; i-=5) {
- display.fillTriangle(display.width()/2, display.height()/2-i,
- display.width()/2-i, display.height()/2+i,
- display.width()/2+i, display.height()/2+i, WHITE);
- if (color == WHITE) color = BLACK;
- else color = WHITE;
- display.display();
- }
-}
-
-void testdrawroundrect(void) {
- for (int16_t i=0; i=0; i-=4) {
- display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
- display.display();
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=display.width()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
- display.display();
- }
- for (int16_t i=display.height()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
- display.display();
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=0; i http://www.adafruit.com/category/63_98
-
-This example is for a 128x64 size display using I2C to communicate
-3 pins are required to interface (2 I2C and one reset)
-
-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.
-BSD license, check license.txt for more information
-All text above, and the splash screen must be included in any redistribution
-*********************************************************************/
-
-#include
-#include
-#include
-#include
-
-#define OLED_RESET 4
-Adafruit_SSD1306 display(OLED_RESET);
-
-#define NUMFLAKES 10
-#define XPOS 0
-#define YPOS 1
-#define DELTAY 2
-
-
-#define LOGO16_GLCD_HEIGHT 16
-#define LOGO16_GLCD_WIDTH 16
-static const unsigned char PROGMEM logo16_glcd_bmp[] =
-{ B00000000, B11000000,
- B00000001, B11000000,
- B00000001, B11000000,
- B00000011, B11100000,
- B11110011, B11100000,
- B11111110, B11111000,
- B01111110, B11111111,
- B00110011, B10011111,
- B00011111, B11111100,
- B00001101, B01110000,
- B00011011, B10100000,
- B00111111, B11100000,
- B00111111, B11110000,
- B01111100, B11110000,
- B01110000, B01110000,
- B00000000, B00110000 };
-
-#if (SSD1306_LCDHEIGHT != 64)
-#error("Height incorrect, please fix Adafruit_SSD1306.h!");
-#endif
-
-void setup() {
- Serial.begin(9600);
-
- // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)
- // init done
-
- // Show image buffer on the display hardware.
- // Since the buffer is intialized with an Adafruit splashscreen
- // internally, this will display the splashscreen.
- display.display();
- delay(2000);
-
- // Clear the buffer.
- display.clearDisplay();
-
- // draw a single pixel
- display.drawPixel(10, 10, WHITE);
- // Show the display buffer on the hardware.
- // NOTE: You _must_ call display after making any drawing commands
- // to make them visible on the display hardware!
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw many lines
- testdrawline();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw rectangles
- testdrawrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw multiple rectangles
- testfillrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw mulitple circles
- testdrawcircle();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw a white circle, 10 pixel radius
- display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- testdrawroundrect();
- delay(2000);
- display.clearDisplay();
-
- testfillroundrect();
- delay(2000);
- display.clearDisplay();
-
- testdrawtriangle();
- delay(2000);
- display.clearDisplay();
-
- testfilltriangle();
- delay(2000);
- display.clearDisplay();
-
- // draw the first ~12 characters in the font
- testdrawchar();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw scrolling text
- testscrolltext();
- delay(2000);
- display.clearDisplay();
-
- // text display tests
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
- display.println("Hello, world!");
- display.setTextColor(BLACK, WHITE); // 'inverted' text
- display.println(3.141592);
- display.setTextSize(2);
- display.setTextColor(WHITE);
- display.print("0x"); display.println(0xDEADBEEF, HEX);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // miniature bitmap display
- display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
- display.display();
- delay(1);
-
- // invert the display
- display.invertDisplay(true);
- delay(1000);
- display.invertDisplay(false);
- delay(1000);
- display.clearDisplay();
-
- // draw a bitmap icon and 'animate' movement
- testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
-}
-
-
-void loop() {
-
-}
-
-
-void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
- uint8_t icons[NUMFLAKES][3];
-
- // initialize
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
-
- Serial.print("x: ");
- Serial.print(icons[f][XPOS], DEC);
- Serial.print(" y: ");
- Serial.print(icons[f][YPOS], DEC);
- Serial.print(" dy: ");
- Serial.println(icons[f][DELTAY], DEC);
- }
-
- while (1) {
- // draw each icon
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
- }
- display.display();
- delay(200);
-
- // then erase it + move it
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
- // move it
- icons[f][YPOS] += icons[f][DELTAY];
- // if its gone, reinit
- if (icons[f][YPOS] > display.height()) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
- }
- }
- }
-}
-
-
-void testdrawchar(void) {
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
-
- for (uint8_t i=0; i < 168; i++) {
- if (i == '\n') continue;
- display.write(i);
- if ((i > 0) && (i % 21 == 0))
- display.println();
- }
- display.display();
- delay(1);
-}
-
-void testdrawcircle(void) {
- for (int16_t i=0; i0; i-=5) {
- display.fillTriangle(display.width()/2, display.height()/2-i,
- display.width()/2-i, display.height()/2+i,
- display.width()/2+i, display.height()/2+i, WHITE);
- if (color == WHITE) color = BLACK;
- else color = WHITE;
- display.display();
- delay(1);
- }
-}
-
-void testdrawroundrect(void) {
- for (int16_t i=0; i=0; i-=4) {
- display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
- display.display();
- delay(1);
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=display.width()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
- display.display();
- delay(1);
- }
- for (int16_t i=display.height()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
- display.display();
- delay(1);
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=0; i http://www.adafruit.com/category/63_98
-
-This example is for a 128x64 size display using 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 Limor Fried/Ladyada for Adafruit Industries.
-BSD license, check license.txt for more information
-All text above, and the splash screen must be included in any redistribution
-*********************************************************************/
-
-#include
-#include
-#include
-#include
-
-// If using software SPI (the default case):
-#define OLED_MOSI 9
-#define OLED_CLK 10
-#define OLED_DC 11
-#define OLED_CS 12
-#define OLED_RESET 13
-Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
-
-/* Uncomment this block to use hardware SPI
-#define OLED_DC 6
-#define OLED_CS 7
-#define OLED_RESET 8
-Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
-*/
-
-#define NUMFLAKES 10
-#define XPOS 0
-#define YPOS 1
-#define DELTAY 2
-
-#define LOGO16_GLCD_HEIGHT 16
-#define LOGO16_GLCD_WIDTH 16
-static const unsigned char PROGMEM logo16_glcd_bmp[] =
-{ B00000000, B11000000,
- B00000001, B11000000,
- B00000001, B11000000,
- B00000011, B11100000,
- B11110011, B11100000,
- B11111110, B11111000,
- B01111110, B11111111,
- B00110011, B10011111,
- B00011111, B11111100,
- B00001101, B01110000,
- B00011011, B10100000,
- B00111111, B11100000,
- B00111111, B11110000,
- B01111100, B11110000,
- B01110000, B01110000,
- B00000000, B00110000 };
-
-#if (SSD1306_LCDHEIGHT != 64)
-#error("Height incorrect, please fix Adafruit_SSD1306.h!");
-#endif
-
-void setup() {
- Serial.begin(9600);
-
- // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
- display.begin(SSD1306_SWITCHCAPVCC);
- // init done
-
- // Show image buffer on the display hardware.
- // Since the buffer is intialized with an Adafruit splashscreen
- // internally, this will display the splashscreen.
- display.display();
- delay(2000);
-
- // Clear the buffer.
- display.clearDisplay();
-
- // draw a single pixel
- display.drawPixel(10, 10, WHITE);
- // Show the display buffer on the hardware.
- // NOTE: You _must_ call display after making any drawing commands
- // to make them visible on the display hardware!
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw many lines
- testdrawline();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw rectangles
- testdrawrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw multiple rectangles
- testfillrect();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw mulitple circles
- testdrawcircle();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw a white circle, 10 pixel radius
- display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- testdrawroundrect();
- delay(2000);
- display.clearDisplay();
-
- testfillroundrect();
- delay(2000);
- display.clearDisplay();
-
- testdrawtriangle();
- delay(2000);
- display.clearDisplay();
-
- testfilltriangle();
- delay(2000);
- display.clearDisplay();
-
- // draw the first ~12 characters in the font
- testdrawchar();
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // draw scrolling text
- testscrolltext();
- delay(2000);
- display.clearDisplay();
-
- // text display tests
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
- display.println("Hello, world!");
- display.setTextColor(BLACK, WHITE); // 'inverted' text
- display.println(3.141592);
- display.setTextSize(2);
- display.setTextColor(WHITE);
- display.print("0x"); display.println(0xDEADBEEF, HEX);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- // miniature bitmap display
- display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
- display.display();
-
- // invert the display
- display.invertDisplay(true);
- delay(1000);
- display.invertDisplay(false);
- delay(1000);
- display.clearDisplay();
-
- // draw a bitmap icon and 'animate' movement
- testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
-}
-
-
-void loop() {
-
-}
-
-
-void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
- uint8_t icons[NUMFLAKES][3];
-
- // initialize
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
-
- Serial.print("x: ");
- Serial.print(icons[f][XPOS], DEC);
- Serial.print(" y: ");
- Serial.print(icons[f][YPOS], DEC);
- Serial.print(" dy: ");
- Serial.println(icons[f][DELTAY], DEC);
- }
-
- while (1) {
- // draw each icon
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
- }
- display.display();
- delay(200);
-
- // then erase it + move it
- for (uint8_t f=0; f< NUMFLAKES; f++) {
- display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
- // move it
- icons[f][YPOS] += icons[f][DELTAY];
- // if its gone, reinit
- if (icons[f][YPOS] > display.height()) {
- icons[f][XPOS] = random(display.width());
- icons[f][YPOS] = 0;
- icons[f][DELTAY] = random(5) + 1;
- }
- }
- }
-}
-
-
-void testdrawchar(void) {
- display.setTextSize(1);
- display.setTextColor(WHITE);
- display.setCursor(0,0);
-
- for (uint8_t i=0; i < 168; i++) {
- if (i == '\n') continue;
- display.write(i);
- if ((i > 0) && (i % 21 == 0))
- display.println();
- }
- display.display();
-}
-
-void testdrawcircle(void) {
- for (int16_t i=0; i0; i-=5) {
- display.fillTriangle(display.width()/2, display.height()/2-i,
- display.width()/2-i, display.height()/2+i,
- display.width()/2+i, display.height()/2+i, WHITE);
- if (color == WHITE) color = BLACK;
- else color = WHITE;
- display.display();
- }
-}
-
-void testdrawroundrect(void) {
- for (int16_t i=0; i=0; i-=4) {
- display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
- display.display();
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=display.width()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
- display.display();
- }
- for (int16_t i=display.height()-1; i>=0; i-=4) {
- display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
- display.display();
- }
- delay(250);
-
- display.clearDisplay();
- for (int16_t i=0; i
-sentence=SSD1306 oled driver library for 'monochrome' 128x64 and 128x32 OLEDs!
-paragraph=SSD1306 oled driver library for 'monochrome' 128x64 and 128x32 OLEDs!
-category=Display
-url=https://github.com/adafruit/Adafruit_SSD1306
-architectures=*
diff --git a/lib/Adafruit_SSD1306-1.1.2/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_SSD1306-1.3.0/.github/ISSUE_TEMPLATE.md
similarity index 100%
rename from lib/Adafruit_SSD1306-1.1.2/.github/ISSUE_TEMPLATE.md
rename to lib/Adafruit_SSD1306-1.3.0/.github/ISSUE_TEMPLATE.md
diff --git a/lib/Adafruit_SSD1306-1.1.2/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_SSD1306-1.3.0/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from lib/Adafruit_SSD1306-1.1.2/.github/PULL_REQUEST_TEMPLATE.md
rename to lib/Adafruit_SSD1306-1.3.0/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/lib/Adafruit_SSD1306-1.3.0/.gitignore b/lib/Adafruit_SSD1306-1.3.0/.gitignore
new file mode 100644
index 000000000..c2a26c038
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/.gitignore
@@ -0,0 +1,4 @@
+# Our handy .gitignore for automation ease
+Doxyfile*
+doxygen_sqlite3.db
+html
diff --git a/lib/Adafruit_SSD1306-1.3.0/.travis.yml b/lib/Adafruit_SSD1306-1.3.0/.travis.yml
new file mode 100644
index 000000000..1d9184e52
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/.travis.yml
@@ -0,0 +1,29 @@
+language: c
+sudo: false
+cache:
+ directories:
+ - ~/arduino_ide
+ - ~/.arduino15/packages/
+git:
+ depth: false
+ quiet: true
+env:
+ global:
+ - ARDUINO_IDE_VERSION="1.8.5"
+ - PRETTYNAME="Adafruit SSD1306"
+# Optional, will default to "$TRAVIS_BUILD_DIR/Doxyfile"
+# - DOXYFILE: $TRAVIS_BUILD_DIR/Doxyfile
+
+before_install:
+ - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
+
+install:
+ - arduino --install-library "Adafruit GFX Library"
+
+script:
+ - build_main_platforms
+
+# Generate and deploy documentation
+after_success:
+ - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
+ - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
diff --git a/lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.cpp b/lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.cpp
new file mode 100644
index 000000000..46218d7dd
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.cpp
@@ -0,0 +1,1101 @@
+/*!
+ * @file Adafruit_SSD1306.cpp
+ *
+ * @mainpage Arduino library for monochrome OLEDs based on SSD1306 drivers.
+ *
+ * @section intro_sec Introduction
+ *
+ * This is documentation for Adafruit's SSD1306 library for monochrome
+ * OLED displays: http://www.adafruit.com/category/63_98
+ *
+ * These displays use I2C or SPI to communicate. I2C requires 2 pins
+ * (SCL+SDA) and optionally a RESET pin. SPI requires 4 pins (MOSI, SCK,
+ * select, data/command) and optionally a reset pin. Hardware SPI or
+ * 'bitbang' software SPI are both supported.
+ *
+ * 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
+ * Adafruit_GFX being present on your system. Please make sure you have
+ * installed the latest version before using this library.
+ *
+ * @section author Author
+ *
+ * Written by Limor Fried/Ladyada for Adafruit Industries, with
+ * contributions from the open source community.
+ *
+ * @section license License
+ *
+ * BSD license, all text above, and the splash screen included below,
+ * must be included in any redistribution.
+ *
+ */
+
+#ifdef __AVR__
+ #include
+#elif defined(ESP8266) || defined(ESP32)
+ #include
+#else
+ #define pgm_read_byte(addr) \
+ (*(const unsigned char *)(addr)) ///< PROGMEM workaround for non-AVR
+#endif
+
+#if !defined(__ARM_ARCH) && !defined(ENERGIA) && !defined(ESP8266) && !defined(ESP32) && !defined(__arc__)
+ #include
+#endif
+
+#include
+#include "Adafruit_SSD1306.h"
+#include "splash.h"
+
+// SOME DEFINES AND STATIC VARIABLES USED INTERNALLY -----------------------
+
+#if defined(BUFFER_LENGTH)
+ #define WIRE_MAX BUFFER_LENGTH ///< AVR or similar Wire lib
+#elif defined(SERIAL_BUFFER_SIZE)
+ #define WIRE_MAX (SERIAL_BUFFER_SIZE-1) ///< Newer Wire uses RingBuffer
+#else
+ #define WIRE_MAX 32 ///< Use common Arduino core default
+#endif
+
+#define ssd1306_swap(a, b) \
+ (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
+
+#if ARDUINO >= 100
+ #define WIRE_WRITE wire->write ///< Wire write function in recent Arduino lib
+#else
+ #define WIRE_WRITE wire->send ///< Wire write function in older Arduino lib
+#endif
+
+#ifdef HAVE_PORTREG
+ #define SSD1306_SELECT *csPort &= ~csPinMask; ///< Device select
+ #define SSD1306_DESELECT *csPort |= csPinMask; ///< Device deselect
+ #define SSD1306_MODE_COMMAND *dcPort &= ~dcPinMask; ///< Command mode
+ #define SSD1306_MODE_DATA *dcPort |= dcPinMask; ///< Data mode
+#else
+ #define SSD1306_SELECT digitalWrite(csPin, LOW); ///< Device select
+ #define SSD1306_DESELECT digitalWrite(csPin, HIGH); ///< Device deselect
+ #define SSD1306_MODE_COMMAND digitalWrite(dcPin, LOW); ///< Command mode
+ #define SSD1306_MODE_DATA digitalWrite(dcPin, HIGH); ///< Data mode
+#endif
+
+#if (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER)
+ #define SETWIRECLOCK wire->setClock(wireClk) ///< Set before I2C transfer
+ #define RESWIRECLOCK wire->setClock(restoreClk) ///< Restore after I2C xfer
+#else // setClock() is not present in older Arduino Wire lib (or WICED)
+ #define SETWIRECLOCK ///< Dummy stand-in define
+ #define RESWIRECLOCK ///< keeps compiler happy
+#endif
+
+#if defined(SPI_HAS_TRANSACTION)
+ #define SPI_TRANSACTION_START spi->beginTransaction(spiSettings) ///< Pre-SPI
+ #define SPI_TRANSACTION_END spi->endTransaction() ///< Post-SPI
+#else // SPI transactions likewise not present in older Arduino SPI lib
+ #define SPI_TRANSACTION_START ///< Dummy stand-in define
+ #define SPI_TRANSACTION_END ///< keeps compiler happy
+#endif
+
+// The definition of 'transaction' is broadened a bit in the context of
+// this library -- referring not just to SPI transactions (if supported
+// in the version of the SPI library being used), but also chip select
+// (if SPI is being used, whether hardware or soft), and also to the
+// beginning and end of I2C transfers (the Wire clock may be sped up before
+// issuing data to the display, then restored to the default rate afterward
+// so other I2C device types still work). All of these are encapsulated
+// in the TRANSACTION_* macros.
+
+// Check first if Wire, then hardware SPI, then soft SPI:
+#define TRANSACTION_START \
+ if(wire) { \
+ SETWIRECLOCK; \
+ } else { \
+ if(spi) { \
+ SPI_TRANSACTION_START; \
+ } \
+ SSD1306_SELECT; \
+ } ///< Wire, SPI or bitbang transfer setup
+#define TRANSACTION_END \
+ if(wire) { \
+ RESWIRECLOCK; \
+ } else { \
+ SSD1306_DESELECT; \
+ if(spi) { \
+ SPI_TRANSACTION_END; \
+ } \
+ } ///< Wire, SPI or bitbang transfer end
+
+// CONSTRUCTORS, DESTRUCTOR ------------------------------------------------
+
+/*!
+ @brief Constructor for I2C-interfaced SSD1306 displays.
+ @param w
+ Display width in pixels
+ @param h
+ Display height in pixels
+ @param twi
+ Pointer to an existing TwoWire instance (e.g. &Wire, the
+ microcontroller's primary I2C bus).
+ @param rst_pin
+ Reset pin (using Arduino pin numbering), or -1 if not used
+ (some displays might be wired to share the microcontroller's
+ reset pin).
+ @param clkDuring
+ Speed (in Hz) for Wire transmissions in SSD1306 library calls.
+ Defaults to 400000 (400 KHz), a known 'safe' value for most
+ microcontrollers, and meets the SSD1306 datasheet spec.
+ Some systems can operate I2C faster (800 KHz for ESP32, 1 MHz
+ for many other 32-bit MCUs), and some (perhaps not all)
+ SSD1306's can work with this -- so it's optionally be specified
+ here and is not a default behavior. (Ignored if using pre-1.5.7
+ Arduino software, which operates I2C at a fixed 100 KHz.)
+ @param clkAfter
+ Speed (in Hz) for Wire transmissions following SSD1306 library
+ calls. Defaults to 100000 (100 KHz), the default Arduino Wire
+ speed. This is done rather than leaving it at the 'during' speed
+ because other devices on the I2C bus might not be compatible
+ with the faster rate. (Ignored if using pre-1.5.7 Arduino
+ software, which operates I2C at a fixed 100 KHz.)
+ @return Adafruit_SSD1306 object.
+ @note Call the object's begin() function before use -- buffer
+ allocation is performed there!
+*/
+Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi,
+ int8_t rst_pin, uint32_t clkDuring, uint32_t clkAfter) :
+ Adafruit_GFX(w, h), spi(NULL), wire(twi ? twi : &Wire), buffer(NULL),
+ mosiPin(-1), clkPin(-1), dcPin(-1), csPin(-1), rstPin(rst_pin),
+ wireClk(clkDuring), restoreClk(clkAfter) {
+}
+
+/*!
+ @brief Constructor for SPI SSD1306 displays, using software (bitbang)
+ SPI.
+ @param w
+ Display width in pixels
+ @param h
+ Display height in pixels
+ @param mosi_pin
+ MOSI (master out, slave in) pin (using Arduino pin numbering).
+ This transfers serial data from microcontroller to display.
+ @param sclk_pin
+ SCLK (serial clock) pin (using Arduino pin numbering).
+ This clocks each bit from MOSI.
+ @param dc_pin
+ Data/command pin (using Arduino pin numbering), selects whether
+ display is receiving commands (low) or data (high).
+ @param rst_pin
+ Reset pin (using Arduino pin numbering), or -1 if not used
+ (some displays might be wired to share the microcontroller's
+ reset pin).
+ @param cs_pin
+ Chip-select pin (using Arduino pin numbering) for sharing the
+ bus with other devices. Active low.
+ @return Adafruit_SSD1306 object.
+ @note Call the object's begin() function before use -- buffer
+ allocation is performed there!
+*/
+Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h,
+ int8_t mosi_pin, int8_t sclk_pin, int8_t dc_pin, int8_t rst_pin,
+ int8_t cs_pin) : Adafruit_GFX(w, h), spi(NULL), wire(NULL), buffer(NULL),
+ mosiPin(mosi_pin), clkPin(sclk_pin), dcPin(dc_pin), csPin(cs_pin),
+ rstPin(rst_pin) {
+}
+
+/*!
+ @brief Constructor for SPI SSD1306 displays, using native hardware SPI.
+ @param w
+ Display width in pixels
+ @param h
+ Display height in pixels
+ @param spi
+ Pointer to an existing SPIClass instance (e.g. &SPI, the
+ microcontroller's primary SPI bus).
+ @param dc_pin
+ Data/command pin (using Arduino pin numbering), selects whether
+ display is receiving commands (low) or data (high).
+ @param rst_pin
+ Reset pin (using Arduino pin numbering), or -1 if not used
+ (some displays might be wired to share the microcontroller's
+ reset pin).
+ @param cs_pin
+ Chip-select pin (using Arduino pin numbering) for sharing the
+ bus with other devices. Active low.
+ @param bitrate
+ SPI clock rate for transfers to this display. Default if
+ unspecified is 8000000UL (8 MHz).
+ @return Adafruit_SSD1306 object.
+ @note Call the object's begin() function before use -- buffer
+ allocation is performed there!
+*/
+Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, SPIClass *spi,
+ int8_t dc_pin, int8_t rst_pin, int8_t cs_pin, uint32_t bitrate) :
+ Adafruit_GFX(w, h), spi(spi ? spi : &SPI), wire(NULL), buffer(NULL),
+ mosiPin(-1), clkPin(-1), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin) {
+#ifdef SPI_HAS_TRANSACTION
+ spiSettings = SPISettings(bitrate, MSBFIRST, SPI_MODE0);
+#endif
+}
+
+/*!
+ @brief DEPRECATED constructor for SPI SSD1306 displays, using software
+ (bitbang) SPI. Provided for older code to maintain compatibility
+ with the current library. Screen size is determined by enabling
+ one of the SSD1306_* size defines in Adafruit_SSD1306.h. New
+ code should NOT use this.
+ @param mosi_pin
+ MOSI (master out, slave in) pin (using Arduino pin numbering).
+ This transfers serial data from microcontroller to display.
+ @param sclk_pin
+ SCLK (serial clock) pin (using Arduino pin numbering).
+ This clocks each bit from MOSI.
+ @param dc_pin
+ Data/command pin (using Arduino pin numbering), selects whether
+ display is receiving commands (low) or data (high).
+ @param rst_pin
+ Reset pin (using Arduino pin numbering), or -1 if not used
+ (some displays might be wired to share the microcontroller's
+ reset pin).
+ @param cs_pin
+ Chip-select pin (using Arduino pin numbering) for sharing the
+ bus with other devices. Active low.
+ @return Adafruit_SSD1306 object.
+ @note Call the object's begin() function before use -- buffer
+ allocation is performed there!
+*/
+Adafruit_SSD1306::Adafruit_SSD1306(int8_t mosi_pin, int8_t sclk_pin,
+ int8_t dc_pin, int8_t rst_pin, int8_t cs_pin) :
+ Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT), spi(NULL), wire(NULL),
+ buffer(NULL), mosiPin(mosi_pin), clkPin(sclk_pin), dcPin(dc_pin),
+ csPin(cs_pin), rstPin(rst_pin) {
+}
+
+/*!
+ @brief DEPRECATED constructor for SPI SSD1306 displays, using native
+ hardware SPI. Provided for older code to maintain compatibility
+ with the current library. Screen size is determined by enabling
+ one of the SSD1306_* size defines in Adafruit_SSD1306.h. New
+ code should NOT use this. Only the primary SPI bus is supported,
+ and bitrate is fixed at 8 MHz.
+ @param dc_pin
+ Data/command pin (using Arduino pin numbering), selects whether
+ display is receiving commands (low) or data (high).
+ @param rst_pin
+ Reset pin (using Arduino pin numbering), or -1 if not used
+ (some displays might be wired to share the microcontroller's
+ reset pin).
+ @param cs_pin
+ Chip-select pin (using Arduino pin numbering) for sharing the
+ bus with other devices. Active low.
+ @return Adafruit_SSD1306 object.
+ @note Call the object's begin() function before use -- buffer
+ allocation is performed there!
+*/
+Adafruit_SSD1306::Adafruit_SSD1306(int8_t dc_pin, int8_t rst_pin,
+ int8_t cs_pin) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT),
+ spi(&SPI), wire(NULL), buffer(NULL), mosiPin(-1), clkPin(-1),
+ dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin) {
+#ifdef SPI_HAS_TRANSACTION
+ spiSettings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
+#endif
+}
+
+/*!
+ @brief DEPRECATED constructor for I2C SSD1306 displays. Provided for
+ older code to maintain compatibility with the current library.
+ Screen size is determined by enabling one of the SSD1306_* size
+ defines in Adafruit_SSD1306.h. New code should NOT use this.
+ Only the primary I2C bus is supported.
+ @param rst_pin
+ Reset pin (using Arduino pin numbering), or -1 if not used
+ (some displays might be wired to share the microcontroller's
+ reset pin).
+ @return Adafruit_SSD1306 object.
+ @note Call the object's begin() function before use -- buffer
+ allocation is performed there!
+*/
+Adafruit_SSD1306::Adafruit_SSD1306(int8_t rst_pin) :
+ Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT), spi(NULL), wire(&Wire),
+ buffer(NULL), mosiPin(-1), clkPin(-1), dcPin(-1), csPin(-1),
+ rstPin(rst_pin) {
+}
+
+/*!
+ @brief Destructor for Adafruit_SSD1306 object.
+*/
+Adafruit_SSD1306::~Adafruit_SSD1306(void) {
+ if(buffer) {
+ free(buffer);
+ buffer = NULL;
+ }
+}
+
+// LOW-LEVEL UTILS ---------------------------------------------------------
+
+// Issue single byte out SPI, either soft or hardware as appropriate.
+// SPI transaction/selection must be performed in calling function.
+inline void Adafruit_SSD1306::SPIwrite(uint8_t d) {
+ if(spi) {
+ (void)spi->transfer(d);
+ } else {
+ for(uint8_t bit = 0x80; bit; bit >>= 1) {
+#ifdef HAVE_PORTREG
+ if(d & bit) *mosiPort |= mosiPinMask;
+ else *mosiPort &= ~mosiPinMask;
+ *clkPort |= clkPinMask; // Clock high
+ *clkPort &= ~clkPinMask; // Clock low
+#else
+ digitalWrite(mosiPin, d & bit);
+ digitalWrite(clkPin , HIGH);
+ digitalWrite(clkPin , LOW);
+#endif
+ }
+ }
+}
+
+// Issue single command to SSD1306, using I2C or hard/soft SPI as needed.
+// Because command calls are often grouped, SPI transaction and selection
+// must be started/ended in calling function for efficiency.
+// This is a private function, not exposed (see ssd1306_command() instead).
+void Adafruit_SSD1306::ssd1306_command1(uint8_t c) {
+ if(wire) { // I2C
+ wire->beginTransmission(i2caddr);
+ WIRE_WRITE((uint8_t)0x00); // Co = 0, D/C = 0
+ WIRE_WRITE(c);
+ wire->endTransmission();
+ } else { // SPI (hw or soft) -- transaction started in calling function
+ SSD1306_MODE_COMMAND
+ SPIwrite(c);
+ }
+}
+
+// Issue list of commands to SSD1306, same rules as above re: transactions.
+// This is a private function, not exposed.
+void Adafruit_SSD1306::ssd1306_commandList(const uint8_t *c, uint8_t n) {
+ if(wire) { // I2C
+ wire->beginTransmission(i2caddr);
+ WIRE_WRITE((uint8_t)0x00); // Co = 0, D/C = 0
+ uint8_t bytesOut = 1;
+ while(n--) {
+ if(bytesOut >= WIRE_MAX) {
+ wire->endTransmission();
+ wire->beginTransmission(i2caddr);
+ WIRE_WRITE((uint8_t)0x00); // Co = 0, D/C = 0
+ bytesOut = 1;
+ }
+ WIRE_WRITE(pgm_read_byte(c++));
+ bytesOut++;
+ }
+ wire->endTransmission();
+ } else { // SPI -- transaction started in calling function
+ SSD1306_MODE_COMMAND
+ while(n--) SPIwrite(pgm_read_byte(c++));
+ }
+}
+
+// A public version of ssd1306_command1(), for existing user code that
+// might rely on that function. This encapsulates the command transfer
+// in a transaction start/end, similar to old library's handling of it.
+/*!
+ @brief Issue a single low-level command directly to the SSD1306
+ display, bypassing the library.
+ @param c
+ Command to issue (0x00 to 0xFF, see datasheet).
+ @return None (void).
+*/
+void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
+ TRANSACTION_START
+ ssd1306_command1(c);
+ TRANSACTION_END
+}
+
+// ALLOCATE & INIT DISPLAY -------------------------------------------------
+
+/*!
+ @brief Allocate RAM for image buffer, initialize peripherals and pins.
+ @param vcs
+ VCC selection. Pass SSD1306_SWITCHCAPVCC to generate the display
+ voltage (step up) from the 3.3V source, or SSD1306_EXTERNALVCC
+ otherwise. Most situations with Adafruit SSD1306 breakouts will
+ want SSD1306_SWITCHCAPVCC.
+ @param addr
+ I2C address of corresponding SSD1306 display (or pass 0 to use
+ default of 0x3C for 128x32 display, 0x3D for all others).
+ SPI displays (hardware or software) do not use addresses, but
+ this argument is still required (pass 0 or any value really,
+ it will simply be ignored). Default if unspecified is 0.
+ @param reset
+ If true, and if the reset pin passed to the constructor is
+ valid, a hard reset will be performed before initializing the
+ display. If using multiple SSD1306 displays on the same bus, and
+ if they all share the same reset pin, you should only pass true
+ on the first display being initialized, false on all others,
+ else the already-initialized displays would be reset. Default if
+ unspecified is true.
+ @param periphBegin
+ If true, and if a hardware peripheral is being used (I2C or SPI,
+ but not software SPI), call that peripheral's begin() function,
+ else (false) it has already been done in one's sketch code.
+ Cases where false might be used include multiple displays or
+ other devices sharing a common bus, or situations on some
+ platforms where a nonstandard begin() function is available
+ (e.g. a TwoWire interface on non-default pins, as can be done
+ on the ESP8266 and perhaps others).
+ @return true on successful allocation/init, false otherwise.
+ Well-behaved code should check the return value before
+ proceeding.
+ @note MUST call this function before any drawing or updates!
+*/
+boolean Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, boolean reset,
+ boolean periphBegin) {
+
+ if((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
+ return false;
+
+ clearDisplay();
+ if(HEIGHT > 32) {
+ drawBitmap((WIDTH - splash1_width) / 2, (HEIGHT - splash1_height) / 2,
+ splash1_data, splash1_width, splash1_height, 1);
+ } else {
+ drawBitmap((WIDTH - splash2_width) / 2, (HEIGHT - splash2_height) / 2,
+ splash2_data, splash2_width, splash2_height, 1);
+ }
+
+ vccstate = vcs;
+
+ // Setup pin directions
+ if(wire) { // Using I2C
+ // If I2C address is unspecified, use default
+ // (0x3C for 32-pixel-tall displays, 0x3D for all others).
+ i2caddr = addr ? addr : ((HEIGHT == 32) ? 0x3C : 0x3D);
+ // TwoWire begin() function might be already performed by the calling
+ // function if it has unusual circumstances (e.g. TWI variants that
+ // can accept different SDA/SCL pins, or if two SSD1306 instances
+ // with different addresses -- only a single begin() is needed).
+ if(periphBegin) wire->begin();
+ } else { // Using one of the SPI modes, either soft or hardware
+ pinMode(dcPin, OUTPUT); // Set data/command pin as output
+ pinMode(csPin, OUTPUT); // Same for chip select
+#ifdef HAVE_PORTREG
+ dcPort = (PortReg *)portOutputRegister(digitalPinToPort(dcPin));
+ dcPinMask = digitalPinToBitMask(dcPin);
+ csPort = (PortReg *)portOutputRegister(digitalPinToPort(csPin));
+ csPinMask = digitalPinToBitMask(csPin);
+#endif
+ SSD1306_DESELECT
+ if(spi) { // Hardware SPI
+ // SPI peripheral begin same as wire check above.
+ if(periphBegin) spi->begin();
+ } else { // Soft SPI
+ pinMode(mosiPin, OUTPUT); // MOSI and SCLK outputs
+ pinMode(clkPin , OUTPUT);
+#ifdef HAVE_PORTREG
+ mosiPort = (PortReg *)portOutputRegister(digitalPinToPort(mosiPin));
+ mosiPinMask = digitalPinToBitMask(mosiPin);
+ clkPort = (PortReg *)portOutputRegister(digitalPinToPort(clkPin));
+ clkPinMask = digitalPinToBitMask(clkPin);
+ *clkPort &= ~clkPinMask; // Clock low
+#else
+ digitalWrite(clkPin, LOW); // Clock low
+#endif
+ }
+ }
+
+ // Reset SSD1306 if requested and reset pin specified in constructor
+ if(reset && (rstPin >= 0)) {
+ pinMode( rstPin, OUTPUT);
+ digitalWrite(rstPin, HIGH);
+ delay(1); // VDD goes high at start, pause for 1 ms
+ digitalWrite(rstPin, LOW); // Bring reset low
+ delay(10); // Wait 10 ms
+ digitalWrite(rstPin, HIGH); // Bring out of reset
+ }
+
+ TRANSACTION_START
+
+ // Init sequence
+ static const uint8_t PROGMEM init1[] = {
+ SSD1306_DISPLAYOFF, // 0xAE
+ SSD1306_SETDISPLAYCLOCKDIV, // 0xD5
+ 0x80, // the suggested ratio 0x80
+ SSD1306_SETMULTIPLEX }; // 0xA8
+ ssd1306_commandList(init1, sizeof(init1));
+ ssd1306_command1(HEIGHT - 1);
+
+ static const uint8_t PROGMEM init2[] = {
+ SSD1306_SETDISPLAYOFFSET, // 0xD3
+ 0x0, // no offset
+ SSD1306_SETSTARTLINE | 0x0, // line #0
+ SSD1306_CHARGEPUMP }; // 0x8D
+ ssd1306_commandList(init2, sizeof(init2));
+
+ ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0x14);
+
+ static const uint8_t PROGMEM init3[] = {
+ SSD1306_MEMORYMODE, // 0x20
+ 0x00, // 0x0 act like ks0108
+ SSD1306_SEGREMAP | 0x1,
+ SSD1306_COMSCANDEC };
+ ssd1306_commandList(init3, sizeof(init3));
+
+ if((WIDTH == 128) && (HEIGHT == 32)) {
+ static const uint8_t PROGMEM init4a[] = {
+ SSD1306_SETCOMPINS, // 0xDA
+ 0x02,
+ SSD1306_SETCONTRAST, // 0x81
+ 0x8F };
+ ssd1306_commandList(init4a, sizeof(init4a));
+ } else if((WIDTH == 128) && (HEIGHT == 64)) {
+ static const uint8_t PROGMEM init4b[] = {
+ SSD1306_SETCOMPINS, // 0xDA
+ 0x12,
+ SSD1306_SETCONTRAST }; // 0x81
+ ssd1306_commandList(init4b, sizeof(init4b));
+ ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF);
+ } else if((WIDTH == 96) && (HEIGHT == 16)) {
+ static const uint8_t PROGMEM init4c[] = {
+ SSD1306_SETCOMPINS, // 0xDA
+ 0x2, // ada x12
+ SSD1306_SETCONTRAST }; // 0x81
+ ssd1306_commandList(init4c, sizeof(init4c));
+ ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0xAF);
+ } else {
+ // Other screen varieties -- TBD
+ }
+
+ ssd1306_command1(SSD1306_SETPRECHARGE); // 0xd9
+ ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1);
+ static const uint8_t PROGMEM init5[] = {
+ SSD1306_SETVCOMDETECT, // 0xDB
+ 0x40,
+ SSD1306_DISPLAYALLON_RESUME, // 0xA4
+ SSD1306_NORMALDISPLAY, // 0xA6
+ SSD1306_DEACTIVATE_SCROLL,
+ SSD1306_DISPLAYON }; // Main screen turn on
+ ssd1306_commandList(init5, sizeof(init5));
+
+ TRANSACTION_END
+
+ return true; // Success
+}
+
+// DRAWING FUNCTIONS -------------------------------------------------------
+
+/*!
+ @brief Set/clear/invert a single pixel. This is also invoked by the
+ Adafruit_GFX library in generating many higher-level graphics
+ primitives.
+ @param x
+ Column of display -- 0 at left to (screen width - 1) at right.
+ @param y
+ Row of display -- 0 at top to (screen height -1) at bottom.
+ @param color
+ Pixel color, one of: BLACK, WHITE or INVERT.
+ @return None (void).
+ @note Changes buffer contents only, no immediate effect on display.
+ Follow up with a call to display(), or with other graphics
+ commands as needed by one's own application.
+*/
+void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
+ if((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
+ // Pixel is in-bounds. Rotate coordinates if needed.
+ switch(getRotation()) {
+ case 1:
+ ssd1306_swap(x, y);
+ x = WIDTH - x - 1;
+ break;
+ case 2:
+ x = WIDTH - x - 1;
+ y = HEIGHT - y - 1;
+ break;
+ case 3:
+ ssd1306_swap(x, y);
+ y = HEIGHT - y - 1;
+ break;
+ }
+ switch(color) {
+ case WHITE: buffer[x + (y/8)*WIDTH] |= (1 << (y&7)); break;
+ case BLACK: buffer[x + (y/8)*WIDTH] &= ~(1 << (y&7)); break;
+ case INVERSE: buffer[x + (y/8)*WIDTH] ^= (1 << (y&7)); break;
+ }
+ }
+}
+
+/*!
+ @brief Clear contents of display buffer (set all pixels to off).
+ @return None (void).
+ @note Changes buffer contents only, no immediate effect on display.
+ Follow up with a call to display(), or with other graphics
+ commands as needed by one's own application.
+*/
+void Adafruit_SSD1306::clearDisplay(void) {
+ memset(buffer, 0, WIDTH * ((HEIGHT + 7) / 8));
+}
+
+/*!
+ @brief Draw a horizontal line. This is also invoked by the Adafruit_GFX
+ library in generating many higher-level graphics primitives.
+ @param x
+ Leftmost column -- 0 at left to (screen width - 1) at right.
+ @param y
+ Row of display -- 0 at top to (screen height -1) at bottom.
+ @param w
+ Width of line, in pixels.
+ @param color
+ Line color, one of: BLACK, WHITE or INVERT.
+ @return None (void).
+ @note Changes buffer contents only, no immediate effect on display.
+ Follow up with a call to display(), or with other graphics
+ commands as needed by one's own application.
+*/
+void Adafruit_SSD1306::drawFastHLine(
+ int16_t x, int16_t y, int16_t w, uint16_t color) {
+ boolean bSwap = false;
+ switch(rotation) {
+ case 1:
+ // 90 degree rotation, swap x & y for rotation, then invert x
+ bSwap = true;
+ ssd1306_swap(x, y);
+ x = WIDTH - x - 1;
+ break;
+ case 2:
+ // 180 degree rotation, invert x and y, then shift y around for height.
+ x = WIDTH - x - 1;
+ y = HEIGHT - y - 1;
+ x -= (w-1);
+ break;
+ case 3:
+ // 270 degree rotation, swap x & y for rotation,
+ // then invert y and adjust y for w (not to become h)
+ bSwap = true;
+ ssd1306_swap(x, y);
+ y = HEIGHT - y - 1;
+ y -= (w-1);
+ break;
+ }
+
+ if(bSwap) drawFastVLineInternal(x, y, w, color);
+ else drawFastHLineInternal(x, y, w, color);
+}
+
+void Adafruit_SSD1306::drawFastHLineInternal(
+ int16_t x, int16_t y, int16_t w, uint16_t color) {
+
+ if((y >= 0) && (y < HEIGHT)) { // Y coord in bounds?
+ if(x < 0) { // Clip left
+ w += x;
+ x = 0;
+ }
+ if((x + w) > WIDTH) { // Clip right
+ w = (WIDTH - x);
+ }
+ if(w > 0) { // Proceed only if width is positive
+ uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x],
+ mask = 1 << (y & 7);
+ switch(color) {
+ case WHITE: while(w--) { *pBuf++ |= mask; }; break;
+ case BLACK: mask = ~mask; while(w--) { *pBuf++ &= mask; }; break;
+ case INVERSE: while(w--) { *pBuf++ ^= mask; }; break;
+ }
+ }
+ }
+}
+
+/*!
+ @brief Draw a vertical line. This is also invoked by the Adafruit_GFX
+ library in generating many higher-level graphics primitives.
+ @param x
+ Column of display -- 0 at left to (screen width -1) at right.
+ @param y
+ Topmost row -- 0 at top to (screen height - 1) at bottom.
+ @param h
+ Height of line, in pixels.
+ @param color
+ Line color, one of: BLACK, WHITE or INVERT.
+ @return None (void).
+ @note Changes buffer contents only, no immediate effect on display.
+ Follow up with a call to display(), or with other graphics
+ commands as needed by one's own application.
+*/
+void Adafruit_SSD1306::drawFastVLine(
+ int16_t x, int16_t y, int16_t h, uint16_t color) {
+ boolean bSwap = false;
+ switch(rotation) {
+ case 1:
+ // 90 degree rotation, swap x & y for rotation,
+ // then invert x and adjust x for h (now to become w)
+ bSwap = true;
+ ssd1306_swap(x, y);
+ x = WIDTH - x - 1;
+ x -= (h-1);
+ break;
+ case 2:
+ // 180 degree rotation, invert x and y, then shift y around for height.
+ x = WIDTH - x - 1;
+ y = HEIGHT - y - 1;
+ y -= (h-1);
+ break;
+ case 3:
+ // 270 degree rotation, swap x & y for rotation, then invert y
+ bSwap = true;
+ ssd1306_swap(x, y);
+ y = HEIGHT - y - 1;
+ break;
+ }
+
+ if(bSwap) drawFastHLineInternal(x, y, h, color);
+ else drawFastVLineInternal(x, y, h, color);
+}
+
+void Adafruit_SSD1306::drawFastVLineInternal(
+ int16_t x, int16_t __y, int16_t __h, uint16_t color) {
+
+ if((x >= 0) && (x < WIDTH)) { // X coord in bounds?
+ if(__y < 0) { // Clip top
+ __h += __y;
+ __y = 0;
+ }
+ if((__y + __h) > HEIGHT) { // Clip bottom
+ __h = (HEIGHT - __y);
+ }
+ if(__h > 0) { // Proceed only if height is now positive
+ // this display doesn't need ints for coordinates,
+ // use local byte registers for faster juggling
+ uint8_t y = __y, h = __h;
+ uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x];
+
+ // do the first partial byte, if necessary - this requires some masking
+ uint8_t mod = (y & 7);
+ if(mod) {
+ // mask off the high n bits we want to set
+ mod = 8 - mod;
+ // note - lookup table results in a nearly 10% performance
+ // improvement in fill* functions
+ // uint8_t mask = ~(0xFF >> mod);
+ static const uint8_t PROGMEM premask[8] =
+ { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
+ uint8_t mask = pgm_read_byte(&premask[mod]);
+ // adjust the mask if we're not going to reach the end of this byte
+ if(h < mod) mask &= (0XFF >> (mod - h));
+
+ switch(color) {
+ case WHITE: *pBuf |= mask; break;
+ case BLACK: *pBuf &= ~mask; break;
+ case INVERSE: *pBuf ^= mask; break;
+ }
+ pBuf += WIDTH;
+ }
+
+ if(h >= mod) { // More to go?
+ h -= mod;
+ // Write solid bytes while we can - effectively 8 rows at a time
+ if(h >= 8) {
+ if(color == INVERSE) {
+ // separate copy of the code so we don't impact performance of
+ // black/white write version with an extra comparison per loop
+ do {
+ *pBuf ^= 0xFF; // Invert byte
+ pBuf += WIDTH; // Advance pointer 8 rows
+ h -= 8; // Subtract 8 rows from height
+ } while(h >= 8);
+ } else {
+ // store a local value to work with
+ uint8_t val = (color != BLACK) ? 255 : 0;
+ do {
+ *pBuf = val; // Set byte
+ pBuf += WIDTH; // Advance pointer 8 rows
+ h -= 8; // Subtract 8 rows from height
+ } while(h >= 8);
+ }
+ }
+
+ if(h) { // Do the final partial byte, if necessary
+ mod = h & 7;
+ // this time we want to mask the low bits of the byte,
+ // vs the high bits we did above
+ // uint8_t mask = (1 << mod) - 1;
+ // note - lookup table results in a nearly 10% performance
+ // improvement in fill* functions
+ static const uint8_t PROGMEM postmask[8] =
+ { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
+ uint8_t mask = pgm_read_byte(&postmask[mod]);
+ switch(color) {
+ case WHITE: *pBuf |= mask; break;
+ case BLACK: *pBuf &= ~mask; break;
+ case INVERSE: *pBuf ^= mask; break;
+ }
+ }
+ }
+ } // endif positive height
+ } // endif x in bounds
+}
+
+/*!
+ @brief Return color of a single pixel in display buffer.
+ @param x
+ Column of display -- 0 at left to (screen width - 1) at right.
+ @param y
+ Row of display -- 0 at top to (screen height -1) at bottom.
+ @return true if pixel is set (usually WHITE, unless display invert mode
+ is enabled), false if clear (BLACK).
+ @note Reads from buffer contents; may not reflect current contents of
+ screen if display() has not been called.
+*/
+boolean Adafruit_SSD1306::getPixel(int16_t x, int16_t y) {
+ if((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
+ // Pixel is in-bounds. Rotate coordinates if needed.
+ switch(getRotation()) {
+ case 1:
+ ssd1306_swap(x, y);
+ x = WIDTH - x - 1;
+ break;
+ case 2:
+ x = WIDTH - x - 1;
+ y = HEIGHT - y - 1;
+ break;
+ case 3:
+ ssd1306_swap(x, y);
+ y = HEIGHT - y - 1;
+ break;
+ }
+ return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
+ }
+ return false; // Pixel out of bounds
+}
+
+/*!
+ @brief Get base address of display buffer for direct reading or writing.
+ @return Pointer to an unsigned 8-bit array, column-major, columns padded
+ to full byte boundary if needed.
+*/
+uint8_t *Adafruit_SSD1306::getBuffer(void) {
+ return buffer;
+}
+
+// REFRESH DISPLAY ---------------------------------------------------------
+
+/*!
+ @brief Push data currently in RAM to SSD1306 display.
+ @return None (void).
+ @note Drawing operations are not visible until this function is
+ called. Call after each graphics command, or after a whole set
+ of graphics commands, as best needed by one's own application.
+*/
+void Adafruit_SSD1306::display(void) {
+ TRANSACTION_START
+ static const uint8_t PROGMEM dlist1[] = {
+ SSD1306_PAGEADDR,
+ 0, // Page start address
+ 0xFF, // Page end (not really, but works here)
+ SSD1306_COLUMNADDR,
+ 0 }; // Column start address
+ ssd1306_commandList(dlist1, sizeof(dlist1));
+ ssd1306_command1(WIDTH - 1); // Column end address
+
+#if defined(ESP8266)
+ // ESP8266 needs a periodic yield() call to avoid watchdog reset.
+ // With the limited size of SSD1306 displays, and the fast bitrate
+ // being used (1 MHz or more), I think one yield() immediately before
+ // a screen write and one immediately after should cover it. But if
+ // not, if this becomes a problem, yields() might be added in the
+ // 32-byte transfer condition below.
+ yield();
+#endif
+ uint16_t count = WIDTH * ((HEIGHT + 7) / 8);
+ uint8_t *ptr = buffer;
+ if(wire) { // I2C
+ wire->beginTransmission(i2caddr);
+ WIRE_WRITE((uint8_t)0x40);
+ uint8_t bytesOut = 1;
+ while(count--) {
+ if(bytesOut >= WIRE_MAX) {
+ wire->endTransmission();
+ wire->beginTransmission(i2caddr);
+ WIRE_WRITE((uint8_t)0x40);
+ bytesOut = 1;
+ }
+ WIRE_WRITE(*ptr++);
+ bytesOut++;
+ }
+ wire->endTransmission();
+ } else { // SPI
+ SSD1306_MODE_DATA
+ while(count--) SPIwrite(*ptr++);
+ }
+ TRANSACTION_END
+#if defined(ESP8266)
+ yield();
+#endif
+}
+
+// SCROLLING FUNCTIONS -----------------------------------------------------
+
+/*!
+ @brief Activate a right-handed scroll for all or part of the display.
+ @param start
+ First row.
+ @param stop
+ Last row.
+ @return None (void).
+*/
+// To scroll the whole display, run: display.startscrollright(0x00, 0x0F)
+void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop) {
+ TRANSACTION_START
+ static const uint8_t PROGMEM scrollList1a[] = {
+ SSD1306_RIGHT_HORIZONTAL_SCROLL,
+ 0X00 };
+ ssd1306_commandList(scrollList1a, sizeof(scrollList1a));
+ ssd1306_command1(start);
+ ssd1306_command1(0X00);
+ ssd1306_command1(stop);
+ static const uint8_t PROGMEM scrollList1b[] = {
+ 0X00,
+ 0XFF,
+ SSD1306_ACTIVATE_SCROLL };
+ ssd1306_commandList(scrollList1b, sizeof(scrollList1b));
+ TRANSACTION_END
+}
+
+/*!
+ @brief Activate a left-handed scroll for all or part of the display.
+ @param start
+ First row.
+ @param stop
+ Last row.
+ @return None (void).
+*/
+// To scroll the whole display, run: display.startscrollleft(0x00, 0x0F)
+void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop) {
+ TRANSACTION_START
+ static const uint8_t PROGMEM scrollList2a[] = {
+ SSD1306_LEFT_HORIZONTAL_SCROLL,
+ 0X00 };
+ ssd1306_commandList(scrollList2a, sizeof(scrollList2a));
+ ssd1306_command1(start);
+ ssd1306_command1(0X00);
+ ssd1306_command1(stop);
+ static const uint8_t PROGMEM scrollList2b[] = {
+ 0X00,
+ 0XFF,
+ SSD1306_ACTIVATE_SCROLL };
+ ssd1306_commandList(scrollList2b, sizeof(scrollList2b));
+ TRANSACTION_END
+}
+
+/*!
+ @brief Activate a diagonal scroll for all or part of the display.
+ @param start
+ First row.
+ @param stop
+ Last row.
+ @return None (void).
+*/
+// display.startscrolldiagright(0x00, 0x0F)
+void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop) {
+ TRANSACTION_START
+ static const uint8_t PROGMEM scrollList3a[] = {
+ SSD1306_SET_VERTICAL_SCROLL_AREA,
+ 0X00 };
+ ssd1306_commandList(scrollList3a, sizeof(scrollList3a));
+ ssd1306_command1(HEIGHT);
+ static const uint8_t PROGMEM scrollList3b[] = {
+ SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL,
+ 0X00 };
+ ssd1306_commandList(scrollList3b, sizeof(scrollList3b));
+ ssd1306_command1(start);
+ ssd1306_command1(0X00);
+ ssd1306_command1(stop);
+ static const uint8_t PROGMEM scrollList3c[] = {
+ 0X01,
+ SSD1306_ACTIVATE_SCROLL };
+ ssd1306_commandList(scrollList3c, sizeof(scrollList3c));
+ TRANSACTION_END
+}
+
+/*!
+ @brief Activate alternate diagonal scroll for all or part of the display.
+ @param start
+ First row.
+ @param stop
+ Last row.
+ @return None (void).
+*/
+// To scroll the whole display, run: display.startscrolldiagleft(0x00, 0x0F)
+void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop) {
+ TRANSACTION_START
+ static const uint8_t PROGMEM scrollList4a[] = {
+ SSD1306_SET_VERTICAL_SCROLL_AREA,
+ 0X00 };
+ ssd1306_commandList(scrollList4a, sizeof(scrollList4a));
+ ssd1306_command1(HEIGHT);
+ static const uint8_t PROGMEM scrollList4b[] = {
+ SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL,
+ 0X00 };
+ ssd1306_commandList(scrollList4b, sizeof(scrollList4b));
+ ssd1306_command1(start);
+ ssd1306_command1(0X00);
+ ssd1306_command1(stop);
+ static const uint8_t PROGMEM scrollList4c[] = {
+ 0X01,
+ SSD1306_ACTIVATE_SCROLL };
+ ssd1306_commandList(scrollList4c, sizeof(scrollList4c));
+ TRANSACTION_END
+}
+
+/*!
+ @brief Cease a previously-begun scrolling action.
+ @return None (void).
+*/
+void Adafruit_SSD1306::stopscroll(void) {
+ TRANSACTION_START
+ ssd1306_command1(SSD1306_DEACTIVATE_SCROLL);
+ TRANSACTION_END
+}
+
+// OTHER HARDWARE SETTINGS -------------------------------------------------
+
+/*!
+ @brief Enable or disable display invert mode (white-on-black vs
+ black-on-white).
+ @param i
+ If true, switch to invert mode (black-on-white), else normal
+ mode (white-on-black).
+ @return None (void).
+ @note This has an immediate effect on the display, no need to call the
+ display() function -- buffer contents are not changed, rather a
+ different pixel mode of the display hardware is used. When
+ enabled, drawing BLACK (value 0) pixels will actually draw white,
+ WHITE (value 1) will draw black.
+*/
+void Adafruit_SSD1306::invertDisplay(boolean i) {
+ TRANSACTION_START
+ ssd1306_command1(i ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
+ TRANSACTION_END
+}
+
+/*!
+ @brief Dim the display.
+ @param dim
+ true to enable lower brightness mode, false for full brightness.
+ @return None (void).
+ @note This has an immediate effect on the display, no need to call the
+ display() function -- buffer contents are not changed.
+*/
+void Adafruit_SSD1306::dim(boolean dim) {
+ uint8_t contrast;
+
+ if(dim) {
+ contrast = 0; // Dimmed display
+ } else {
+ contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF;
+ }
+ // the range of contrast to too small to be really useful
+ // it is useful to dim the display
+ TRANSACTION_START
+ ssd1306_command1(SSD1306_SETCONTRAST);
+ ssd1306_command1(contrast);
+ TRANSACTION_END
+}
+
diff --git a/lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.h b/lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.h
new file mode 100644
index 000000000..9fe3d723c
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/Adafruit_SSD1306.h
@@ -0,0 +1,179 @@
+/*!
+ * @file Adafruit_SSD1306.h
+ *
+ * This is part of for Adafruit's SSD1306 library for monochrome
+ * OLED displays: http://www.adafruit.com/category/63_98
+ *
+ * These displays use I2C or SPI to communicate. I2C requires 2 pins
+ * (SCL+SDA) and optionally a RESET pin. SPI requires 4 pins (MOSI, SCK,
+ * select, data/command) and optionally a reset pin. Hardware SPI or
+ * 'bitbang' software SPI are both supported.
+ *
+ * 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, with
+ * contributions from the open source community.
+ *
+ * BSD license, all text above, and the splash screen header file,
+ * must be included in any redistribution.
+ *
+ */
+
+#ifndef _Adafruit_SSD1306_H_
+#define _Adafruit_SSD1306_H_
+
+// ONE of the following three lines must be #defined:
+#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
+//#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
+//#define SSD1306_96_16 ///< DEPRECATED: old way to specify 96x16 screen
+// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
+// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
+// AND HEIGHT ARGUMENTS).
+
+#if defined(ARDUINO_STM32_FEATHER)
+ typedef class HardwareSPI SPIClass;
+#endif
+
+#include
+#include
+#include
+
+#if defined(__AVR__)
+ typedef volatile uint8_t PortReg;
+ typedef uint8_t PortMask;
+ #define HAVE_PORTREG
+#elif defined(__SAM3X8E__)
+ typedef volatile RwReg PortReg;
+ typedef uint32_t PortMask;
+ #define HAVE_PORTREG
+#elif defined(__arm__) || defined(ARDUINO_FEATHER52)
+ typedef volatile uint32_t PortReg;
+ typedef uint32_t PortMask;
+ #define HAVE_PORTREG
+#endif
+
+#define BLACK 0 ///< Draw 'off' pixels
+#define WHITE 1 ///< Draw 'on' pixels
+#define INVERSE 2 ///< Invert pixels
+
+#define SSD1306_MEMORYMODE 0x20 ///< See datasheet
+#define SSD1306_COLUMNADDR 0x21 ///< See datasheet
+#define SSD1306_PAGEADDR 0x22 ///< See datasheet
+#define SSD1306_SETCONTRAST 0x81 ///< See datasheet
+#define SSD1306_CHARGEPUMP 0x8D ///< See datasheet
+#define SSD1306_SEGREMAP 0xA0 ///< See datasheet
+#define SSD1306_DISPLAYALLON_RESUME 0xA4 ///< See datasheet
+#define SSD1306_DISPLAYALLON 0xA5 ///< Not currently used
+#define SSD1306_NORMALDISPLAY 0xA6 ///< See datasheet
+#define SSD1306_INVERTDISPLAY 0xA7 ///< See datasheet
+#define SSD1306_SETMULTIPLEX 0xA8 ///< See datasheet
+#define SSD1306_DISPLAYOFF 0xAE ///< See datasheet
+#define SSD1306_DISPLAYON 0xAF ///< See datasheet
+#define SSD1306_COMSCANINC 0xC0 ///< Not currently used
+#define SSD1306_COMSCANDEC 0xC8 ///< See datasheet
+#define SSD1306_SETDISPLAYOFFSET 0xD3 ///< See datasheet
+#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 ///< See datasheet
+#define SSD1306_SETPRECHARGE 0xD9 ///< See datasheet
+#define SSD1306_SETCOMPINS 0xDA ///< See datasheet
+#define SSD1306_SETVCOMDETECT 0xDB ///< See datasheet
+
+#define SSD1306_SETLOWCOLUMN 0x00 ///< Not currently used
+#define SSD1306_SETHIGHCOLUMN 0x10 ///< Not currently used
+#define SSD1306_SETSTARTLINE 0x40 ///< See datasheet
+
+#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source
+#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V
+
+#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 ///< Init rt scroll
+#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 ///< Init left scroll
+#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 ///< Init diag scroll
+#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A ///< Init diag scroll
+#define SSD1306_DEACTIVATE_SCROLL 0x2E ///< Stop scroll
+#define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll
+#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range
+
+// Deprecated size stuff for backwards compatibility with old sketches
+#if defined SSD1306_128_64
+ #define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_64 defined
+ #define SSD1306_LCDHEIGHT 64 ///< DEPRECATED: height w/SSD1306_128_64 defined
+#endif
+#if defined SSD1306_128_32
+ #define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_32 defined
+ #define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_128_32 defined
+#endif
+#if defined SSD1306_96_16
+ #define SSD1306_LCDWIDTH 96 ///< DEPRECATED: width w/SSD1306_96_16 defined
+ #define SSD1306_LCDHEIGHT 16 ///< DEPRECATED: height w/SSD1306_96_16 defined
+#endif
+
+/*!
+ @brief Class that stores state and functions for interacting with
+ SSD1306 OLED displays.
+*/
+class Adafruit_SSD1306 : public Adafruit_GFX {
+ public:
+ // NEW CONSTRUCTORS -- recommended for new projects
+ Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi=&Wire, int8_t rst_pin=-1,
+ uint32_t clkDuring=400000UL, uint32_t clkAfter=100000UL);
+ Adafruit_SSD1306(uint8_t w, uint8_t h, int8_t mosi_pin, int8_t sclk_pin,
+ int8_t dc_pin, int8_t rst_pin, int8_t cs_pin);
+ Adafruit_SSD1306(uint8_t w, uint8_t h, SPIClass *spi,
+ int8_t dc_pin, int8_t rst_pin, int8_t cs_pin, uint32_t bitrate=8000000UL);
+
+ // DEPRECATED CONSTRUCTORS - for back compatibility, avoid in new projects
+ Adafruit_SSD1306(int8_t mosi_pin, int8_t sclk_pin, int8_t dc_pin,
+ int8_t rst_pin, int8_t cs_pin);
+ Adafruit_SSD1306(int8_t dc_pin, int8_t rst_pin, int8_t cs_pin);
+ Adafruit_SSD1306(int8_t rst_pin = -1);
+
+ ~Adafruit_SSD1306(void);
+
+ boolean begin(uint8_t switchvcc=SSD1306_SWITCHCAPVCC,
+ uint8_t i2caddr=0, boolean reset=true,
+ boolean periphBegin=true);
+ void display(void);
+ void clearDisplay(void);
+ void invertDisplay(boolean i);
+ void dim(boolean dim);
+ void drawPixel(int16_t x, int16_t y, uint16_t color);
+ virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
+ virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
+ void startscrollright(uint8_t start, uint8_t stop);
+ void startscrollleft(uint8_t start, uint8_t stop);
+ void startscrolldiagright(uint8_t start, uint8_t stop);
+ void startscrolldiagleft(uint8_t start, uint8_t stop);
+ void stopscroll(void);
+ void ssd1306_command(uint8_t c);
+ boolean getPixel(int16_t x, int16_t y);
+ uint8_t *getBuffer(void);
+
+ private:
+ inline void SPIwrite(uint8_t d) __attribute__((always_inline));
+ void drawFastHLineInternal(int16_t x, int16_t y, int16_t w,
+ uint16_t color);
+ void drawFastVLineInternal(int16_t x, int16_t y, int16_t h,
+ uint16_t color);
+ void ssd1306_command1(uint8_t c);
+ void ssd1306_commandList(const uint8_t *c, uint8_t n);
+
+ SPIClass *spi;
+ TwoWire *wire;
+ uint8_t *buffer;
+ int8_t i2caddr, vccstate, page_end;
+ int8_t mosiPin , clkPin , dcPin , csPin, rstPin;
+#ifdef HAVE_PORTREG
+ PortReg *mosiPort , *clkPort , *dcPort , *csPort;
+ PortMask mosiPinMask, clkPinMask, dcPinMask, csPinMask;
+#endif
+#if defined(SPI_HAS_TRANSACTION)
+ SPISettings spiSettings;
+#endif
+#if ARDUINO >= 157
+ uint32_t wireClk; // Wire speed for SSD1306 transfers
+ uint32_t restoreClk; // Wire speed following SSD1306 transfers
+#endif
+};
+
+#endif // _Adafruit_SSD1306_H_
diff --git a/lib/Adafruit_SSD1306-1.3.0/README.md b/lib/Adafruit_SSD1306-1.3.0/README.md
new file mode 100644
index 000000000..f2e01ad4b
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/README.md
@@ -0,0 +1,54 @@
+# Adafruit_SSD1306 [](https://travis-ci.org/adafruit/Adafruit_SSD1306)
+
+This is a library for our Monochrome OLEDs based on SSD1306 drivers
+
+ Pick one up today in the adafruit shop!
+ ------> http://www.adafruit.com/category/63_98
+
+These displays use I2C or SPI to communicate, 2 to 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 Limor Fried/Ladyada for Adafruit Industries, with contributions from the open source community. Scrolling code contributed by Michael Gregg. Dynamic buffer allocation based on work by Andrew Canaday.
+BSD license, check license.txt for more information. All text above must be included in any redistribution
+
+Preferred installation method is to use the Arduino IDE Library Manager. To download the source from Github instead, click "Clone or download" above, then "Download ZIP." After uncompressing, rename the resulting folder Adafruit_SSD1306. Check that the Adafruit_SSD1306 folder contains Adafruit_SSD1306.cpp and Adafruit_SSD1306.h.
+
+You will also have to install the **Adafruit GFX library** which provides graphics primitves such as lines, circles, text, etc. This also can be found in the Arduino Library Manager, or you can get the source from https://github.com/adafruit/Adafruit-GFX-Library
+
+## Changes
+
+Version 1.2 (November 2018) introduces some significant changes:
+
+ * Display dimensions are now specified in the constructor...you no longer need to edit the .h file for different screens (though old sketches can continue to work that way).
+ * SPI transactions are used and SPI bitrate can be specified (both require Arduino 1.6 or later).
+ * SPI and Wire (I2C) interfaces other than the defaults are supported.
+
+
+
+## Compatibility
+
+MCU |Tested Works|Doesn't Work|Not Tested|Notes
+------------|:----------:|:----------:|:--------:|-----
+Atmega328 | X | | |
+Atmega32u4 | X | | |
+Atmega2560 | X | | |
+ESP8266 | X | | | Change OLED_RESET to different pin if using default I2C pins D4/D5.
+ESP32 | X | | |
+ATSAM3X8E | X | | |
+ATSAM21D | X | | |
+Intel Curie | X | | |
+WICED | X | | | No hardware SPI - bitbang only
+ATtiny85 | | X | |
+
+ * ATmega328 : Arduino UNO, Adafruit Pro Trinket, Adafruit Metro 328, Adafruit Metro Mini
+ * ATmega32u4 : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0, Adafruit Flora, Bluefruit Micro
+ * ATmega2560 : Arduino Mega
+ * ESP8266 : Adafruit Huzzah
+ * ATSAM3X8E : Arduino Due
+ * ATSAM21D : Arduino Zero, M0 Pro, Adafruit Metro Express, Feather M0
+ * ATtiny85 : Adafruit Gemma, Arduino Gemma, Adafruit Trinket
+
+
diff --git a/lib/Adafruit_SSD1306-1.3.0/examples/OLED_featherwing/OLED_featherwing.ino b/lib/Adafruit_SSD1306-1.3.0/examples/OLED_featherwing/OLED_featherwing.ino
new file mode 100644
index 000000000..2d0d24646
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/examples/OLED_featherwing/OLED_featherwing.ino
@@ -0,0 +1,79 @@
+#include
+#include
+#include
+#include
+
+Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
+
+// OLED FeatherWing buttons map to different pins depending on board:
+#if defined(ESP8266)
+ #define BUTTON_A 0
+ #define BUTTON_B 16
+ #define BUTTON_C 2
+#elif defined(ESP32)
+ #define BUTTON_A 15
+ #define BUTTON_B 32
+ #define BUTTON_C 14
+#elif defined(ARDUINO_STM32_FEATHER)
+ #define BUTTON_A PA15
+ #define BUTTON_B PC7
+ #define BUTTON_C PC5
+#elif defined(TEENSYDUINO)
+ #define BUTTON_A 4
+ #define BUTTON_B 3
+ #define BUTTON_C 8
+#elif defined(ARDUINO_FEATHER52832)
+ #define BUTTON_A 31
+ #define BUTTON_B 30
+ #define BUTTON_C 27
+#else // 32u4, M0, M4, nrf52840 and 328p
+ #define BUTTON_A 9
+ #define BUTTON_B 6
+ #define BUTTON_C 5
+#endif
+
+void setup() {
+ Serial.begin(9600);
+
+ Serial.println("OLED FeatherWing test");
+ // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+ display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32
+
+ Serial.println("OLED begun");
+
+ // Show image buffer on the display hardware.
+ // Since the buffer is intialized with an Adafruit splashscreen
+ // internally, this will display the splashscreen.
+ display.display();
+ delay(1000);
+
+ // Clear the buffer.
+ display.clearDisplay();
+ display.display();
+
+ Serial.println("IO test");
+
+ pinMode(BUTTON_A, INPUT_PULLUP);
+ pinMode(BUTTON_B, INPUT_PULLUP);
+ pinMode(BUTTON_C, INPUT_PULLUP);
+
+ // text display tests
+ display.setTextSize(1);
+ display.setTextColor(WHITE);
+ display.setCursor(0,0);
+ display.print("Connecting to SSID\n'adafruit':");
+ display.print("connected!");
+ display.println("IP: 10.0.1.23");
+ display.println("Sending val #0");
+ display.setCursor(0,0);
+ display.display(); // actually display all of the above
+}
+
+void loop() {
+ if(!digitalRead(BUTTON_A)) display.print("A");
+ if(!digitalRead(BUTTON_B)) display.print("B");
+ if(!digitalRead(BUTTON_C)) display.print("C");
+ delay(10);
+ yield();
+ display.display();
+}
diff --git a/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino
new file mode 100644
index 000000000..68bfee354
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_i2c/ssd1306_128x32_i2c.ino
@@ -0,0 +1,410 @@
+/**************************************************************************
+ This is an example for our Monochrome OLEDs based on SSD1306 drivers
+
+ Pick one up today in the adafruit shop!
+ ------> http://www.adafruit.com/category/63_98
+
+ This example is for a 128x32 pixel display using I2C to communicate
+ 3 pins are required to interface (two I2C and one reset).
+
+ 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,
+ with contributions from the open source community.
+ BSD license, check license.txt for more information
+ All text above, and the splash screen below must be
+ included in any redistribution.
+ **************************************************************************/
+
+#include
+#include
+#include
+#include
+
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 32 // OLED display height, in pixels
+
+// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
+#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
+
+#define NUMFLAKES 10 // Number of snowflakes in the animation example
+
+#define LOGO_HEIGHT 16
+#define LOGO_WIDTH 16
+static const unsigned char PROGMEM logo_bmp[] =
+{ B00000000, B11000000,
+ B00000001, B11000000,
+ B00000001, B11000000,
+ B00000011, B11100000,
+ B11110011, B11100000,
+ B11111110, B11111000,
+ B01111110, B11111111,
+ B00110011, B10011111,
+ B00011111, B11111100,
+ B00001101, B01110000,
+ B00011011, B10100000,
+ B00111111, B11100000,
+ B00111111, B11110000,
+ B01111100, B11110000,
+ B01110000, B01110000,
+ B00000000, B00110000 };
+
+void setup() {
+ Serial.begin(9600);
+
+ // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+ if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
+ Serial.println(F("SSD1306 allocation failed"));
+ for(;;); // Don't proceed, loop forever
+ }
+
+ // Show initial display buffer contents on the screen --
+ // the library initializes this with an Adafruit splash screen.
+ display.display();
+ delay(2000); // Pause for 2 seconds
+
+ // Clear the buffer
+ display.clearDisplay();
+
+ // Draw a single pixel in white
+ display.drawPixel(10, 10, WHITE);
+
+ // Show the display buffer on the screen. You MUST call display() after
+ // drawing commands to make them visible on screen!
+ display.display();
+ delay(2000);
+ // display.display() is NOT necessary after every single drawing command,
+ // unless that's what you want...rather, you can batch up a bunch of
+ // drawing operations and then update the screen all at once by calling
+ // display.display(). These examples demonstrate both approaches...
+
+ testdrawline(); // Draw many lines
+
+ testdrawrect(); // Draw rectangles (outlines)
+
+ testfillrect(); // Draw rectangles (filled)
+
+ testdrawcircle(); // Draw circles (outlines)
+
+ testfillcircle(); // Draw circles (filled)
+
+ testdrawroundrect(); // Draw rounded rectangles (outlines)
+
+ testfillroundrect(); // Draw rounded rectangles (filled)
+
+ testdrawtriangle(); // Draw triangles (outlines)
+
+ testfilltriangle(); // Draw triangles (filled)
+
+ testdrawchar(); // Draw characters of the default font
+
+ testdrawstyles(); // Draw 'stylized' characters
+
+ testscrolltext(); // Draw scrolling text
+
+ testdrawbitmap(); // Draw a small bitmap image
+
+ // Invert and restore display, pausing in-between
+ display.invertDisplay(true);
+ delay(1000);
+ display.invertDisplay(false);
+ delay(1000);
+
+ testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
+}
+
+void loop() {
+}
+
+void testdrawline() {
+ int16_t i;
+
+ display.clearDisplay(); // Clear display buffer
+
+ for(i=0; i=0; i-=4) {
+ display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=display.width()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
+ display.display();
+ delay(1);
+ }
+ for(i=display.height()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=0; i0; i-=3) {
+ // The INVERSE color is used so circles alternate white/black
+ display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
+ display.display(); // Update screen with each newly-drawn circle
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawroundrect(void) {
+ display.clearDisplay();
+
+ for(int16_t i=0; i0; i-=5) {
+ // The INVERSE color is used so triangles alternate white/black
+ display.fillTriangle(
+ display.width()/2 , display.height()/2-i,
+ display.width()/2-i, display.height()/2+i,
+ display.width()/2+i, display.height()/2+i, INVERSE);
+ display.display();
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawchar(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0, 0); // Start at top-left corner
+ display.cp437(true); // Use full 256 char 'Code Page 437' font
+
+ // Not all the characters will fit on the display. This is normal.
+ // Library will draw what it can and the rest will be clipped.
+ for(int16_t i=0; i<256; i++) {
+ if(i == '\n') display.write(' ');
+ else display.write(i);
+ }
+
+ display.display();
+ delay(2000);
+}
+
+void testdrawstyles(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0,0); // Start at top-left corner
+ display.println(F("Hello, world!"));
+
+ display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
+ display.println(3.141592);
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.print(F("0x")); display.println(0xDEADBEEF, HEX);
+
+ display.display();
+ delay(2000);
+}
+
+void testscrolltext(void) {
+ display.clearDisplay();
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.setCursor(10, 0);
+ display.println(F("scroll"));
+ display.display(); // Show initial text
+ delay(100);
+
+ // Scroll in various directions, pausing in-between:
+ display.startscrollright(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrollleft(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrolldiagright(0x00, 0x07);
+ delay(2000);
+ display.startscrolldiagleft(0x00, 0x07);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+}
+
+void testdrawbitmap(void) {
+ display.clearDisplay();
+
+ display.drawBitmap(
+ (display.width() - LOGO_WIDTH ) / 2,
+ (display.height() - LOGO_HEIGHT) / 2,
+ logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
+ display.display();
+ delay(1000);
+}
+
+#define XPOS 0 // Indexes into the 'icons' array in function below
+#define YPOS 1
+#define DELTAY 2
+
+void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
+ int8_t f, icons[NUMFLAKES][3];
+
+ // Initialize 'snowflake' positions
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ Serial.print(F("x: "));
+ Serial.print(icons[f][XPOS], DEC);
+ Serial.print(F(" y: "));
+ Serial.print(icons[f][YPOS], DEC);
+ Serial.print(F(" dy: "));
+ Serial.println(icons[f][DELTAY], DEC);
+ }
+
+ for(;;) { // Loop forever...
+ display.clearDisplay(); // Clear the display buffer
+
+ // Draw each snowflake:
+ for(f=0; f< NUMFLAKES; f++) {
+ display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
+ }
+
+ display.display(); // Show the display buffer on the screen
+ delay(200); // Pause for 1/10 second
+
+ // Then update coordinates of each flake...
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][YPOS] += icons[f][DELTAY];
+ // If snowflake is off the bottom of the screen...
+ if (icons[f][YPOS] >= display.height()) {
+ // Reinitialize to a random position, just off the top
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ }
+ }
+ }
+}
diff --git a/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_spi/ssd1306_128x32_spi.ino b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_spi/ssd1306_128x32_spi.ino
new file mode 100644
index 000000000..b254785f3
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x32_spi/ssd1306_128x32_spi.ino
@@ -0,0 +1,423 @@
+/**************************************************************************
+ This is an example for our Monochrome OLEDs based on SSD1306 drivers
+
+ Pick one up today in the adafruit shop!
+ ------> http://www.adafruit.com/category/63_98
+
+ This example is for a 128x32 pixel display using 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 Limor Fried/Ladyada for Adafruit Industries,
+ with contributions from the open source community.
+ BSD license, check license.txt for more information
+ All text above, and the splash screen below must be
+ included in any redistribution.
+ **************************************************************************/
+
+#include
+#include
+#include
+#include
+
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 32 // OLED display height, in pixels
+
+// Declaration for SSD1306 display connected using software SPI (default case):
+#define OLED_MOSI 9
+#define OLED_CLK 10
+#define OLED_DC 11
+#define OLED_CS 12
+#define OLED_RESET 13
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
+ OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
+
+/* Comment out above, uncomment this block to use hardware SPI
+#define OLED_DC 6
+#define OLED_CS 7
+#define OLED_RESET 8
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
+ &SPI, OLED_DC, OLED_RESET, OLED_CS);
+*/
+
+#define NUMFLAKES 10 // Number of snowflakes in the animation example
+
+#define LOGO_HEIGHT 16
+#define LOGO_WIDTH 16
+static const unsigned char PROGMEM logo_bmp[] =
+{ B00000000, B11000000,
+ B00000001, B11000000,
+ B00000001, B11000000,
+ B00000011, B11100000,
+ B11110011, B11100000,
+ B11111110, B11111000,
+ B01111110, B11111111,
+ B00110011, B10011111,
+ B00011111, B11111100,
+ B00001101, B01110000,
+ B00011011, B10100000,
+ B00111111, B11100000,
+ B00111111, B11110000,
+ B01111100, B11110000,
+ B01110000, B01110000,
+ B00000000, B00110000 };
+
+void setup() {
+ Serial.begin(9600);
+
+ // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+ if(!display.begin(SSD1306_SWITCHCAPVCC)) {
+ Serial.println(F("SSD1306 allocation failed"));
+ for(;;); // Don't proceed, loop forever
+ }
+
+ // Show initial display buffer contents on the screen --
+ // the library initializes this with an Adafruit splash screen.
+ display.display();
+ delay(2000); // Pause for 2 seconds
+
+ // Clear the buffer
+ display.clearDisplay();
+
+ // Draw a single pixel in white
+ display.drawPixel(10, 10, WHITE);
+
+ // Show the display buffer on the screen. You MUST call display() after
+ // drawing commands to make them visible on screen!
+ display.display();
+ delay(2000);
+ // display.display() is NOT necessary after every single drawing command,
+ // unless that's what you want...rather, you can batch up a bunch of
+ // drawing operations and then update the screen all at once by calling
+ // display.display(). These examples demonstrate both approaches...
+
+ testdrawline(); // Draw many lines
+
+ testdrawrect(); // Draw rectangles (outlines)
+
+ testfillrect(); // Draw rectangles (filled)
+
+ testdrawcircle(); // Draw circles (outlines)
+
+ testfillcircle(); // Draw circles (filled)
+
+ testdrawroundrect(); // Draw rounded rectangles (outlines)
+
+ testfillroundrect(); // Draw rounded rectangles (filled)
+
+ testdrawtriangle(); // Draw triangles (outlines)
+
+ testfilltriangle(); // Draw triangles (filled)
+
+ testdrawchar(); // Draw characters of the default font
+
+ testdrawstyles(); // Draw 'stylized' characters
+
+ testscrolltext(); // Draw scrolling text
+
+ testdrawbitmap(); // Draw a small bitmap image
+
+ // Invert and restore display, pausing in-between
+ display.invertDisplay(true);
+ delay(1000);
+ display.invertDisplay(false);
+ delay(1000);
+
+ testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
+}
+
+void loop() {
+}
+
+void testdrawline() {
+ int16_t i;
+
+ display.clearDisplay(); // Clear display buffer
+
+ for(i=0; i=0; i-=4) {
+ display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=display.width()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
+ display.display();
+ delay(1);
+ }
+ for(i=display.height()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=0; i0; i-=3) {
+ // The INVERSE color is used so circles alternate white/black
+ display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
+ display.display(); // Update screen with each newly-drawn circle
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawroundrect(void) {
+ display.clearDisplay();
+
+ for(int16_t i=0; i0; i-=5) {
+ // The INVERSE color is used so triangles alternate white/black
+ display.fillTriangle(
+ display.width()/2 , display.height()/2-i,
+ display.width()/2-i, display.height()/2+i,
+ display.width()/2+i, display.height()/2+i, INVERSE);
+ display.display();
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawchar(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0, 0); // Start at top-left corner
+ display.cp437(true); // Use full 256 char 'Code Page 437' font
+
+ // Not all the characters will fit on the display. This is normal.
+ // Library will draw what it can and the rest will be clipped.
+ for(int16_t i=0; i<256; i++) {
+ if(i == '\n') display.write(' ');
+ else display.write(i);
+ }
+
+ display.display();
+ delay(2000);
+}
+
+void testdrawstyles(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0,0); // Start at top-left corner
+ display.println(F("Hello, world!"));
+
+ display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
+ display.println(3.141592);
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.print(F("0x")); display.println(0xDEADBEEF, HEX);
+
+ display.display();
+ delay(2000);
+}
+
+void testscrolltext(void) {
+ display.clearDisplay();
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.setCursor(10, 0);
+ display.println(F("scroll"));
+ display.display(); // Show initial text
+ delay(100);
+
+ // Scroll in various directions, pausing in-between:
+ display.startscrollright(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrollleft(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrolldiagright(0x00, 0x07);
+ delay(2000);
+ display.startscrolldiagleft(0x00, 0x07);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+}
+
+void testdrawbitmap(void) {
+ display.clearDisplay();
+
+ display.drawBitmap(
+ (display.width() - LOGO_WIDTH ) / 2,
+ (display.height() - LOGO_HEIGHT) / 2,
+ logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
+ display.display();
+ delay(1000);
+}
+
+#define XPOS 0 // Indexes into the 'icons' array in function below
+#define YPOS 1
+#define DELTAY 2
+
+void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
+ int8_t f, icons[NUMFLAKES][3];
+
+ // Initialize 'snowflake' positions
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ Serial.print(F("x: "));
+ Serial.print(icons[f][XPOS], DEC);
+ Serial.print(F(" y: "));
+ Serial.print(icons[f][YPOS], DEC);
+ Serial.print(F(" dy: "));
+ Serial.println(icons[f][DELTAY], DEC);
+ }
+
+ for(;;) { // Loop forever...
+ display.clearDisplay(); // Clear the display buffer
+
+ // Draw each snowflake:
+ for(f=0; f< NUMFLAKES; f++) {
+ display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
+ }
+
+ display.display(); // Show the display buffer on the screen
+ delay(200); // Pause for 1/10 second
+
+ // Then update coordinates of each flake...
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][YPOS] += icons[f][DELTAY];
+ // If snowflake is off the bottom of the screen...
+ if (icons[f][YPOS] >= display.height()) {
+ // Reinitialize to a random position, just off the top
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ }
+ }
+ }
+}
diff --git a/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino
new file mode 100644
index 000000000..6d7d5ddd0
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino
@@ -0,0 +1,410 @@
+/**************************************************************************
+ This is an example for our Monochrome OLEDs based on SSD1306 drivers
+
+ Pick one up today in the adafruit shop!
+ ------> http://www.adafruit.com/category/63_98
+
+ This example is for a 128x32 pixel display using I2C to communicate
+ 3 pins are required to interface (two I2C and one reset).
+
+ 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,
+ with contributions from the open source community.
+ BSD license, check license.txt for more information
+ All text above, and the splash screen below must be
+ included in any redistribution.
+ **************************************************************************/
+
+#include
+#include
+#include
+#include
+
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 64 // OLED display height, in pixels
+
+// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
+#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
+
+#define NUMFLAKES 10 // Number of snowflakes in the animation example
+
+#define LOGO_HEIGHT 16
+#define LOGO_WIDTH 16
+static const unsigned char PROGMEM logo_bmp[] =
+{ B00000000, B11000000,
+ B00000001, B11000000,
+ B00000001, B11000000,
+ B00000011, B11100000,
+ B11110011, B11100000,
+ B11111110, B11111000,
+ B01111110, B11111111,
+ B00110011, B10011111,
+ B00011111, B11111100,
+ B00001101, B01110000,
+ B00011011, B10100000,
+ B00111111, B11100000,
+ B00111111, B11110000,
+ B01111100, B11110000,
+ B01110000, B01110000,
+ B00000000, B00110000 };
+
+void setup() {
+ Serial.begin(9600);
+
+ // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+ if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
+ Serial.println(F("SSD1306 allocation failed"));
+ for(;;); // Don't proceed, loop forever
+ }
+
+ // Show initial display buffer contents on the screen --
+ // the library initializes this with an Adafruit splash screen.
+ display.display();
+ delay(2000); // Pause for 2 seconds
+
+ // Clear the buffer
+ display.clearDisplay();
+
+ // Draw a single pixel in white
+ display.drawPixel(10, 10, WHITE);
+
+ // Show the display buffer on the screen. You MUST call display() after
+ // drawing commands to make them visible on screen!
+ display.display();
+ delay(2000);
+ // display.display() is NOT necessary after every single drawing command,
+ // unless that's what you want...rather, you can batch up a bunch of
+ // drawing operations and then update the screen all at once by calling
+ // display.display(). These examples demonstrate both approaches...
+
+ testdrawline(); // Draw many lines
+
+ testdrawrect(); // Draw rectangles (outlines)
+
+ testfillrect(); // Draw rectangles (filled)
+
+ testdrawcircle(); // Draw circles (outlines)
+
+ testfillcircle(); // Draw circles (filled)
+
+ testdrawroundrect(); // Draw rounded rectangles (outlines)
+
+ testfillroundrect(); // Draw rounded rectangles (filled)
+
+ testdrawtriangle(); // Draw triangles (outlines)
+
+ testfilltriangle(); // Draw triangles (filled)
+
+ testdrawchar(); // Draw characters of the default font
+
+ testdrawstyles(); // Draw 'stylized' characters
+
+ testscrolltext(); // Draw scrolling text
+
+ testdrawbitmap(); // Draw a small bitmap image
+
+ // Invert and restore display, pausing in-between
+ display.invertDisplay(true);
+ delay(1000);
+ display.invertDisplay(false);
+ delay(1000);
+
+ testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
+}
+
+void loop() {
+}
+
+void testdrawline() {
+ int16_t i;
+
+ display.clearDisplay(); // Clear display buffer
+
+ for(i=0; i=0; i-=4) {
+ display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=display.width()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
+ display.display();
+ delay(1);
+ }
+ for(i=display.height()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=0; i0; i-=3) {
+ // The INVERSE color is used so circles alternate white/black
+ display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
+ display.display(); // Update screen with each newly-drawn circle
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawroundrect(void) {
+ display.clearDisplay();
+
+ for(int16_t i=0; i0; i-=5) {
+ // The INVERSE color is used so triangles alternate white/black
+ display.fillTriangle(
+ display.width()/2 , display.height()/2-i,
+ display.width()/2-i, display.height()/2+i,
+ display.width()/2+i, display.height()/2+i, INVERSE);
+ display.display();
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawchar(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0, 0); // Start at top-left corner
+ display.cp437(true); // Use full 256 char 'Code Page 437' font
+
+ // Not all the characters will fit on the display. This is normal.
+ // Library will draw what it can and the rest will be clipped.
+ for(int16_t i=0; i<256; i++) {
+ if(i == '\n') display.write(' ');
+ else display.write(i);
+ }
+
+ display.display();
+ delay(2000);
+}
+
+void testdrawstyles(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0,0); // Start at top-left corner
+ display.println(F("Hello, world!"));
+
+ display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
+ display.println(3.141592);
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.print(F("0x")); display.println(0xDEADBEEF, HEX);
+
+ display.display();
+ delay(2000);
+}
+
+void testscrolltext(void) {
+ display.clearDisplay();
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.setCursor(10, 0);
+ display.println(F("scroll"));
+ display.display(); // Show initial text
+ delay(100);
+
+ // Scroll in various directions, pausing in-between:
+ display.startscrollright(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrollleft(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrolldiagright(0x00, 0x07);
+ delay(2000);
+ display.startscrolldiagleft(0x00, 0x07);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+}
+
+void testdrawbitmap(void) {
+ display.clearDisplay();
+
+ display.drawBitmap(
+ (display.width() - LOGO_WIDTH ) / 2,
+ (display.height() - LOGO_HEIGHT) / 2,
+ logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
+ display.display();
+ delay(1000);
+}
+
+#define XPOS 0 // Indexes into the 'icons' array in function below
+#define YPOS 1
+#define DELTAY 2
+
+void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
+ int8_t f, icons[NUMFLAKES][3];
+
+ // Initialize 'snowflake' positions
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ Serial.print(F("x: "));
+ Serial.print(icons[f][XPOS], DEC);
+ Serial.print(F(" y: "));
+ Serial.print(icons[f][YPOS], DEC);
+ Serial.print(F(" dy: "));
+ Serial.println(icons[f][DELTAY], DEC);
+ }
+
+ for(;;) { // Loop forever...
+ display.clearDisplay(); // Clear the display buffer
+
+ // Draw each snowflake:
+ for(f=0; f< NUMFLAKES; f++) {
+ display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
+ }
+
+ display.display(); // Show the display buffer on the screen
+ delay(200); // Pause for 1/10 second
+
+ // Then update coordinates of each flake...
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][YPOS] += icons[f][DELTAY];
+ // If snowflake is off the bottom of the screen...
+ if (icons[f][YPOS] >= display.height()) {
+ // Reinitialize to a random position, just off the top
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ }
+ }
+ }
+}
diff --git a/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_spi/ssd1306_128x64_spi.ino b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_spi/ssd1306_128x64_spi.ino
new file mode 100644
index 000000000..dbe300d43
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/examples/ssd1306_128x64_spi/ssd1306_128x64_spi.ino
@@ -0,0 +1,424 @@
+/**************************************************************************
+ This is an example for our Monochrome OLEDs based on SSD1306 drivers
+
+ Pick one up today in the adafruit shop!
+ ------> http://www.adafruit.com/category/63_98
+
+ This example is for a 128x64 pixel display using 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 Limor Fried/Ladyada for Adafruit Industries,
+ with contributions from the open source community.
+ BSD license, check license.txt for more information
+ All text above, and the splash screen below must be
+ included in any redistribution.
+ **************************************************************************/
+
+#include
+#include
+#include
+#include
+
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 64 // OLED display height, in pixels
+
+// Declaration for SSD1306 display connected using software SPI (default case):
+#define OLED_MOSI 9
+#define OLED_CLK 10
+#define OLED_DC 11
+#define OLED_CS 12
+#define OLED_RESET 13
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
+ OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
+
+/* Comment out above, uncomment this block to use hardware SPI
+#define OLED_DC 6
+#define OLED_CS 7
+#define OLED_RESET 8
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
+ &SPI, OLED_DC, OLED_RESET, OLED_CS);
+*/
+
+#define NUMFLAKES 10 // Number of snowflakes in the animation example
+
+#define LOGO_HEIGHT 16
+#define LOGO_WIDTH 16
+static const unsigned char PROGMEM logo_bmp[] =
+{ B00000000, B11000000,
+ B00000001, B11000000,
+ B00000001, B11000000,
+ B00000011, B11100000,
+ B11110011, B11100000,
+ B11111110, B11111000,
+ B01111110, B11111111,
+ B00110011, B10011111,
+ B00011111, B11111100,
+ B00001101, B01110000,
+ B00011011, B10100000,
+ B00111111, B11100000,
+ B00111111, B11110000,
+ B01111100, B11110000,
+ B01110000, B01110000,
+ B00000000, B00110000 };
+
+void setup() {
+ Serial.begin(9600);
+
+ // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+ if(!display.begin(SSD1306_SWITCHCAPVCC)) {
+ Serial.println(F("SSD1306 allocation failed"));
+ for(;;); // Don't proceed, loop forever
+ }
+
+
+ // Show initial display buffer contents on the screen --
+ // the library initializes this with an Adafruit splash screen.
+ display.display();
+ delay(2000); // Pause for 2 seconds
+
+ // Clear the buffer
+ display.clearDisplay();
+
+ // Draw a single pixel in white
+ display.drawPixel(10, 10, WHITE);
+
+ // Show the display buffer on the screen. You MUST call display() after
+ // drawing commands to make them visible on screen!
+ display.display();
+ delay(2000);
+ // display.display() is NOT necessary after every single drawing command,
+ // unless that's what you want...rather, you can batch up a bunch of
+ // drawing operations and then update the screen all at once by calling
+ // display.display(). These examples demonstrate both approaches...
+
+ testdrawline(); // Draw many lines
+
+ testdrawrect(); // Draw rectangles (outlines)
+
+ testfillrect(); // Draw rectangles (filled)
+
+ testdrawcircle(); // Draw circles (outlines)
+
+ testfillcircle(); // Draw circles (filled)
+
+ testdrawroundrect(); // Draw rounded rectangles (outlines)
+
+ testfillroundrect(); // Draw rounded rectangles (filled)
+
+ testdrawtriangle(); // Draw triangles (outlines)
+
+ testfilltriangle(); // Draw triangles (filled)
+
+ testdrawchar(); // Draw characters of the default font
+
+ testdrawstyles(); // Draw 'stylized' characters
+
+ testscrolltext(); // Draw scrolling text
+
+ testdrawbitmap(); // Draw a small bitmap image
+
+ // Invert and restore display, pausing in-between
+ display.invertDisplay(true);
+ delay(1000);
+ display.invertDisplay(false);
+ delay(1000);
+
+ testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
+}
+
+void loop() {
+}
+
+void testdrawline() {
+ int16_t i;
+
+ display.clearDisplay(); // Clear display buffer
+
+ for(i=0; i=0; i-=4) {
+ display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=display.width()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
+ display.display();
+ delay(1);
+ }
+ for(i=display.height()-1; i>=0; i-=4) {
+ display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
+ display.display();
+ delay(1);
+ }
+ delay(250);
+
+ display.clearDisplay();
+
+ for(i=0; i0; i-=3) {
+ // The INVERSE color is used so circles alternate white/black
+ display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
+ display.display(); // Update screen with each newly-drawn circle
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawroundrect(void) {
+ display.clearDisplay();
+
+ for(int16_t i=0; i0; i-=5) {
+ // The INVERSE color is used so triangles alternate white/black
+ display.fillTriangle(
+ display.width()/2 , display.height()/2-i,
+ display.width()/2-i, display.height()/2+i,
+ display.width()/2+i, display.height()/2+i, INVERSE);
+ display.display();
+ delay(1);
+ }
+
+ delay(2000);
+}
+
+void testdrawchar(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0, 0); // Start at top-left corner
+ display.cp437(true); // Use full 256 char 'Code Page 437' font
+
+ // Not all the characters will fit on the display. This is normal.
+ // Library will draw what it can and the rest will be clipped.
+ for(int16_t i=0; i<256; i++) {
+ if(i == '\n') display.write(' ');
+ else display.write(i);
+ }
+
+ display.display();
+ delay(2000);
+}
+
+void testdrawstyles(void) {
+ display.clearDisplay();
+
+ display.setTextSize(1); // Normal 1:1 pixel scale
+ display.setTextColor(WHITE); // Draw white text
+ display.setCursor(0,0); // Start at top-left corner
+ display.println(F("Hello, world!"));
+
+ display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
+ display.println(3.141592);
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.print(F("0x")); display.println(0xDEADBEEF, HEX);
+
+ display.display();
+ delay(2000);
+}
+
+void testscrolltext(void) {
+ display.clearDisplay();
+
+ display.setTextSize(2); // Draw 2X-scale text
+ display.setTextColor(WHITE);
+ display.setCursor(10, 0);
+ display.println(F("scroll"));
+ display.display(); // Show initial text
+ delay(100);
+
+ // Scroll in various directions, pausing in-between:
+ display.startscrollright(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrollleft(0x00, 0x0F);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+ display.startscrolldiagright(0x00, 0x07);
+ delay(2000);
+ display.startscrolldiagleft(0x00, 0x07);
+ delay(2000);
+ display.stopscroll();
+ delay(1000);
+}
+
+void testdrawbitmap(void) {
+ display.clearDisplay();
+
+ display.drawBitmap(
+ (display.width() - LOGO_WIDTH ) / 2,
+ (display.height() - LOGO_HEIGHT) / 2,
+ logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
+ display.display();
+ delay(1000);
+}
+
+#define XPOS 0 // Indexes into the 'icons' array in function below
+#define YPOS 1
+#define DELTAY 2
+
+void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
+ int8_t f, icons[NUMFLAKES][3];
+
+ // Initialize 'snowflake' positions
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ Serial.print(F("x: "));
+ Serial.print(icons[f][XPOS], DEC);
+ Serial.print(F(" y: "));
+ Serial.print(icons[f][YPOS], DEC);
+ Serial.print(F(" dy: "));
+ Serial.println(icons[f][DELTAY], DEC);
+ }
+
+ for(;;) { // Loop forever...
+ display.clearDisplay(); // Clear the display buffer
+
+ // Draw each snowflake:
+ for(f=0; f< NUMFLAKES; f++) {
+ display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
+ }
+
+ display.display(); // Show the display buffer on the screen
+ delay(200); // Pause for 1/10 second
+
+ // Then update coordinates of each flake...
+ for(f=0; f< NUMFLAKES; f++) {
+ icons[f][YPOS] += icons[f][DELTAY];
+ // If snowflake is off the bottom of the screen...
+ if (icons[f][YPOS] >= display.height()) {
+ // Reinitialize to a random position, just off the top
+ icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
+ icons[f][YPOS] = -LOGO_HEIGHT;
+ icons[f][DELTAY] = random(1, 6);
+ }
+ }
+ }
+}
diff --git a/lib/Adafruit_SSD1306-1.3.0/library.properties b/lib/Adafruit_SSD1306-1.3.0/library.properties
new file mode 100644
index 000000000..61b8efa07
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/library.properties
@@ -0,0 +1,9 @@
+name=Adafruit SSD1306
+version=1.3.0
+author=Adafruit
+maintainer=Adafruit
+sentence=SSD1306 oled driver library for monochrome 128x64 and 128x32 displays
+paragraph=SSD1306 oled driver library for monochrome 128x64 and 128x32 displays
+category=Display
+url=https://github.com/adafruit/Adafruit_SSD1306
+architectures=*
diff --git a/lib/Adafruit_SSD1306-1.1.2/license.txt b/lib/Adafruit_SSD1306-1.3.0/license.txt
similarity index 100%
rename from lib/Adafruit_SSD1306-1.1.2/license.txt
rename to lib/Adafruit_SSD1306-1.3.0/license.txt
diff --git a/lib/Adafruit_SSD1306-1.3.0/splash.h b/lib/Adafruit_SSD1306-1.3.0/splash.h
new file mode 100644
index 000000000..487daecb4
--- /dev/null
+++ b/lib/Adafruit_SSD1306-1.3.0/splash.h
@@ -0,0 +1,108 @@
+#define splash1_width 82
+#define splash1_height 64
+
+const uint8_t PROGMEM splash1_data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,
+ 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x7F, 0xF0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1F, 0xFF, 0xFB, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0F, 0xFF, 0xF9, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0F, 0xFF, 0xF9, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0xFF, 0xF1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC,
+ 0x73, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x3F,
+ 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x1E, 0x0F,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x1F, 0xFC,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xDF, 0xFF, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x19, 0xFF, 0xC0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7E, 0x7C, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7F, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xEF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xCF, 0xFE,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x07, 0xFE, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x07, 0xFE, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x03, 0xFE, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x80, 0x00, 0xFC, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x07, 0x80,
+ 0x01, 0xFC, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01,
+ 0xFC, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0xE0,
+ 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0xE0, 0x00,
+ 0x00, 0x00, 0x1E, 0x00, 0x7F, 0xE3, 0xF7, 0x9F, 0xF9, 0xFD, 0xE7, 0x78,
+ 0x7B, 0xDF, 0xC0, 0xFF, 0xF7, 0xFF, 0xBF, 0xFD, 0xFD, 0xFF, 0x78, 0x7B,
+ 0xDF, 0xC0, 0xFF, 0xF7, 0xFF, 0xBF, 0xFD, 0xFD, 0xFF, 0x78, 0x7B, 0xDF,
+ 0xC0, 0xF0, 0xF7, 0x87, 0xBC, 0x3D, 0xE1, 0xFF, 0x78, 0x7B, 0xDE, 0x00,
+ 0xF0, 0xF7, 0x87, 0xBC, 0x3D, 0xE1, 0xF0, 0x78, 0x7B, 0xDE, 0x00, 0x00,
+ 0xF7, 0x87, 0x80, 0x3D, 0xE1, 0xE0, 0x78, 0x7B, 0xDE, 0x00, 0x7F, 0xF7,
+ 0x87, 0x9F, 0xFD, 0xE1, 0xE0, 0x78, 0x7B, 0xDE, 0x00, 0xFF, 0xF7, 0x87,
+ 0xBF, 0xFD, 0xE1, 0xE0, 0x78, 0x7B, 0xDE, 0x00, 0xF0, 0xF7, 0x87, 0xBC,
+ 0x3D, 0xE1, 0xE0, 0x78, 0x7B, 0xDE, 0x00, 0xF0, 0xF7, 0x87, 0xBC, 0x3D,
+ 0xE1, 0xE0, 0x78, 0x7B, 0xDE, 0x00, 0xF0, 0xF7, 0x87, 0xBC, 0x3D, 0xE1,
+ 0xE0, 0x78, 0x7B, 0xDE, 0x00, 0xFF, 0xF7, 0xFF, 0xBF, 0xFD, 0xE1, 0xE0,
+ 0x7F, 0xFB, 0xDF, 0xC0, 0xFF, 0xF7, 0xFF, 0xBF, 0xFD, 0xE1, 0xE0, 0x7F,
+ 0xFB, 0xDF, 0xC0, 0x7C, 0xF3, 0xF3, 0x9F, 0x3D, 0xE1, 0xE0, 0x3E, 0x7B,
+ 0xCF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x68, 0xDB, 0x11, 0x1A, 0x31, 0xC0, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFD, 0x2B, 0x5A, 0xFB, 0x6A, 0xEF, 0xC0, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x4B, 0x5B, 0x3B, 0x1A, 0x33, 0xC0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFD, 0x6B, 0x5B, 0xDB, 0x6A, 0xFD, 0xC0 };
+
+#define splash2_width 115
+#define splash2_height 32
+
+const uint8_t PROGMEM splash2_data[] = {
+ 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8,
+ 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x7E, 0x00, 0x00, 0x01, 0xE0, 0x00,
+ 0x7F, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xFE, 0x00, 0x00,
+ 0x01, 0xE0, 0x00, 0xFF, 0xEF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00,
+ 0xFE, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00,
+ 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x7F, 0xFE, 0x7F,
+ 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0x00,
+ 0x3F, 0xFE, 0x7F, 0xF8, 0x3F, 0xF1, 0xFB, 0xCF, 0xFC, 0xFE, 0xF3, 0xBC,
+ 0x3D, 0xEF, 0xE0, 0x1F, 0xFE, 0x7F, 0xFF, 0x7F, 0xFB, 0xFF, 0xDF, 0xFE,
+ 0xFE, 0xFF, 0xBC, 0x3D, 0xEF, 0xE0, 0x1F, 0xC6, 0xFF, 0xFF, 0x7F, 0xFB,
+ 0xFF, 0xDF, 0xFE, 0xFE, 0xFF, 0xBC, 0x3D, 0xEF, 0xE0, 0x0F, 0xE3, 0xC7,
+ 0xFE, 0x78, 0x7B, 0xC3, 0xDE, 0x1E, 0xF0, 0xFF, 0xBC, 0x3D, 0xEF, 0x00,
+ 0x07, 0xFF, 0x87, 0xFC, 0x78, 0x7B, 0xC3, 0xDE, 0x1E, 0xF0, 0xF8, 0x3C,
+ 0x3D, 0xEF, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x7B, 0xC3, 0xC0, 0x1E,
+ 0xF0, 0xF0, 0x3C, 0x3D, 0xEF, 0x00, 0x01, 0xF3, 0x7F, 0xE0, 0x3F, 0xFB,
+ 0xC3, 0xCF, 0xFE, 0xF0, 0xF0, 0x3C, 0x3D, 0xEF, 0x00, 0x03, 0xE3, 0x3F,
+ 0x80, 0x7F, 0xFB, 0xC3, 0xDF, 0xFE, 0xF0, 0xF0, 0x3C, 0x3D, 0xEF, 0x00,
+ 0x07, 0xE7, 0x3C, 0x00, 0x78, 0x7B, 0xC3, 0xDE, 0x1E, 0xF0, 0xF0, 0x3C,
+ 0x3D, 0xEF, 0x00, 0x07, 0xFF, 0xBE, 0x00, 0x78, 0x7B, 0xC3, 0xDE, 0x1E,
+ 0xF0, 0xF0, 0x3C, 0x3D, 0xEF, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x78, 0x7B,
+ 0xC3, 0xDE, 0x1E, 0xF0, 0xF0, 0x3C, 0x3D, 0xEF, 0x00, 0x0F, 0xFF, 0xFE,
+ 0x00, 0x7F, 0xFB, 0xFF, 0xDF, 0xFE, 0xF0, 0xF0, 0x3F, 0xFD, 0xEF, 0xE0,
+ 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFB, 0xFF, 0xDF, 0xFE, 0xF0, 0xF0, 0x3F,
+ 0xFD, 0xEF, 0xE0, 0x0F, 0xF9, 0xFF, 0x00, 0x3E, 0x79, 0xF9, 0xCF, 0x9E,
+ 0xF0, 0xF0, 0x1F, 0x3D, 0xE7, 0xE0, 0x1F, 0xF1, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0xFF,
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
+ 0x1C, 0x00, 0x7F, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xB4, 0x6D, 0x88,
+ 0x8D, 0x18, 0xE0, 0x00, 0x00, 0x1F, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0x95, 0xAD, 0x7D, 0xB5, 0x77, 0xE0, 0x00, 0x00, 0x0F, 0x00, 0x7F, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0xA5, 0xAD, 0x9D, 0x8D, 0x19, 0xE0, 0x00, 0x00, 0x06,
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xB5, 0xAD, 0xED, 0xB5, 0x7E, 0xE0 };