Merge pull request #201 from adafruit/pb-tft8

Add 8-bit parallel interface support
This commit is contained in:
Paint Your Dragon 2019-03-01 20:10:21 -08:00 committed by GitHub
commit 3ccd00912f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1928 additions and 711 deletions

View File

@ -103,6 +103,9 @@ WIDTH(w), HEIGHT(h)
/**************************************************************************/ /**************************************************************************/
void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
uint16_t color) { uint16_t color) {
#if defined(ESP8266)
yield();
#endif
int16_t steep = abs(y1 - y0) > abs(x1 - x0); int16_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) { if (steep) {
_swap_int16_t(x0, y0); _swap_int16_t(x0, y0);
@ -317,6 +320,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, void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
uint16_t color) { uint16_t color) {
#if defined(ESP8266)
yield();
#endif
int16_t f = 1 - r; int16_t f = 1 - r;
int16_t ddF_x = 1; int16_t ddF_x = 1;
int16_t ddF_y = -2 * r; int16_t ddF_y = -2 * r;

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +1,485 @@
#ifndef _ADAFRUIT_SPITFT_ /*!
#define _ADAFRUIT_SPITFT_ * @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.
*/
#if !defined(__AVR_ATtiny85__) // NOT A CHANCE of this stuff working on ATtiny #ifndef _ADAFRUIT_SPITFT_H_
#define _ADAFRUIT_SPITFT_H_
#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
#if ARDUINO >= 100
#include "Arduino.h"
#include "Print.h"
#else
#include "WProgram.h"
#endif
#include <SPI.h> #include <SPI.h>
#include "Adafruit_GFX.h" #include "Adafruit_GFX.h"
#define USE_FAST_PINIO ///< If set, use PORT access instead of digitalWrite() // HARDWARE CONFIG ---------------------------------------------------------
//#define USE_SPI_DMA ///< If set, use SPI DMA if available
#if defined(__AVR__)
typedef uint8_t 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 PORT_t; ///< PORT values are 32-bit
#elif defined(__arm__)
#if defined(ARDUINO_ARCH_SAMD)
// Adafruit M0, M4
typedef uint32_t 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 3.x
typedef uint8_t PORT_t; ///< PORT values are 8-bit
#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 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 PORT_t; ///< PORT values are 32-bit
#endif // end !ARM
typedef volatile 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
//#define USE_SPI_DMA ///< If set, use SPI DMA if available
// Another "oops" name -- in the future parallel DMA will also be handled.
// If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h> // If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h>
// Estimated RAM usage: // Estimated RAM usage:
// 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis, // 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis,
// e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes. // e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes.
#if !defined(ARDUINO_ARCH_SAMD) #if !defined(ARDUINO_ARCH_SAMD)
#undef USE_SPI_DMA ///< Only for SAMD chips #undef USE_SPI_DMA ///< DMA currently for SAMD chips only
#endif #endif
#ifdef USE_SPI_DMA #if defined(USE_SPI_DMA)
#pragma message ("SPI DMA IS ENABLED. HIGHLY EXPERIMENTAL.") #pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
#include <Adafruit_ZeroDMA.h> #include <Adafruit_ZeroDMA.h>
#endif #endif
#if defined(__AVR__) // This is kind of a kludge. Needed a way to disambiguate the software SPI
typedef volatile uint8_t RwReg; // and parallel constructors via their argument lists. Originally tried a
#elif defined(ARDUINO_STM32_FEATHER) // bool as the first argument to the parallel constructor (specifying 8-bit
typedef volatile uint32 RwReg; // vs 16-bit interface) but the compiler regards this as equivalent to an
#undef USE_FAST_PINIO // integer and thus still ambiguous. SO...the parallel constructor requires
typedef class HardwareSPI SPIClass; // an enumerated type as the first argument: tft8 (for 8-bit parallel) or
#elif defined(__OPENCR__) || defined (__OPENCM904__) // tft16 (for 16-bit)...even though 16-bit isn't fully implemented or tested
#undef USE_FAST_PINIO // and might never be, still needed that disambiguation from soft SPI.
#elif defined(ARDUINO_FEATHER52) || defined(__arm__) enum tftBusWidth { tft8, tft16 }; ///< For first arg to parallel constructor
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" // CLASS DEFINITION --------------------------------------------------------
/// 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. /*!
@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 { class Adafruit_SPITFT : public Adafruit_GFX {
public: 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);
Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, 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); // CONSTRUCTORS --------------------------------------------------------
// Required Non-Transaction // Software SPI constructor: expects width & height (at default rotation
void drawPixel(int16_t x, int16_t y, uint16_t color); // 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);
// Transaction API // Hardware SPI constructor using the default SPI port: expects width &
void startWrite(void); // height (at default rotation setting 0), 2 signal pins (cs, dc),
void endWrite(void); // 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);
void writePixel(int16_t x, int16_t y, uint16_t color); // Hardware SPI constructor using an arbitrary SPI peripheral: expects
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); // width & height (rotation 0), SPIClass pointer, 2 signal pins (cs, dc)
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); // and optional reset pin. cs is required but can be -1 if unused.
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass,
int8_t cs, int8_t dc, int8_t rst = -1);
// Transaction API not used by GFX // 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 ----------------------------------------------
@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;
/*! // These first two functions MUST be declared by subclasses:
@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); @brief Display-specific initialization function.
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); @param freq SPI frequency, in hz (or 0 for default or unused).
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); */
virtual void begin(uint32_t freq) = 0;
using Adafruit_GFX::drawRGBBitmap; // Check base class first /*!
void drawRGBBitmap(int16_t x, int16_t y, @brief Set up the specific display hardware's "address window"
uint16_t *pcolors, int16_t w, int16_t h); for subsequent pixel-pushing operations.
void invertDisplay(boolean i); @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;
uint16_t color565(uint8_t r, uint8_t g, uint8_t b); // Remaining functions do not need to be declared in subclasses
void writeCommand(uint8_t cmd); // unless they wish to provide hardware-specific optimizations.
void spiWrite(uint8_t v); // Brief comments here...documented more thoroughly in .cpp file.
uint8_t spiRead(void);
protected: // Subclass' begin() function invokes this to initialize hardware.
SPIClass *_spi; ///< The SPI device we want to use (set in constructor) // Name is outdated (interface may be parallel) but for compatibility:
uint32_t _freq; ///< SPI clock frequency (for hardware SPI) void initSPI(uint32_t freq = 0); // 0 = use default SPI speed
#if defined (__AVR__) || defined(TEENSYDUINO) || defined (ESP8266) || defined (ESP32) // Chip select and/or hardware SPI transaction start as needed:
int8_t _cs, _dc, _rst, _sclk, _mosi, _miso; void startWrite(void);
// Chip deselect and/or hardware SPI transaction end as needed:
void endWrite(void);
// 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);
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);
// 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(ARDUINO_STM32_FEATHER)
union {
#endif
struct { // Values specific to HARDWARE SPI:
SPIClass *_spi; ///< SPI class pointer
#if defined(SPI_HAS_TRANSACTION)
SPISettings settings; ///< SPI transaction settings
#else #else
int32_t _cs, ///< Arduino pin # for chip-select pin uint32_t _freq; ///< SPI bitrate (if no SPI transactions)
_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 #endif
} hwspi; ///< Hardware SPI values
#ifdef USE_FAST_PINIO struct { // Values specific to SOFTWARE SPI:
volatile RwReg *mosiport, ///< Direct chip register for toggling MOSI with fast bitbang IO #if defined(USE_FAST_PINIO)
*misoport, ///< Direct chip register for toggling MISO with fast bitbang IO PORTreg_t misoPort; ///< PORT (PIN) register for MISO
*clkport, ///< Direct chip register for toggling CLK with fast bitbang IO #if defined(HAS_PORT_SET_CLR)
*dcport, ///< Direct chip register for toggling DC with fast bitbang IO PORTreg_t mosiPortSet; ///< PORT register for MOSI SET
*csport; ///< Direct chip register for toggling CS with fast bitbang IO PORTreg_t mosiPortClr; ///< PORT register for MOSI CLEAR
RwReg mosipinmask, ///< bitmask for turning on/off MOSI with fast register bitbang IO PORTreg_t sckPortSet; ///< PORT register for SCK SET
misopinmask, ///< bitmask for turning on/off MISO with fast register bitbang IO PORTreg_t sckPortClr; ///< PORT register for SCK CLEAR
clkpinmask, ///< bitmask for turning on/off CLK with fast register bitbang IO #if !defined(KINETISK)
cspinmask, ///< bitmask for turning on/off CS with fast register bitbang IO PORT_t mosiPinMask; ///< Bitmask for MOSI
dcpinmask; ///< bitmask for turning on/off DC with fast register bitbang IO 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
PORT_t mosiPinMaskSet; ///< Bitmask for MOSI SET (OR)
PORT_t mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND)
PORT_t sckPinMaskSet; ///< Bitmask for SCK SET (OR bitmask)
PORT_t sckPinMaskClr; ///< Bitmask for SCK CLEAR (AND)
#endif // end HAS_PORT_SET_CLR
#if !defined(KINETISK)
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)
volatile uint8_t *writePort; ///< PORT register for DATA WRITE
volatile uint8_t *readPort; ///< PORT (PIN) register for DATA READ
#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.
volatile uint8_t *dirSet; ///< PORT byte data direction SET
volatile uint8_t *dirClr; ///< PORT byte data direction CLEAR
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)
PORT_t wrPinMask; ///< Bitmask for write strobe
#endif // end !KINETISK
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
PORT_t wrPinMaskSet; ///< Bitmask for write strobe SET (OR)
PORT_t wrPinMaskClr; ///< Bitmask for write strobe CLEAR (AND)
PORT_t rdPinMaskSet; ///< Bitmask for read strobe SET (OR)
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(ARDUINO_STM32_FEATHER)
}; ///< Only one interface is active
#endif #endif
#if defined(USE_SPI_DMA) // Used by hardware SPI and tft8
uint8_t invertOnCommand = 0, ///< SPI command byte to turn on invert Adafruit_ZeroDMA dma; ///< DMA instance
invertOffCommand = 0; ///< SPI command byte to turn off invert DmacDescriptor *dptr = NULL; ///< 1st descriptor
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 DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list
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 uint16_t *pixelBuf[2]; ///< Working buffers
uint16_t maxFillLen; ///< Max pixels per DMA xfer
#ifdef USE_SPI_DMA uint16_t lastFillColor = 0; ///< Last color used w/fill
Adafruit_ZeroDMA dma; ///< DMA instance uint32_t lastFillLen = 0; ///< # of pixels w/last fill
DmacDescriptor *dptr = NULL; ///< 1st descriptor uint8_t onePixelBuf; ///< For hi==lo fill
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 #endif
#if defined(USE_FAST_PINIO)
#if defined(HAS_PORT_SET_CLR)
#if !defined(KINETISK)
PORT_t csPinMask; ///< Bitmask for chip select
PORT_t dcPinMask; ///< Bitmask for data/command
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR)
PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR)
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 // !__AVR_ATtiny85__ #endif // end __AVR_ATtiny85__
#endif // end _ADAFRUIT_SPITFT_H_
#endif // !_ADAFRUIT_SPITFT_

