Adafruit-RGB_matrix_Panel(32*32)

Dependencies:   Adafruit-GFX

Dependents:   Experience

Committer:
lelect
Date:
Sun May 25 12:02:10 2014 +0000
Revision:
8:6d98c8cd8045
Parent:
6:b594794a132e
DigitalOut* array test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lelect 2:6136465ffd3a 1 #define DEBUG
lelect 5:1f8409ee8850 2 #undef DEBUG
lelect 0:06d9443a018f 3 #include "RGBmatrixPanel.h"
lelect 0:06d9443a018f 4 #include "gamma.h"
lelect 0:06d9443a018f 5
lelect 0:06d9443a018f 6 #define nPlanes 4
lelect 0:06d9443a018f 7
lelect 0:06d9443a018f 8 // The fact that the display driver interrupt stuff is tied to the
lelect 0:06d9443a018f 9 // singular Timer1 doesn't really take well to object orientation with
lelect 0:06d9443a018f 10 // multiple RGBmatrixPanel instances. The solution at present is to
lelect 0:06d9443a018f 11 // allow instances, but only one is active at any given time, via its
lelect 0:06d9443a018f 12 // begin() method. The implementation is still incomplete in parts;
lelect 0:06d9443a018f 13 // the prior active panel really should be gracefully disabled, and a
lelect 0:06d9443a018f 14 // stop() method should perhaps be added...assuming multiple instances
lelect 0:06d9443a018f 15 // are even an actual need.
lelect 4:0ff6053c4bb2 16 //static RGBmatrixPanel *activePanel = NULL;
lelect 0:06d9443a018f 17
lelect 0:06d9443a018f 18 // Code common to both the 16x32 and 32x32 constructors:
lelect 2:6136465ffd3a 19 void RGBmatrixPanel::init(uint8_t rows, bool dbuf)
lelect 0:06d9443a018f 20 {
lelect 0:06d9443a018f 21 nRows = rows; // Number of multiplexed rows; actual height is 2X this
lelect 0:06d9443a018f 22 // Allocate and initialize matrix buffer:
lelect 3:aa3762e0dfee 23 int buffsize = 32*nRows*3, // x3 = 3 bytes holds 4 planes "packed"
lelect 0:06d9443a018f 24 allocsize = (dbuf == true) ? (buffsize * 2) : buffsize;
lelect 0:06d9443a018f 25 if(NULL == (matrixbuff[0] = (uint8_t *)malloc(allocsize))) return;
lelect 0:06d9443a018f 26 memset(matrixbuff[0], 0, allocsize);
lelect 0:06d9443a018f 27 // If not double-buffered, both buffers then point to the same address:
lelect 0:06d9443a018f 28 matrixbuff[1] = (dbuf == true) ? &matrixbuff[0][buffsize] : matrixbuff[0];
lelect 0:06d9443a018f 29
lelect 0:06d9443a018f 30 plane = nPlanes - 1;
lelect 0:06d9443a018f 31 row = nRows - 1;
lelect 0:06d9443a018f 32 swapflag = false;
lelect 0:06d9443a018f 33 backindex = 0; // Array index of back buffer
lelect 0:06d9443a018f 34 }
lelect 0:06d9443a018f 35
lelect 0:06d9443a018f 36 // Constructor for 16x32 panel:
lelect 3:aa3762e0dfee 37 RGBmatrixPanel::RGBmatrixPanel(PinName r1,PinName r2,PinName g1,PinName g2,PinName b1,PinName b2,PinName a,PinName b, PinName c, PinName sclk, PinName latch, PinName oe, bool dbuf)
lelect 2:6136465ffd3a 38 :Adafruit_GFX(32, 16),
lelect 5:1f8409ee8850 39 _rowBus(a,b,c),
lelect 5:1f8409ee8850 40 _d(NC),
lelect 2:6136465ffd3a 41 _sclk(sclk),
lelect 2:6136465ffd3a 42 _latch(latch),
lelect 5:1f8409ee8850 43 _oe(oe)
lelect 0:06d9443a018f 44 {
lelect 8:6d98c8cd8045 45 PinName pins[6] = {r1,g1,b1,r2,g2,b2};
lelect 8:6d98c8cd8045 46 for(int i=0; i<6; i++) {
lelect 8:6d98c8cd8045 47 _pin[i] = (pins[i] != NC) ? new DigitalOut(pins[i]) : 0;
lelect 8:6d98c8cd8045 48 }
lelect 2:6136465ffd3a 49 init(8, dbuf);
lelect 0:06d9443a018f 50 }
lelect 0:06d9443a018f 51
lelect 0:06d9443a018f 52 // Constructor for 32x32 panel:
lelect 3:aa3762e0dfee 53 RGBmatrixPanel::RGBmatrixPanel(PinName r1,PinName r2,PinName g1,PinName g2,PinName b1,PinName b2,PinName a,PinName b,PinName c,PinName d,PinName sclk,PinName latch,PinName oe,bool dbuf)
lelect 2:6136465ffd3a 54 :Adafruit_GFX(32, 32),
lelect 5:1f8409ee8850 55 _rowBus(a,b,c),
lelect 5:1f8409ee8850 56 _d(d),// Init 32x32-specific elements:
lelect 2:6136465ffd3a 57 _sclk(sclk),
lelect 2:6136465ffd3a 58 _latch(latch),
lelect 5:1f8409ee8850 59 _oe(oe)
lelect 0:06d9443a018f 60 {
lelect 8:6d98c8cd8045 61 PinName pins[6] = {r1,g1,b1,r2,g2,b2};
lelect 8:6d98c8cd8045 62 for(int i=0; i<6; i++) {
lelect 8:6d98c8cd8045 63 _pin[i] = (pins[i] != NC) ? new DigitalOut(pins[i]) : 0;
lelect 8:6d98c8cd8045 64 }
lelect 2:6136465ffd3a 65 init(16,dbuf);
lelect 0:06d9443a018f 66 }
lelect 0:06d9443a018f 67
lelect 0:06d9443a018f 68 void RGBmatrixPanel::begin(void)
lelect 0:06d9443a018f 69 {
lelect 0:06d9443a018f 70
lelect 0:06d9443a018f 71 backindex = 0; // Back buffer
lelect 0:06d9443a018f 72 buffptr = matrixbuff[1 - backindex]; // -> front buffer
lelect 4:0ff6053c4bb2 73 // activePanel = this; // For interrupt hander
lelect 0:06d9443a018f 74
lelect 3:aa3762e0dfee 75 // Set up Timer for interrupt:
lelect 4:0ff6053c4bb2 76 #ifndef DEBUG
lelect 6:b594794a132e 77 _refresh.attach_us(this,(&RGBmatrixPanel::updateDisplay),200); //updateDisplay() called every 1ms
lelect 4:0ff6053c4bb2 78 #else
lelect 5:1f8409ee8850 79 _refresh.attach(this,(&RGBmatrixPanel::updateDisplay),0.5); //updateDisplay() called every 2s
lelect 4:0ff6053c4bb2 80 #endif
lelect 0:06d9443a018f 81 }
lelect 0:06d9443a018f 82
lelect 0:06d9443a018f 83 // Original RGBmatrixPanel library used 3/3/3 color. Later version used
lelect 0:06d9443a018f 84 // 4/4/4. Then Adafruit_GFX (core library used across all Adafruit
lelect 0:06d9443a018f 85 // display devices now) standardized on 5/6/5. The matrix still operates
lelect 0:06d9443a018f 86 // internally on 4/4/4 color, but all the graphics functions are written
lelect 0:06d9443a018f 87 // to expect 5/6/5...the matrix lib will truncate the color components as
lelect 0:06d9443a018f 88 // needed when drawing. These next functions are mostly here for the
lelect 0:06d9443a018f 89 // benefit of older code using one of the original color formats.
lelect 0:06d9443a018f 90
lelect 0:06d9443a018f 91 // Promote 3/3/3 RGB to Adafruit_GFX 5/6/5
lelect 0:06d9443a018f 92 uint16_t RGBmatrixPanel::Color333(uint8_t r, uint8_t g, uint8_t b)
lelect 0:06d9443a018f 93 {
lelect 0:06d9443a018f 94 // RRRrrGGGgggBBBbb
lelect 0:06d9443a018f 95 return ((r & 0x7) << 13) | ((r & 0x6) << 10) |
lelect 0:06d9443a018f 96 ((g & 0x7) << 8) | ((g & 0x7) << 5) |
lelect 0:06d9443a018f 97 ((b & 0x7) << 2) | ((b & 0x6) >> 1);
lelect 0:06d9443a018f 98 }
lelect 0:06d9443a018f 99
lelect 0:06d9443a018f 100 // Promote 4/4/4 RGB to Adafruit_GFX 5/6/5
lelect 0:06d9443a018f 101 uint16_t RGBmatrixPanel::Color444(uint8_t r, uint8_t g, uint8_t b)
lelect 0:06d9443a018f 102 {
lelect 0:06d9443a018f 103 // RRRRrGGGGggBBBBb
lelect 0:06d9443a018f 104 return ((r & 0xF) << 12) | ((r & 0x8) << 8) |
lelect 0:06d9443a018f 105 ((g & 0xF) << 7) | ((g & 0xC) << 3) |
lelect 0:06d9443a018f 106 ((b & 0xF) << 1) | ((b & 0x8) >> 3);
lelect 0:06d9443a018f 107 }
lelect 0:06d9443a018f 108
lelect 0:06d9443a018f 109 // Demote 8/8/8 to Adafruit_GFX 5/6/5
lelect 0:06d9443a018f 110 // If no gamma flag passed, assume linear color
lelect 0:06d9443a018f 111 uint16_t RGBmatrixPanel::Color888(uint8_t r, uint8_t g, uint8_t b)
lelect 0:06d9443a018f 112 {
lelect 0:06d9443a018f 113 return ((r & 0xF8) << 11) | ((g & 0xFC) << 5) | (b >> 3);
lelect 0:06d9443a018f 114 }
lelect 0:06d9443a018f 115
lelect 0:06d9443a018f 116 // 8/8/8 -> gamma -> 5/6/5
lelect 1:0078213d3fa4 117 uint16_t RGBmatrixPanel::Color888(uint8_t r, uint8_t g, uint8_t b, bool gflag)
lelect 0:06d9443a018f 118 {
lelect 0:06d9443a018f 119 if(gflag) { // Gamma-corrected color?
lelect 1:0078213d3fa4 120 r = gamma[r]; // Gamma correction table maps
lelect 1:0078213d3fa4 121 g = gamma[g]; // 8-bit input to 4-bit output
lelect 1:0078213d3fa4 122 b = gamma[b];
lelect 0:06d9443a018f 123 return (r << 12) | ((r & 0x8) << 8) | // 4/4/4 -> 5/6/5
lelect 0:06d9443a018f 124 (g << 7) | ((g & 0xC) << 3) |
lelect 0:06d9443a018f 125 (b << 1) | ( b >> 3);
lelect 0:06d9443a018f 126 } // else linear (uncorrected) color
lelect 0:06d9443a018f 127 return ((r & 0xF8) << 11) | ((g & 0xFC) << 5) | (b >> 3);
lelect 0:06d9443a018f 128 }
lelect 0:06d9443a018f 129
lelect 1:0078213d3fa4 130 uint16_t RGBmatrixPanel::ColorHSV(long hue, uint8_t sat, uint8_t val, bool gflag)
lelect 0:06d9443a018f 131 {
lelect 0:06d9443a018f 132
lelect 0:06d9443a018f 133 uint8_t r, g, b, lo;
lelect 0:06d9443a018f 134 uint16_t s1, v1;
lelect 0:06d9443a018f 135
lelect 0:06d9443a018f 136 // Hue
lelect 0:06d9443a018f 137 hue %= 1536; // -1535 to +1535
lelect 0:06d9443a018f 138 if(hue < 0) hue += 1536; // 0 to +1535
lelect 0:06d9443a018f 139 lo = hue & 255; // Low byte = primary/secondary color mix
lelect 0:06d9443a018f 140 switch(hue >> 8) { // High byte = sextant of colorwheel
lelect 0:06d9443a018f 141 case 0 :
lelect 0:06d9443a018f 142 r = 255 ;
lelect 0:06d9443a018f 143 g = lo ;
lelect 0:06d9443a018f 144 b = 0 ;
lelect 0:06d9443a018f 145 break; // R to Y
lelect 0:06d9443a018f 146 case 1 :
lelect 0:06d9443a018f 147 r = 255 - lo;
lelect 0:06d9443a018f 148 g = 255 ;
lelect 0:06d9443a018f 149 b = 0 ;
lelect 0:06d9443a018f 150 break; // Y to G
lelect 0:06d9443a018f 151 case 2 :
lelect 0:06d9443a018f 152 r = 0 ;
lelect 0:06d9443a018f 153 g = 255 ;
lelect 0:06d9443a018f 154 b = lo ;
lelect 0:06d9443a018f 155 break; // G to C
lelect 0:06d9443a018f 156 case 3 :
lelect 0:06d9443a018f 157 r = 0 ;
lelect 0:06d9443a018f 158 g = 255 - lo;
lelect 0:06d9443a018f 159 b = 255 ;
lelect 0:06d9443a018f 160 break; // C to B
lelect 0:06d9443a018f 161 case 4 :
lelect 0:06d9443a018f 162 r = lo ;
lelect 0:06d9443a018f 163 g = 0 ;
lelect 0:06d9443a018f 164 b = 255 ;
lelect 0:06d9443a018f 165 break; // B to M
lelect 0:06d9443a018f 166 default:
lelect 0:06d9443a018f 167 r = 255 ;
lelect 0:06d9443a018f 168 g = 0 ;
lelect 0:06d9443a018f 169 b = 255 - lo;
lelect 0:06d9443a018f 170 break; // M to R
lelect 0:06d9443a018f 171 }
lelect 0:06d9443a018f 172
lelect 0:06d9443a018f 173 // Saturation: add 1 so range is 1 to 256, allowig a quick shift operation
lelect 0:06d9443a018f 174 // on the result rather than a costly divide, while the type upgrade to int
lelect 0:06d9443a018f 175 // avoids repeated type conversions in both directions.
lelect 0:06d9443a018f 176 s1 = sat + 1;
lelect 0:06d9443a018f 177 r = 255 - (((255 - r) * s1) >> 8);
lelect 0:06d9443a018f 178 g = 255 - (((255 - g) * s1) >> 8);
lelect 0:06d9443a018f 179 b = 255 - (((255 - b) * s1) >> 8);
lelect 0:06d9443a018f 180
lelect 0:06d9443a018f 181 // Value (brightness) & 16-bit color reduction: similar to above, add 1
lelect 0:06d9443a018f 182 // to allow shifts, and upgrade to int makes other conversions implicit.
lelect 0:06d9443a018f 183 v1 = val + 1;
lelect 0:06d9443a018f 184 if(gflag) { // Gamma-corrected color?
lelect 2:6136465ffd3a 185 r = gamma[(r * v1) >> 8]; // Gamma correction table maps
lelect 2:6136465ffd3a 186 g = gamma[(g * v1) >> 8]; // 8-bit input to 4-bit output
lelect 2:6136465ffd3a 187 b = gamma[(b * v1) >> 8];
lelect 2:6136465ffd3a 188 //before pgm_read_byte(&gamma[(b * v1) >> 8])
lelect 0:06d9443a018f 189 } else { // linear (uncorrected) color
lelect 0:06d9443a018f 190 r = (r * v1) >> 12; // 4-bit results
lelect 0:06d9443a018f 191 g = (g * v1) >> 12;
lelect 0:06d9443a018f 192 b = (b * v1) >> 12;
lelect 0:06d9443a018f 193 }
lelect 0:06d9443a018f 194 return (r << 12) | ((r & 0x8) << 8) | // 4/4/4 -> 5/6/5
lelect 0:06d9443a018f 195 (g << 7) | ((g & 0xC) << 3) |
lelect 0:06d9443a018f 196 (b << 1) | ( b >> 3);
lelect 0:06d9443a018f 197 }
lelect 0:06d9443a018f 198
lelect 0:06d9443a018f 199 void RGBmatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t c)
lelect 0:06d9443a018f 200 {
lelect 0:06d9443a018f 201 uint8_t r, g, b, bit, limit, *ptr;
lelect 0:06d9443a018f 202 if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return;
lelect 0:06d9443a018f 203 switch(rotation) {
lelect 0:06d9443a018f 204 case 1:
lelect 0:06d9443a018f 205 swap(x, y);
lelect 0:06d9443a018f 206 x = _rawWidth - 1 - x;
lelect 0:06d9443a018f 207 break;
lelect 0:06d9443a018f 208 case 2:
lelect 0:06d9443a018f 209 x = _rawWidth - 1 - x;
lelect 0:06d9443a018f 210 y = _rawHeight - 1 - y;
lelect 0:06d9443a018f 211 break;
lelect 0:06d9443a018f 212 case 3:
lelect 0:06d9443a018f 213 swap(x, y);
lelect 0:06d9443a018f 214 y = _rawHeight - 1 - y;
lelect 0:06d9443a018f 215 break;
lelect 0:06d9443a018f 216 }
lelect 0:06d9443a018f 217
lelect 0:06d9443a018f 218 // Adafruit_GFX uses 16-bit color in 5/6/5 format, while matrix needs
lelect 0:06d9443a018f 219 // 4/4/4. Pluck out relevant bits while separating into R,G,B:
lelect 0:06d9443a018f 220 r = c >> 12; // RRRRrggggggbbbbb
lelect 0:06d9443a018f 221 g = (c >> 7) & 0xF; // rrrrrGGGGggbbbbb
lelect 0:06d9443a018f 222 b = (c >> 1) & 0xF; // rrrrrggggggBBBBb
lelect 0:06d9443a018f 223 // Loop counter stuff
lelect 4:0ff6053c4bb2 224 //log_debug("(%X, %X, %X)@(%d,%d)%s",r,g,b,x,y,"\t");
lelect 0:06d9443a018f 225 bit = 2;
lelect 0:06d9443a018f 226 limit = 1 << nPlanes;
lelect 0:06d9443a018f 227
lelect 0:06d9443a018f 228 if(y < nRows) {
lelect 2:6136465ffd3a 229 // Data for the upper half of the display is stored in the lower bits of each byte.
lelect 2:6136465ffd3a 230 ptr = &matrixbuff[backindex][y*_rawWidth*(nPlanes-1) + x]; // Base addr
lelect 4:0ff6053c4bb2 231 // Plane 0 is a tricky case -- its data is spread about, stored in least two bits not used by the other planes.
lelect 4:0ff6053c4bb2 232 ptr[64] &= ~(_BV(1)|_BV(0)); // Plane 0 R,G mask(0b11111100) out in one op
lelect 2:6136465ffd3a 233 if(r & 1) ptr[64] |= _BV(0); // Plane 0 R: 64 bytes ahead, bit 0
lelect 2:6136465ffd3a 234 if(g & 1) ptr[64] |= _BV(1); // Plane 0 G: 64 bytes ahead, bit 1
lelect 2:6136465ffd3a 235 if(b & 1) ptr[32] |= _BV(0); // Plane 0 B: 32 bytes ahead, bit 0
lelect 2:6136465ffd3a 236 else ptr[32] &= ~_BV(0); // Plane 0 B unset; mask out
lelect 0:06d9443a018f 237 // The remaining three image planes are more normal-ish.
lelect 0:06d9443a018f 238 // Data is stored in the high 6 bits so it can be quickly
lelect 0:06d9443a018f 239 // copied to the DATAPORT register w/6 output lines.
lelect 0:06d9443a018f 240 for(; bit < limit; bit <<= 1) {
lelect 5:1f8409ee8850 241 *ptr &= ~(_BV(4)|_BV(3)|_BV(2)) ; // Mask(0b11100011) out R,G,B in one op
lelect 4:0ff6053c4bb2 242 if(r & bit) *ptr |= _BV(2); // Plane N R: bit 2
lelect 4:0ff6053c4bb2 243 if(g & bit) *ptr |= _BV(3); // Plane N G: bit 3
lelect 4:0ff6053c4bb2 244 if(b & bit) *ptr |= _BV(4); // Plane N B: bit 4
lelect 4:0ff6053c4bb2 245 ptr += _rawWidth; // Advance to next bit plane
lelect 0:06d9443a018f 246 }
lelect 0:06d9443a018f 247 } else {
lelect 2:6136465ffd3a 248 // Data for the lower half of the display is stored in the upper bits, except for the plane 0 stuff, using 2 least bits.
lelect 2:6136465ffd3a 249 ptr = &matrixbuff[backindex][(y-nRows)*_rawWidth*(nPlanes-1) + x];
lelect 4:0ff6053c4bb2 250 *ptr &= ~(_BV(1)|_BV(0)); // Plane 0 G,B mask out in one op
lelect 2:6136465ffd3a 251 if(r & 1) ptr[32] |= _BV(1); // Plane 0 R: 32 bytes ahead, bit 1
lelect 4:0ff6053c4bb2 252 else ptr[32] &= ~_BV(1); // Plane 0 R unset; mask out
lelect 2:6136465ffd3a 253 if(g & 1) *ptr |= _BV(0); // Plane 0 G: bit 0
lelect 2:6136465ffd3a 254 if(b & 1) *ptr |= _BV(1); // Plane 0 B: bit 0
lelect 0:06d9443a018f 255 for(; bit < limit; bit <<= 1) {
lelect 4:0ff6053c4bb2 256 *ptr &= ~(_BV(7)|_BV(6)|_BV(5)); // Mask out R,G,B in one op
lelect 2:6136465ffd3a 257 if(r & bit) *ptr |= _BV(5); // Plane N R: bit 5
lelect 2:6136465ffd3a 258 if(g & bit) *ptr |= _BV(6); // Plane N G: bit 6
lelect 2:6136465ffd3a 259 if(b & bit) *ptr |= _BV(7); // Plane N B: bit 7
lelect 2:6136465ffd3a 260 ptr += _rawWidth; // Advance to next bit plane
lelect 0:06d9443a018f 261 }
lelect 0:06d9443a018f 262 }
lelect 0:06d9443a018f 263 }
lelect 0:06d9443a018f 264
lelect 0:06d9443a018f 265 void RGBmatrixPanel::fillScreen(uint16_t c)
lelect 0:06d9443a018f 266 {
lelect 0:06d9443a018f 267 if((c == 0x0000) || (c == 0xffff)) {
lelect 0:06d9443a018f 268 // For black or white, all bits in frame buffer will be identically
lelect 0:06d9443a018f 269 // set or unset (regardless of weird bit packing), so it's OK to just
lelect 0:06d9443a018f 270 // quickly memset the whole thing:
lelect 0:06d9443a018f 271 memset(matrixbuff[backindex], c, 32 * nRows * 3);
lelect 0:06d9443a018f 272 } else {
lelect 0:06d9443a018f 273 // Otherwise, need to handle it the long way:
lelect 0:06d9443a018f 274 Adafruit_GFX::fillScreen(c);
lelect 0:06d9443a018f 275 }
lelect 0:06d9443a018f 276 }
lelect 0:06d9443a018f 277
lelect 0:06d9443a018f 278 // Return address of back buffer -- can then load/store data directly
lelect 0:06d9443a018f 279 uint8_t *RGBmatrixPanel::backBuffer()
lelect 0:06d9443a018f 280 {
lelect 0:06d9443a018f 281 return matrixbuff[backindex];
lelect 0:06d9443a018f 282 }
lelect 0:06d9443a018f 283
lelect 0:06d9443a018f 284 // For smooth animation -- drawing always takes place in the "back" buffer;
lelect 0:06d9443a018f 285 // this method pushes it to the "front" for display. Passing "true", the
lelect 0:06d9443a018f 286 // updated display contents are then copied to the new back buffer and can
lelect 0:06d9443a018f 287 // be incrementally modified. If "false", the back buffer then contains
lelect 0:06d9443a018f 288 // the old front buffer contents -- your code can either clear this or
lelect 0:06d9443a018f 289 // draw over every pixel. (No effect if double-buffering is not enabled.)
lelect 0:06d9443a018f 290 void RGBmatrixPanel::swapBuffers(bool copy)
lelect 0:06d9443a018f 291 {
lelect 4:0ff6053c4bb2 292 log_debug("\r\ncall swapBuffers %s","\r\n");
lelect 0:06d9443a018f 293 if(matrixbuff[0] != matrixbuff[1]) {
lelect 0:06d9443a018f 294 // To avoid 'tearing' display, actual swap takes place in the interrupt
lelect 0:06d9443a018f 295 // handler, at the end of a complete screen refresh cycle.
lelect 0:06d9443a018f 296 swapflag = true; // Set flag here, then...
lelect 2:6136465ffd3a 297 while(swapflag == true) wait_ms(1); // wait for interrupt to clear it
lelect 3:aa3762e0dfee 298 if(copy == true) {
lelect 3:aa3762e0dfee 299 log_debug("\tmemcpy %s","\r\n");
lelect 0:06d9443a018f 300 memcpy(matrixbuff[backindex], matrixbuff[1-backindex], 32 * nRows * 3);
lelect 3:aa3762e0dfee 301 } else {
lelect 3:aa3762e0dfee 302 log_debug("\tnot memcpy %s","\r\n");
lelect 3:aa3762e0dfee 303 }
lelect 0:06d9443a018f 304 }
lelect 0:06d9443a018f 305 }
lelect 0:06d9443a018f 306
lelect 0:06d9443a018f 307 // Dump display contents to the Serial Monitor, adding some formatting to
lelect 0:06d9443a018f 308 // simplify copy-and-paste of data as a PROGMEM-embedded image for another
lelect 0:06d9443a018f 309 // sketch. If using multiple dumps this way, you'll need to edit the
lelect 0:06d9443a018f 310 // output to change the 'img' name for each. Data can then be loaded
lelect 0:06d9443a018f 311 // back into the display using a pgm_read_byte() loop.
lelect 0:06d9443a018f 312 void RGBmatrixPanel::dumpMatrix(void)
lelect 0:06d9443a018f 313 {
lelect 4:0ff6053c4bb2 314 #ifdef DEBUG
lelect 4:0ff6053c4bb2 315 log_debug("\r\ncall dumpMatrix%s","\r\n");
lelect 3:aa3762e0dfee 316 int buffsize=32*nRows*3;
lelect 3:aa3762e0dfee 317 for(int item=0; item<buffsize; item++) {
lelect 3:aa3762e0dfee 318 log_debug("0x%02X",matrixbuff[backindex][item]);
lelect 3:aa3762e0dfee 319 if((item%32)==31) log_debug(",\r\n");
lelect 3:aa3762e0dfee 320 else log_debug(",");
lelect 0:06d9443a018f 321 }
lelect 4:0ff6053c4bb2 322 log_debug("%s","\r\n\r\n");
lelect 4:0ff6053c4bb2 323 #endif
lelect 0:06d9443a018f 324
lelect 0:06d9443a018f 325 }
lelect 8:6d98c8cd8045 326 void RGBmatrixPanel::setBus(int value)
lelect 8:6d98c8cd8045 327 {
lelect 8:6d98c8cd8045 328 for (int i=0; i<6; i++) {
lelect 8:6d98c8cd8045 329 if (_pin[i] != 0) {
lelect 8:6d98c8cd8045 330 _pin[i]->write((value >> i) & 1);
lelect 8:6d98c8cd8045 331 }
lelect 8:6d98c8cd8045 332 }
lelect 8:6d98c8cd8045 333 }
lelect 8:6d98c8cd8045 334 int RGBmatrixPanel::readBus()
lelect 8:6d98c8cd8045 335 {
lelect 8:6d98c8cd8045 336 int v = 0;
lelect 8:6d98c8cd8045 337 for (int i=0; i<6; i++) {
lelect 8:6d98c8cd8045 338 if (_pin[i] != 0) {
lelect 8:6d98c8cd8045 339 v |= _pin[i]->read() << i;
lelect 8:6d98c8cd8045 340 }
lelect 8:6d98c8cd8045 341 }
lelect 8:6d98c8cd8045 342 return v;
lelect 8:6d98c8cd8045 343 }
lelect 0:06d9443a018f 344
lelect 0:06d9443a018f 345 void RGBmatrixPanel::updateDisplay(void)
lelect 0:06d9443a018f 346 {
lelect 5:1f8409ee8850 347 uint8_t *ptr;
lelect 4:0ff6053c4bb2 348 log_debug("\r\ncall updateDisplay\r\n");
lelect 3:aa3762e0dfee 349 _oe=1;
lelect 3:aa3762e0dfee 350 _latch=1;
lelect 3:aa3762e0dfee 351 if(++plane >= nPlanes) { // Advance plane counter. Maxed out?
lelect 0:06d9443a018f 352 plane = 0; // Yes, reset to plane 0, and
lelect 0:06d9443a018f 353 if(++row >= nRows) { // advance row counter. Maxed out?
lelect 3:aa3762e0dfee 354 row= 0; // Yes, reset row counter, then...
lelect 3:aa3762e0dfee 355 if(swapflag == true) { // Swap front/back buffers if requested
lelect 0:06d9443a018f 356 backindex = 1 - backindex;
lelect 3:aa3762e0dfee 357 log_debug("\t\treset swapflag%s","\r\n");
lelect 0:06d9443a018f 358 swapflag = false;
lelect 0:06d9443a018f 359 }
lelect 3:aa3762e0dfee 360 log_debug("\tReset into front buffer[%d]%s",backindex,"\r\n");
lelect 0:06d9443a018f 361 buffptr = matrixbuff[1-backindex]; // Reset into front buffer
lelect 0:06d9443a018f 362 }
lelect 0:06d9443a018f 363 } else if(plane == 1) {
lelect 4:0ff6053c4bb2 364 log_debug("\tupdate row%s","\r\n");
lelect 5:1f8409ee8850 365 _rowBus.write(row);
lelect 0:06d9443a018f 366 }
lelect 8:6d98c8cd8045 367 setBus(0);
lelect 3:aa3762e0dfee 368 _oe=0;
lelect 3:aa3762e0dfee 369 _latch=0;
lelect 5:1f8409ee8850 370 ptr = (uint8_t *)buffptr;
lelect 5:1f8409ee8850 371
lelect 4:0ff6053c4bb2 372 log_debug("\t(row@plane)=(%d,%d)\r\n",row,plane);
lelect 4:0ff6053c4bb2 373 int color;
lelect 4:0ff6053c4bb2 374 if(plane > 0) {
lelect 5:1f8409ee8850 375 //ptr[i]>>2
lelect 3:aa3762e0dfee 376 for(int i=0; i<32; i++) {
lelect 5:1f8409ee8850 377 color=*(ptr+i);
lelect 5:1f8409ee8850 378 color=(color>>2)&0x3F;
lelect 8:6d98c8cd8045 379 setBus(color);
lelect 3:aa3762e0dfee 380 _sclk=1;
lelect 3:aa3762e0dfee 381 _sclk=0;
lelect 8:6d98c8cd8045 382 #if 0
lelect 8:6d98c8cd8045 383 #ifdef DEBUG
lelect 8:6d98c8cd8045 384 if(int(readBus)==color) {
lelect 8:6d98c8cd8045 385 log_debug(" %02x",int(_dataBus));
lelect 8:6d98c8cd8045 386 } else {
lelect 8:6d98c8cd8045 387 _dataBus=color;
lelect 8:6d98c8cd8045 388 log_debug(" (%x->%x)%s",color,int(_dataBus),"\0");
lelect 8:6d98c8cd8045 389 }
lelect 8:6d98c8cd8045 390 #endif
lelect 8:6d98c8cd8045 391 #endif
lelect 8:6d98c8cd8045 392 }
lelect 8:6d98c8cd8045 393 buffptr += _rawWidth;
lelect 8:6d98c8cd8045 394 } else {
lelect 8:6d98c8cd8045 395 //((ptr[i]<<4)|((ptr[i+32]<<2)&0x0C)|((ptr[i+64])&0x03));
lelect 8:6d98c8cd8045 396 for(int i=0; i<32; i++) {
lelect 8:6d98c8cd8045 397 color=0x3F&((ptr[i]<<4)|((ptr[i+32]<<2)&0x0C)|((ptr[i+64])&0x03));
lelect 8:6d98c8cd8045 398 setBus(color);
lelect 8:6d98c8cd8045 399 _sclk=1;
lelect 8:6d98c8cd8045 400 _sclk=0;
lelect 8:6d98c8cd8045 401 #if 0
lelect 4:0ff6053c4bb2 402 #ifdef DEBUG
lelect 4:0ff6053c4bb2 403 if(int(_dataBus)==color) {
lelect 4:0ff6053c4bb2 404 log_debug(" %02x",int(_dataBus));
lelect 4:0ff6053c4bb2 405 } else {
lelect 4:0ff6053c4bb2 406 _dataBus=color;
lelect 4:0ff6053c4bb2 407 log_debug(" (%x->%x)%s",color,int(_dataBus),"\0");
lelect 4:0ff6053c4bb2 408 }
lelect 4:0ff6053c4bb2 409 #endif
lelect 4:0ff6053c4bb2 410 #endif
lelect 0:06d9443a018f 411 }
lelect 0:06d9443a018f 412 }
lelect 5:1f8409ee8850 413
lelect 0:06d9443a018f 414 }
lelect 4:0ff6053c4bb2 415