forked from mrcodetastic/ESP32-HUB75-MatrixPanel-DMA
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathESP32-VirtualMatrixPanel-I2S-DMA.h
More file actions
199 lines (155 loc) · 6.48 KB
/
ESP32-VirtualMatrixPanel-I2S-DMA.h
File metadata and controls
199 lines (155 loc) · 6.48 KB
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
187
188
189
190
191
192
193
194
195
196
197
198
199
#ifndef _ESP32_VIRTUAL_MATRIX_PANEL_I2S_DMA
#define _ESP32_VIRTUAL_MATRIX_PANEL_I2S_DMA
/*******************************************************************
Class contributed by Brian Lough, and expanded by Faptastic.
YouTube: https://www.youtube.com/brianlough
Tindie: https://www.tindie.com/stores/brianlough/
Twitter: https://twitter.com/witnessmenow
*******************************************************************/
#include "ESP32-RGB64x32MatrixPanel-I2S-DMA.h"
#include <Fonts/FreeSansBold12pt7b.h>
struct VirtualCoords {
int16_t x;
int16_t y;
};
#ifdef USE_GFX_ROOT
class VirtualMatrixPanel : public GFX
#else
class VirtualMatrixPanel : public Adafruit_GFX
#endif
{
public:
int16_t virtualResX;
int16_t virtualResY;
int16_t module_rows;
int16_t module_cols;
int16_t panelResX;
int16_t panelResY;
RGB64x32MatrixPanel_I2S_DMA *display;
#ifdef USE_GFX_ROOT
VirtualMatrixPanel(RGB64x32MatrixPanel_I2S_DMA &disp, int vmodule_rows, int vmodule_cols, int panelX, int panelY, bool serpentine_chain = true, bool top_down_chain = false)
: GFX(vmodule_cols*panelX, vmodule_rows*panelY)
#else
VirtualMatrixPanel(RGB64x32MatrixPanel_I2S_DMA &disp, int vmodule_rows, int vmodule_cols, int panelX, int panelY, bool serpentine_chain = true, bool top_down_chain = false )
: Adafruit_GFX(vmodule_cols*panelX, vmodule_rows*panelY)
#endif
{
this->display = &disp;
panelResX = panelX;
panelResY = panelY;
module_rows = vmodule_rows;
module_cols = vmodule_cols;
virtualResY = vmodule_rows*panelY;
virtualResX = vmodule_cols*panelX;
_s_chain_party = serpentine_chain; // serpentine, or 'S' chain?
_chain_top_down= top_down_chain;
}
VirtualCoords getCoords(int16_t x, int16_t y);
// equivalent methods of the matrix library so it can be just swapped out.
virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
virtual void fillScreen(uint16_t color); // overwrite adafruit implementation
void clearScreen() {
fillScreen(0);
}
void drawPixelRGB565(int16_t x, int16_t y, uint16_t color);
void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b);
void drawPixelRGB24(int16_t x, int16_t y, RGB24 color);
void drawIcon (int *ico, int16_t x, int16_t y, int16_t module_cols, int16_t module_rows);
uint16_t color444(uint8_t r, uint8_t g, uint8_t b) {
return display->color444(r, g, b);
}
uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
return display->color565(r, g, b);
}
uint16_t color333(uint8_t r, uint8_t g, uint8_t b) {
return display->color333(r, g, b);
}
void flipDMABuffer() { display->flipDMABuffer(); }
void showDMABuffer() { display->showDMABuffer(); }
void drawDisplayTest();
private:
VirtualCoords coords;
bool _s_chain_party = true; // Are we chained? Ain't no party like a...
bool _chain_top_down = false; // is the ESP at the top or bottom of the matrix of devices?
}; // end Class header
inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t x, int16_t y) {
coords.x = coords.y = 0;
if (x < 0 || x > module_cols*panelResX || y < 0 || y > module_rows*panelResY ) {
//Serial.printf("VirtualMatrixPanel::getCoords(): Invalid virtual display coordinate. x,y: %d, %d\r\n", x, y);
return coords;
}
uint8_t row = (y / panelResY) + 1; //a non indexed 0 row number
if( ( _s_chain_party && !_chain_top_down && (row % 2 == 0) ) // serpentine vertically stacked chain starting from bottom row (i.e. ESP closest to ground), upwards
||
( _s_chain_party && _chain_top_down && (row % 2 != 0) ) // serpentine vertically stacked chain starting from the sky downwards
)
{
// First portion gets you to the correct offset for the row you need
// Second portion inverts the x on the row
coords.x = (y / panelResY) * (module_cols * panelResX) + (virtualResX - 1 - x);
// inverts the y the row
coords.y = panelResY - 1 - (y % panelResY);
}
else
{
coords.x = x + (y / panelResY) * (module_cols * panelResX) ;
coords.y = y % panelResY;
}
// Reverse co-ordinates if panel chain from ESP starts from the TOP RIGHT
if (_chain_top_down)
{
coords.x = (this->display->width()-1) - coords.x;
coords.y = (this->display->height()-1) - coords.y;
}
//Serial.print("Mapping to x: "); Serial.print(coords.x, DEC); Serial.print(", y: "); Serial.println(coords.y, DEC);
return coords;
}
inline void VirtualMatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t color)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixel(coords.x, coords.y, color);
}
inline void VirtualMatrixPanel::fillScreen(uint16_t color) // adafruit virtual void override
{
// No need to map this.
this->display->fillScreen(color);
}
inline void VirtualMatrixPanel::drawPixelRGB565(int16_t x, int16_t y, uint16_t color)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixelRGB565( coords.x, coords.y, color);
}
inline void VirtualMatrixPanel::drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixelRGB888( coords.x, coords.y, r, g, b);
}
inline void VirtualMatrixPanel::drawPixelRGB24(int16_t x, int16_t y, RGB24 color)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixelRGB24(coords.x, coords.y, color);
}
inline void VirtualMatrixPanel::drawDisplayTest()
{
this->display->setFont(&FreeSansBold12pt7b);
this->display->setTextColor(this->display->color565(255, 255, 0));
this->display->setTextSize(1);
for ( int panel = 0; panel < module_cols*module_rows; panel++ ) {
int top_left_x = (panel == 0) ? 0:(panel*panelResX);
this->display->drawRect( top_left_x, 0, panelResX, panelResY, this->display->color565( 0, 255, 0));
this->display->setCursor(panel*panelResX, panelResY-3);
this->display->print((module_cols*module_rows)-panel);
}
}
// need to recreate this one, as it wouldnt work to just map where it starts.
inline void VirtualMatrixPanel::drawIcon (int *ico, int16_t x, int16_t y, int16_t module_cols, int16_t module_rows) {
int i, j;
for (i = 0; i < module_rows; i++) {
for (j = 0; j < module_cols; j++) {
// This is a call to this libraries version of drawPixel
// which will map each pixel, which is what we want.
drawPixelRGB565 (x + j, y + i, ico[i * module_cols + j]);
}
}
}
#endif