2017-09-25 22:35:26 -04:00
# ifndef _ADAFRUIT_SPITFT_
# define _ADAFRUIT_SPITFT_
2018-11-15 22:14:23 -05:00
# if !defined(__AVR_ATtiny85__) // NOT A CHANCE of this stuff working on ATtiny
2017-09-25 22:35:26 -04:00
# if ARDUINO >= 100
# include "Arduino.h"
# include "Print.h"
# else
# include "WProgram.h"
# endif
# include <SPI.h>
# include "Adafruit_GFX.h"
2018-12-06 20:40:49 -05:00
# define USE_FAST_PINIO ///< If set, use PORT access instead of digitalWrite()
2018-12-10 18:02:33 -05:00
//#define USE_SPI_DMA ///< If set, use SPI DMA if available
2018-12-06 20:40:49 -05:00
// If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h>
// 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 ///< Only for SAMD chips
# endif
# ifdef USE_SPI_DMA
2018-12-11 23:25:34 -05:00
# pragma message ("SPI DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
2018-12-06 20:40:49 -05:00
# include <Adafruit_ZeroDMA.h>
# endif
2018-07-14 15:39:11 -04:00
2018-07-14 02:08:49 -04:00
# if defined(__AVR__)
2018-08-11 02:22:53 -04:00
typedef volatile uint8_t RwReg ;
2018-07-14 02:08:49 -04:00
# elif defined(ARDUINO_STM32_FEATHER)
2019-01-31 18:17:08 -05:00
typedef volatile uint32_t RwReg ;
2018-08-11 02:22:53 -04:00
# undef USE_FAST_PINIO
2018-11-17 01:09:07 -05:00
typedef class HardwareSPI SPIClass ;
2018-07-26 13:36:31 -04:00
# elif defined(__OPENCR__) || defined (__OPENCM904__)
2018-08-11 02:22:53 -04:00
# undef USE_FAST_PINIO
2018-07-14 02:08:49 -04:00
# elif defined(ARDUINO_FEATHER52) || defined(__arm__)
2018-08-11 02:22:53 -04:00
typedef volatile uint32_t RwReg ;
2018-07-14 15:39:11 -04:00
# elif defined(ESP32) || defined(ESP8266)
2018-08-11 02:22:53 -04:00
typedef volatile uint32_t RwReg ;
# undef USE_FAST_PINIO
2018-07-14 15:39:11 -04:00
# else
2018-08-11 02:22:53 -04:00
# undef USE_FAST_PINIO
2017-09-25 22:35:26 -04:00
# endif
2018-07-14 23:05:47 -04:00
# include "Adafruit_SPITFT_Macros.h"
2018-07-14 02:08:49 -04:00
2018-07-14 15:21:57 -04:00
/// 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.
2017-09-25 22:35:26 -04:00
class Adafruit_SPITFT : public Adafruit_GFX {
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 ) ;
2018-11-03 17:39:10 -04:00
Adafruit_SPITFT ( uint16_t w , uint16_t h , SPIClass * spiClass , int8_t _CS , int8_t _DC , int8_t _RST = - 1 ) ;
2018-08-11 02:22:53 -04:00
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
2017-09-25 22:35:26 -04:00
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 ) ;
2018-07-14 16:57:42 -04:00
2017-09-25 22:35:26 -04:00
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
2018-07-14 16:01:33 -04:00
/*!
@ 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 ;
2018-07-14 16:57:42 -04:00
/*!
@ 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 ) ; }
2017-09-25 22:35:26 -04:00
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 ) ;
2018-07-14 02:02:02 -04:00
void invertDisplay ( boolean i ) ;
2017-09-25 22:35:26 -04:00
uint16_t color565 ( uint8_t r , uint8_t g , uint8_t b ) ;
2018-11-29 14:59:07 -05:00
void writeCommand ( uint8_t cmd ) ;
void spiWrite ( uint8_t v ) ;
uint8_t spiRead ( void ) ;
2017-09-25 22:35:26 -04:00
protected :
2018-11-03 17:39:10 -04:00
SPIClass * _spi ; ///< The SPI device we want to use (set in constructor)
2018-07-14 15:21:57 -04:00
uint32_t _freq ; ///< SPI clock frequency (for hardware SPI)
2017-09-25 22:35:26 -04:00
# if defined (__AVR__) || defined(TEENSYDUINO) || defined (ESP8266) || defined (ESP32)
int8_t _cs , _dc , _rst , _sclk , _mosi , _miso ;
# else
2018-07-14 15:21:57 -04:00
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
2017-09-25 22:35:26 -04:00
# endif
# ifdef USE_FAST_PINIO
2018-07-14 15:21:57 -04:00
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
2017-09-25 22:35:26 -04:00
# endif
2018-07-14 15:21:57 -04:00
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
2018-12-06 20:40:49 -05:00
# ifdef USE_SPI_DMA
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
2017-09-25 22:35:26 -04:00
} ;
2018-11-15 22:14:23 -05:00
# endif // !__AVR_ATtiny85__
# endif // !_ADAFRUIT_SPITFT_