forked from moononournation/Arduino_GFX
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathArduino_SWSPI.h
186 lines (169 loc) · 8.02 KB
/
Arduino_SWSPI.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#ifndef _ARDUINO_SWSPI_H_
#define _ARDUINO_SWSPI_H_
// HARDWARE CONFIG ---------------------------------------------------------
#if defined(__AVR__)
typedef uint8_t ARDUINOGFX_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 ARDUINOGFX_PORT_t; ///< PORT values are 32-bit
#elif defined(__arm__)
#if defined(ARDUINO_ARCH_SAMD)
// Adafruit M0, M4
typedef uint32_t ARDUINOGFX_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 ARDUINOGFX_PORT_t; ///< PORT values are 32-bit
// PJRC Teensy 3.x
#else
typedef uint8_t ARDUINOGFX_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 ARDUINOGFX_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
#elif defined(ESP32)
typedef uint32_t ARDUINOGFX_PORT_t;
#define USE_FAST_PINIO ///< Use direct PORT register access
#define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
#else // !ARM
// Probably ESP8266. 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 ARDUINOGFX_PORT_t; ///< PORT values are 32-bit
#endif // end !ARM
typedef volatile ARDUINOGFX_PORT_t *PORTreg_t; ///< PORT register type
#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || defined(ADAFRUIT_PYGAMER_M4_EXPRESS) || defined(ADAFRUIT_HALLOWING_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 <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 ///< DMA currently for SAMD chips only
#endif
#if defined(USE_SPI_DMA)
#include <Adafruit_ZeroDMA.h>
#endif
#include "Arduino_DataBus.h"
class Arduino_SWSPI : public Arduino_DataBus
{
public:
Arduino_SWSPI(int8_t dc, int8_t cs, int8_t _sck, int8_t _mosi, int8_t _miso = -1); // Constructor
virtual void begin(int speed = 0, int8_t dataMode = -1);
virtual void beginWrite();
virtual void writeCommand(uint8_t);
virtual void writeCommand16(uint16_t);
virtual void writeCommand32(uint32_t);
virtual void write(uint8_t);
virtual void write16(uint16_t);
virtual void write32(uint32_t);
virtual void writeRepeat(uint16_t p, uint32_t len);
virtual void writeBytes(uint8_t *data, uint32_t len);
virtual void writePixels(uint16_t *data, uint32_t len);
virtual void writePattern(uint8_t *data, uint8_t len, uint32_t repeat);
virtual void endWrite();
virtual void sendCommand(uint8_t);
virtual void sendCommand16(uint16_t);
virtual void sendCommand32(uint32_t);
virtual void sendData(uint8_t);
virtual void sendData16(uint16_t);
virtual void sendData32(uint32_t);
private:
INLINE void WRITE9BITCOMMAND(uint8_t c);
INLINE void WRITE9BITDATA(uint8_t d);
INLINE void WRITE(uint8_t d);
INLINE void WRITE16(uint16_t d);
INLINE void WRITE32(uint32_t d);
INLINE void CS_HIGH(void);
INLINE void CS_LOW(void);
INLINE void DC_HIGH(void);
INLINE void DC_LOW(void);
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);
int8_t _dc, _cs, _sck, _mosi, _miso;
// 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(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)
ARDUINOGFX_PORT_t mosiPinMask; ///< Bitmask for MOSI
ARDUINOGFX_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
ARDUINOGFX_PORT_t mosiPinMaskSet; ///< Bitmask for MOSI SET (OR)
ARDUINOGFX_PORT_t mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND)
ARDUINOGFX_PORT_t sckPinMaskSet; ///< Bitmask for SCK SET (OR bitmask)
ARDUINOGFX_PORT_t sckPinMaskClr; ///< Bitmask for SCK CLEAR (AND)
#endif // end HAS_PORT_SET_CLR
#if !defined(KINETISK)
ARDUINOGFX_PORT_t misoPinMask; ///< Bitmask for MISO
#endif // end !KINETISK
#endif // end USE_FAST_PINIO
#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)
ARDUINOGFX_PORT_t csPinMask; ///< Bitmask for chip select
ARDUINOGFX_PORT_t dcPinMask; ///< Bitmask for data/command
#endif // end !KINETISK
#else // !HAS_PORT_SET_CLR
ARDUINOGFX_PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR)
ARDUINOGFX_PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
ARDUINOGFX_PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ARDUINOGFX_PORT_t dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
#endif // end HAS_PORT_SET_CLR
#endif // end USE_FAST_PINIO
};
#endif // _ARDUINO_SWSPI_H_