View File

@ -1,116 +1,6 @@
#ifndef _ADAFRUIT_SPITFT_MACROS // THIS FILE INTENTIONALLY LEFT BLANK.
#define _ADAFRUIT_SPITFT_MACROS
/* // Macros previously #defined here have been made into (mostly) inline
* Control Pins // 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.
#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
* */
#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1)
#define HSPI_SET_CLOCK() _spi->setClockDivider(SPI_CLOCK_DIV2);
#elif defined (__arm__)
#define HSPI_SET_CLOCK() _spi->setClockDivider(11);
#elif defined(ESP8266) || defined(ESP32)
#define HSPI_SET_CLOCK() _spi->setFrequency(_freq);
#elif defined(RASPI)
#define HSPI_SET_CLOCK() _spi->setClock(_freq);
#elif defined(ARDUINO_ARCH_STM32F1)
#define HSPI_SET_CLOCK() _spi->setClock(_freq);
#else
#define HSPI_SET_CLOCK()
#endif
#ifdef SPI_HAS_TRANSACTION
#define HSPI_BEGIN_TRANSACTION() _spi->beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE0))
#define HSPI_END_TRANSACTION() _spi->endTransaction()
#else
#define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); _spi->setBitOrder(MSBFIRST); _spi->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->transfer(0)
#define HSPI_WRITE(b) _spi->write(b)
#define HSPI_WRITE16(s) _spi->write16(s)
#define HSPI_WRITE32(l) _spi->write32(l)
#ifdef SPI_HAS_WRITE_PIXELS
#define SPI_MAX_PIXELS_AT_ONCE 32
#define HSPI_WRITE_PIXELS(c,l) _spi->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->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->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

View File

@ -1,5 +1,5 @@
name=Adafruit GFX Library name=Adafruit GFX Library
version=1.3.6 version=1.4
author=Adafruit author=Adafruit
maintainer=Adafruit <info@adafruit.com> maintainer=Adafruit <info@adafruit.com>
sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from. sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from.